1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.syncope.core.persistence.jpa.dao;
20
21 import java.util.List;
22 import java.util.Set;
23 import java.util.concurrent.atomic.AtomicBoolean;
24 import java.util.stream.Collectors;
25 import javax.persistence.Query;
26 import javax.persistence.TypedQuery;
27 import org.apache.syncope.common.lib.to.Provision;
28 import org.apache.syncope.common.lib.types.IdMEntitlement;
29 import org.apache.syncope.common.lib.types.TaskType;
30 import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO;
31 import org.apache.syncope.core.persistence.api.dao.ExternalResourceDAO;
32 import org.apache.syncope.core.persistence.api.dao.GroupDAO;
33 import org.apache.syncope.core.persistence.api.dao.PolicyDAO;
34 import org.apache.syncope.core.persistence.api.dao.RealmDAO;
35 import org.apache.syncope.core.persistence.api.dao.TaskDAO;
36 import org.apache.syncope.core.persistence.api.dao.UserDAO;
37 import org.apache.syncope.core.persistence.api.dao.VirSchemaDAO;
38 import org.apache.syncope.core.persistence.api.entity.AnyTypeClass;
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.policy.AccountPolicy;
42 import org.apache.syncope.core.persistence.api.entity.policy.PasswordPolicy;
43 import org.apache.syncope.core.persistence.api.entity.policy.Policy;
44 import org.apache.syncope.core.persistence.api.entity.policy.PropagationPolicy;
45 import org.apache.syncope.core.persistence.api.entity.policy.PullPolicy;
46 import org.apache.syncope.core.persistence.api.entity.policy.PushPolicy;
47 import org.apache.syncope.core.persistence.jpa.entity.JPAExternalResource;
48 import org.apache.syncope.core.spring.security.AuthContextUtils;
49 import org.apache.syncope.core.spring.security.DelegatedAdministrationException;
50 import org.springframework.transaction.annotation.Transactional;
51 import org.springframework.util.CollectionUtils;
52
53 public class JPAExternalResourceDAO extends AbstractDAO<ExternalResource> implements ExternalResourceDAO {
54
55 protected final TaskDAO taskDAO;
56
57 protected final AnyObjectDAO anyObjectDAO;
58
59 protected final UserDAO userDAO;
60
61 protected final GroupDAO groupDAO;
62
63 protected final PolicyDAO policyDAO;
64
65 protected final VirSchemaDAO virSchemaDAO;
66
67 protected final RealmDAO realmDAO;
68
69 public JPAExternalResourceDAO(
70 final TaskDAO taskDAO,
71 final AnyObjectDAO anyObjectDAO,
72 final UserDAO userDAO,
73 final GroupDAO groupDAO,
74 final PolicyDAO policyDAO,
75 final VirSchemaDAO virSchemaDAO,
76 final RealmDAO realmDAO) {
77
78 this.taskDAO = taskDAO;
79 this.anyObjectDAO = anyObjectDAO;
80 this.userDAO = userDAO;
81 this.groupDAO = groupDAO;
82 this.policyDAO = policyDAO;
83 this.virSchemaDAO = virSchemaDAO;
84 this.realmDAO = realmDAO;
85 }
86
87 @Transactional(readOnly = true)
88 @Override
89 public int count() {
90 Query query = entityManager().createQuery(
91 "SELECT COUNT(e) FROM " + JPAExternalResource.class.getSimpleName() + " e");
92 return ((Number) query.getSingleResult()).intValue();
93 }
94
95 @Transactional(readOnly = true)
96 @Override
97 public ExternalResource find(final String name) {
98 return entityManager().find(JPAExternalResource.class, name);
99 }
100
101 @Override
102 public ExternalResource authFind(final String key) {
103 ExternalResource resource = find(key);
104 if (resource == null) {
105 return null;
106 }
107
108 Set<String> authRealms = AuthContextUtils.getAuthorizations().get(IdMEntitlement.RESOURCE_READ);
109 if (authRealms == null || authRealms.isEmpty()
110 || !authRealms.stream().anyMatch(realm -> resource.getConnector() != null
111 && resource.getConnector().getAdminRealm().getFullPath().startsWith(realm))) {
112
113 throw new DelegatedAdministrationException(
114 resource.getConnector().getAdminRealm().getFullPath(),
115 ExternalResource.class.getSimpleName(),
116 resource.getKey());
117 }
118
119 return resource;
120 }
121
122 @Override
123 public List<Provision> findProvisionsByAuxClass(final AnyTypeClass anyTypeClass) {
124 return findAll().stream().
125 flatMap(resource -> resource.getProvisions().stream()).
126 filter(provision -> provision.getAuxClasses().contains(anyTypeClass.getKey())).
127 collect(Collectors.toList());
128 }
129
130 @Override
131 public boolean anyItemHaving(final Implementation transformer) {
132 return findAll().stream().
133 flatMap(resource -> resource.getProvisions().stream()).
134 flatMap(provision -> provision.getMapping().getItems().stream()).
135 filter(item -> item.getTransformers().contains(transformer.getKey())).
136 count() > 0;
137 }
138
139 @Transactional(readOnly = true)
140 @Override
141 public List<ExternalResource> findByConnInstance(final String connInstance) {
142 TypedQuery<ExternalResource> query = entityManager().createQuery(
143 "SELECT e FROM " + JPAExternalResource.class.getSimpleName() + " e "
144 + "WHERE e.connector.id=:connInstance", ExternalResource.class);
145 query.setParameter("connInstance", connInstance);
146
147 return query.getResultList();
148 }
149
150 @Override
151 public List<ExternalResource> findByPropagationActions(final Implementation propagationActions) {
152 TypedQuery<ExternalResource> query = entityManager().createQuery(
153 "SELECT e FROM " + JPAExternalResource.class.getSimpleName() + " e "
154 + "WHERE :propagationActions MEMBER OF e.propagationActions", ExternalResource.class);
155 query.setParameter("propagationActions", propagationActions);
156
157 return query.getResultList();
158 }
159
160 @Override
161 public List<ExternalResource> findByProvisionSorter(final Implementation provisionSorter) {
162 TypedQuery<ExternalResource> query = entityManager().createQuery(
163 "SELECT e FROM " + JPAExternalResource.class.getSimpleName() + " e "
164 + "WHERE e.provisionSorter=:provisionSorter", ExternalResource.class);
165 query.setParameter("provisionSorter", provisionSorter);
166
167 return query.getResultList();
168 }
169
170 protected StringBuilder getByPolicyQuery(final Class<? extends Policy> policyClass) {
171 StringBuilder query = new StringBuilder("SELECT e FROM ").
172 append(JPAExternalResource.class.getSimpleName()).
173 append(" e WHERE e.");
174
175 if (AccountPolicy.class.isAssignableFrom(policyClass)) {
176 query.append("accountPolicy");
177 } else if (PasswordPolicy.class.isAssignableFrom(policyClass)) {
178 query.append("passwordPolicy");
179 } else if (PropagationPolicy.class.isAssignableFrom(policyClass)) {
180 query.append("propagationPolicy");
181 } else if (PullPolicy.class.isAssignableFrom(policyClass)) {
182 query.append("pullPolicy");
183 } else if (PushPolicy.class.isAssignableFrom(policyClass)) {
184 query.append("pushPolicy");
185 }
186
187 return query;
188 }
189
190 @Override
191 public List<ExternalResource> findByPolicy(final Policy policy) {
192 TypedQuery<ExternalResource> query = entityManager().createQuery(
193 getByPolicyQuery(policy.getClass()).append("=:policy").toString(), ExternalResource.class);
194 query.setParameter("policy", policy);
195 return query.getResultList();
196 }
197
198 @Transactional(readOnly = true)
199 @Override
200 public List<ExternalResource> findAll() {
201 Set<String> authRealms = AuthContextUtils.getAuthorizations().get(IdMEntitlement.RESOURCE_LIST);
202 if (CollectionUtils.isEmpty(authRealms)) {
203 return List.of();
204 }
205
206 TypedQuery<ExternalResource> query = entityManager().createQuery(
207 "SELECT e FROM " + JPAExternalResource.class.getSimpleName() + " e", ExternalResource.class);
208
209 return query.getResultList().stream().filter(resource -> authRealms.stream().
210 anyMatch(realm -> resource.getConnector() != null
211 && resource.getConnector().getAdminRealm().getFullPath().startsWith(realm))).
212 collect(Collectors.toList());
213 }
214
215 @Transactional(rollbackFor = { Throwable.class })
216 @Override
217 public ExternalResource save(final ExternalResource resource) {
218 ((JPAExternalResource) resource).list2json();
219 return entityManager().merge(resource);
220 }
221
222 @Override
223 public void deleteMapping(final String intAttrName) {
224 findAll().forEach(resource -> {
225 AtomicBoolean removed = new AtomicBoolean(false);
226
227 resource.getProvisions().forEach(provision -> removed.set(
228 removed.get()
229 || (provision.getMapping() != null
230 && provision.getMapping().getItems().removeIf(item -> intAttrName.equals(item.getIntAttrName())))));
231
232 if (removed.get()) {
233 entityManager().merge(resource);
234 }
235 });
236 }
237
238 @Override
239 public void delete(final String name) {
240 ExternalResource resource = find(name);
241 if (resource == null) {
242 return;
243 }
244
245 taskDAO.deleteAll(resource, TaskType.PROPAGATION);
246 taskDAO.deleteAll(resource, TaskType.PULL);
247 taskDAO.deleteAll(resource, TaskType.PUSH);
248
249 realmDAO.findByResource(resource).
250 forEach(realm -> realm.getResources().remove(resource));
251 anyObjectDAO.findByResource(resource).
252 forEach(anyObject -> anyObject.getResources().remove(resource));
253 userDAO.findLinkedAccountsByResource(resource).forEach(account -> {
254 account.getOwner().getLinkedAccounts().remove(account);
255 account.setOwner(null);
256 });
257 userDAO.findByResource(resource).
258 forEach(user -> user.getResources().remove(resource));
259 groupDAO.findByResource(resource).
260 forEach(group -> group.getResources().remove(resource));
261 policyDAO.findByResource(resource).
262 forEach(policy -> policy.getResources().remove(resource));
263
264 virSchemaDAO.find(resource).forEach(virSchemaDAO::delete);
265
266 if (resource.getConnector() != null
267 && resource.getConnector().getResources() != null
268 && !resource.getConnector().getResources().isEmpty()) {
269
270 resource.getConnector().getResources().remove(resource);
271 }
272 resource.setConnector(null);
273
274 entityManager().remove(resource);
275 }
276 }