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.logic;
20  
21  import java.lang.reflect.Method;
22  import java.util.List;
23  import java.util.stream.Collectors;
24  import java.util.stream.Stream;
25  import org.apache.commons.lang3.ArrayUtils;
26  import org.apache.syncope.common.lib.SyncopeConstants;
27  import org.apache.syncope.common.lib.to.DelegationTO;
28  import org.apache.syncope.common.lib.types.AnyTypeKind;
29  import org.apache.syncope.common.lib.types.IdRepoEntitlement;
30  import org.apache.syncope.core.persistence.api.dao.DelegationDAO;
31  import org.apache.syncope.core.persistence.api.dao.NotFoundException;
32  import org.apache.syncope.core.persistence.api.dao.UserDAO;
33  import org.apache.syncope.core.persistence.api.entity.Delegation;
34  import org.apache.syncope.core.provisioning.api.data.DelegationDataBinder;
35  import org.apache.syncope.core.spring.security.AuthContextUtils;
36  import org.apache.syncope.core.spring.security.DelegatedAdministrationException;
37  import org.springframework.security.access.prepost.PreAuthorize;
38  import org.springframework.transaction.annotation.Transactional;
39  
40  public class DelegationLogic extends AbstractTransactionalLogic<DelegationTO> {
41  
42      protected final DelegationDataBinder binder;
43  
44      protected final DelegationDAO delegationDAO;
45  
46      protected final UserDAO userDAO;
47  
48      public DelegationLogic(
49              final DelegationDataBinder binder,
50              final DelegationDAO delegationDAO,
51              final UserDAO userDAO) {
52  
53          this.binder = binder;
54          this.delegationDAO = delegationDAO;
55          this.userDAO = userDAO;
56      }
57  
58      protected void securityChecks(final String delegating, final String entitlement) {
59          if (!AuthContextUtils.getAuthorizations().keySet().contains(entitlement)
60                  && (delegating == null || !delegating.equals(userDAO.findKey(AuthContextUtils.getUsername())))) {
61  
62              throw new DelegatedAdministrationException(
63                      SyncopeConstants.ROOT_REALM, AnyTypeKind.USER.name(), delegating);
64          }
65      }
66  
67      @PreAuthorize("isAuthenticated()")
68      @Transactional(readOnly = true)
69      public DelegationTO read(final String key) {
70          Delegation delegation = delegationDAO.find(key);
71          if (delegation == null) {
72              LOG.error("Could not find delegation '" + key + "'");
73              throw new NotFoundException(key);
74          }
75  
76          securityChecks(delegation.getDelegating().getKey(), IdRepoEntitlement.DELEGATION_READ);
77  
78          return binder.getDelegationTO(delegation);
79      }
80  
81      @PreAuthorize("isAuthenticated()")
82      @Transactional(readOnly = true)
83      public List<DelegationTO> list() {
84          Stream<DelegationTO> delegations = delegationDAO.findAll().stream().map(binder::getDelegationTO);
85  
86          if (!AuthContextUtils.getAuthorizations().keySet().contains(IdRepoEntitlement.DELEGATION_LIST)) {
87              String authUserKey = userDAO.findKey(AuthContextUtils.getUsername());
88              delegations = delegations.filter(delegation -> delegation.getDelegating().equals(authUserKey));
89          }
90  
91          return delegations.collect(Collectors.toList());
92      }
93  
94      @PreAuthorize("isAuthenticated()")
95      public DelegationTO create(final DelegationTO delegationTO) {
96          if (delegationTO.getDelegating() != null
97                  && !SyncopeConstants.UUID_PATTERN.matcher(delegationTO.getDelegating()).matches()) {
98  
99              delegationTO.setDelegating(userDAO.findKey(delegationTO.getDelegating()));
100         }
101         if (delegationTO.getDelegated() != null
102                 && !SyncopeConstants.UUID_PATTERN.matcher(delegationTO.getDelegated()).matches()) {
103 
104             delegationTO.setDelegated(userDAO.findKey(delegationTO.getDelegated()));
105         }
106 
107         securityChecks(delegationTO.getDelegating(), IdRepoEntitlement.DELEGATION_CREATE);
108 
109         return binder.getDelegationTO(delegationDAO.save(binder.create(delegationTO)));
110     }
111 
112     @PreAuthorize("isAuthenticated()")
113     public DelegationTO update(final DelegationTO delegationTO) {
114         Delegation delegation = delegationDAO.find(delegationTO.getKey());
115         if (delegation == null) {
116             LOG.error("Could not find delegation '" + delegationTO.getKey() + "'");
117             throw new NotFoundException(delegationTO.getKey());
118         }
119 
120         securityChecks(delegation.getDelegating().getKey(), IdRepoEntitlement.DELEGATION_UPDATE);
121 
122         return binder.getDelegationTO(delegationDAO.save(binder.update(delegation, delegationTO)));
123     }
124 
125     @PreAuthorize("isAuthenticated()")
126     public DelegationTO delete(final String key) {
127         Delegation delegation = delegationDAO.find(key);
128         if (delegation == null) {
129             LOG.error("Could not find delegation '" + key + "'");
130             throw new NotFoundException(key);
131         }
132 
133         securityChecks(delegation.getDelegating().getKey(), IdRepoEntitlement.DELEGATION_DELETE);
134 
135         DelegationTO deleted = binder.getDelegationTO(delegation);
136         delegationDAO.delete(key);
137         return deleted;
138     }
139 
140     @Override
141     protected DelegationTO resolveReference(final Method method, final Object... args)
142             throws UnresolvedReferenceException {
143 
144         String key = null;
145 
146         if (ArrayUtils.isNotEmpty(args)) {
147             for (int i = 0; key == null && i < args.length; i++) {
148                 if (args[i] instanceof String) {
149                     key = (String) args[i];
150                 } else if (args[i] instanceof DelegationTO) {
151                     key = ((DelegationTO) args[i]).getKey();
152                 }
153             }
154         }
155 
156         if (key != null) {
157             try {
158                 return binder.getDelegationTO(delegationDAO.find(key));
159             } catch (Throwable ignore) {
160                 LOG.debug("Unresolved reference", ignore);
161                 throw new UnresolvedReferenceException(ignore);
162             }
163         }
164 
165         throw new UnresolvedReferenceException();
166     }
167 }