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.persistence.jpa.inner;
20  
21  import static org.junit.jupiter.api.Assertions.assertEquals;
22  import static org.junit.jupiter.api.Assertions.assertFalse;
23  import static org.junit.jupiter.api.Assertions.assertNotNull;
24  import static org.junit.jupiter.api.Assertions.assertNull;
25  import static org.junit.jupiter.api.Assertions.assertThrows;
26  import static org.junit.jupiter.api.Assertions.assertTrue;
27  import static org.junit.jupiter.api.Assertions.fail;
28  
29  import java.util.List;
30  import java.util.stream.Collectors;
31  import org.apache.syncope.common.lib.SyncopeConstants;
32  import org.apache.syncope.common.lib.to.Item;
33  import org.apache.syncope.common.lib.to.Mapping;
34  import org.apache.syncope.common.lib.to.Provision;
35  import org.apache.syncope.common.lib.types.AnyTypeKind;
36  import org.apache.syncope.common.lib.types.EntityViolationType;
37  import org.apache.syncope.common.lib.types.IdMEntitlement;
38  import org.apache.syncope.common.lib.types.MappingPurpose;
39  import org.apache.syncope.core.persistence.api.attrvalue.validation.InvalidEntityException;
40  import org.apache.syncope.core.persistence.api.dao.ExternalResourceDAO;
41  import org.apache.syncope.core.persistence.api.entity.ConnInstance;
42  import org.apache.syncope.core.persistence.api.entity.ExternalResource;
43  import org.apache.syncope.core.persistence.jpa.AbstractTest;
44  import org.apache.syncope.core.spring.security.DelegatedAdministrationException;
45  import org.apache.syncope.core.spring.security.SyncopeAuthenticationDetails;
46  import org.apache.syncope.core.spring.security.SyncopeGrantedAuthority;
47  import org.identityconnectors.framework.common.objects.ObjectClass;
48  import org.junit.jupiter.api.Test;
49  import org.springframework.beans.factory.annotation.Autowired;
50  import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
51  import org.springframework.security.core.GrantedAuthority;
52  import org.springframework.security.core.context.SecurityContextHolder;
53  import org.springframework.transaction.annotation.Transactional;
54  
55  @Transactional("Master")
56  public class ResourceTest extends AbstractTest {
57  
58      @Autowired
59      private ExternalResourceDAO resourceDAO;
60  
61      @Test
62      public void findById() {
63          ExternalResource resource = resourceDAO.find("ws-target-resource-1");
64          assertNotNull(resource);
65  
66          ConnInstance connector = resource.getConnector();
67          assertNotNull(connector);
68          assertEquals("net.tirasa.connid.bundles.soap.WebServiceConnector", connector.getConnectorName());
69          assertEquals("net.tirasa.connid.bundles.soap", connector.getBundleName());
70  
71          Mapping mapping = resource.getProvisionByAnyType(AnyTypeKind.USER.name()).get().getMapping();
72          assertFalse(mapping.getItems().isEmpty());
73  
74          assertTrue(mapping.getItems().stream().
75                  anyMatch(item -> "email".equals(item.getExtAttrName()) && "email".equals(item.getIntAttrName())));
76  
77          try {
78              resourceDAO.authFind("ws-target-resource-1");
79              fail("This should not happen");
80          } catch (DelegatedAdministrationException e) {
81              assertNotNull(e);
82          }
83      }
84  
85      @Test
86      public void findByConnInstance() {
87          List<ExternalResource> resources = resourceDAO.findByConnInstance("88a7a819-dab5-46b4-9b90-0b9769eabdb8");
88          assertEquals(6, resources.size());
89          assertTrue(resources.contains(resourceDAO.find("ws-target-resource-1")));
90      }
91  
92      @Test
93      public void findWithOrgUnit() {
94          ExternalResource resource = resourceDAO.find("resource-ldap-orgunit");
95          assertNotNull(resource);
96          assertNotNull(resource.getOrgUnit());
97      }
98  
99      @Test
100     public void findAll() {
101         List<GrantedAuthority> authorities = IdMEntitlement.values().stream().
102                 map(entitlement -> new SyncopeGrantedAuthority(entitlement, SyncopeConstants.ROOT_REALM)).
103                 collect(Collectors.toList());
104 
105         UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken(
106                 new org.springframework.security.core.userdetails.User(
107                         "admin", "FAKE_PASSWORD", authorities), "FAKE_PASSWORD", authorities);
108         auth.setDetails(new SyncopeAuthenticationDetails(SyncopeConstants.MASTER_DOMAIN, null));
109         SecurityContextHolder.getContext().setAuthentication(auth);
110 
111         try {
112             List<ExternalResource> resources = resourceDAO.findAll();
113             assertNotNull(resources);
114             assertFalse(resources.isEmpty());
115         } finally {
116             SecurityContextHolder.getContext().setAuthentication(null);
117         }
118     }
119 
120     @Test
121     public void getConnObjectKey() {
122         ExternalResource resource = resourceDAO.find("ws-target-resource-2");
123         assertNotNull(resource);
124         assertEquals("fullname", resource.getProvisionByAnyType(AnyTypeKind.USER.name()).get().
125                 getMapping().getConnObjectKeyItem().get().getIntAttrName());
126     }
127 
128     @Test
129     public void save() {
130         ExternalResource resource = entityFactory.newEntity(ExternalResource.class);
131         resource.setKey("ws-target-resource-basic-save");
132         resource.setPropagationPriority(2);
133 
134         Provision provision = new Provision();
135         provision.setAnyType(AnyTypeKind.USER.name());
136         provision.setObjectClass(ObjectClass.ACCOUNT_NAME);
137         resource.getProvisions().add(provision);
138 
139         Mapping mapping = new Mapping();
140         provision.setMapping(mapping);
141 
142         Item connObjectKey = new Item();
143         connObjectKey.setExtAttrName("username");
144         connObjectKey.setIntAttrName("fullname");
145         connObjectKey.setPurpose(MappingPurpose.BOTH);
146         mapping.setConnObjectKeyItem(connObjectKey);
147 
148         ConnInstance connector = resourceDAO.find("ws-target-resource-1").getConnector();
149         resource.setConnector(connector);
150 
151         // save the resource
152         ExternalResource actual = resourceDAO.save(resource);
153         entityManager().flush();
154         assertNotNull(actual);
155         assertNotNull(actual.getConnector());
156         assertNotNull(actual.getProvisionByAnyType(AnyTypeKind.USER.name()).
157                 get().getMapping());
158         assertFalse(actual.getProvisionByAnyType(AnyTypeKind.USER.name()).
159                 get().getMapping().getItems().isEmpty());
160         assertEquals(Integer.valueOf(2), actual.getPropagationPriority());
161     }
162 
163     @Test
164     public void saveInvalidMappingIntAttr() {
165         assertThrows(InvalidEntityException.class, () -> {
166             ExternalResource resource = entityFactory.newEntity(ExternalResource.class);
167             resource.setKey("ws-target-resource-basic-save-invalid");
168 
169             ConnInstance connector = resourceDAO.find("ws-target-resource-1").getConnector();
170             resource.setConnector(connector);
171 
172             Provision provision = new Provision();
173             provision.setAnyType(AnyTypeKind.USER.name());
174             provision.setObjectClass(ObjectClass.ACCOUNT_NAME);
175             resource.getProvisions().add(provision);
176 
177             Mapping mapping = new Mapping();
178             provision.setMapping(mapping);
179 
180             Item connObjectKey = new Item();
181             connObjectKey.setConnObjectKey(true);
182             mapping.add(connObjectKey);
183 
184             // save the resource
185             resourceDAO.save(resource);
186         });
187     }
188 
189     @Test
190     public void saveInvalidMappingExtAttr() {
191         assertThrows(InvalidEntityException.class, () -> {
192             ExternalResource resource = entityFactory.newEntity(ExternalResource.class);
193             resource.setKey("ws-target-resource-basic-save-invalid");
194 
195             ConnInstance connector = resourceDAO.find("ws-target-resource-1").getConnector();
196             resource.setConnector(connector);
197 
198             Provision provision = new Provision();
199             provision.setAnyType(AnyTypeKind.USER.name());
200             provision.setObjectClass(ObjectClass.ACCOUNT_NAME);
201             resource.getProvisions().add(provision);
202 
203             Mapping mapping = new Mapping();
204             provision.setMapping(mapping);
205 
206             Item item = new Item();
207             item.setConnObjectKey(true);
208             item.setIntAttrName("fullname");
209             mapping.add(item);
210 
211             item = new Item();
212             item.setIntAttrName("userId");
213             mapping.add(item);
214 
215             resourceDAO.save(resource);
216         });
217     }
218 
219     @Test
220     public void saveInvalidProvision() {
221         assertThrows(InvalidEntityException.class, () -> {
222             ExternalResource resource = entityFactory.newEntity(ExternalResource.class);
223             resource.setKey("invalidProvision");
224 
225             Provision provision = new Provision();
226             provision.setAnyType(AnyTypeKind.USER.name());
227             provision.setObjectClass(ObjectClass.ACCOUNT_NAME);
228             resource.getProvisions().add(provision);
229 
230             Mapping mapping = new Mapping();
231             provision.setMapping(mapping);
232 
233             Item connObjectKey = new Item();
234             connObjectKey.setExtAttrName("username");
235             connObjectKey.setIntAttrName("fullname");
236             connObjectKey.setPurpose(MappingPurpose.BOTH);
237             mapping.setConnObjectKeyItem(connObjectKey);
238 
239             provision = new Provision();
240             provision.setAnyType(AnyTypeKind.GROUP.name());
241             provision.setObjectClass(ObjectClass.ACCOUNT_NAME);
242             resource.getProvisions().add(provision);
243 
244             ConnInstance connector = resourceDAO.find("ws-target-resource-1").getConnector();
245             resource.setConnector(connector);
246 
247             // save the resource
248             resourceDAO.save(resource);
249         });
250     }
251 
252     @Test
253     public void saveVirtualMapping() {
254         ExternalResource resource = entityFactory.newEntity(ExternalResource.class);
255         resource.setKey("ws-target-resource-virtual-mapping");
256         resource.setPropagationPriority(2);
257 
258         Provision provision = new Provision();
259         provision.setAnyType(AnyTypeKind.USER.name());
260         provision.setObjectClass(ObjectClass.ACCOUNT_NAME);
261         resource.getProvisions().add(provision);
262 
263         Mapping mapping = new Mapping();
264         provision.setMapping(mapping);
265 
266         Item connObjectKey = new Item();
267         connObjectKey.setExtAttrName("username");
268         connObjectKey.setIntAttrName("fullname");
269         connObjectKey.setPurpose(MappingPurpose.BOTH);
270         mapping.setConnObjectKeyItem(connObjectKey);
271 
272         Item virtualMapItem = new Item();
273         virtualMapItem.setIntAttrName("virtualReadOnly");
274         virtualMapItem.setExtAttrName("TEST");
275         virtualMapItem.setPurpose(MappingPurpose.PROPAGATION);
276         mapping.add(virtualMapItem);
277 
278         ConnInstance connector = resourceDAO.find("ws-target-resource-1").getConnector();
279         resource.setConnector(connector);
280 
281         resourceDAO.save(resource);
282     }
283 
284     @Test
285     public void saveWithGroupMappingType() {
286         ExternalResource resource = entityFactory.newEntity(ExternalResource.class);
287         resource.setKey("ws-target-resource-basic-save-invalid");
288 
289         ConnInstance connector = resourceDAO.find("ws-target-resource-1").getConnector();
290         resource.setConnector(connector);
291 
292         Provision provision = new Provision();
293         provision.setAnyType(AnyTypeKind.USER.name());
294         provision.setObjectClass(ObjectClass.ACCOUNT_NAME);
295         resource.getProvisions().add(provision);
296 
297         Mapping mapping = new Mapping();
298         provision.setMapping(mapping);
299 
300         Item item = new Item();
301         item.setIntAttrName("fullname");
302         item.setExtAttrName("fullname");
303         item.setPurpose(MappingPurpose.BOTH);
304         mapping.setConnObjectKeyItem(item);
305 
306         item = new Item();
307         item.setIntAttrName("icon");
308         item.setExtAttrName("icon");
309         item.setPurpose(MappingPurpose.BOTH);
310         mapping.add(item);
311 
312         item = new Item();
313         item.setIntAttrName("mderiveddata");
314         item.setExtAttrName("mderiveddata");
315         item.setPurpose(MappingPurpose.PROPAGATION);
316         mapping.add(item);
317 
318         // save the resource
319         ExternalResource actual = resourceDAO.save(resource);
320         entityManager().flush();
321         assertNotNull(actual);
322 
323         assertEquals(3, actual.getProvisionByAnyType(AnyTypeKind.USER.name()).
324                 get().getMapping().getItems().size());
325     }
326 
327     @Test
328     public void delete() {
329         ExternalResource resource = resourceDAO.find("ws-target-resource-2");
330         assertNotNull(resource);
331 
332         resourceDAO.delete(resource.getKey());
333 
334         ExternalResource actual = resourceDAO.find("ws-target-resource-2");
335         assertNull(actual);
336     }
337 
338     @Test
339     public void issueSYNCOPE418() {
340         ExternalResource resource = entityFactory.newEntity(ExternalResource.class);
341         resource.setKey("http://schemas.examples.org/security/authorization/organizationUnit");
342 
343         try {
344             resourceDAO.save(resource);
345             fail("This should not happen");
346         } catch (InvalidEntityException e) {
347             assertTrue(e.hasViolation(EntityViolationType.InvalidKey));
348         }
349     }
350 }