View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.syncope.fit.core;
20  
21  import static org.junit.jupiter.api.Assertions.assertEquals;
22  import static org.junit.jupiter.api.Assertions.assertFalse;
23  import static org.junit.jupiter.api.Assertions.assertNotNull;
24  import static org.junit.jupiter.api.Assertions.assertNull;
25  import static org.junit.jupiter.api.Assertions.assertTrue;
26  import static org.junit.jupiter.api.Assertions.fail;
27  
28  import java.util.List;
29  import java.util.UUID;
30  import javax.ws.rs.NotFoundException;
31  import javax.ws.rs.core.GenericType;
32  import javax.ws.rs.core.Response;
33  import org.apache.syncope.common.lib.SyncopeClientException;
34  import org.apache.syncope.common.lib.SyncopeConstants;
35  import org.apache.syncope.common.lib.policy.AccessPolicyTO;
36  import org.apache.syncope.common.lib.policy.AccountPolicyTO;
37  import org.apache.syncope.common.lib.policy.AttrReleasePolicyTO;
38  import org.apache.syncope.common.lib.policy.AuthPolicyTO;
39  import org.apache.syncope.common.lib.policy.DefaultAccessPolicyConf;
40  import org.apache.syncope.common.lib.policy.DefaultAccountRuleConf;
41  import org.apache.syncope.common.lib.policy.DefaultAttrReleasePolicyConf;
42  import org.apache.syncope.common.lib.policy.DefaultAuthPolicyConf;
43  import org.apache.syncope.common.lib.to.ImplementationTO;
44  import org.apache.syncope.common.lib.to.PagedResult;
45  import org.apache.syncope.common.lib.to.ProvisioningResult;
46  import org.apache.syncope.common.lib.to.RealmTO;
47  import org.apache.syncope.common.lib.types.ClientExceptionType;
48  import org.apache.syncope.common.lib.types.ExecStatus;
49  import org.apache.syncope.common.lib.types.IdRepoImplementationType;
50  import org.apache.syncope.common.lib.types.ImplementationEngine;
51  import org.apache.syncope.common.lib.types.PolicyType;
52  import org.apache.syncope.common.rest.api.RESTHeaders;
53  import org.apache.syncope.common.rest.api.beans.RealmQuery;
54  import org.apache.syncope.core.provisioning.api.serialization.POJOHelper;
55  import org.apache.syncope.fit.AbstractITCase;
56  import org.junit.jupiter.api.Test;
57  
58  public class RealmITCase extends AbstractITCase {
59  
60      @Test
61      public void search() {
62          PagedResult<RealmTO> match = REALM_SERVICE.search(new RealmQuery.Builder().keyword("*o*").build());
63          assertTrue(match.getResult().stream().allMatch(realm -> realm.getName().contains("o")));
64      }
65  
66      @Test
67      public void createUpdate() {
68          RealmTO realm = new RealmTO();
69          realm.setName("last");
70  
71          // 1. create
72          Response response = REALM_SERVICE.create("/even/two", realm);
73          RealmTO actual = getRealm(response.getHeaderString(RESTHeaders.RESOURCE_KEY)).
74                  orElseThrow(() -> new NotFoundException());
75          assertNotNull(actual.getKey());
76          assertEquals("last", actual.getName());
77          assertEquals("/even/two/last", actual.getFullPath());
78          assertEquals(actual.getParent(), getRealm("/even/two").get().getKey());
79          assertNull(realm.getAccountPolicy());
80          assertNull(realm.getPasswordPolicy());
81  
82          // 2. update setting policies
83          actual.setAccountPolicy("06e2ed52-6966-44aa-a177-a0ca7434201f");
84          actual.setPasswordPolicy("986d1236-3ac5-4a19-810c-5ab21d79cba1");
85          actual.setAuthPolicy("b912a0d4-a890-416f-9ab8-84ab077eb028");
86          actual.setAccessPolicy("419935c7-deb3-40b3-8a9a-683037e523a2");
87          actual.setAttrReleasePolicy("319935c7-deb3-40b3-8a9a-683037e523a2");
88          REALM_SERVICE.update(actual);
89  
90          actual = getRealm(actual.getFullPath()).get();
91          assertNotNull(actual.getAccountPolicy());
92          assertNotNull(actual.getPasswordPolicy());
93          assertNotNull(actual.getAuthPolicy());
94          assertNotNull(actual.getAccessPolicy());
95          assertNotNull(actual.getAttrReleasePolicy());
96  
97          // 3. update changing parent
98          actual.setParent(getRealm("/odd").get().getKey());
99          REALM_SERVICE.update(actual);
100 
101         actual = getRealm("/odd/last").get();
102         assertNotNull(actual);
103         assertEquals("/odd/last", actual.getFullPath());
104 
105         assertEquals(1, REALM_SERVICE.search(new RealmQuery.Builder().base(SyncopeConstants.ROOT_REALM).build()).
106                 getResult().stream().filter(r -> realm.getName().equals(r.getName())).count());
107 
108         // 4. create under invalid path
109         try {
110             REALM_SERVICE.create("a name", realm);
111             fail("This should not happen");
112         } catch (SyncopeClientException e) {
113             assertEquals(ClientExceptionType.InvalidPath, e.getType());
114         }
115 
116         // 5. attempt to create duplicate
117         try {
118             REALM_SERVICE.create("/odd", realm);
119             fail("This should not happen");
120         } catch (SyncopeClientException e) {
121             assertEquals(ClientExceptionType.EntityExists, e.getType());
122         }
123     }
124 
125     @Test
126     public void createWithTilde() {
127         RealmTO realm = new RealmTO();
128         realm.setName("73~1~19534");
129 
130         Response response = REALM_SERVICE.create("/even/two", realm);
131         assertEquals(Response.Status.CREATED.getStatusCode(), response.getStatus());
132 
133         List<RealmTO> realms = REALM_SERVICE.search(new RealmQuery.Builder().
134                 base("/even/two/73~1~19534").build()).getResult();
135         assertEquals(1, realms.size());
136         assertEquals(realm.getName(), realms.get(0).getName());
137     }
138 
139     @Test
140     public void deletingAccountPolicy() {
141         // 1. create account policy
142         DefaultAccountRuleConf ruleConf = new DefaultAccountRuleConf();
143         ruleConf.setMinLength(3);
144         ruleConf.setMaxLength(8);
145 
146         ImplementationTO rule = new ImplementationTO();
147         rule.setKey("DefaultAccountRuleConf" + UUID.randomUUID().toString());
148         rule.setEngine(ImplementationEngine.JAVA);
149         rule.setType(IdRepoImplementationType.ACCOUNT_RULE);
150         rule.setBody(POJOHelper.serialize(ruleConf));
151         Response response = IMPLEMENTATION_SERVICE.create(rule);
152         rule.setKey(response.getHeaderString(RESTHeaders.RESOURCE_KEY));
153 
154         AccountPolicyTO policy = new AccountPolicyTO();
155         policy.setName("deletingAccountPolicy");
156         policy.getRules().add(rule.getKey());
157 
158         policy = createPolicy(PolicyType.ACCOUNT, policy);
159         assertNotNull(policy);
160 
161         // 2. create realm with policy assigned
162         RealmTO realm = new RealmTO();
163         realm.setName("withPolicy");
164 
165         response = REALM_SERVICE.create(SyncopeConstants.ROOT_REALM, realm);
166         realm = getRealm(response.getHeaderString(RESTHeaders.RESOURCE_KEY)).
167                 orElseThrow(() -> new NotFoundException());
168 
169         String existingAccountPolicy = realm.getAccountPolicy();
170 
171         realm.setAccountPolicy(policy.getKey());
172         REALM_SERVICE.update(realm);
173 
174         RealmTO actual = getRealm(response.getHeaderString(RESTHeaders.RESOURCE_KEY)).
175                 orElseThrow(() -> new NotFoundException());
176         assertEquals(policy.getKey(), actual.getAccountPolicy());
177 
178         // 3. remove policy
179         POLICY_SERVICE.delete(PolicyType.ACCOUNT, policy.getKey());
180 
181         // 4. verify
182         actual = getRealm(actual.getFullPath()).get();
183         assertEquals(existingAccountPolicy, actual.getAccountPolicy());
184     }
185 
186     @Test
187     public void deletingAuthPolicy() {
188         // 1. create authentication policy
189         DefaultAuthPolicyConf ruleConf = new DefaultAuthPolicyConf();
190         ruleConf.getAuthModules().addAll(List.of("LdapAuthentication1"));
191 
192         AuthPolicyTO policy = new AuthPolicyTO();
193         policy.setName("Test Authentication policy");
194         policy.setConf(ruleConf);
195         policy = createPolicy(PolicyType.AUTH, policy);
196         assertNotNull(policy);
197 
198         // 2. create realm with policy assigned
199         RealmTO realm = new RealmTO();
200         realm.setName("withAuthPolicy");
201 
202         Response response = REALM_SERVICE.create(SyncopeConstants.ROOT_REALM, realm);
203         realm = getRealm(response.getHeaderString(RESTHeaders.RESOURCE_KEY)).
204                 orElseThrow(() -> new NotFoundException());
205 
206         String existingAuthPolicy = realm.getAuthPolicy();
207 
208         realm.setAuthPolicy(policy.getKey());
209         REALM_SERVICE.update(realm);
210 
211         RealmTO actual = getRealm(response.getHeaderString(RESTHeaders.RESOURCE_KEY)).
212                 orElseThrow(() -> new NotFoundException());
213         assertEquals(policy.getKey(), actual.getAuthPolicy());
214 
215         // 3. remove policy
216         POLICY_SERVICE.delete(PolicyType.AUTH, policy.getKey());
217 
218         // 4. verify
219         actual = getRealm(actual.getFullPath()).get();
220         assertEquals(existingAuthPolicy, actual.getAuthPolicy());
221     }
222 
223     @Test
224     public void deletingAccessPolicy() {
225         // 1. create access policy
226         DefaultAccessPolicyConf conf = new DefaultAccessPolicyConf();
227         conf.getRequiredAttrs().put("cn", "admin,Admin,TheAdmin");
228 
229         AccessPolicyTO policy = new AccessPolicyTO();
230         policy.setName("Test Access policy");
231         policy.setConf(conf);
232         policy = createPolicy(PolicyType.ACCESS, policy);
233         assertNotNull(policy);
234 
235         // 2. create realm with policy assigned
236         RealmTO realm = new RealmTO();
237         realm.setName("withAccessPolicy");
238 
239         Response response = REALM_SERVICE.create(SyncopeConstants.ROOT_REALM, realm);
240         realm = getRealm(response.getHeaderString(RESTHeaders.RESOURCE_KEY)).
241                 orElseThrow(() -> new NotFoundException());
242 
243         String existingAccessPolicy = realm.getAccessPolicy();
244 
245         realm.setAccessPolicy(policy.getKey());
246         REALM_SERVICE.update(realm);
247 
248         RealmTO actual = getRealm(response.getHeaderString(RESTHeaders.RESOURCE_KEY)).
249                 orElseThrow(() -> new NotFoundException());
250         assertEquals(policy.getKey(), actual.getAccessPolicy());
251 
252         // 3. remove policy
253         POLICY_SERVICE.delete(PolicyType.ACCESS, policy.getKey());
254 
255         // 4. verify
256         actual = getRealm(actual.getFullPath()).get();
257         assertEquals(existingAccessPolicy, actual.getAccessPolicy());
258     }
259 
260     @Test
261     public void deletingAttributeReleasePolicy() {
262         // 1. create attribute release policy
263         DefaultAttrReleasePolicyConf conf = new DefaultAttrReleasePolicyConf();
264         conf.getAllowedAttrs().addAll(List.of("cn", "givenName"));
265         conf.getIncludeOnlyAttrs().add("cn");
266 
267         AttrReleasePolicyTO policy = new AttrReleasePolicyTO();
268         policy.setName("Test Attribute Release policy");
269         policy.setConf(conf);
270         policy = createPolicy(PolicyType.ATTR_RELEASE, policy);
271         assertNotNull(policy);
272 
273         // 2. create realm with policy assigned
274         RealmTO realm = new RealmTO();
275         realm.setName("withAttrReleasePolicy");
276 
277         Response response = REALM_SERVICE.create(SyncopeConstants.ROOT_REALM, realm);
278         realm = getRealm(response.getHeaderString(RESTHeaders.RESOURCE_KEY)).
279                 orElseThrow(() -> new NotFoundException());
280 
281         String existingAttrReleasePolicy = realm.getAttrReleasePolicy();
282 
283         realm.setAttrReleasePolicy(policy.getKey());
284         REALM_SERVICE.update(realm);
285 
286         RealmTO actual = getRealm(response.getHeaderString(RESTHeaders.RESOURCE_KEY)).
287                 orElseThrow(() -> new NotFoundException());
288         assertEquals(policy.getKey(), actual.getAttrReleasePolicy());
289 
290         // 3. remove policy
291         POLICY_SERVICE.delete(PolicyType.ATTR_RELEASE, policy.getKey());
292 
293         // 4. verify
294         actual = getRealm(actual.getFullPath()).get();
295         assertEquals(existingAttrReleasePolicy, actual.getAttrReleasePolicy());
296     }
297 
298     @Test
299     public void delete() {
300         RealmTO realm = new RealmTO();
301         realm.setName("deletable3");
302 
303         Response response = REALM_SERVICE.create("/even/two", realm);
304         RealmTO actual = getRealm(response.getHeaderString(RESTHeaders.RESOURCE_KEY)).
305                 orElseThrow(() -> new NotFoundException());
306 
307         REALM_SERVICE.delete(actual.getFullPath());
308 
309         try {
310             REALM_SERVICE.search(new RealmQuery.Builder().base(actual.getFullPath()).build());
311             fail("This should not happen");
312         } catch (SyncopeClientException e) {
313             assertEquals(ClientExceptionType.NotFound, e.getType());
314         }
315     }
316 
317     @Test
318     public void deleteNonEmpty() {
319         try {
320             REALM_SERVICE.delete("/even/two");
321             fail("This should not happen");
322         } catch (SyncopeClientException e) {
323             assertEquals(ClientExceptionType.RealmContains, e.getType());
324         }
325     }
326 
327     @Test
328     public void propagate() {
329         // 1. create realm and add the LDAP resource
330         RealmTO realm = new RealmTO();
331         realm.setName("test");
332         realm.getResources().add(RESOURCE_NAME_LDAP_ORGUNIT);
333         RealmTO childRealm = new RealmTO();
334         childRealm.setName("child");
335         childRealm.getResources().add(RESOURCE_NAME_LDAP_ORGUNIT);
336         RealmTO descendantRealm = new RealmTO();
337         descendantRealm.setName("test");
338         descendantRealm.getResources().add(RESOURCE_NAME_LDAP_ORGUNIT);
339 
340         // 2. check propagation
341         ProvisioningResult<RealmTO> result = REALM_SERVICE.create("/", realm).readEntity(new GenericType<>() {
342         });
343         assertNotNull(result);
344         assertEquals(1, result.getPropagationStatuses().size());
345         assertEquals(RESOURCE_NAME_LDAP_ORGUNIT, result.getPropagationStatuses().get(0).getResource());
346         assertEquals(ExecStatus.SUCCESS, result.getPropagationStatuses().get(0).getStatus());
347 
348         ProvisioningResult<RealmTO> resultChild = REALM_SERVICE.create("/test", childRealm).readEntity(
349                 new GenericType<>() {
350         });
351         assertNotNull(resultChild);
352         assertEquals(1, resultChild.getPropagationStatuses().size());
353         assertEquals(RESOURCE_NAME_LDAP_ORGUNIT, resultChild.getPropagationStatuses().get(0).getResource());
354         assertEquals(ExecStatus.SUCCESS, resultChild.getPropagationStatuses().get(0).getStatus());
355 
356         ProvisioningResult<RealmTO> resultDescendant = REALM_SERVICE.create("/test/child", descendantRealm).readEntity(
357                 new GenericType<>() {
358         });
359         assertNotNull(resultDescendant);
360         assertEquals(1, resultDescendant.getPropagationStatuses().size());
361         assertEquals(RESOURCE_NAME_LDAP_ORGUNIT, resultDescendant.getPropagationStatuses().get(0).getResource());
362         assertEquals(ExecStatus.SUCCESS, resultDescendant.getPropagationStatuses().get(0).getStatus());
363 
364         // 3. check on LDAP
365         assertNotNull(
366                 getLdapRemoteObject(RESOURCE_LDAP_ADMIN_DN, RESOURCE_LDAP_ADMIN_PWD, "ou=test,o=isp"));
367         assertNotNull(
368                 getLdapRemoteObject(RESOURCE_LDAP_ADMIN_DN, RESOURCE_LDAP_ADMIN_PWD, "ou=child,ou=test,o=isp"));
369         assertNotNull(
370                 getLdapRemoteObject(RESOURCE_LDAP_ADMIN_DN, RESOURCE_LDAP_ADMIN_PWD, "ou=test,ou=child,ou=test,o=isp"));
371 
372         // 4. remove realms
373         REALM_SERVICE.delete("/test/child/test");
374         REALM_SERVICE.delete("/test/child");
375         REALM_SERVICE.delete("/test");
376 
377         // 5. check on LDAP: both realms should be deleted
378         assertNull(
379                 getLdapRemoteObject(RESOURCE_LDAP_ADMIN_DN, RESOURCE_LDAP_ADMIN_PWD, "ou=test,ou=child,ou=test,o=isp"));
380         assertNull(
381                 getLdapRemoteObject(RESOURCE_LDAP_ADMIN_DN, RESOURCE_LDAP_ADMIN_PWD, "ou=child,ou=test,o=isp"));
382         assertNull(
383                 getLdapRemoteObject(RESOURCE_LDAP_ADMIN_DN, RESOURCE_LDAP_ADMIN_PWD, "ou=test,o=isp"));
384     }
385 
386     @Test
387     public void issueSYNCOPE1472() {
388         // 1. assign twice resource-ldap-orgunit to /odd
389         RealmTO realmTO = REALM_SERVICE.search(new RealmQuery.Builder().base("/odd").build()).getResult().get(0);
390         realmTO.getResources().clear();
391         realmTO.getResources().add("resource-ldap-orgunit");
392         realmTO.getResources().add("resource-ldap-orgunit");
393         realmTO = REALM_SERVICE.update(realmTO).readEntity(new GenericType<ProvisioningResult<RealmTO>>() {
394         }).getEntity();
395 
396         // 2. remove resource-ldap-orgunit resource
397         realmTO.getResources().remove("resource-ldap-orgunit");
398 
399         realmTO = REALM_SERVICE.update(realmTO).readEntity(new GenericType<ProvisioningResult<RealmTO>>() {
400         }).getEntity();
401 
402         assertFalse(realmTO.getResources().contains("resource-ldap-orgunit"), "Should not contain removed resources");
403     }
404 }