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.Optional;
22  import org.apache.syncope.common.lib.SyncopeClientException;
23  import org.apache.syncope.common.lib.to.RealmTO;
24  import org.apache.syncope.common.lib.types.ClientExceptionType;
25  import org.apache.syncope.common.lib.types.ResourceOperation;
26  import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO;
27  import org.apache.syncope.core.persistence.api.dao.ExternalResourceDAO;
28  import org.apache.syncope.core.persistence.api.dao.ImplementationDAO;
29  import org.apache.syncope.core.persistence.api.dao.PolicyDAO;
30  import org.apache.syncope.core.persistence.api.dao.RealmDAO;
31  import org.apache.syncope.core.persistence.api.entity.AnyTemplateRealm;
32  import org.apache.syncope.core.persistence.api.entity.AnyType;
33  import org.apache.syncope.core.persistence.api.entity.EntityFactory;
34  import org.apache.syncope.core.persistence.api.entity.ExternalResource;
35  import org.apache.syncope.core.persistence.api.entity.Implementation;
36  import org.apache.syncope.core.persistence.api.entity.Realm;
37  import org.apache.syncope.core.persistence.api.entity.policy.AccessPolicy;
38  import org.apache.syncope.core.persistence.api.entity.policy.AccountPolicy;
39  import org.apache.syncope.core.persistence.api.entity.policy.AttrReleasePolicy;
40  import org.apache.syncope.core.persistence.api.entity.policy.AuthPolicy;
41  import org.apache.syncope.core.persistence.api.entity.policy.PasswordPolicy;
42  import org.apache.syncope.core.persistence.api.entity.policy.Policy;
43  import org.apache.syncope.core.persistence.api.entity.policy.TicketExpirationPolicy;
44  import org.apache.syncope.core.provisioning.api.PropagationByResource;
45  import org.apache.syncope.core.provisioning.api.data.RealmDataBinder;
46  import org.apache.syncope.core.provisioning.java.utils.TemplateUtils;
47  import org.slf4j.Logger;
48  import org.slf4j.LoggerFactory;
49  
50  public class RealmDataBinderImpl implements RealmDataBinder {
51  
52      protected static final Logger LOG = LoggerFactory.getLogger(RealmDataBinder.class);
53  
54      protected final AnyTypeDAO anyTypeDAO;
55  
56      protected final ImplementationDAO implementationDAO;
57  
58      protected final RealmDAO realmDAO;
59  
60      protected final PolicyDAO policyDAO;
61  
62      protected final ExternalResourceDAO resourceDAO;
63  
64      protected final EntityFactory entityFactory;
65  
66      public RealmDataBinderImpl(
67              final AnyTypeDAO anyTypeDAO,
68              final ImplementationDAO implementationDAO,
69              final RealmDAO realmDAO,
70              final PolicyDAO policyDAO,
71              final ExternalResourceDAO resourceDAO,
72              final EntityFactory entityFactory) {
73  
74          this.anyTypeDAO = anyTypeDAO;
75          this.implementationDAO = implementationDAO;
76          this.realmDAO = realmDAO;
77          this.policyDAO = policyDAO;
78          this.resourceDAO = resourceDAO;
79          this.entityFactory = entityFactory;
80      }
81  
82      protected void setTemplates(final RealmTO realmTO, final Realm realm) {
83          // validate JEXL expressions from templates and proceed if fine
84          TemplateUtils.check(realmTO.getTemplates(), ClientExceptionType.InvalidRealm);
85          realmTO.getTemplates().forEach((key, template) -> {
86              AnyType type = anyTypeDAO.find(key);
87              if (type == null) {
88                  LOG.debug("Invalid AnyType {} specified, ignoring...", key);
89              } else {
90                  AnyTemplateRealm anyTemplate = realm.getTemplate(type).orElse(null);
91                  if (anyTemplate == null) {
92                      anyTemplate = entityFactory.newEntity(AnyTemplateRealm.class);
93                      anyTemplate.setAnyType(type);
94                      anyTemplate.setRealm(realm);
95  
96                      realm.add(anyTemplate);
97                  }
98                  anyTemplate.set(template);
99              }
100         });
101         // remove all templates not contained in the TO
102         realm.getTemplates().
103                 removeIf(template -> !realmTO.getTemplates().containsKey(template.getAnyType().getKey()));
104     }
105 
106     @Override
107     public Realm create(final Realm parent, final RealmTO realmTO) {
108         Realm realm = entityFactory.newEntity(Realm.class);
109 
110         realm.setName(realmTO.getName());
111         realm.setParent(parent);
112 
113         if (realmTO.getPasswordPolicy() != null) {
114             Policy policy = policyDAO.find(realmTO.getPasswordPolicy());
115             if (policy instanceof PasswordPolicy) {
116                 realm.setPasswordPolicy((PasswordPolicy) policy);
117             } else {
118                 SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.InvalidPolicy);
119                 sce.getElements().add("Expected " + PasswordPolicy.class.getSimpleName()
120                         + ", found " + policy.getClass().getSimpleName());
121                 throw sce;
122             }
123         }
124         if (realmTO.getAccountPolicy() != null) {
125             Policy policy = policyDAO.find(realmTO.getAccountPolicy());
126             if (policy instanceof AccountPolicy) {
127                 realm.setAccountPolicy((AccountPolicy) policy);
128             } else {
129                 SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.InvalidPolicy);
130                 sce.getElements().add("Expected " + AccountPolicy.class.getSimpleName()
131                         + ", found " + policy.getClass().getSimpleName());
132                 throw sce;
133             }
134         }
135         if (realmTO.getAuthPolicy() != null) {
136             Policy policy = policyDAO.find(realmTO.getAuthPolicy());
137             if (policy instanceof AuthPolicy) {
138                 realm.setAuthPolicy((AuthPolicy) policy);
139             } else {
140                 SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.InvalidPolicy);
141                 sce.getElements().add("Expected " + AuthPolicy.class.getSimpleName()
142                         + ", found " + policy.getClass().getSimpleName());
143                 throw sce;
144             }
145         }
146         if (realmTO.getAccessPolicy() != null) {
147             Policy policy = policyDAO.find(realmTO.getAccessPolicy());
148             if (policy instanceof AccessPolicy) {
149                 realm.setAccessPolicy((AccessPolicy) policy);
150             } else {
151                 SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.InvalidPolicy);
152                 sce.getElements().add("Expected " + AccessPolicy.class.getSimpleName()
153                         + ", found " + policy.getClass().getSimpleName());
154                 throw sce;
155             }
156         }
157         if (realmTO.getAttrReleasePolicy() != null) {
158             Policy policy = policyDAO.find(realmTO.getAttrReleasePolicy());
159             if (policy instanceof AttrReleasePolicy) {
160                 realm.setAttrReleasePolicy((AttrReleasePolicy) policy);
161             } else {
162                 SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.InvalidPolicy);
163                 sce.getElements().add("Expected " + AttrReleasePolicy.class.getSimpleName()
164                         + ", found " + policy.getClass().getSimpleName());
165                 throw sce;
166             }
167         }
168         if (realmTO.getTicketExpirationPolicy() != null) {
169             Policy policy = policyDAO.find(realmTO.getTicketExpirationPolicy());
170             if (policy instanceof TicketExpirationPolicy) {
171                 realm.setTicketExpirationPolicy((TicketExpirationPolicy) policy);
172             } else {
173                 SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.InvalidPolicy);
174                 sce.getElements().add("Expected " + TicketExpirationPolicy.class.getSimpleName()
175                         + ", found " + policy.getClass().getSimpleName());
176                 throw sce;
177             }
178         }
179 
180         realmTO.getActions().forEach(logicActionsKey -> {
181             Implementation logicAction = implementationDAO.find(logicActionsKey);
182             if (logicAction == null) {
183                 LOG.debug("Invalid " + Implementation.class.getSimpleName() + " {}, ignoring...", logicActionsKey);
184             } else {
185                 realm.add(logicAction);
186             }
187         });
188 
189         setTemplates(realmTO, realm);
190 
191         realmTO.getResources().forEach(resourceKey -> {
192             ExternalResource resource = resourceDAO.find(resourceKey);
193             if (resource == null) {
194                 LOG.debug("Invalid " + ExternalResource.class.getSimpleName() + " {}, ignoring...", resourceKey);
195             } else {
196                 realm.add(resource);
197             }
198         });
199 
200         return realm;
201     }
202 
203     @Override
204     public PropagationByResource<String> update(final Realm realm, final RealmTO realmTO) {
205         realm.setName(realmTO.getName());
206         realm.setParent(realmTO.getParent() == null ? null : realmDAO.find(realmTO.getParent()));
207 
208         if (realmTO.getAccountPolicy() == null) {
209             realm.setAccountPolicy(null);
210         } else {
211             Policy policy = policyDAO.find(realmTO.getAccountPolicy());
212             if (policy instanceof AccountPolicy) {
213                 realm.setAccountPolicy((AccountPolicy) policy);
214             } else {
215                 SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.InvalidPolicy);
216                 sce.getElements().add("Expected " + AccountPolicy.class.getSimpleName()
217                         + ", found " + policy.getClass().getSimpleName());
218                 throw sce;
219             }
220         }
221 
222         if (realmTO.getPasswordPolicy() == null) {
223             realm.setPasswordPolicy(null);
224         } else {
225             Policy policy = policyDAO.find(realmTO.getPasswordPolicy());
226             if (policy instanceof PasswordPolicy) {
227                 realm.setPasswordPolicy((PasswordPolicy) policy);
228             } else {
229                 SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.InvalidPolicy);
230                 sce.getElements().add("Expected " + PasswordPolicy.class.getSimpleName()
231                         + ", found " + policy.getClass().getSimpleName());
232                 throw sce;
233             }
234         }
235 
236         if (realmTO.getAuthPolicy() == null) {
237             realm.setAuthPolicy(null);
238         } else {
239             Policy policy = policyDAO.find(realmTO.getAuthPolicy());
240             if (policy instanceof AuthPolicy) {
241                 realm.setAuthPolicy((AuthPolicy) policy);
242             } else {
243                 SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.InvalidPolicy);
244                 sce.getElements().add("Expected " + AuthPolicy.class.getSimpleName()
245                         + ", found " + policy.getClass().getSimpleName());
246                 throw sce;
247             }
248         }
249 
250         if (realmTO.getAccessPolicy() == null) {
251             realm.setAccessPolicy(null);
252         } else {
253             Policy policy = policyDAO.find(realmTO.getAccessPolicy());
254             if (policy instanceof AccessPolicy) {
255                 realm.setAccessPolicy((AccessPolicy) policy);
256             } else {
257                 SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.InvalidPolicy);
258                 sce.getElements().add("Expected " + AccessPolicy.class.getSimpleName()
259                         + ", found " + policy.getClass().getSimpleName());
260                 throw sce;
261             }
262         }
263 
264         if (realmTO.getAttrReleasePolicy() == null) {
265             realm.setAttrReleasePolicy(null);
266         } else {
267             Policy policy = policyDAO.find(realmTO.getAttrReleasePolicy());
268             if (policy instanceof AttrReleasePolicy) {
269                 realm.setAttrReleasePolicy((AttrReleasePolicy) policy);
270             } else {
271                 SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.InvalidPolicy);
272                 sce.getElements().add("Expected " + AttrReleasePolicy.class.getSimpleName()
273                         + ", found " + policy.getClass().getSimpleName());
274                 throw sce;
275             }
276         }
277 
278         if (realmTO.getTicketExpirationPolicy() == null) {
279             realm.setTicketExpirationPolicy(null);
280         } else {
281             Policy policy = policyDAO.find(realmTO.getTicketExpirationPolicy());
282             if (policy instanceof TicketExpirationPolicy) {
283                 realm.setTicketExpirationPolicy((TicketExpirationPolicy) policy);
284             } else {
285                 SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.InvalidPolicy);
286                 sce.getElements().add("Expected " + TicketExpirationPolicy.class.getSimpleName()
287                         + ", found " + policy.getClass().getSimpleName());
288                 throw sce;
289             }
290         }
291 
292         realmTO.getActions().forEach(logicActionsKey -> {
293             Implementation logicActions = implementationDAO.find(logicActionsKey);
294             if (logicActions == null) {
295                 LOG.debug("Invalid " + Implementation.class.getSimpleName() + " {}, ignoring...", logicActionsKey);
296             } else {
297                 realm.add(logicActions);
298             }
299         });
300         // remove all implementations not contained in the TO
301         realm.getActions().
302                 removeIf(implementation -> !realmTO.getActions().contains(implementation.getKey()));
303 
304         setTemplates(realmTO, realm);
305 
306         PropagationByResource<String> propByRes = new PropagationByResource<>();
307         realmTO.getResources().forEach(resourceKey -> {
308             ExternalResource resource = resourceDAO.find(resourceKey);
309             if (resource == null) {
310                 LOG.debug("Invalid " + ExternalResource.class.getSimpleName() + " {}, ignoring...", resourceKey);
311             } else {
312                 realm.add(resource);
313                 propByRes.add(ResourceOperation.CREATE, resource.getKey());
314             }
315         });
316         // remove all resources not contained in the TO
317         realm.getResources().removeIf(resource -> {
318             boolean contained = realmTO.getResources().contains(resource.getKey());
319             if (!contained) {
320                 propByRes.add(ResourceOperation.DELETE, resource.getKey());
321             }
322             return !contained;
323         });
324 
325         return propByRes;
326     }
327 
328     @Override
329     public RealmTO getRealmTO(final Realm realm, final boolean admin) {
330         RealmTO realmTO = new RealmTO();
331 
332         realmTO.setKey(realm.getKey());
333         realmTO.setName(realm.getName());
334         Optional.ofNullable(realm.getParent()).ifPresent(parent -> realmTO.setParent(parent.getKey()));
335         realmTO.setFullPath(realm.getFullPath());
336 
337         if (admin) {
338             Optional.ofNullable(realm.getAccountPolicy()).
339                     ifPresent(policy -> realmTO.setAccountPolicy(policy.getKey()));
340             Optional.ofNullable(realm.getPasswordPolicy()).
341                     ifPresent(policy -> realmTO.setPasswordPolicy(policy.getKey()));
342             Optional.ofNullable(realm.getAuthPolicy()).
343                     ifPresent(policy -> realmTO.setAuthPolicy(policy.getKey()));
344             Optional.ofNullable(realm.getAccessPolicy()).
345                     ifPresent(policy -> realmTO.setAccessPolicy(policy.getKey()));
346             Optional.ofNullable(realm.getAttrReleasePolicy()).
347                     ifPresent(policy -> realmTO.setAttrReleasePolicy(policy.getKey()));
348             Optional.ofNullable(realm.getTicketExpirationPolicy()).
349                     ifPresent(policy -> realmTO.setTicketExpirationPolicy(policy.getKey()));
350 
351             realm.getActions().forEach(action -> realmTO.getActions().add(action.getKey()));
352 
353             realm.getTemplates().forEach(
354                     template -> realmTO.getTemplates().put(template.getAnyType().getKey(), template.get()));
355 
356             realm.getResources().forEach(resource -> realmTO.getResources().add(resource.getKey()));
357         }
358 
359         return realmTO;
360     }
361 }