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.spring.policy;
20  
21  import java.util.ArrayList;
22  import java.util.Collection;
23  import java.util.List;
24  import java.util.Map;
25  import java.util.Optional;
26  import java.util.concurrent.ConcurrentHashMap;
27  import org.apache.syncope.core.persistence.api.dao.RealmDAO;
28  import org.apache.syncope.core.persistence.api.entity.ExternalResource;
29  import org.apache.syncope.core.persistence.api.entity.Implementation;
30  import org.apache.syncope.core.persistence.api.entity.Realm;
31  import org.apache.syncope.core.persistence.api.entity.policy.AccountPolicy;
32  import org.apache.syncope.core.persistence.api.entity.policy.PasswordPolicy;
33  import org.apache.syncope.core.provisioning.api.rules.AccountRule;
34  import org.apache.syncope.core.provisioning.api.rules.PasswordRule;
35  import org.apache.syncope.core.provisioning.api.rules.RuleEnforcer;
36  import org.apache.syncope.core.spring.implementation.ImplementationManager;
37  import org.slf4j.Logger;
38  import org.slf4j.LoggerFactory;
39  import org.springframework.transaction.annotation.Transactional;
40  
41  public class DefaultRuleEnforcer implements RuleEnforcer {
42  
43      protected static final Logger LOG = LoggerFactory.getLogger(RuleEnforcer.class);
44  
45      protected final RealmDAO realmDAO;
46  
47      protected final Map<String, AccountRule> perContextAccountRules = new ConcurrentHashMap<>();
48  
49      protected final Map<String, PasswordRule> perContextPasswordRules = new ConcurrentHashMap<>();
50  
51      public DefaultRuleEnforcer(final RealmDAO realmDAO) {
52          this.realmDAO = realmDAO;
53      }
54  
55      @Transactional(readOnly = true)
56      @Override
57      public List<AccountPolicy> getAccountPolicies(final Realm realm, final Collection<ExternalResource> resources) {
58          List<AccountPolicy> policies = new ArrayList<>();
59  
60          // add resource policies
61          resources.forEach(resource -> Optional.ofNullable(resource.getAccountPolicy()).
62                  filter(p -> !policies.contains(p)).
63                  ifPresent(policies::add));
64  
65          // add realm policies
66          if (realm != null) {
67              realmDAO.findAncestors(realm).
68                      forEach(r -> Optional.ofNullable(r.getAccountPolicy()).
69                      filter(p -> !policies.contains(p)).
70                      ifPresent(policies::add));
71          }
72  
73          return policies;
74      }
75  
76      @Transactional(readOnly = true)
77      @Override
78      public List<AccountRule> getAccountRules(final AccountPolicy policy) {
79          List<AccountRule> result = new ArrayList<>();
80  
81          for (Implementation impl : policy.getRules()) {
82              try {
83                  ImplementationManager.buildAccountRule(
84                          impl,
85                          () -> perContextAccountRules.get(impl.getKey()),
86                          instance -> perContextAccountRules.put(impl.getKey(), instance)).
87                          ifPresent(result::add);
88              } catch (Exception e) {
89                  LOG.warn("While building {}", impl, e);
90              }
91          }
92  
93          return result;
94      }
95  
96      @Transactional(readOnly = true)
97      @Override
98      public List<PasswordPolicy> getPasswordPolicies(final Realm realm, final Collection<ExternalResource> resources) {
99          List<PasswordPolicy> policies = new ArrayList<>();
100 
101         // add resource policies
102         resources.forEach(resource -> Optional.ofNullable(resource.getPasswordPolicy()).
103                 filter(p -> !policies.contains(p)).
104                 ifPresent(policies::add));
105 
106         // add realm policies
107         if (realm != null) {
108             realmDAO.findAncestors(realm).
109                     forEach(r -> Optional.ofNullable(r.getPasswordPolicy()).
110                     filter(p -> !policies.contains(p)).
111                     ifPresent(policies::add));
112         }
113 
114         return policies;
115     }
116 
117     @Transactional(readOnly = true)
118     @Override
119     public List<PasswordRule> getPasswordRules(final PasswordPolicy policy) {
120         List<PasswordRule> result = new ArrayList<>();
121 
122         for (Implementation impl : policy.getRules()) {
123             try {
124                 ImplementationManager.buildPasswordRule(
125                         impl,
126                         () -> perContextPasswordRules.get(impl.getKey()),
127                         instance -> perContextPasswordRules.put(impl.getKey(), instance)).
128                         ifPresent(result::add);
129             } catch (Exception e) {
130                 LOG.warn("While building {}", impl, e);
131             }
132         }
133 
134         return result;
135     }
136 }