1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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 org.apache.commons.lang3.ArrayUtils;
25 import org.apache.commons.lang3.StringUtils;
26 import org.apache.syncope.common.lib.SyncopeClientException;
27 import org.apache.syncope.common.lib.to.ImplementationTO;
28 import org.apache.syncope.common.lib.types.ClientExceptionType;
29 import org.apache.syncope.common.lib.types.IdMImplementationType;
30 import org.apache.syncope.common.lib.types.IdRepoEntitlement;
31 import org.apache.syncope.common.lib.types.IdRepoImplementationType;
32 import org.apache.syncope.common.lib.types.ImplementationTypesHolder;
33 import org.apache.syncope.core.persistence.api.dao.DuplicateException;
34 import org.apache.syncope.core.persistence.api.dao.ExternalResourceDAO;
35 import org.apache.syncope.core.persistence.api.dao.ImplementationDAO;
36 import org.apache.syncope.core.persistence.api.dao.NotFoundException;
37 import org.apache.syncope.core.persistence.api.dao.NotificationDAO;
38 import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO;
39 import org.apache.syncope.core.persistence.api.dao.PolicyDAO;
40 import org.apache.syncope.core.persistence.api.dao.RealmDAO;
41 import org.apache.syncope.core.persistence.api.dao.ReportDAO;
42 import org.apache.syncope.core.persistence.api.dao.TaskDAO;
43 import org.apache.syncope.core.persistence.api.entity.Implementation;
44 import org.apache.syncope.core.provisioning.api.data.ImplementationDataBinder;
45 import org.springframework.security.access.prepost.PreAuthorize;
46 import org.springframework.transaction.annotation.Transactional;
47
48 public class ImplementationLogic extends AbstractTransactionalLogic<ImplementationTO> {
49
50 protected final ImplementationDataBinder binder;
51
52 protected final ImplementationDAO implementationDAO;
53
54 protected final ReportDAO reportDAO;
55
56 protected final PolicyDAO policyDAO;
57
58 protected final ExternalResourceDAO resourceDAO;
59
60 protected final TaskDAO taskDAO;
61
62 protected final RealmDAO realmDAO;
63
64 protected final PlainSchemaDAO plainSchemaDAO;
65
66 protected final NotificationDAO notificationDAO;
67
68 public ImplementationLogic(
69 final ImplementationDataBinder binder,
70 final ImplementationDAO implementationDAO,
71 final ReportDAO reportDAO,
72 final PolicyDAO policyDAO,
73 final ExternalResourceDAO resourceDAO,
74 final TaskDAO taskDAO,
75 final RealmDAO realmDAO,
76 final PlainSchemaDAO plainSchemaDAO,
77 final NotificationDAO notificationDAO) {
78
79 this.binder = binder;
80 this.implementationDAO = implementationDAO;
81 this.reportDAO = reportDAO;
82 this.policyDAO = policyDAO;
83 this.resourceDAO = resourceDAO;
84 this.taskDAO = taskDAO;
85 this.realmDAO = realmDAO;
86 this.plainSchemaDAO = plainSchemaDAO;
87 this.notificationDAO = notificationDAO;
88 }
89
90 protected void checkType(final String type) {
91 if (!ImplementationTypesHolder.getInstance().getValues().containsKey(type)) {
92 SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.InvalidImplementationType);
93 sce.getElements().add("Implementation type not found: ");
94 throw sce;
95 }
96 }
97
98 @PreAuthorize("hasRole('" + IdRepoEntitlement.IMPLEMENTATION_LIST + "')")
99 @Transactional(readOnly = true)
100 public List<ImplementationTO> list(final String type) {
101 checkType(type);
102
103 return implementationDAO.findByType(type).stream().
104 map(binder::getImplementationTO).collect(Collectors.toList());
105 }
106
107 @PreAuthorize("hasRole('" + IdRepoEntitlement.IMPLEMENTATION_READ + "')")
108 @Transactional(readOnly = true)
109 public ImplementationTO read(final String type, final String key) {
110 checkType(type);
111
112 Implementation implementation = implementationDAO.find(key);
113 if (implementation == null) {
114 LOG.error("Could not find implementation '" + key + '\'');
115
116 throw new NotFoundException(key);
117 }
118
119 if (!implementation.getType().equals(type)) {
120 SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.InvalidRequest);
121 sce.getElements().add("Found " + type + ", expected " + implementation.getType());
122 throw sce;
123 }
124
125 return binder.getImplementationTO(implementation);
126 }
127
128 @PreAuthorize("hasRole('" + IdRepoEntitlement.IMPLEMENTATION_CREATE + "')")
129 public ImplementationTO create(final ImplementationTO implementationTO) {
130 if (StringUtils.isBlank(implementationTO.getKey())) {
131 SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.RequiredValuesMissing);
132 sce.getElements().add("Implementation key");
133 throw sce;
134 }
135
136 checkType(implementationTO.getType());
137
138 Implementation implementation = implementationDAO.find(implementationTO.getKey());
139 if (implementation != null) {
140 throw new DuplicateException(implementationTO.getKey());
141 }
142
143 return binder.getImplementationTO(implementationDAO.save(binder.create(implementationTO)));
144 }
145
146 @PreAuthorize("hasRole('" + IdRepoEntitlement.IMPLEMENTATION_UPDATE + "')")
147 public ImplementationTO update(final ImplementationTO implementationTO) {
148 Implementation implementation = implementationDAO.find(implementationTO.getKey());
149 if (implementation == null) {
150 LOG.error("Could not find implementation '" + implementationTO.getKey() + '\'');
151
152 throw new NotFoundException(implementationTO.getKey());
153 }
154
155 checkType(implementationTO.getType());
156
157 binder.update(implementation, implementationTO);
158 implementation = implementationDAO.save(implementation);
159
160 return binder.getImplementationTO(implementation);
161 }
162
163 @PreAuthorize("hasRole('" + IdRepoEntitlement.IMPLEMENTATION_DELETE + "')")
164 public void delete(final String type, final String key) {
165 Implementation implementation = implementationDAO.find(key);
166 if (implementation == null) {
167 LOG.error("Could not find implementation '" + key + '\'');
168
169 throw new NotFoundException(key);
170 }
171
172 if (!implementation.getType().equals(type)) {
173 SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.InvalidRequest);
174 sce.getElements().add("Found " + type + ", expected " + implementation.getType());
175 throw sce;
176 }
177
178 boolean inUse = false;
179 switch (implementation.getType()) {
180 case IdRepoImplementationType.ACCOUNT_RULE:
181 inUse = !policyDAO.findByAccountRule(implementation).isEmpty();
182 break;
183
184 case IdRepoImplementationType.PASSWORD_RULE:
185 inUse = !policyDAO.findByPasswordRule(implementation).isEmpty();
186 break;
187
188 case IdRepoImplementationType.ITEM_TRANSFORMER:
189 inUse = resourceDAO.anyItemHaving(implementation);
190 break;
191
192 case IdRepoImplementationType.TASKJOB_DELEGATE:
193 inUse = !taskDAO.findByDelegate(implementation).isEmpty();
194 break;
195
196 case IdRepoImplementationType.REPORT_DELEGATE:
197 inUse = !reportDAO.findByDelegate(implementation).isEmpty();
198 break;
199
200 case IdRepoImplementationType.COMMAND:
201 inUse = !taskDAO.findByCommand(implementation).isEmpty();
202 break;
203
204 case IdMImplementationType.RECON_FILTER_BUILDER:
205 inUse = !taskDAO.findByReconFilterBuilder(implementation).isEmpty();
206 break;
207
208 case IdRepoImplementationType.LOGIC_ACTIONS:
209 inUse = !realmDAO.findByLogicActions(implementation).isEmpty();
210 break;
211
212 case IdMImplementationType.PROVISION_SORTER:
213 inUse = !resourceDAO.findByProvisionSorter(implementation).isEmpty();
214 break;
215
216 case IdMImplementationType.PROPAGATION_ACTIONS:
217 inUse = !resourceDAO.findByPropagationActions(implementation).isEmpty();
218 break;
219
220 case IdMImplementationType.PULL_ACTIONS:
221 inUse = !taskDAO.findByPullActions(implementation).isEmpty();
222 break;
223
224 case IdMImplementationType.PUSH_ACTIONS:
225 inUse = !taskDAO.findByPushActions(implementation).isEmpty();
226 break;
227
228 case IdMImplementationType.PULL_CORRELATION_RULE:
229 inUse = !policyDAO.findByPullCorrelationRule(implementation).isEmpty();
230 break;
231
232 case IdMImplementationType.PUSH_CORRELATION_RULE:
233 inUse = !policyDAO.findByPushCorrelationRule(implementation).isEmpty();
234 break;
235
236 case IdRepoImplementationType.VALIDATOR:
237 inUse = !plainSchemaDAO.findByValidator(implementation).isEmpty();
238 break;
239
240 case IdRepoImplementationType.RECIPIENTS_PROVIDER:
241 inUse = !notificationDAO.findByRecipientsProvider(implementation).isEmpty();
242 break;
243
244 default:
245 }
246
247 if (inUse) {
248 SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.InUse);
249 sce.getElements().add("This implementation is in use");
250 throw sce;
251 }
252
253 implementationDAO.delete(key);
254 }
255
256 @Override
257 protected ImplementationTO resolveReference(final Method method, final Object... args)
258 throws UnresolvedReferenceException {
259
260 String key = null;
261
262 if (ArrayUtils.isNotEmpty(args)) {
263 for (int i = 0; key == null && i < args.length; i++) {
264 if (args[i] instanceof String) {
265 key = (String) args[i];
266 } else if (args[i] instanceof ImplementationTO) {
267 key = ((ImplementationTO) args[i]).getKey();
268 }
269 }
270 }
271
272 if (StringUtils.isNotBlank(key)) {
273 try {
274 return binder.getImplementationTO(implementationDAO.find(key));
275 } catch (Throwable ignore) {
276 LOG.debug("Unresolved reference", ignore);
277 throw new UnresolvedReferenceException(ignore);
278 }
279 }
280
281 throw new UnresolvedReferenceException();
282 }
283 }