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.assertNotEquals;
24  import static org.junit.jupiter.api.Assertions.assertNotNull;
25  import static org.junit.jupiter.api.Assertions.assertTrue;
26  import static org.junit.jupiter.api.Assertions.fail;
27  
28  import java.io.IOException;
29  import java.nio.charset.StandardCharsets;
30  import java.util.List;
31  import java.util.Set;
32  import javax.ws.rs.core.Response;
33  import org.apache.commons.io.IOUtils;
34  import org.apache.commons.lang3.SerializationUtils;
35  import org.apache.syncope.common.lib.SyncopeClientException;
36  import org.apache.syncope.common.lib.policy.AccessPolicyTO;
37  import org.apache.syncope.common.lib.policy.AccountPolicyTO;
38  import org.apache.syncope.common.lib.policy.AttrReleasePolicyTO;
39  import org.apache.syncope.common.lib.policy.AuthPolicyTO;
40  import org.apache.syncope.common.lib.policy.DefaultAccessPolicyConf;
41  import org.apache.syncope.common.lib.policy.DefaultAccountRuleConf;
42  import org.apache.syncope.common.lib.policy.DefaultAttrReleasePolicyConf;
43  import org.apache.syncope.common.lib.policy.DefaultAuthPolicyConf;
44  import org.apache.syncope.common.lib.policy.DefaultPasswordRuleConf;
45  import org.apache.syncope.common.lib.policy.DefaultTicketExpirationPolicyConf;
46  import org.apache.syncope.common.lib.policy.PasswordPolicyTO;
47  import org.apache.syncope.common.lib.policy.PropagationPolicyTO;
48  import org.apache.syncope.common.lib.policy.PullPolicyTO;
49  import org.apache.syncope.common.lib.policy.PushPolicyTO;
50  import org.apache.syncope.common.lib.policy.TicketExpirationPolicyTO;
51  import org.apache.syncope.common.lib.to.ImplementationTO;
52  import org.apache.syncope.common.lib.types.AnyTypeKind;
53  import org.apache.syncope.common.lib.types.BackOffStrategy;
54  import org.apache.syncope.common.lib.types.IdMImplementationType;
55  import org.apache.syncope.common.lib.types.IdRepoImplementationType;
56  import org.apache.syncope.common.lib.types.ImplementationEngine;
57  import org.apache.syncope.common.lib.types.PolicyType;
58  import org.apache.syncope.common.rest.api.RESTHeaders;
59  import org.apache.syncope.core.provisioning.api.serialization.POJOHelper;
60  import org.apache.syncope.fit.AbstractITCase;
61  import org.apache.syncope.fit.core.reference.DummyPullCorrelationRule;
62  import org.apache.syncope.fit.core.reference.DummyPushCorrelationRule;
63  import org.junit.jupiter.api.Test;
64  
65  public class PolicyITCase extends AbstractITCase {
66  
67      private PullPolicyTO buildPullPolicyTO() throws IOException {
68          ImplementationTO corrRule = null;
69          try {
70              corrRule = IMPLEMENTATION_SERVICE.read(IdMImplementationType.PULL_CORRELATION_RULE, "TestPullRule");
71          } catch (SyncopeClientException e) {
72              if (e.getType().getResponseStatus() == Response.Status.NOT_FOUND) {
73                  corrRule = new ImplementationTO();
74                  corrRule.setKey("TestPullRule");
75                  corrRule.setEngine(ImplementationEngine.GROOVY);
76                  corrRule.setType(IdMImplementationType.PULL_CORRELATION_RULE);
77                  corrRule.setBody(IOUtils.toString(
78                          getClass().getResourceAsStream("/TestPullRule.groovy"), StandardCharsets.UTF_8));
79                  Response response = IMPLEMENTATION_SERVICE.create(corrRule);
80                  corrRule = IMPLEMENTATION_SERVICE.read(
81                          corrRule.getType(), response.getHeaderString(RESTHeaders.RESOURCE_KEY));
82                  assertNotNull(corrRule);
83              }
84          }
85          assertNotNull(corrRule);
86  
87          PullPolicyTO policy = new PullPolicyTO();
88          policy.getCorrelationRules().put(AnyTypeKind.USER.name(), corrRule.getKey());
89          policy.setName("Pull policy");
90  
91          return policy;
92      }
93  
94      private PushPolicyTO buildPushPolicyTO() throws IOException {
95          ImplementationTO corrRule = null;
96          try {
97              corrRule = IMPLEMENTATION_SERVICE.read(IdMImplementationType.PUSH_CORRELATION_RULE, "TestPushRule");
98          } catch (SyncopeClientException e) {
99              if (e.getType().getResponseStatus() == Response.Status.NOT_FOUND) {
100                 corrRule = new ImplementationTO();
101                 corrRule.setKey("TestPushRule");
102                 corrRule.setEngine(ImplementationEngine.GROOVY);
103                 corrRule.setType(IdMImplementationType.PUSH_CORRELATION_RULE);
104                 corrRule.setBody(IOUtils.toString(
105                         getClass().getResourceAsStream("/TestPushRule.groovy"), StandardCharsets.UTF_8));
106                 Response response = IMPLEMENTATION_SERVICE.create(corrRule);
107                 corrRule = IMPLEMENTATION_SERVICE.read(
108                         corrRule.getType(), response.getHeaderString(RESTHeaders.RESOURCE_KEY));
109                 assertNotNull(corrRule);
110             }
111         }
112         assertNotNull(corrRule);
113 
114         PushPolicyTO policy = new PushPolicyTO();
115         policy.getCorrelationRules().put(AnyTypeKind.USER.name(), corrRule.getKey());
116         policy.setName("Push policy");
117 
118         return policy;
119     }
120 
121     @Test
122     public void listByType() {
123         List<PropagationPolicyTO> propagationPolicies = POLICY_SERVICE.list(PolicyType.PROPAGATION);
124         assertNotNull(propagationPolicies);
125         assertFalse(propagationPolicies.isEmpty());
126 
127         List<PullPolicyTO> pullPolicies = POLICY_SERVICE.list(PolicyType.PULL);
128         assertNotNull(pullPolicies);
129         assertFalse(pullPolicies.isEmpty());
130     }
131 
132     @Test
133     public void getAccountPolicy() {
134         AccountPolicyTO policyTO = POLICY_SERVICE.read(PolicyType.ACCOUNT, "06e2ed52-6966-44aa-a177-a0ca7434201f");
135 
136         assertNotNull(policyTO);
137         assertTrue(policyTO.getUsedByResources().isEmpty());
138         assertTrue(policyTO.getUsedByRealms().contains("/odd"));
139     }
140 
141     @Test
142     public void getPasswordPolicy() {
143         PasswordPolicyTO policyTO = POLICY_SERVICE.read(PolicyType.PASSWORD, "986d1236-3ac5-4a19-810c-5ab21d79cba1");
144 
145         assertNotNull(policyTO);
146         assertTrue(policyTO.getUsedByResources().contains(RESOURCE_NAME_NOPROPAGATION));
147         assertTrue(policyTO.getUsedByRealms().containsAll(List.of("/", "/odd", "/even")));
148     }
149 
150     @Test
151     public void getPropagationPolicy() {
152         PropagationPolicyTO policyTO =
153                 POLICY_SERVICE.read(PolicyType.PROPAGATION, "89d322db-9878-420c-b49c-67be13df9a12");
154 
155         assertNotNull(policyTO);
156         assertTrue(policyTO.getUsedByResources().contains(RESOURCE_NAME_DBSCRIPTED));
157         assertTrue(policyTO.getUsedByRealms().isEmpty());
158     }
159 
160     @Test
161     public void getPullPolicy() {
162         PullPolicyTO policyTO = POLICY_SERVICE.read(PolicyType.PULL, "66691e96-285f-4464-bc19-e68384ea4c85");
163 
164         assertNotNull(policyTO);
165         assertTrue(policyTO.getUsedByRealms().isEmpty());
166     }
167 
168     @Test
169     public void getAuthPolicy() {
170         AuthPolicyTO policyTO = POLICY_SERVICE.read(PolicyType.AUTH, "659b9906-4b6e-4bc0-aca0-6809dff346d4");
171 
172         assertNotNull(policyTO);
173         assertTrue(policyTO.getUsedByRealms().isEmpty());
174     }
175 
176     @Test
177     public void getAccessPolicy() {
178         AccessPolicyTO policyTO = POLICY_SERVICE.read(PolicyType.ACCESS, "419935c7-deb3-40b3-8a9a-683037e523a2");
179 
180         assertNotNull(policyTO);
181         assertTrue(policyTO.getUsedByRealms().isEmpty());
182     }
183 
184     @Test
185     public void getAttributeReleasePolicy() {
186         AttrReleasePolicyTO policyTO =
187                 POLICY_SERVICE.read(PolicyType.ATTR_RELEASE, "319935c7-deb3-40b3-8a9a-683037e523a2");
188 
189         assertNotNull(policyTO);
190         assertTrue(policyTO.getUsedByRealms().isEmpty());
191     }
192 
193     @Test
194     public void create() throws IOException {
195         PropagationPolicyTO propagationPolicyTO = new PropagationPolicyTO();
196         propagationPolicyTO.setName("propagation policy name");
197         propagationPolicyTO.setBackOffStrategy(BackOffStrategy.EXPONENTIAL);
198         propagationPolicyTO = createPolicy(PolicyType.PROPAGATION, propagationPolicyTO);
199         assertNotNull(propagationPolicyTO);
200         assertEquals(3, propagationPolicyTO.getMaxAttempts());
201         assertEquals(BackOffStrategy.EXPONENTIAL.getDefaultBackOffParams(), propagationPolicyTO.getBackOffParams());
202 
203         PullPolicyTO pullPolicyTO = createPolicy(PolicyType.PULL, buildPullPolicyTO());
204         assertNotNull(pullPolicyTO);
205         assertEquals("TestPullRule", pullPolicyTO.getCorrelationRules().get(AnyTypeKind.USER.name()));
206 
207         PushPolicyTO pushPolicyTO = createPolicy(PolicyType.PUSH, buildPushPolicyTO());
208         assertNotNull(pushPolicyTO);
209         assertEquals("TestPushRule", pushPolicyTO.getCorrelationRules().get(AnyTypeKind.USER.name()));
210 
211         AuthPolicyTO authPolicyTO = createPolicy(PolicyType.AUTH, buildAuthPolicyTO("LdapAuthentication1"));
212         assertNotNull(authPolicyTO);
213         assertEquals("Test Authentication policy", authPolicyTO.getName());
214 
215         AccessPolicyTO accessPolicyTO = createPolicy(PolicyType.ACCESS, buildAccessPolicyTO());
216         assertNotNull(accessPolicyTO);
217         assertEquals("Test Access policy", accessPolicyTO.getName());
218 
219         AttrReleasePolicyTO attrReleasePolicyTO = createPolicy(PolicyType.ATTR_RELEASE, buildAttrReleasePolicyTO());
220         assertNotNull(attrReleasePolicyTO);
221         assertEquals("Test Attribute Release policy", attrReleasePolicyTO.getName());
222 
223         TicketExpirationPolicyTO ticketExpirationPolicyTO =
224                 createPolicy(PolicyType.TICKET_EXPIRATION, buildTicketExpirationPolicyTO());
225         assertNotNull(ticketExpirationPolicyTO);
226         assertEquals("Test Ticket Expiration policy", ticketExpirationPolicyTO.getName());
227     }
228 
229     @Test
230     public void updatePasswordPolicy() {
231         PasswordPolicyTO globalPolicy = POLICY_SERVICE.read(
232                 PolicyType.PASSWORD, "ce93fcda-dc3a-4369-a7b0-a6108c261c85");
233 
234         PasswordPolicyTO policy = SerializationUtils.clone(globalPolicy);
235         policy.setName("A simple password policy");
236 
237         // create a new password policy using the former as a template
238         policy = createPolicy(PolicyType.PASSWORD, policy);
239         assertNotNull(policy);
240         assertNotEquals("ce93fcda-dc3a-4369-a7b0-a6108c261c85", policy.getKey());
241 
242         ImplementationTO rule = IMPLEMENTATION_SERVICE.read(
243                 IdRepoImplementationType.PASSWORD_RULE, policy.getRules().get(0));
244         assertNotNull(rule);
245 
246         DefaultPasswordRuleConf ruleConf = POJOHelper.deserialize(rule.getBody(), DefaultPasswordRuleConf.class);
247         ruleConf.setMaxLength(22);
248         rule.setBody(POJOHelper.serialize(ruleConf));
249 
250         // update new password policy
251         POLICY_SERVICE.update(PolicyType.PASSWORD, policy);
252         policy = POLICY_SERVICE.read(PolicyType.PASSWORD, policy.getKey());
253         assertNotNull(policy);
254 
255         ruleConf = POJOHelper.deserialize(rule.getBody(), DefaultPasswordRuleConf.class);
256         assertEquals(22, ruleConf.getMaxLength());
257         assertEquals(8, ruleConf.getMinLength());
258     }
259 
260     @Test
261     public void updateAuthPolicy() {
262         AuthPolicyTO newAuthPolicyTO = buildAuthPolicyTO("LdapAuthentication1");
263         assertNotNull(newAuthPolicyTO);
264         newAuthPolicyTO = createPolicy(PolicyType.AUTH, newAuthPolicyTO);
265 
266         DefaultAuthPolicyConf authPolicyConf = (DefaultAuthPolicyConf) newAuthPolicyTO.getConf();
267         authPolicyConf.getAuthModules().add("LdapAuthentication");
268 
269         // update new authentication policy
270         POLICY_SERVICE.update(PolicyType.AUTH, newAuthPolicyTO);
271         newAuthPolicyTO = POLICY_SERVICE.read(PolicyType.AUTH, newAuthPolicyTO.getKey());
272         assertNotNull(newAuthPolicyTO);
273 
274         authPolicyConf = (DefaultAuthPolicyConf) newAuthPolicyTO.getConf();
275         assertNotNull(authPolicyConf);
276         assertEquals(2, authPolicyConf.getAuthModules().size());
277         assertTrue(authPolicyConf.getAuthModules().contains("LdapAuthentication"));
278     }
279 
280     @Test
281     public void updateAccessPolicy() {
282         AccessPolicyTO newAccessPolicyTO = createPolicy(PolicyType.ACCESS, buildAccessPolicyTO());
283         assertNotNull(newAccessPolicyTO);
284 
285         DefaultAccessPolicyConf accessPolicyConf = (DefaultAccessPolicyConf) newAccessPolicyTO.getConf();
286         accessPolicyConf.getRequiredAttrs().put("ou", "test");
287         accessPolicyConf.getRequiredAttrs().remove("cn");
288         accessPolicyConf.getRequiredAttrs().put("cn", "admin,Admin");
289 
290         // update new authentication policy
291         POLICY_SERVICE.update(PolicyType.ACCESS, newAccessPolicyTO);
292         newAccessPolicyTO = POLICY_SERVICE.read(PolicyType.ACCESS, newAccessPolicyTO.getKey());
293         assertNotNull(newAccessPolicyTO);
294 
295         accessPolicyConf = (DefaultAccessPolicyConf) newAccessPolicyTO.getConf();
296         assertEquals(2, accessPolicyConf.getRequiredAttrs().size());
297         assertTrue(accessPolicyConf.getRequiredAttrs().containsKey("cn"));
298         assertTrue(accessPolicyConf.getRequiredAttrs().containsKey("ou"));
299     }
300 
301     @Test
302     public void updateAttrReleasePolicy() {
303         AttrReleasePolicyTO newPolicyTO = createPolicy(PolicyType.ATTR_RELEASE, buildAttrReleasePolicyTO());
304         assertNotNull(newPolicyTO);
305 
306         DefaultAttrReleasePolicyConf policyConf = (DefaultAttrReleasePolicyConf) newPolicyTO.getConf();
307         policyConf.getAllowedAttrs().add("postalCode");
308 
309         // update new policy
310         POLICY_SERVICE.update(PolicyType.ATTR_RELEASE, newPolicyTO);
311         newPolicyTO = POLICY_SERVICE.read(PolicyType.ATTR_RELEASE, newPolicyTO.getKey());
312         assertNotNull(newPolicyTO);
313 
314         policyConf = (DefaultAttrReleasePolicyConf) newPolicyTO.getConf();
315         assertEquals(3, policyConf.getAllowedAttrs().size());
316         assertTrue(policyConf.getAllowedAttrs().contains("cn"));
317         assertTrue(policyConf.getAllowedAttrs().contains("postalCode"));
318         assertTrue(policyConf.getAllowedAttrs().contains("givenName"));
319         assertTrue(policyConf.getIncludeOnlyAttrs().contains("cn"));
320     }
321 
322     @Test
323     public void updateTicketExpirationPolicy() {
324         TicketExpirationPolicyTO newPolicyTO =
325                 createPolicy(PolicyType.TICKET_EXPIRATION, buildTicketExpirationPolicyTO());
326         assertNotNull(newPolicyTO);
327 
328         DefaultTicketExpirationPolicyConf policyConf = (DefaultTicketExpirationPolicyConf) newPolicyTO.getConf();
329         policyConf.getStConf().setNumberOfUses(2);
330 
331         // update new policy
332         POLICY_SERVICE.update(PolicyType.TICKET_EXPIRATION, newPolicyTO);
333         newPolicyTO = POLICY_SERVICE.read(PolicyType.TICKET_EXPIRATION, newPolicyTO.getKey());
334         assertNotNull(newPolicyTO);
335 
336         policyConf = (DefaultTicketExpirationPolicyConf) newPolicyTO.getConf();
337         assertEquals(2, policyConf.getStConf().getNumberOfUses());
338     }
339 
340     @Test
341     public void delete() throws IOException {
342         PullPolicyTO policy = buildPullPolicyTO();
343 
344         PullPolicyTO policyTO = createPolicy(PolicyType.PULL, policy);
345         assertNotNull(policyTO);
346 
347         POLICY_SERVICE.delete(PolicyType.PULL, policyTO.getKey());
348 
349         try {
350             POLICY_SERVICE.read(PolicyType.PULL, policyTO.getKey());
351             fail("This should not happen");
352         } catch (SyncopeClientException e) {
353             assertNotNull(e);
354         }
355 
356         AuthPolicyTO authPolicy = buildAuthPolicyTO("LdapAuthentication1");
357 
358         AuthPolicyTO authPolicyTO = createPolicy(PolicyType.AUTH, authPolicy);
359         assertNotNull(authPolicyTO);
360 
361         POLICY_SERVICE.delete(PolicyType.AUTH, authPolicyTO.getKey());
362 
363         try {
364             POLICY_SERVICE.read(PolicyType.AUTH, authPolicyTO.getKey());
365             fail("This should not happen");
366         } catch (SyncopeClientException e) {
367             assertNotNull(e);
368         }
369 
370         AccessPolicyTO accessPolicyTO = createPolicy(PolicyType.ACCESS, buildAccessPolicyTO());
371         assertNotNull(accessPolicyTO);
372 
373         POLICY_SERVICE.delete(PolicyType.ACCESS, accessPolicyTO.getKey());
374 
375         try {
376             POLICY_SERVICE.read(PolicyType.ACCESS, accessPolicyTO.getKey());
377             fail("This should not happen");
378         } catch (SyncopeClientException e) {
379             assertNotNull(e);
380         }
381 
382         AttrReleasePolicyTO attrReleasePolicyTO = createPolicy(PolicyType.ATTR_RELEASE, buildAttrReleasePolicyTO());
383         assertNotNull(attrReleasePolicyTO);
384 
385         POLICY_SERVICE.delete(PolicyType.ATTR_RELEASE, attrReleasePolicyTO.getKey());
386 
387         try {
388             POLICY_SERVICE.read(PolicyType.ATTR_RELEASE, attrReleasePolicyTO.getKey());
389             fail("This should not happen");
390         } catch (SyncopeClientException e) {
391             assertNotNull(e);
392         }
393 
394         TicketExpirationPolicyTO ticketExpirationPolicyTO =
395                 createPolicy(PolicyType.TICKET_EXPIRATION, buildTicketExpirationPolicyTO());
396         assertNotNull(ticketExpirationPolicyTO);
397 
398         POLICY_SERVICE.delete(PolicyType.TICKET_EXPIRATION, ticketExpirationPolicyTO.getKey());
399 
400         try {
401             POLICY_SERVICE.read(PolicyType.TICKET_EXPIRATION, ticketExpirationPolicyTO.getKey());
402             fail("This should not happen");
403         } catch (SyncopeClientException e) {
404             assertNotNull(e);
405         }
406     }
407 
408     @Test
409     public void getPullCorrelationRuleJavaClasses() {
410         Set<String> classes = ANONYMOUS_CLIENT.platform().
411                 getJavaImplInfo(IdMImplementationType.PULL_CORRELATION_RULE).get().getClasses();
412         assertEquals(1, classes.size());
413         assertEquals(DummyPullCorrelationRule.class.getName(), classes.iterator().next());
414     }
415 
416     @Test
417     public void getPushCorrelationRuleJavaClasses() {
418         Set<String> classes = ANONYMOUS_CLIENT.platform().
419                 getJavaImplInfo(IdMImplementationType.PUSH_CORRELATION_RULE).get().getClasses();
420         assertEquals(1, classes.size());
421         assertEquals(DummyPushCorrelationRule.class.getName(), classes.iterator().next());
422     }
423 
424     @Test
425     public void issueSYNCOPE553() {
426         AccountPolicyTO policy = new AccountPolicyTO();
427         policy.setName("SYNCOPE553");
428 
429         DefaultAccountRuleConf ruleConf = new DefaultAccountRuleConf();
430         ruleConf.setMinLength(3);
431         ruleConf.setMaxLength(8);
432 
433         ImplementationTO rule = new ImplementationTO();
434         rule.setKey("DefaultAccountRuleConf" + getUUIDString());
435         rule.setEngine(ImplementationEngine.JAVA);
436         rule.setType(IdRepoImplementationType.ACCOUNT_RULE);
437         rule.setBody(POJOHelper.serialize(ruleConf));
438         Response response = IMPLEMENTATION_SERVICE.create(rule);
439         rule.setKey(response.getHeaderString(RESTHeaders.RESOURCE_KEY));
440 
441         policy.getRules().add(rule.getKey());
442 
443         policy = createPolicy(PolicyType.ACCOUNT, policy);
444         assertNotNull(policy);
445     }
446 
447     @Test
448     public void issueSYNCOPE682() {
449         AccountPolicyTO policy = new AccountPolicyTO();
450         policy.setName("SYNCOPE682");
451         policy.getPassthroughResources().add(RESOURCE_NAME_LDAP);
452 
453         DefaultAccountRuleConf ruleConf = new DefaultAccountRuleConf();
454         ruleConf.setMinLength(3);
455         ruleConf.setMaxLength(8);
456 
457         ImplementationTO rule = new ImplementationTO();
458         rule.setKey("DefaultAccountRuleConf" + getUUIDString());
459         rule.setEngine(ImplementationEngine.JAVA);
460         rule.setType(IdRepoImplementationType.ACCOUNT_RULE);
461         rule.setBody(POJOHelper.serialize(ruleConf));
462         Response response = IMPLEMENTATION_SERVICE.create(rule);
463         rule.setKey(response.getHeaderString(RESTHeaders.RESOURCE_KEY));
464 
465         policy.getRules().add(rule.getKey());
466 
467         policy = createPolicy(PolicyType.ACCOUNT, policy);
468         assertNotNull(policy);
469     }
470 }