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 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.assertTrue;
26  import static org.mockito.ArgumentMatchers.any;
27  import static org.mockito.Mockito.mock;
28  import static org.mockito.Mockito.when;
29  
30  import java.util.List;
31  import java.util.stream.Collectors;
32  import org.apache.syncope.common.lib.SyncopeConstants;
33  import org.apache.syncope.common.lib.to.Item;
34  import org.apache.syncope.common.lib.to.Mapping;
35  import org.apache.syncope.common.lib.to.OrgUnit;
36  import org.apache.syncope.common.lib.to.Provision;
37  import org.apache.syncope.common.lib.to.ResourceTO;
38  import org.apache.syncope.common.lib.types.AnyTypeKind;
39  import org.apache.syncope.common.lib.types.ConnectorCapability;
40  import org.apache.syncope.common.lib.types.IdMEntitlement;
41  import org.apache.syncope.common.lib.types.MappingPurpose;
42  import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO;
43  import org.apache.syncope.core.persistence.api.dao.ExternalResourceDAO;
44  import org.apache.syncope.core.persistence.api.entity.ExternalResource;
45  import org.apache.syncope.core.provisioning.api.Connector;
46  import org.apache.syncope.core.provisioning.api.ConnectorManager;
47  import org.apache.syncope.core.spring.security.SyncopeAuthenticationDetails;
48  import org.apache.syncope.core.spring.security.SyncopeGrantedAuthority;
49  import org.identityconnectors.framework.common.objects.ObjectClass;
50  import org.identityconnectors.framework.common.objects.SyncToken;
51  import org.junit.jupiter.api.AfterAll;
52  import org.junit.jupiter.api.BeforeAll;
53  import org.junit.jupiter.api.Test;
54  import org.springframework.beans.factory.annotation.Autowired;
55  import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
56  import org.springframework.security.core.GrantedAuthority;
57  import org.springframework.security.core.context.SecurityContextHolder;
58  import org.springframework.transaction.annotation.Transactional;
59  
60  @Transactional("Master")
61  public class ResourceLogicTest extends AbstractTest {
62  
63      @BeforeAll
64      public static void setAuthContext() {
65          List<GrantedAuthority> authorities = IdMEntitlement.values().stream().
66                  map(entitlement -> new SyncopeGrantedAuthority(entitlement, SyncopeConstants.ROOT_REALM)).
67                  collect(Collectors.toList());
68  
69          UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken(
70                  new org.springframework.security.core.userdetails.User(
71                          "admin", "FAKE_PASSWORD", authorities), "FAKE_PASSWORD", authorities);
72          auth.setDetails(new SyncopeAuthenticationDetails(SyncopeConstants.MASTER_DOMAIN, null));
73          SecurityContextHolder.getContext().setAuthentication(auth);
74      }
75  
76      @AfterAll
77      public static void unsetAuthContext() {
78          SecurityContextHolder.getContext().setAuthentication(null);
79      }
80  
81      private static ResourceTO buildResourceTO(final String resourceKey) {
82          ResourceTO resourceTO = new ResourceTO();
83  
84          resourceTO.setKey(resourceKey);
85          resourceTO.setConnector("5ffbb4ac-a8c3-4b44-b699-11b398a1ba08");
86  
87          Provision provisionTO = new Provision();
88          provisionTO.setAnyType(AnyTypeKind.USER.name());
89          provisionTO.setObjectClass(ObjectClass.ACCOUNT_NAME);
90          resourceTO.getProvisions().add(provisionTO);
91  
92          Mapping mapping = new Mapping();
93          provisionTO.setMapping(mapping);
94  
95          Item item = new Item();
96          item.setExtAttrName("userId");
97          item.setIntAttrName("userId");
98          item.setPurpose(MappingPurpose.BOTH);
99          mapping.add(item);
100 
101         item = new Item();
102         item.setExtAttrName("username");
103         item.setIntAttrName("key");
104         item.setPurpose(MappingPurpose.BOTH);
105         mapping.setConnObjectKeyItem(item);
106 
107         item = new Item();
108         item.setExtAttrName("fullname");
109         item.setIntAttrName("cn");
110         item.setConnObjectKey(false);
111         item.setPurpose(MappingPurpose.PROPAGATION);
112         mapping.add(item);
113 
114         return resourceTO;
115     }
116 
117     @Autowired
118     private ResourceLogic logic;
119 
120     @Autowired
121     private ExternalResourceDAO resourceDAO;
122 
123     @Autowired
124     private AnyTypeDAO anyTypeDAO;
125 
126     @Test
127     public void updateChangePurpose() {
128         ResourceTO ws1 = logic.read("ws-target-resource-1");
129         assertNotNull(ws1);
130 
131         Mapping ws1NewUMapping = ws1.getProvision(AnyTypeKind.USER.name()).get().getMapping();
132         // change purpose from NONE to BOTH
133         ws1NewUMapping.getItems().stream().
134                 filter(itemTO -> "firstname".equals(itemTO.getIntAttrName())).
135                 forEach(itemTO -> itemTO.setPurpose(MappingPurpose.BOTH));
136         ws1.getProvision(AnyTypeKind.USER.name()).get().setMapping(ws1NewUMapping);
137 
138         ws1 = logic.update(ws1);
139         assertNotNull(ws1);
140     }
141 
142     @Test
143     public void updateChangeOverrideCapabilities() {
144         ResourceTO ldap = logic.read("resource-ldap");
145         assertNotNull(ldap);
146         assertFalse(ldap.isOverrideCapabilities());
147         assertTrue(ldap.getCapabilitiesOverride().isEmpty());
148 
149         ldap.getCapabilitiesOverride().add(ConnectorCapability.SEARCH);
150         ldap = logic.update(ldap);
151         assertNotNull(ldap);
152         assertFalse(ldap.isOverrideCapabilities());
153         assertEquals(1, ldap.getCapabilitiesOverride().size());
154         assertTrue(ldap.getCapabilitiesOverride().contains(ConnectorCapability.SEARCH));
155 
156         ldap.setOverrideCapabilities(true);
157         ldap = logic.update(ldap);
158         assertNotNull(ldap);
159         assertTrue(ldap.isOverrideCapabilities());
160         assertEquals(1, ldap.getCapabilitiesOverride().size());
161         assertTrue(ldap.getCapabilitiesOverride().contains(ConnectorCapability.SEARCH));
162 
163         ldap.getCapabilitiesOverride().clear();
164         ldap.setOverrideCapabilities(false);
165         logic.update(ldap);
166     }
167 
168     @Test
169     public void orgUnit() {
170         ResourceTO resourceTO = buildResourceTO("ws-orgunit");
171         assertNull(resourceTO.getOrgUnit());
172         assertNull(resourceTO.getPropagationPriority());
173 
174         resourceTO = logic.create(resourceTO);
175         entityManager().flush();
176         assertNull(resourceTO.getOrgUnit());
177 
178         OrgUnit orgUnit = new OrgUnit();
179         orgUnit.setConnObjectLink("'ou=' + name + ',o=isp'");
180         orgUnit.setObjectClass("organizationalUnit");
181 
182         Item item = new Item();
183         item.setIntAttrName("name");
184         item.setExtAttrName("ou");
185         item.setMandatoryCondition("true");
186         item.setPurpose(MappingPurpose.BOTH);
187         orgUnit.setConnObjectKeyItem(item);
188 
189         resourceTO.setOrgUnit(orgUnit);
190         logic.update(resourceTO);
191         entityManager().flush();
192         assertNull(resourceTO.getPropagationPriority());
193 
194         resourceTO = logic.read("ws-orgunit");
195         assertNotNull(resourceTO.getOrgUnit());
196 
197         resourceTO.setOrgUnit(null);
198         resourceTO.setPropagationPriority(11);
199         logic.update(resourceTO);
200         entityManager().flush();
201 
202         resourceTO = logic.read("ws-orgunit");
203         assertNull(resourceTO.getOrgUnit());
204         assertEquals(11, resourceTO.getPropagationPriority());
205     }
206 
207     @Test
208     public void setLatestSyncToken() {
209         ConnectorManager connectorManager = mock(ConnectorManager.class);
210         when(connectorManager.getConnector(any(ExternalResource.class))).thenAnswer(ic -> {
211             Connector connector = mock(Connector.class);
212             when(connector.getLatestSyncToken(any(ObjectClass.class))).thenAnswer(ic2 -> new SyncToken("tokenValue"));
213             return connector;
214         });
215 
216         ResourceTO resourceTO = logic.create(buildResourceTO("lss"));
217         assertNotNull(resourceTO);
218         assertNull(resourceTO.getProvision(AnyTypeKind.USER.name()).get().getSyncToken());
219 
220         ResourceLogic resourceLogic = new ResourceLogic(
221                 resourceDAO, anyTypeDAO, null, null, null, null, null, null, null, connectorManager, null);
222 
223         resourceLogic.setLatestSyncToken(resourceTO.getKey(), AnyTypeKind.USER.name());
224         entityManager().flush();
225 
226         resourceTO = logic.read(resourceTO.getKey());
227         assertNotNull(resourceTO.getProvision(AnyTypeKind.USER.name()).get().getSyncToken());
228     }
229 }