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.core.provisioning.java.data;
20  
21  import java.util.stream.Collectors;
22  import org.apache.syncope.common.lib.policy.AccessPolicyTO;
23  import org.apache.syncope.common.lib.policy.AccountPolicyTO;
24  import org.apache.syncope.common.lib.policy.AttrReleasePolicyTO;
25  import org.apache.syncope.common.lib.policy.AuthPolicyTO;
26  import org.apache.syncope.common.lib.policy.PasswordPolicyTO;
27  import org.apache.syncope.common.lib.policy.PolicyTO;
28  import org.apache.syncope.common.lib.policy.PropagationPolicyTO;
29  import org.apache.syncope.common.lib.policy.PullPolicyTO;
30  import org.apache.syncope.common.lib.policy.PushPolicyTO;
31  import org.apache.syncope.common.lib.policy.TicketExpirationPolicyTO;
32  import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO;
33  import org.apache.syncope.core.persistence.api.dao.ExternalResourceDAO;
34  import org.apache.syncope.core.persistence.api.dao.ImplementationDAO;
35  import org.apache.syncope.core.persistence.api.dao.NotFoundException;
36  import org.apache.syncope.core.persistence.api.dao.RealmDAO;
37  import org.apache.syncope.core.persistence.api.entity.AnyType;
38  import org.apache.syncope.core.persistence.api.entity.EntityFactory;
39  import org.apache.syncope.core.persistence.api.entity.ExternalResource;
40  import org.apache.syncope.core.persistence.api.entity.Implementation;
41  import org.apache.syncope.core.persistence.api.entity.Realm;
42  import org.apache.syncope.core.persistence.api.entity.policy.AccessPolicy;
43  import org.apache.syncope.core.persistence.api.entity.policy.AccountPolicy;
44  import org.apache.syncope.core.persistence.api.entity.policy.AttrReleasePolicy;
45  import org.apache.syncope.core.persistence.api.entity.policy.AuthPolicy;
46  import org.apache.syncope.core.persistence.api.entity.policy.PasswordPolicy;
47  import org.apache.syncope.core.persistence.api.entity.policy.Policy;
48  import org.apache.syncope.core.persistence.api.entity.policy.PropagationPolicy;
49  import org.apache.syncope.core.persistence.api.entity.policy.PullCorrelationRuleEntity;
50  import org.apache.syncope.core.persistence.api.entity.policy.PullPolicy;
51  import org.apache.syncope.core.persistence.api.entity.policy.PushCorrelationRuleEntity;
52  import org.apache.syncope.core.persistence.api.entity.policy.PushPolicy;
53  import org.apache.syncope.core.persistence.api.entity.policy.TicketExpirationPolicy;
54  import org.apache.syncope.core.provisioning.api.data.PolicyDataBinder;
55  import org.slf4j.Logger;
56  import org.slf4j.LoggerFactory;
57  
58  public class PolicyDataBinderImpl implements PolicyDataBinder {
59  
60      protected static final Logger LOG = LoggerFactory.getLogger(PolicyDataBinder.class);
61  
62      protected final ExternalResourceDAO resourceDAO;
63  
64      protected final RealmDAO realmDAO;
65  
66      protected final AnyTypeDAO anyTypeDAO;
67  
68      protected final ImplementationDAO implementationDAO;
69  
70      protected final EntityFactory entityFactory;
71  
72      public PolicyDataBinderImpl(
73              final ExternalResourceDAO resourceDAO,
74              final RealmDAO realmDAO,
75              final AnyTypeDAO anyTypeDAO,
76              final ImplementationDAO implementationDAO,
77              final EntityFactory entityFactory) {
78  
79          this.resourceDAO = resourceDAO;
80          this.realmDAO = realmDAO;
81          this.anyTypeDAO = anyTypeDAO;
82          this.implementationDAO = implementationDAO;
83          this.entityFactory = entityFactory;
84      }
85  
86      @SuppressWarnings("unchecked")
87      protected <T extends Policy> T getPolicy(final T policy, final PolicyTO policyTO) {
88          T result = policy;
89  
90          if (policyTO instanceof PasswordPolicyTO) {
91              if (result == null) {
92                  result = (T) entityFactory.newEntity(PasswordPolicy.class);
93              }
94  
95              PasswordPolicy passwordPolicy = PasswordPolicy.class.cast(result);
96              PasswordPolicyTO passwordPolicyTO = PasswordPolicyTO.class.cast(policyTO);
97  
98              passwordPolicy.setAllowNullPassword(passwordPolicyTO.isAllowNullPassword());
99              passwordPolicy.setHistoryLength(passwordPolicyTO.getHistoryLength());
100 
101             passwordPolicyTO.getRules().forEach(ruleKey -> {
102                 Implementation rule = implementationDAO.find(ruleKey);
103                 if (rule == null) {
104                     LOG.debug("Invalid " + Implementation.class.getSimpleName() + " {}, ignoring...", ruleKey);
105                 } else {
106                     passwordPolicy.add(rule);
107                 }
108             });
109             // remove all implementations not contained in the TO
110             passwordPolicy.getRules().
111                     removeIf(implementation -> !passwordPolicyTO.getRules().contains(implementation.getKey()));
112         } else if (policyTO instanceof AccountPolicyTO) {
113             if (result == null) {
114                 result = (T) entityFactory.newEntity(AccountPolicy.class);
115             }
116 
117             AccountPolicy accountPolicy = AccountPolicy.class.cast(result);
118             AccountPolicyTO accountPolicyTO = AccountPolicyTO.class.cast(policyTO);
119 
120             accountPolicy.setMaxAuthenticationAttempts(accountPolicyTO.getMaxAuthenticationAttempts());
121             accountPolicy.setPropagateSuspension(accountPolicyTO.isPropagateSuspension());
122 
123             accountPolicyTO.getRules().forEach(ruleKey -> {
124                 Implementation rule = implementationDAO.find(ruleKey);
125                 if (rule == null) {
126                     LOG.debug("Invalid " + Implementation.class.getSimpleName() + " {}, ignoring...", ruleKey);
127                 } else {
128                     accountPolicy.add(rule);
129                 }
130             });
131             // remove all implementations not contained in the TO
132             accountPolicy.getRules().
133                     removeIf(implementation -> !accountPolicyTO.getRules().contains(implementation.getKey()));
134 
135             accountPolicy.getResources().clear();
136             accountPolicyTO.getPassthroughResources().forEach(resourceName -> {
137                 ExternalResource resource = resourceDAO.find(resourceName);
138                 if (resource == null) {
139                     LOG.debug("Ignoring invalid resource {} ", resourceName);
140                 } else {
141                     accountPolicy.add(resource);
142                 }
143             });
144         } else if (policyTO instanceof PropagationPolicyTO) {
145             if (result == null) {
146                 result = (T) entityFactory.newEntity(PropagationPolicy.class);
147             }
148 
149             PropagationPolicy propagationPolicy = PropagationPolicy.class.cast(result);
150             PropagationPolicyTO propagationPolicyTO = PropagationPolicyTO.class.cast(policyTO);
151 
152             propagationPolicy.setFetchAroundProvisioning(propagationPolicyTO.isFetchAroundProvisioning());
153             propagationPolicy.setUpdateDelta(propagationPolicyTO.isUpdateDelta());
154             propagationPolicy.setBackOffStrategy(propagationPolicyTO.getBackOffStrategy());
155             propagationPolicy.setBackOffParams(propagationPolicyTO.getBackOffParams());
156             propagationPolicy.setMaxAttempts(propagationPolicyTO.getMaxAttempts());
157         } else if (policyTO instanceof PullPolicyTO) {
158             if (result == null) {
159                 result = (T) entityFactory.newEntity(PullPolicy.class);
160             }
161 
162             PullPolicy pullPolicy = PullPolicy.class.cast(result);
163             PullPolicyTO pullPolicyTO = PullPolicyTO.class.cast(policyTO);
164 
165             pullPolicy.setConflictResolutionAction(pullPolicyTO.getConflictResolutionAction());
166 
167             pullPolicyTO.getCorrelationRules().forEach((type, impl) -> {
168                 AnyType anyType = anyTypeDAO.find(type);
169                 if (anyType == null) {
170                     LOG.debug("Invalid AnyType {} specified, ignoring...", type);
171                 } else {
172                     PullCorrelationRuleEntity correlationRule = pullPolicy.
173                             getCorrelationRule(anyType.getKey()).orElse(null);
174                     if (correlationRule == null) {
175                         correlationRule = entityFactory.newEntity(PullCorrelationRuleEntity.class);
176                         correlationRule.setAnyType(anyType);
177                         correlationRule.setPullPolicy(pullPolicy);
178                         pullPolicy.add(correlationRule);
179                     }
180 
181                     Implementation rule = implementationDAO.find(impl);
182                     if (rule == null) {
183                         throw new NotFoundException("Implementation " + type + ' ' + impl);
184                     }
185                     correlationRule.setImplementation(rule);
186                 }
187             });
188             // remove all rules not contained in the TO
189             pullPolicy.getCorrelationRules().removeIf(anyFilter -> !pullPolicyTO.getCorrelationRules().
190                     containsKey(anyFilter.getAnyType().getKey()));
191         } else if (policyTO instanceof PushPolicyTO) {
192             if (result == null) {
193                 result = (T) entityFactory.newEntity(PushPolicy.class);
194             }
195 
196             PushPolicy pushPolicy = PushPolicy.class.cast(result);
197             PushPolicyTO pushPolicyTO = PushPolicyTO.class.cast(policyTO);
198 
199             pushPolicy.setConflictResolutionAction(pushPolicyTO.getConflictResolutionAction());
200 
201             pushPolicyTO.getCorrelationRules().forEach((type, impl) -> {
202                 AnyType anyType = anyTypeDAO.find(type);
203                 if (anyType == null) {
204                     LOG.debug("Invalid AnyType {} specified, ignoring...", type);
205                 } else {
206                     PushCorrelationRuleEntity correlationRule = pushPolicy.
207                             getCorrelationRule(anyType.getKey()).orElse(null);
208                     if (correlationRule == null) {
209                         correlationRule = entityFactory.newEntity(PushCorrelationRuleEntity.class);
210                         correlationRule.setAnyType(anyType);
211                         correlationRule.setPushPolicy(pushPolicy);
212                         pushPolicy.add(correlationRule);
213                     }
214 
215                     Implementation rule = implementationDAO.find(impl);
216                     if (rule == null) {
217                         throw new NotFoundException("Implementation " + type + ' ' + impl);
218                     }
219                     correlationRule.setImplementation(rule);
220                 }
221             });
222             // remove all rules not contained in the TO
223             pushPolicy.getCorrelationRules().removeIf(anyFilter
224                     -> !pushPolicyTO.getCorrelationRules().containsKey(anyFilter.getAnyType().getKey()));
225         } else if (policyTO instanceof AuthPolicyTO) {
226             if (result == null) {
227                 result = (T) entityFactory.newEntity(AuthPolicy.class);
228             }
229 
230             AuthPolicy authPolicy = AuthPolicy.class.cast(result);
231             AuthPolicyTO authPolicyTO = AuthPolicyTO.class.cast(policyTO);
232 
233             authPolicy.setName(authPolicyTO.getKey());
234             authPolicy.setConf(authPolicyTO.getConf());
235         } else if (policyTO instanceof AccessPolicyTO) {
236             if (result == null) {
237                 result = (T) entityFactory.newEntity(AccessPolicy.class);
238             }
239 
240             AccessPolicy accessPolicy = AccessPolicy.class.cast(result);
241             AccessPolicyTO accessPolicyTO = AccessPolicyTO.class.cast(policyTO);
242 
243             accessPolicy.setName(accessPolicyTO.getKey());
244             accessPolicy.setConf(accessPolicyTO.getConf());
245         } else if (policyTO instanceof AttrReleasePolicyTO) {
246             if (result == null) {
247                 result = (T) entityFactory.newEntity(AttrReleasePolicy.class);
248             }
249 
250             AttrReleasePolicy attrReleasePolicy = AttrReleasePolicy.class.cast(result);
251             AttrReleasePolicyTO attrReleasePolicyTO = AttrReleasePolicyTO.class.cast(policyTO);
252 
253             attrReleasePolicy.setName(attrReleasePolicyTO.getKey());
254             attrReleasePolicy.setOrder(attrReleasePolicyTO.getOrder());
255             attrReleasePolicy.setStatus(attrReleasePolicyTO.getStatus());
256             attrReleasePolicy.setConf(attrReleasePolicyTO.getConf());
257         } else if (policyTO instanceof TicketExpirationPolicyTO) {
258             if (result == null) {
259                 result = (T) entityFactory.newEntity(TicketExpirationPolicy.class);
260             }
261 
262             TicketExpirationPolicy ticketExpirationPolicy = TicketExpirationPolicy.class.cast(result);
263             TicketExpirationPolicyTO ticketExpirationPolicyTO = TicketExpirationPolicyTO.class.cast(policyTO);
264 
265             ticketExpirationPolicy.setConf(ticketExpirationPolicyTO.getConf());
266         }
267 
268         if (result != null) {
269             result.setName(policyTO.getName());
270         }
271 
272         return result;
273     }
274 
275     @Override
276     public <T extends Policy> T create(final PolicyTO policyTO) {
277         return getPolicy(null, policyTO);
278     }
279 
280     @Override
281     public <T extends Policy> T update(final T policy, final PolicyTO policyTO) {
282         return getPolicy(policy, policyTO);
283     }
284 
285     @SuppressWarnings("unchecked")
286     @Override
287     public <T extends PolicyTO> T getPolicyTO(final Policy policy) {
288         T policyTO = null;
289 
290         if (policy instanceof PasswordPolicy) {
291             PasswordPolicy passwordPolicy = PasswordPolicy.class.cast(policy);
292             PasswordPolicyTO passwordPolicyTO = new PasswordPolicyTO();
293             policyTO = (T) passwordPolicyTO;
294 
295             passwordPolicyTO.setAllowNullPassword(passwordPolicy.isAllowNullPassword());
296             passwordPolicyTO.setHistoryLength(passwordPolicy.getHistoryLength());
297 
298             passwordPolicyTO.getRules().addAll(
299                     passwordPolicy.getRules().stream().map(Implementation::getKey).collect(Collectors.toList()));
300         } else if (policy instanceof AccountPolicy) {
301             AccountPolicy accountPolicy = AccountPolicy.class.cast(policy);
302             AccountPolicyTO accountPolicyTO = new AccountPolicyTO();
303             policyTO = (T) accountPolicyTO;
304 
305             accountPolicyTO.setMaxAuthenticationAttempts(accountPolicy.getMaxAuthenticationAttempts());
306             accountPolicyTO.setPropagateSuspension(accountPolicy.isPropagateSuspension());
307 
308             accountPolicyTO.getRules().addAll(
309                     accountPolicy.getRules().stream().map(Implementation::getKey).collect(Collectors.toList()));
310 
311             accountPolicyTO.getPassthroughResources().addAll(
312                     accountPolicy.getResources().stream().map(ExternalResource::getKey).collect(Collectors.toList()));
313         } else if (policy instanceof PropagationPolicy) {
314             PropagationPolicy propagationPolicy = PropagationPolicy.class.cast(policy);
315             PropagationPolicyTO propagationPolicyTO = new PropagationPolicyTO();
316             policyTO = (T) propagationPolicyTO;
317 
318             propagationPolicyTO.setFetchAroundProvisioning(propagationPolicy.isFetchAroundProvisioning());
319             propagationPolicyTO.setUpdateDelta(propagationPolicy.isUpdateDelta());
320             propagationPolicyTO.setBackOffStrategy(propagationPolicy.getBackOffStrategy());
321             propagationPolicyTO.setBackOffParams(propagationPolicy.getBackOffParams());
322             propagationPolicyTO.setMaxAttempts(propagationPolicy.getMaxAttempts());
323         } else if (policy instanceof PullPolicy) {
324             PullPolicy pullPolicy = PullPolicy.class.cast(policy);
325             PullPolicyTO pullPolicyTO = new PullPolicyTO();
326             policyTO = (T) pullPolicyTO;
327 
328             pullPolicyTO.setConflictResolutionAction(((PullPolicy) policy).getConflictResolutionAction());
329             pullPolicy.getCorrelationRules().
330                     forEach(rule -> pullPolicyTO.getCorrelationRules().
331                     put(rule.getAnyType().getKey(), rule.getImplementation().getKey()));
332         } else if (policy instanceof PushPolicy) {
333             PushPolicy pushPolicy = PushPolicy.class.cast(policy);
334             PushPolicyTO pushPolicyTO = new PushPolicyTO();
335             policyTO = (T) pushPolicyTO;
336 
337             pushPolicyTO.setConflictResolutionAction(((PushPolicy) policy).getConflictResolutionAction());
338             pushPolicy.getCorrelationRules().
339                     forEach(rule -> pushPolicyTO.getCorrelationRules().
340                     put(rule.getAnyType().getKey(), rule.getImplementation().getKey()));
341         } else if (policy instanceof AuthPolicy) {
342             AuthPolicyTO authPolicyTO = new AuthPolicyTO();
343             policyTO = (T) authPolicyTO;
344 
345             authPolicyTO.setConf(((AuthPolicy) policy).getConf());
346         } else if (policy instanceof AccessPolicy) {
347             AccessPolicyTO accessPolicyTO = new AccessPolicyTO();
348             policyTO = (T) accessPolicyTO;
349 
350             accessPolicyTO.setConf(((AccessPolicy) policy).getConf());
351         } else if (policy instanceof AttrReleasePolicy) {
352             AttrReleasePolicy attrReleasePolicy = AttrReleasePolicy.class.cast(policy);
353             AttrReleasePolicyTO attrReleasePolicyTO = new AttrReleasePolicyTO();
354             policyTO = (T) attrReleasePolicyTO;
355 
356             attrReleasePolicyTO.setOrder(attrReleasePolicy.getOrder());
357             attrReleasePolicyTO.setStatus(attrReleasePolicy.getStatus());
358             attrReleasePolicyTO.setConf(attrReleasePolicy.getConf());
359         } else if (policy instanceof TicketExpirationPolicy) {
360             TicketExpirationPolicy ticketExpirationPolicy = TicketExpirationPolicy.class.cast(policy);
361             TicketExpirationPolicyTO ticketExpirationPolicyTO = new TicketExpirationPolicyTO();
362             policyTO = (T) ticketExpirationPolicyTO;
363 
364             ticketExpirationPolicyTO.setConf(ticketExpirationPolicy.getConf());
365         }
366 
367         if (policyTO != null) {
368             policyTO.setKey(policy.getKey());
369             policyTO.setName(policy.getName());
370 
371             if (!(policy instanceof AuthPolicy)
372                     && !(policy instanceof AccessPolicy)
373                     && !(policy instanceof AttrReleasePolicy)
374                     && !(policy instanceof TicketExpirationPolicy)) {
375 
376                 policyTO.getUsedByResources().addAll(
377                         resourceDAO.findByPolicy(policy).stream().
378                                 map(ExternalResource::getKey).collect(Collectors.toList()));
379             }
380 
381             policyTO.getUsedByRealms().addAll(
382                     realmDAO.findByPolicy(policy).stream().
383                             map(Realm::getFullPath).collect(Collectors.toList()));
384         }
385 
386         return policyTO;
387     }
388 }