You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@syncope.apache.org by il...@apache.org on 2015/08/26 16:54:12 UTC
[4/7] syncope git commit: [SYNCOPE-686] Merge from 1_2_X
http://git-wip-us.apache.org/repos/asf/syncope/blob/054ea9ca/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/UserITCase.java
----------------------------------------------------------------------
diff --cc fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/UserITCase.java
index 5fe876f,0000000..375f0d7
mode 100644,000000..100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/UserITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/UserITCase.java
@@@ -1,2527 -1,0 +1,2576 @@@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.fit.core.reference;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.security.AccessControlException;
+import java.text.SimpleDateFormat;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import javax.naming.NamingException;
+import javax.ws.rs.core.EntityTag;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.lang3.tuple.Pair;
+import org.apache.cxf.common.util.Base64Utility;
+import org.apache.cxf.helpers.IOUtils;
+import org.apache.syncope.client.lib.SyncopeClient;
+import org.apache.syncope.common.lib.AnyOperations;
+import org.apache.syncope.common.lib.SyncopeClientException;
+import org.apache.syncope.common.lib.SyncopeConstants;
+import org.apache.syncope.common.lib.mod.ResourceAssociationMod;
+import org.apache.syncope.common.lib.mod.StatusMod;
+import org.apache.syncope.common.lib.mod.UserMod;
+import org.apache.syncope.common.lib.policy.AccountPolicyTO;
+import org.apache.syncope.common.lib.policy.DefaultPasswordRuleConf;
+import org.apache.syncope.common.lib.policy.PasswordPolicyTO;
+import org.apache.syncope.common.lib.to.AttrTO;
+import org.apache.syncope.common.lib.to.BulkAction;
+import org.apache.syncope.common.lib.to.BulkActionResult;
+import org.apache.syncope.common.lib.to.BulkActionResult.Status;
+import org.apache.syncope.common.lib.to.ConnObjectTO;
+import org.apache.syncope.common.lib.to.MappingItemTO;
+import org.apache.syncope.common.lib.to.MappingTO;
+import org.apache.syncope.common.lib.to.MembershipTO;
+import org.apache.syncope.common.lib.to.PagedResult;
+import org.apache.syncope.common.lib.to.PropagationStatus;
+import org.apache.syncope.common.lib.to.PropagationTaskTO;
+import org.apache.syncope.common.lib.to.ResourceTO;
+import org.apache.syncope.common.lib.to.GroupTO;
+import org.apache.syncope.common.lib.to.RealmTO;
+import org.apache.syncope.common.lib.to.UserTO;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
+import org.apache.syncope.common.lib.types.CipherAlgorithm;
+import org.apache.syncope.common.lib.types.ClientExceptionType;
+import org.apache.syncope.common.lib.types.MappingPurpose;
+import org.apache.syncope.common.lib.types.PropagationTaskExecStatus;
+import org.apache.syncope.common.lib.types.ResourceAssociationAction;
+import org.apache.syncope.common.lib.types.ResourceDeassociationActionType;
+import org.apache.syncope.common.lib.types.TaskType;
+import org.apache.syncope.common.lib.wrap.ResourceKey;
+import org.apache.syncope.common.rest.api.CollectionWrapper;
+import org.apache.syncope.common.rest.api.Preference;
+import org.apache.syncope.common.rest.api.RESTHeaders;
+import org.apache.syncope.common.rest.api.service.ResourceService;
+import org.apache.syncope.common.rest.api.service.UserSelfService;
+import org.apache.syncope.common.rest.api.service.UserService;
+import org.apache.syncope.core.misc.security.Encryptor;
+import org.apache.syncope.core.provisioning.java.propagation.DBPasswordPropagationActions;
+import org.apache.syncope.core.provisioning.java.propagation.LDAPPasswordPropagationActions;
+import org.identityconnectors.framework.common.objects.Name;
+import org.identityconnectors.framework.common.objects.OperationalAttributes;
+import org.junit.Assume;
+import org.junit.FixMethodOrder;
+import org.junit.Test;
+import org.junit.runners.MethodSorters;
+import org.springframework.dao.EmptyResultDataAccessException;
+import org.springframework.jdbc.core.JdbcTemplate;
+
+@FixMethodOrder(MethodSorters.JVM)
+public class UserITCase extends AbstractITCase {
+
+ private static final ThreadLocal<SimpleDateFormat> DATE_FORMAT = new ThreadLocal<SimpleDateFormat>() {
+
+ @Override
+ protected SimpleDateFormat initialValue() {
+ SimpleDateFormat sdf = new SimpleDateFormat();
+ sdf.applyPattern("yyyy-MM-dd");
+ return sdf;
+ }
+ };
+
+ private boolean getBooleanAttribute(final ConnObjectTO connObjectTO, final String attrName) {
+ return Boolean.parseBoolean(connObjectTO.getPlainAttrMap().get(attrName).getValues().get(0));
+ }
+
+ public static UserTO getUniqueSampleTO(final String email) {
+ return getSampleTO(getUUIDString() + email);
+ }
+
+ public static UserTO getSampleTO(final String email) {
+ UserTO userTO = new UserTO();
+ userTO.setRealm(SyncopeConstants.ROOT_REALM);
+ userTO.setPassword("password123");
+ userTO.setUsername(email);
+
+ userTO.getPlainAttrs().add(attrTO("fullname", email));
+ userTO.getPlainAttrs().add(attrTO("firstname", email));
+ userTO.getPlainAttrs().add(attrTO("surname", "surname"));
+ userTO.getPlainAttrs().add(attrTO("type", "a type"));
+ userTO.getPlainAttrs().add(attrTO("userId", email));
+ userTO.getPlainAttrs().add(attrTO("email", email));
+ userTO.getPlainAttrs().add(attrTO("loginDate", DATE_FORMAT.get().format(new Date())));
+ userTO.getDerAttrs().add(attrTO("cn", null));
+ userTO.getVirAttrs().add(attrTO("virtualdata", "virtualvalue"));
+ return userTO;
+ }
+
+ @Test
+ public void createUserWithNoPropagation() {
+ // get task list
+ PagedResult<PropagationTaskTO> tasks = taskService.list(
+ TaskType.PROPAGATION,
+ SyncopeClient.getListQueryBuilder().page(1).size(1).build());
+ assertNotNull(tasks);
+ assertFalse(tasks.getResult().isEmpty());
+
+ long maxKey = tasks.getResult().iterator().next().getKey();
+
+ // create a new user
+ UserTO userTO = getUniqueSampleTO("xxx@xxx.xxx");
+
+ userTO.setPassword("password123");
+ userTO.getResources().add(RESOURCE_NAME_NOPROPAGATION);
+
+ createUser(userTO);
+
+ // get the new task list
+ tasks = taskService.list(
+ TaskType.PROPAGATION,
+ SyncopeClient.getListQueryBuilder().page(1).size(1).build());
+ assertNotNull(tasks);
+ assertFalse(tasks.getResult().isEmpty());
+
+ long newMaxId = tasks.getResult().iterator().next().getKey();
+
+ assertTrue(newMaxId > maxKey);
+
+ // get last task
+ PropagationTaskTO taskTO = taskService.read(newMaxId);
+
+ assertNotNull(taskTO);
+ assertTrue(taskTO.getExecutions().isEmpty());
+ }
+
+ @Test
+ public void issue186() {
+ // 1. create an user with strict mandatory attributes only
+ UserTO userTO = new UserTO();
+ userTO.setRealm(SyncopeConstants.ROOT_REALM);
+ String userId = getUUIDString() + "issue186@syncope.apache.org";
+ userTO.setUsername(userId);
+ userTO.setPassword("password123");
+
+ userTO.getPlainAttrs().add(attrTO("userId", userId));
+ userTO.getPlainAttrs().add(attrTO("fullname", userId));
+ userTO.getPlainAttrs().add(attrTO("surname", userId));
+
+ userTO = createUser(userTO);
+ assertNotNull(userTO);
+ assertTrue(userTO.getResources().isEmpty());
+
+ // 2. update assigning a resource forcing mandatory constraints: must fail with RequiredValuesMissing
+ UserMod userMod = new UserMod();
+ userMod.setKey(userTO.getKey());
+ userMod.setPassword("newPassword123");
+ userMod.getResourcesToAdd().add(RESOURCE_NAME_WS2);
+
+ try {
+ userTO = updateUser(userMod);
+ fail();
+ } catch (SyncopeClientException e) {
+ assertEquals(ClientExceptionType.RequiredValuesMissing, e.getType());
+ }
+
+ // 3. update assigning a resource NOT forcing mandatory constraints
+ // AND primary: must fail with PropagationException
+ userMod = new UserMod();
+ userMod.setKey(userTO.getKey());
+ userMod.setPassword("newPassword123");
+ userMod.getResourcesToAdd().add(RESOURCE_NAME_WS1);
+
+ userTO = updateUser(userMod);
+ assertNotNull(userTO.getPropagationStatusTOs().get(0).getFailureReason());
+
+ // 4. update assigning a resource NOT forcing mandatory constraints
+ // BUT not primary: must succeed
+ userMod = new UserMod();
+ userMod.setKey(userTO.getKey());
+ userMod.setPassword("newPassword123456");
+ userMod.getResourcesToAdd().add(RESOURCE_NAME_CSV);
+ updateUser(userMod);
+ }
+
+ @Test
+ public void enforceMandatoryCondition() {
+ UserTO userTO = getUniqueSampleTO("enforce@apache.org");
+ userTO.getResources().add(RESOURCE_NAME_WS2);
+ userTO.setPassword("newPassword12");
+
+ AttrTO type = null;
+ for (AttrTO attr : userTO.getPlainAttrs()) {
+ if ("type".equals(attr.getSchema())) {
+ type = attr;
+ }
+ }
+ assertNotNull(type);
+ userTO.getPlainAttrs().remove(type);
+
+ try {
+ userTO = createUser(userTO);
+ fail();
+ } catch (SyncopeClientException e) {
+ assertEquals(ClientExceptionType.RequiredValuesMissing, e.getType());
+ }
+
+ userTO.getPlainAttrs().add(type);
+ userTO = createUser(userTO);
+ assertNotNull(userTO);
+ }
+
+ @Test
+ public void enforceMandatoryConditionOnDerived() {
+ ResourceTO resourceTO = resourceService.read(RESOURCE_NAME_CSV);
+ assertNotNull(resourceTO);
+ resourceTO.setKey("resource-csv-enforcing");
+ resourceTO.setEnforceMandatoryCondition(true);
+
+ Response response = resourceService.create(resourceTO);
+ resourceTO = getObject(response.getLocation(), ResourceService.class, ResourceTO.class);
+ assertNotNull(resourceTO);
+
+ UserTO userTO = getUniqueSampleTO("syncope222@apache.org");
+ userTO.getResources().add(resourceTO.getKey());
+ userTO.setPassword("newPassword12");
+
+ try {
+ userTO = createUser(userTO);
+ fail();
+ } catch (SyncopeClientException e) {
+ assertEquals(ClientExceptionType.RequiredValuesMissing, e.getType());
+ }
+
+ userTO.getAuxClasses().add("csv");
+ userTO.getDerAttrs().add(attrTO("csvuserid", null));
+
+ userTO = createUser(userTO);
+ assertNotNull(userTO);
+ assertEquals(Collections.singleton("resource-csv-enforcing"), userTO.getResources());
+ }
+
+ @Test
+ public void createUserWithDbPropagation() {
+ UserTO userTO = getUniqueSampleTO("yyy@yyy.yyy");
+ userTO.getResources().add(RESOURCE_NAME_TESTDB);
+ userTO = createUser(userTO);
+ assertNotNull(userTO);
+ assertEquals(1, userTO.getPropagationStatusTOs().size());
+ assertTrue(userTO.getPropagationStatusTOs().get(0).getStatus().isSuccessful());
+ }
+
+ @Test(expected = SyncopeClientException.class)
+ public void createWithInvalidPassword() {
+ UserTO userTO = getSampleTO("invalidpasswd@syncope.apache.org");
+ userTO.setPassword("pass");
+ createUser(userTO);
+ }
+
+ @Test(expected = SyncopeClientException.class)
+ public void createWithInvalidUsername() {
+ UserTO userTO = getSampleTO("invalidusername@syncope.apache.org");
+ userTO.setUsername("us");
+ userTO.setRealm("/odd");
+
+ createUser(userTO);
+ }
+
+ @Test(expected = SyncopeClientException.class)
+ public void createWithInvalidPasswordByRes() {
+ UserTO userTO = getSampleTO("invalidPwdByRes@passwd.com");
+
+ // configured to be minLength=16
+ userTO.setPassword("password1");
+ userTO.getResources().add(RESOURCE_NAME_NOPROPAGATION);
+ createUser(userTO);
+ }
+
+ @Test(expected = SyncopeClientException.class)
+ public void createWithInvalidPasswordByGroup() {
+ UserTO userTO = getSampleTO("invalidPwdByGroup@passwd.com");
+
+ // configured to be minLength=16
+ userTO.setPassword("password1");
+
+ MembershipTO membership = new MembershipTO();
+ membership.setRightKey(8L);
+
+ userTO.getMemberships().add(membership);
+
+ createUser(userTO);
+ }
+
+ @Test(expected = SyncopeClientException.class)
+ public void createWithException() {
+ UserTO newUserTO = new UserTO();
+ newUserTO.getPlainAttrs().add(attrTO("userId", "userId@nowhere.org"));
+ createUser(newUserTO);
+ }
+
+ @Test
+ public void create() {
+ // get task list
+ PagedResult<PropagationTaskTO> tasks = taskService.list(
+ TaskType.PROPAGATION,
+ SyncopeClient.getListQueryBuilder().page(1).size(1).build());
+ assertNotNull(tasks);
+ assertFalse(tasks.getResult().isEmpty());
+
+ long maxKey = tasks.getResult().iterator().next().getKey();
+ PropagationTaskTO taskTO = taskService.read(maxKey);
+
+ assertNotNull(taskTO);
+ int maxTaskExecutions = taskTO.getExecutions().size();
+
+ UserTO userTO = getUniqueSampleTO("a.b@c.com");
+
+ // add a membership
+ MembershipTO membershipTO = new MembershipTO();
+ membershipTO.setRightKey(8L);
+ userTO.getMemberships().add(membershipTO);
+
+ // add an attribute with a non-existing schema: must be ignored
+ AttrTO attrWithInvalidSchemaTO = attrTO("invalid schema", "a value");
+ userTO.getPlainAttrs().add(attrWithInvalidSchemaTO);
+
+ // add an attribute with null value: must be ignored
+ userTO.getPlainAttrs().add(attrTO("activationDate", null));
+
+ // 1. create user
+ UserTO newUserTO = createUser(userTO);
+
+ assertNotNull(newUserTO);
+
+ // issue SYNCOPE-15
+ assertNotNull(newUserTO.getCreationDate());
+ assertNotNull(newUserTO.getCreator());
+ assertNotNull(newUserTO.getLastChangeDate());
+ assertNotNull(newUserTO.getLastModifier());
+ assertEquals(newUserTO.getCreationDate(), newUserTO.getLastChangeDate());
+
+ assertFalse(newUserTO.getPlainAttrs().contains(attrWithInvalidSchemaTO));
+
+ // check for changePwdDate
+ assertNotNull(newUserTO.getCreationDate());
+
+ // 2. check for virtual attribute value
+ newUserTO = userService.read(newUserTO.getKey());
+ assertNotNull(newUserTO);
+
+ assertNotNull(newUserTO.getVirAttrMap());
+ assertNotNull(newUserTO.getVirAttrMap().get("virtualdata").getValues());
+ assertFalse(newUserTO.getVirAttrMap().get("virtualdata").getValues().isEmpty());
+ assertEquals("virtualvalue", newUserTO.getVirAttrMap().get("virtualdata").getValues().get(0));
+
+ // get the new task list
+ tasks = taskService.list(
+ TaskType.PROPAGATION,
+ SyncopeClient.getListQueryBuilder().page(1).size(1).build());
+ assertNotNull(tasks);
+ assertFalse(tasks.getResult().isEmpty());
+
+ long newMaxKey = tasks.getResult().iterator().next().getKey();
+
+ // default configuration for ws-target-resource2:
+ // only failed executions have to be registered
+ // --> no more tasks/executions should be added
+ assertEquals(newMaxKey, maxKey);
+
+ // get last task
+ taskTO = taskService.read(newMaxKey);
+
+ assertNotNull(taskTO);
+ assertEquals(maxTaskExecutions, taskTO.getExecutions().size());
+
+ // 3. verify password
+ try {
+ Pair<Map<String, Set<String>>, UserTO> self =
+ clientFactory.create(newUserTO.getUsername(), "password123").self();
+ assertNotNull(self);
+ } catch (AccessControlException e) {
+ fail("Credentials should be valid and not cause AccessControlException");
+ }
+
+ UserSelfService userSelfService2 = clientFactory.create(
+ newUserTO.getUsername(), "passwordXX").getService(UserSelfService.class);
+ try {
+ userSelfService2.read();
+ fail("Credentials are invalid, thus request should raise AccessControlException");
+ } catch (AccessControlException e) {
+ assertNotNull(e);
+ }
+
+ // 4. try (and fail) to create another user with same (unique) values
+ userTO = getSampleTO(userTO.getUsername());
+ AttrTO userIdAttr = userTO.getPlainAttrMap().get("userId");
+ userIdAttr.getValues().clear();
+ userIdAttr.getValues().add("a.b@c.com");
+
+ try {
+ createUser(userTO);
+ fail();
+ } catch (SyncopeClientException e) {
+ assertEquals(ClientExceptionType.GenericPersistence, e.getType());
+ }
+ }
+
+ @Test
+ public void createWithRequiredValueMissing() {
+ UserTO userTO = getSampleTO("a.b@c.it");
+
+ AttrTO type = userTO.getPlainAttrMap().get("type");
+ userTO.getPlainAttrs().remove(type);
+
+ MembershipTO membershipTO = new MembershipTO();
+ membershipTO.setRightKey(8L);
+ userTO.getMemberships().add(membershipTO);
+
+ // 1. create user without type (mandatory by UserSchema)
+ try {
+ createUser(userTO);
+ fail();
+ } catch (SyncopeClientException e) {
+ assertEquals(ClientExceptionType.RequiredValuesMissing, e.getType());
+ }
+
+ userTO.getPlainAttrs().add(attrTO("type", "F"));
+
+ AttrTO surname = userTO.getPlainAttrMap().get("surname");
+ userTO.getPlainAttrs().remove(surname);
+
+ // 2. create user without surname (mandatory when type == 'F')
+ try {
+ createUser(userTO);
+ fail();
+ } catch (SyncopeClientException e) {
+ assertEquals(ClientExceptionType.RequiredValuesMissing, e.getType());
+ }
+ }
+
+ @Test
+ public void delete() {
+ try {
+ userService.delete(0L);
+ } catch (SyncopeClientException e) {
+ assertEquals(Response.Status.NOT_FOUND, e.getType().getResponseStatus());
+ }
+
+ UserTO userTO = getSampleTO("qqgf.z@nn.com");
+
+ // specify a propagation
+ userTO.getResources().add(RESOURCE_NAME_TESTDB);
+
+ userTO = createUser(userTO);
+
+ long id = userTO.getKey();
+
+ userTO = deleteUser(id);
+
+ assertNotNull(userTO);
+ assertEquals(id, userTO.getKey());
+ assertTrue(userTO.getPlainAttrs().isEmpty());
+
+ // check for propagation result
+ assertFalse(userTO.getPropagationStatusTOs().isEmpty());
+ assertTrue(userTO.getPropagationStatusTOs().get(0).getStatus().isSuccessful());
+
+ try {
+ userService.delete(userTO.getKey());
+ } catch (SyncopeClientException e) {
+ assertEquals(Response.Status.NOT_FOUND, e.getType().getResponseStatus());
+ }
+ }
+
+ @Test
+ public void deleteByUsername() {
+ UserTO userTO = getSampleTO("delete.by.username@apache.org");
+
+ // specify a propagation
+ userTO.getResources().add(RESOURCE_NAME_TESTDB);
+
+ userTO = createUser(userTO);
+
+ long id = userTO.getKey();
+ userTO = userService.read(id);
+ userTO = deleteUser(userTO.getKey());
+
+ assertNotNull(userTO);
+ assertEquals(id, userTO.getKey());
+ assertTrue(userTO.getPlainAttrs().isEmpty());
+
+ // check for propagation result
+ assertFalse(userTO.getPropagationStatusTOs().isEmpty());
+ assertTrue(userTO.getPropagationStatusTOs().get(0).getStatus().isSuccessful());
+
+ try {
+ userService.read(userTO.getKey());
+ } catch (SyncopeClientException e) {
+ assertEquals(Response.Status.NOT_FOUND, e.getType().getResponseStatus());
+ }
+ }
+
+ @Test
+ public void list() {
+ PagedResult<UserTO> users = userService.list(
+ SyncopeClient.getAnyListQueryBuilder().realm(SyncopeConstants.ROOT_REALM).build());
+ assertNotNull(users);
+ assertFalse(users.getResult().isEmpty());
+
+ for (UserTO user : users.getResult()) {
+ assertNotNull(user);
+ }
+ }
+
+ @Test
+ public void paginatedList() {
+ PagedResult<UserTO> users = userService.list(
+ SyncopeClient.getAnyListQueryBuilder().realm(SyncopeConstants.ROOT_REALM).page(1).size(2).build());
+ assertNotNull(users);
+ assertFalse(users.getResult().isEmpty());
+ assertEquals(2, users.getResult().size());
+
+ for (UserTO user : users.getResult()) {
+ assertNotNull(user);
+ }
+
+ users = userService.list(SyncopeClient.getAnyListQueryBuilder().realm(SyncopeConstants.ROOT_REALM).
+ page(2).size(2).build());
+ assertNotNull(users);
+ assertEquals(2, users.getPage());
+ assertEquals(2, users.getResult().size());
+
+ users = userService.list(SyncopeClient.getAnyListQueryBuilder().realm(SyncopeConstants.ROOT_REALM).
+ page(100).size(2).build());
+ assertNotNull(users);
+ assertTrue(users.getResult().isEmpty());
+ }
+
+ @Test
+ public void read() {
+ UserTO userTO = userService.read(1L);
+
+ assertNotNull(userTO);
+ assertNotNull(userTO.getPlainAttrs());
+ assertFalse(userTO.getPlainAttrs().isEmpty());
+ }
+
+ @Test
+ public void readWithMailAddressAsUserName() {
+ UserTO userTO = createUser(getUniqueSampleTO("mail@domain.org"));
+ userTO = userService.read(userTO.getKey());
+ assertNotNull(userTO);
+ }
+
+ @Test
+ public void updateWithouPassword() {
+ UserTO userTO = getUniqueSampleTO("updatewithout@password.com");
+
+ userTO = createUser(userTO);
+
+ assertNotNull(userTO);
+
+ UserMod userMod = new UserMod();
+ userMod.setKey(userTO.getKey());
+ userMod.getDerAttrsToRemove().add("cn");
+
+ userTO = updateUser(userMod);
+
+ assertNotNull(userTO);
+ assertNotNull(userTO.getDerAttrMap());
+ assertFalse(userTO.getDerAttrMap().containsKey("cn"));
+ }
+
+ @Test(expected = SyncopeClientException.class)
+ public void updateInvalidPassword() {
+ UserTO userTO = getSampleTO("updateinvalid@password.com");
+
+ userTO = createUser(userTO);
+ assertNotNull(userTO);
+
+ UserMod userMod = new UserMod();
+ userMod.setKey(userTO.getKey());
+ userMod.setPassword("pass");
+
+ userService.update(userMod);
+ }
+
+ @Test(expected = SyncopeClientException.class)
+ public void updateSamePassword() {
+ UserTO userTO = getUniqueSampleTO("updatesame@password.com");
+ userTO.setRealm("/even/two");
+
+ userTO = createUser(userTO);
+ assertNotNull(userTO);
+
+ UserMod userMod = new UserMod();
+ userMod.setKey(userTO.getKey());
+ userMod.setPassword("password123");
+
+ userService.update(userMod);
+ }
+
+ @Test
+ public void update() {
+ UserTO userTO = getUniqueSampleTO("g.h@t.com");
+
+ MembershipTO membershipTO = new MembershipTO();
+ membershipTO.setRightKey(8L);
+ userTO.getMemberships().add(membershipTO);
+
+ userTO = createUser(userTO);
+
+ assertFalse(userTO.getDerAttrs().isEmpty());
+ assertEquals(1, userTO.getMemberships().size());
+
+ UserMod userMod = new UserMod();
+ userMod.setKey(userTO.getKey());
+ userMod.setPassword("new2Password");
+
+ userMod.getPlainAttrsToRemove().add("userId");
+ String newUserId = getUUIDString() + "t.w@spre.net";
+ userMod.getPlainAttrsToUpdate().add(attrMod("userId", newUserId));
+
+ userMod.getPlainAttrsToRemove().add("fullname");
+ String newFullName = getUUIDString() + "g.h@t.com";
+ userMod.getPlainAttrsToUpdate().add(attrMod("fullname", newFullName));
+
+ userMod.getDerAttrsToAdd().add("cn");
+ userMod.getMembershipsToAdd().add(8L);
+ userMod.getMembershipsToRemove().add(userTO.getMemberships().get(0).getRightKey());
+
+ userTO = updateUser(userMod);
+ assertNotNull(userTO);
+
+ // issue SYNCOPE-15
+ assertNotNull(userTO.getCreationDate());
+ assertNotNull(userTO.getCreator());
+ assertNotNull(userTO.getLastChangeDate());
+ assertNotNull(userTO.getLastModifier());
+ assertTrue(userTO.getCreationDate().before(userTO.getLastChangeDate()));
+
+ assertEquals(1, userTO.getMemberships().size());
+ assertFalse(userTO.getDerAttrs().isEmpty());
+
+ AttrTO userIdAttr = userTO.getPlainAttrMap().get("userId");
+ assertEquals(Collections.singletonList(newUserId), userIdAttr.getValues());
+
+ AttrTO fullNameAttr = userTO.getPlainAttrMap().get("fullname");
+ assertEquals(Collections.singletonList(newFullName), fullNameAttr.getValues());
+ }
+
+ @Test
+ public void updatePasswordOnly() {
+ int beforeTasks = taskService.list(TaskType.PROPAGATION,
+ SyncopeClient.getListQueryBuilder().page(1).size(1).build()).getTotalCount();
+ assertFalse(beforeTasks <= 0);
+
+ UserTO userTO = getUniqueSampleTO("pwdonly@t.com");
+ MembershipTO membershipTO = new MembershipTO();
+ membershipTO.setRightKey(8L);
+ userTO.getMemberships().add(membershipTO);
+
+ userTO = createUser(userTO);
+
+ UserMod userMod = new UserMod();
+ userMod.setKey(userTO.getKey());
+ userMod.setPassword("newPassword123");
+
+ userTO = updateUser(userMod);
+
+ // check for changePwdDate
+ assertNotNull(userTO.getChangePwdDate());
+
+ int afterTasks = taskService.list(TaskType.PROPAGATION,
+ SyncopeClient.getListQueryBuilder().page(1).size(1).build()).getTotalCount();
+ assertFalse(beforeTasks <= 0);
+
+ assertTrue(beforeTasks < afterTasks);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Test
+ public void verifyTaskRegistration() {
+ // get task list
+ PagedResult<PropagationTaskTO> tasks = taskService.list(
+ TaskType.PROPAGATION,
+ SyncopeClient.getListQueryBuilder().page(1).size(1).build());
+ assertNotNull(tasks);
+ assertFalse(tasks.getResult().isEmpty());
+
+ long maxKey = tasks.getResult().iterator().next().getKey();
+
+ // --------------------------------------
+ // Create operation
+ // --------------------------------------
+ UserTO userTO = getUniqueSampleTO("t@p.mode");
+
+ // add a membership
+ MembershipTO membershipTO = new MembershipTO();
+ membershipTO.setRightKey(8L);
+ userTO.getMemberships().add(membershipTO);
+
+ // 1. create user
+ userTO = createUser(userTO);
+ assertNotNull(userTO);
+
+ // get the new task list
+ tasks = taskService.list(
+ TaskType.PROPAGATION,
+ SyncopeClient.getListQueryBuilder().page(1).size(1).build());
+ assertNotNull(tasks);
+ assertFalse(tasks.getResult().isEmpty());
+
+ long newMaxKey = tasks.getResult().iterator().next().getKey();
+
+ // default configuration for ws-target-resource2:
+ // only failed executions have to be registered
+ // --> no more tasks/executions should be added
+ assertEquals(newMaxKey, maxKey);
+
+ // --------------------------------------
+ // Update operation
+ // --------------------------------------
+ UserMod userMod = new UserMod();
+ userMod.setKey(userTO.getKey());
+
+ userMod.getPlainAttrsToUpdate().add(attrMod("surname", "surname"));
+
+ userTO = updateUser(userMod);
+
+ assertNotNull(userTO);
+
+ // get the new task list
+ tasks = taskService.list(
+ TaskType.PROPAGATION,
+ SyncopeClient.getListQueryBuilder().page(1).size(1).build());
+
+ maxKey = newMaxKey;
+ newMaxKey = tasks.getResult().iterator().next().getKey();
+
+ // default configuration for ws-target-resource2:
+ // all update executions have to be registered
+ assertTrue(newMaxKey > maxKey);
+
+ final PropagationTaskTO taskTO = taskService.read(newMaxKey);
+
+ assertNotNull(taskTO);
+ assertEquals(1, taskTO.getExecutions().size());
+
+ // --------------------------------------
+ // Delete operation
+ // --------------------------------------
+ userService.delete(userTO.getKey());
+
+ // get the new task list
+ tasks = taskService.list(
+ TaskType.PROPAGATION,
+ SyncopeClient.getListQueryBuilder().page(1).size(1).build());
+
+ maxKey = newMaxKey;
+ newMaxKey = tasks.getResult().iterator().next().getKey();
+
+ // default configuration for ws-target-resource2: no delete executions have to be registered
+ // --> no more tasks/executions should be added
+ assertEquals(newMaxKey, maxKey);
+ }
+
+ @Test
+ public void createActivate() {
+ Assume.assumeTrue(ActivitiDetector.isActivitiEnabledForUsers(syncopeService));
+
+ UserTO userTO = getUniqueSampleTO("createActivate@syncope.apache.org");
+
+ MembershipTO membershipTO = new MembershipTO();
+ membershipTO.setRightKey(11L);
+ userTO.getMemberships().add(membershipTO);
+
+ userTO = createUser(userTO);
+
+ assertNotNull(userTO);
+ assertNotNull(userTO.getToken());
+ assertNotNull(userTO.getTokenExpireTime());
+
+ assertEquals("created", userTO.getStatus());
+
+ StatusMod statusMod = new StatusMod();
+ statusMod.setKey(userTO.getKey());
+ statusMod.setType(StatusMod.ModType.ACTIVATE);
+ statusMod.setToken(userTO.getToken());
+ userTO = userService.status(statusMod).readEntity(UserTO.class);
+
+ assertNotNull(userTO);
+ assertNull(userTO.getToken());
+ assertNull(userTO.getTokenExpireTime());
+ assertEquals("active", userTO.getStatus());
+ }
+
+ @Test
+ public void suspendReactivate() {
+ UserTO userTO = getUniqueSampleTO("suspendReactivate@syncope.apache.org");
+
+ MembershipTO membershipTO = new MembershipTO();
+ membershipTO.setRightKey(7L);
+ userTO.getMemberships().add(membershipTO);
+
+ userTO = createUser(userTO);
+
+ assertNotNull(userTO);
+ assertEquals(ActivitiDetector.isActivitiEnabledForUsers(syncopeService)
+ ? "active"
+ : "created", userTO.getStatus());
+
+ StatusMod statusMod = new StatusMod();
+ statusMod.setKey(userTO.getKey());
+ statusMod.setType(StatusMod.ModType.SUSPEND);
+ userTO = userService.status(statusMod).readEntity(UserTO.class);
+ assertNotNull(userTO);
+ assertEquals("suspended", userTO.getStatus());
+
+ statusMod = new StatusMod();
+ statusMod.setKey(userTO.getKey());
+ statusMod.setType(StatusMod.ModType.REACTIVATE);
+ userTO = userService.status(statusMod).readEntity(UserTO.class);
+ assertNotNull(userTO);
+ assertEquals("active", userTO.getStatus());
+ }
+
+ @Test
+ public void suspendReactivateOnResource() {
+ // Assert resources are present
+ ResourceTO dbTable = resourceService.read(RESOURCE_NAME_TESTDB);
+ assertNotNull(dbTable);
+ ResourceTO ldap = resourceService.read(RESOURCE_NAME_LDAP);
+ assertNotNull(ldap);
+
+ // Create user with reference to resources
+ UserTO userTO = getUniqueSampleTO("suspreactonresource@syncope.apache.org");
+ userTO.getMemberships().clear();
+ userTO.getResources().clear();
+ userTO.getResources().add(RESOURCE_NAME_TESTDB);
+ userTO.getResources().add(RESOURCE_NAME_LDAP);
+ userTO = createUser(userTO);
+ assertNotNull(userTO);
+ assertEquals(ActivitiDetector.isActivitiEnabledForUsers(syncopeService)
+ ? "active"
+ : "created", userTO.getStatus());
+ long userKey = userTO.getKey();
+
+ // Suspend with effect on syncope, ldap and db => user should be suspended in syncope and all resources
+ StatusMod statusMod = new StatusMod();
+ statusMod.setKey(userKey);
+ statusMod.setType(StatusMod.ModType.SUSPEND);
+ statusMod.setOnSyncope(true);
- statusMod.getResourceNames().add(RESOURCE_NAME_TESTDB);
- statusMod.getResourceNames().add(RESOURCE_NAME_LDAP);
++ statusMod.getResources().add(RESOURCE_NAME_TESTDB);
++ statusMod.getResources().add(RESOURCE_NAME_LDAP);
+ userTO = userService.status(statusMod).readEntity(UserTO.class);
+ assertNotNull(userTO);
+ assertEquals("suspended", userTO.getStatus());
+
+ ConnObjectTO connObjectTO =
+ resourceService.readConnObject(RESOURCE_NAME_TESTDB, AnyTypeKind.USER.name(), userKey);
+ assertFalse(getBooleanAttribute(connObjectTO, OperationalAttributes.ENABLE_NAME));
+
+ connObjectTO = resourceService.readConnObject(RESOURCE_NAME_LDAP, AnyTypeKind.USER.name(), userKey);
+ assertNotNull(connObjectTO);
+
+ // Suspend and reactivate only on ldap => db and syncope should still show suspended
+ statusMod = new StatusMod();
+ statusMod.setKey(userKey);
+ statusMod.setType(StatusMod.ModType.SUSPEND);
+ statusMod.setOnSyncope(false);
- statusMod.getResourceNames().add(RESOURCE_NAME_LDAP);
++ statusMod.getResources().add(RESOURCE_NAME_LDAP);
+ userService.status(statusMod);
+ statusMod.setType(StatusMod.ModType.REACTIVATE);
+ userTO = userService.status(statusMod).readEntity(UserTO.class);
+ assertNotNull(userTO);
+ assertEquals("suspended", userTO.getStatus());
+
+ connObjectTO = resourceService.readConnObject(RESOURCE_NAME_TESTDB, AnyTypeKind.USER.name(), userKey);
+ assertFalse(getBooleanAttribute(connObjectTO, OperationalAttributes.ENABLE_NAME));
+
+ // Reactivate on syncope and db => syncope and db should show the user as active
+ statusMod = new StatusMod();
+ statusMod.setKey(userKey);
+ statusMod.setType(StatusMod.ModType.REACTIVATE);
+ statusMod.setOnSyncope(true);
- statusMod.getResourceNames().add(RESOURCE_NAME_TESTDB);
++ statusMod.getResources().add(RESOURCE_NAME_TESTDB);
+
+ userTO = userService.status(statusMod).readEntity(UserTO.class);
+ assertNotNull(userTO);
+ assertEquals("active", userTO.getStatus());
+
+ connObjectTO = resourceService.readConnObject(RESOURCE_NAME_TESTDB, AnyTypeKind.USER.name(), userKey);
+ assertTrue(getBooleanAttribute(connObjectTO, OperationalAttributes.ENABLE_NAME));
+ }
+
+ @Test
+ public void updateMultivalueAttribute() {
+ UserTO userTO = getUniqueSampleTO("multivalue@syncope.apache.org");
+ userTO.getResources().clear();
+ userTO.getDerAttrs().clear();
+ userTO.getVirAttrs().clear();
+
+ userTO = createUser(userTO);
+ assertNotNull(userTO);
+
+ AttrTO loginDate = userTO.getPlainAttrMap().get("loginDate");
+ assertNotNull(loginDate);
+ assertEquals(1, loginDate.getValues().size());
+
+ UserMod userMod = new UserMod();
+
+ userMod.setKey(userTO.getKey());
+ userMod.getPlainAttrsToUpdate().add(attrMod("loginDate", "2000-01-01"));
+
+ userTO = updateUser(userMod);
+ assertNotNull(userTO);
+
+ loginDate = userTO.getPlainAttrMap().get("loginDate");
+ assertNotNull(loginDate);
+ assertEquals(2, loginDate.getValues().size());
+ }
+
+ @Test(expected = EmptyResultDataAccessException.class)
+ public void issue213() {
+ UserTO userTO = getUniqueSampleTO("issue213@syncope.apache.org");
+ userTO.getResources().add(RESOURCE_NAME_TESTDB);
+
+ userTO = createUser(userTO);
+ assertNotNull(userTO);
+ assertEquals(1, userTO.getResources().size());
+
+ JdbcTemplate jdbcTemplate = new JdbcTemplate(testDataSource);
+
+ String username = jdbcTemplate.queryForObject("SELECT id FROM test WHERE id=?", String.class,
+ userTO.getUsername());
+
+ assertEquals(userTO.getUsername(), username);
+
+ UserMod userMod = new UserMod();
+
+ userMod.setKey(userTO.getKey());
+ userMod.getResourcesToRemove().add(RESOURCE_NAME_TESTDB);
+
+ userTO = updateUser(userMod);
+ assertTrue(userTO.getResources().isEmpty());
+
+ jdbcTemplate.queryForObject("SELECT id FROM test WHERE id=?", String.class, userTO.getUsername());
+ }
+
+ @Test
+ public void issue234() {
+ UserTO inUserTO = getUniqueSampleTO("issue234@syncope.apache.org");
+ inUserTO.getResources().add(RESOURCE_NAME_LDAP);
+
+ UserTO userTO = createUser(inUserTO);
+ assertNotNull(userTO);
+
+ UserMod userMod = new UserMod();
+
+ userMod.setKey(userTO.getKey());
+ userMod.setUsername("1" + userTO.getUsername());
+
+ userTO = updateUser(userMod);
+ assertNotNull(userTO);
+ assertEquals("1" + inUserTO.getUsername(), userTO.getUsername());
+ }
+
+ @Test
+ public void issue270() {
+ // 1. create a new user without virtual attributes
+ UserTO original = getUniqueSampleTO("issue270@syncope.apache.org");
+ // be sure to remove all virtual attributes
+ original.getVirAttrs().clear();
+
+ original = createUser(original);
+
+ assertNotNull(original);
+
+ assertTrue(original.getVirAttrs().isEmpty());
+
+ UserTO toBeUpdated = userService.read(original.getKey());
+
+ AttrTO virtual = attrTO("virtualdata", "virtualvalue");
+ toBeUpdated.getVirAttrs().add(virtual);
+
+ // 2. try to update by adding a resource, but no password: must fail
+ UserMod userMod = AnyOperations.diff(toBeUpdated, original);
+ assertNotNull(userMod);
+
+ toBeUpdated = updateUser(userMod);
+ assertNotNull(toBeUpdated);
+
+ assertFalse(toBeUpdated.getVirAttrs().isEmpty());
+ assertNotNull(toBeUpdated.getVirAttrs().iterator().next());
+
+ assertEquals(virtual.getSchema(), toBeUpdated.getVirAttrs().iterator().next().getSchema());
+ }
+
+ @Test
+ public final void issue280() {
+ UserTO userTO = getUniqueSampleTO("issue280@syncope.apache.org");
+ userTO.getResources().clear();
+ userTO.getMemberships().clear();
+ userTO.getDerAttrs().clear();
+
+ userTO = createUser(userTO);
+ assertNotNull(userTO);
+
+ UserMod userMod = new UserMod();
+ userMod.setKey(userTO.getKey());
+ userMod.setPassword("123password");
+ userMod.getResourcesToAdd().add(RESOURCE_NAME_TESTDB);
+
+ final StatusMod st = new StatusMod();
+ st.setOnSyncope(false);
- st.getResourceNames().add(RESOURCE_NAME_TESTDB);
++ st.getResources().add(RESOURCE_NAME_TESTDB);
+ userMod.setPwdPropRequest(st);
+
+ userTO = updateUser(userMod);
+ assertNotNull(userTO);
+
+ final List<PropagationStatus> propagations = userTO.getPropagationStatusTOs();
+
+ assertNotNull(propagations);
+ assertEquals(1, propagations.size());
+
+ final PropagationTaskExecStatus status = propagations.get(0).getStatus();
+ final String resource = propagations.get(0).getResource();
+
+ assertNotNull(status);
+ assertEquals(RESOURCE_NAME_TESTDB, resource);
+ assertTrue(status.isSuccessful());
+ }
+
+ @Test
+ public void issue281() {
+ UserTO userTO = getUniqueSampleTO("issue281@syncope.apache.org");
+ userTO.getResources().clear();
+ userTO.getMemberships().clear();
+ userTO.getDerAttrs().clear();
+ userTO.getResources().add(RESOURCE_NAME_CSV);
+
+ userTO = createUser(userTO);
+ assertNotNull(userTO);
+
+ final List<PropagationStatus> propagations = userTO.getPropagationStatusTOs();
+
+ assertNotNull(propagations);
+ assertEquals(1, propagations.size());
+
+ final PropagationTaskExecStatus status = propagations.get(0).getStatus();
+ final String resource = propagations.get(0).getResource();
+
+ assertNotNull(status);
+ assertEquals(RESOURCE_NAME_CSV, resource);
+ assertFalse(status.isSuccessful());
+ }
+
+ @Test
+ public void issue288() {
+ UserTO userTO = getSampleTO("issue288@syncope.apache.org");
+ userTO.getPlainAttrs().add(attrTO("aLong", "STRING"));
+
+ try {
+ createUser(userTO);
+ fail();
+ } catch (SyncopeClientException e) {
+ assertEquals(ClientExceptionType.InvalidValues, e.getType());
+ }
+ }
+
+ @Test
+ public void groupAttrPropagation() {
+ UserTO userTO = getUniqueSampleTO("checkGroupAttrPropagation@syncope.apache.org");
+ userTO.getResources().clear();
+ userTO.getMemberships().clear();
+ userTO.getDerAttrs().clear();
+ userTO.getVirAttrs().clear();
+
+ userTO.getAuxClasses().add("csv");
+ userTO.getDerAttrs().add(attrTO("csvuserid", null));
+
+ MembershipTO membershipTO = new MembershipTO();
+ membershipTO.setRightKey(1L);
+
+ userTO.getMemberships().add(membershipTO);
+
+ userTO.getResources().add(RESOURCE_NAME_CSV);
+
+ UserTO actual = createUser(userTO);
+ assertNotNull(actual);
+ assertNotNull(actual.getDerAttrMap().get("csvuserid"));
+
+ ConnObjectTO connObjectTO =
+ resourceService.readConnObject(RESOURCE_NAME_CSV, AnyTypeKind.USER.name(), actual.getKey());
+ assertNotNull(connObjectTO);
+ assertEquals("sx-dx", connObjectTO.getPlainAttrMap().get("THEIRGROUP").getValues().get(0));
+ }
+
+ @Test
+ public void noContent() throws IOException {
+ SyncopeClient noContentclient = clientFactory.create(ADMIN_UNAME, ADMIN_PWD);
+ UserService noContentService = noContentclient.prefer(UserService.class, Preference.RETURN_NO_CONTENT);
+
+ UserTO user = getUniqueSampleTO("nocontent@syncope.apache.org");
+
+ Response response = noContentService.create(user, true);
+ assertEquals(Response.Status.CREATED.getStatusCode(), response.getStatus());
+ assertEquals(Preference.RETURN_NO_CONTENT.toString(), response.getHeaderString(RESTHeaders.PREFERENCE_APPLIED));
+ assertEquals(StringUtils.EMPTY, IOUtils.toString((InputStream) response.getEntity()));
+
+ user = getObject(response.getLocation(), UserService.class, UserTO.class);
+ assertNotNull(user);
+
+ UserMod userMod = new UserMod();
+ userMod.setKey(user.getKey());
+ userMod.setPassword("password321");
+
+ response = noContentService.update(userMod);
+ assertEquals(Response.Status.NO_CONTENT.getStatusCode(), response.getStatus());
+ assertEquals(Preference.RETURN_NO_CONTENT.toString(), response.getHeaderString(RESTHeaders.PREFERENCE_APPLIED));
+ assertEquals(StringUtils.EMPTY, IOUtils.toString((InputStream) response.getEntity()));
+
+ response = noContentService.delete(user.getKey());
+ assertEquals(Response.Status.NO_CONTENT.getStatusCode(), response.getStatus());
+ assertEquals(Preference.RETURN_NO_CONTENT.toString(), response.getHeaderString(RESTHeaders.PREFERENCE_APPLIED));
+ assertEquals(StringUtils.EMPTY, IOUtils.toString((InputStream) response.getEntity()));
+ }
+
+ @Test
+ public void customPolicyRules() {
+ // Using custom policy rules with application/xml requires to overwrite
+ // org.apache.syncope.common.lib.policy.AbstractAccountRuleConf's and / or
+ // org.apache.syncope.common.lib.policy.AbstractPasswordRuleConf's
+ // @XmlSeeAlso - the power of JAXB :-/
+ Assume.assumeTrue(MediaType.APPLICATION_JSON_TYPE.equals(clientFactory.getContentType().getMediaType()));
+
+ AccountPolicyTO accountPolicy = new AccountPolicyTO();
+ accountPolicy.setDescription("Account Policy with custom rules");
+ accountPolicy.getRuleConfs().add(new TestAccountRuleConf());
+ accountPolicy = createPolicy(accountPolicy);
+ assertNotNull(accountPolicy);
+
+ PasswordPolicyTO passwordPolicy = new PasswordPolicyTO();
+ passwordPolicy.setDescription("Password Policy with custom rules");
+ passwordPolicy.getRuleConfs().add(new TestPasswordRuleConf());
+ passwordPolicy = createPolicy(passwordPolicy);
+ assertNotNull(passwordPolicy);
+
+ RealmTO realm = realmService.list("/even/two").get(0);
+ Long oldAccountPolicy = realm.getAccountPolicy();
+ realm.setAccountPolicy(accountPolicy.getKey());
+ Long oldPasswordPolicy = realm.getPasswordPolicy();
+ realm.setPasswordPolicy(passwordPolicy.getKey());
+ realmService.update(realm);
+
+ try {
+ UserTO user = getUniqueSampleTO("custompolicyrules@syncope.apache.org");
+ user.setRealm(realm.getFullPath());
+ try {
+ createUser(user);
+ fail();
+ } catch (SyncopeClientException e) {
+ assertEquals(ClientExceptionType.InvalidUser, e.getType());
+ assertTrue(e.getElements().iterator().next().startsWith("InvalidPassword"));
+ }
+
+ user.setPassword(user.getPassword() + "XXX");
+ try {
+ createUser(user);
+ fail();
+ } catch (SyncopeClientException e) {
+ assertEquals(ClientExceptionType.InvalidUser, e.getType());
+ assertTrue(e.getElements().iterator().next().startsWith("InvalidUsername"));
+ }
+
+ user.setUsername("YYY" + user.getUsername());
+ user = createUser(user);
+ assertNotNull(user);
+ } finally {
+ realm.setAccountPolicy(oldAccountPolicy);
+ realm.setPasswordPolicy(oldPasswordPolicy);
+ realmService.update(realm);
+
+ policyService.delete(passwordPolicy.getKey());
+ policyService.delete(accountPolicy.getKey());
+ }
+ }
+
+ @Test
+ public void issueSYNCOPE108() {
+ UserTO userTO = getUniqueSampleTO("syncope108@syncope.apache.org");
+ userTO.getResources().clear();
+ userTO.getMemberships().clear();
+ userTO.getDerAttrs().clear();
+ userTO.getVirAttrs().clear();
+ userTO.getAuxClasses().add("csv");
+ userTO.getDerAttrs().add(attrTO("csvuserid", null));
+
+ MembershipTO memb12 = new MembershipTO();
+ memb12.setRightKey(12L);
+
+ userTO.getMemberships().add(memb12);
+
+ MembershipTO memb13 = new MembershipTO();
+ memb13.setRightKey(13L);
+
+ userTO.getMemberships().add(memb13);
+
+ userTO.getResources().add(RESOURCE_NAME_CSV);
+
+ UserTO actual = createUser(userTO);
+ assertNotNull(actual);
+ assertEquals(2, actual.getMemberships().size());
+ assertEquals(1, actual.getResources().size());
+
+ ConnObjectTO connObjectTO =
+ resourceService.readConnObject(RESOURCE_NAME_CSV, AnyTypeKind.USER.name(), actual.getKey());
+ assertNotNull(connObjectTO);
+
+ // -----------------------------------
+ // Remove the first membership: de-provisioning shouldn't happen
+ // -----------------------------------
+ UserMod userMod = new UserMod();
+ userMod.setKey(actual.getKey());
+
+ userMod.getMembershipsToRemove().add(actual.getMemberships().get(0).getRightKey());
+
+ actual = updateUser(userMod);
+ assertNotNull(actual);
+ assertEquals(1, actual.getMemberships().size());
+
+ connObjectTO = resourceService.readConnObject(RESOURCE_NAME_CSV, AnyTypeKind.USER.name(), actual.getKey());
+ assertNotNull(connObjectTO);
+ // -----------------------------------
+
+ // -----------------------------------
+ // Remove the resource assigned directly: de-provisioning shouldn't happen
+ // -----------------------------------
+ userMod = new UserMod();
+ userMod.setKey(actual.getKey());
+
+ userMod.getResourcesToRemove().add(actual.getResources().iterator().next());
+
+ actual = updateUser(userMod);
+ assertNotNull(actual);
+ assertEquals(1, actual.getMemberships().size());
+ assertFalse(actual.getResources().isEmpty());
+
+ connObjectTO = resourceService.readConnObject(RESOURCE_NAME_CSV, AnyTypeKind.USER.name(), actual.getKey());
+ assertNotNull(connObjectTO);
+ // -----------------------------------
+
+ // -----------------------------------
+ // Remove the first membership: de-provisioning should happen
+ // -----------------------------------
+ userMod = new UserMod();
+ userMod.setKey(actual.getKey());
+
+ userMod.getMembershipsToRemove().add(actual.getMemberships().get(0).getRightKey());
+
+ actual = updateUser(userMod);
+ assertNotNull(actual);
+ assertTrue(actual.getMemberships().isEmpty());
+ assertTrue(actual.getResources().isEmpty());
+
+ try {
+ resourceService.readConnObject(RESOURCE_NAME_CSV, AnyTypeKind.USER.name(), actual.getKey());
+ fail("Read should not succeeed");
+ } catch (SyncopeClientException e) {
+ assertEquals(ClientExceptionType.NotFound, e.getType());
+ }
+ }
+
+ @Test
+ public void issueSYNCOPE185() {
+ // 1. create user with LDAP resource, succesfully propagated
+ UserTO userTO = getSampleTO("syncope185@syncope.apache.org");
+ userTO.getVirAttrs().clear();
+ userTO.getResources().add(RESOURCE_NAME_LDAP);
+
+ userTO = createUser(userTO);
+ assertNotNull(userTO);
+ assertFalse(userTO.getPropagationStatusTOs().isEmpty());
+ assertEquals(RESOURCE_NAME_LDAP, userTO.getPropagationStatusTOs().get(0).getResource());
+ assertEquals(PropagationTaskExecStatus.SUCCESS, userTO.getPropagationStatusTOs().get(0).getStatus());
+
+ // 2. delete this user
+ userService.delete(userTO.getKey());
+
+ // 3. try (and fail) to find this user on the external LDAP resource
+ try {
+ resourceService.readConnObject(RESOURCE_NAME_LDAP, AnyTypeKind.USER.name(), userTO.getKey());
+ fail("This entry should not be present on this resource");
+ } catch (SyncopeClientException e) {
+ assertEquals(ClientExceptionType.NotFound, e.getType());
+ }
+ }
+
+ @Test()
+ public void issueSYNCOPE51() {
+ AttrTO defaultCA = configurationService.get("password.cipher.algorithm");
+ final String originalCAValue = defaultCA.getValues().get(0);
+ defaultCA.getValues().set(0, "MD5");
+ configurationService.set(defaultCA);
+
+ AttrTO newCA = configurationService.get(defaultCA.getSchema());
+ assertEquals(defaultCA, newCA);
+
+ UserTO userTO = getSampleTO("syncope51@syncope.apache.org");
+ userTO.setPassword("password");
+
+ try {
+ createUser(userTO);
+ fail("Create user should not succeed");
+ } catch (SyncopeClientException e) {
+ assertEquals(ClientExceptionType.NotFound, e.getType());
+ assertTrue(e.getElements().iterator().next().contains("MD5"));
+ }
+
+ defaultCA.getValues().set(0, originalCAValue);
+ configurationService.set(defaultCA);
+
+ AttrTO oldCA = configurationService.get(defaultCA.getSchema());
+ assertEquals(defaultCA, oldCA);
+ }
+
+ @Test
+ public void issueSYNCOPE267() {
+ // ----------------------------------
+ // create user and check virtual attribute value propagation
+ // ----------------------------------
+ UserTO userTO = getUniqueSampleTO("syncope267@apache.org");
+ userTO.getResources().clear();
+ userTO.getResources().add(RESOURCE_NAME_DBVIRATTR);
+
+ userTO = createUser(userTO);
+ assertNotNull(userTO);
+ assertFalse(userTO.getPropagationStatusTOs().isEmpty());
+ assertEquals(RESOURCE_NAME_DBVIRATTR, userTO.getPropagationStatusTOs().get(0).getResource());
+ assertEquals(PropagationTaskExecStatus.SUBMITTED, userTO.getPropagationStatusTOs().get(0).getStatus());
+
+ ConnObjectTO connObjectTO =
+ resourceService.readConnObject(RESOURCE_NAME_DBVIRATTR, AnyTypeKind.USER.name(), userTO.getKey());
+ assertNotNull(connObjectTO);
+ assertEquals("virtualvalue", connObjectTO.getPlainAttrMap().get("USERNAME").getValues().get(0));
+ // ----------------------------------
+
+ userTO = userService.read(userTO.getKey());
+
+ assertNotNull(userTO);
+ assertEquals(1, userTO.getVirAttrs().size());
+ assertEquals("virtualvalue", userTO.getVirAttrs().iterator().next().getValues().get(0));
+ }
+
+ @Test
+ public void issueSYNCOPE266() {
+ UserTO userTO = getUniqueSampleTO("syncope266@apache.org");
+ userTO.getResources().clear();
+
+ userTO = createUser(userTO);
+ assertNotNull(userTO);
+
+ UserMod userMod = new UserMod();
+ userMod.setKey(userTO.getKey());
+
+ // this resource has not a mapping for Password
+ userMod.getResourcesToAdd().add(RESOURCE_NAME_UPDATE);
+
+ userTO = updateUser(userMod);
+ assertNotNull(userTO);
+ }
+
+ @Test
+ public void issueSYNCOPE279() {
+ UserTO userTO = getUniqueSampleTO("syncope279@apache.org");
+ userTO.getResources().clear();
+ userTO.getResources().add(RESOURCE_NAME_TIMEOUT);
+ userTO = createUser(userTO);
+ assertEquals(RESOURCE_NAME_TIMEOUT, userTO.getPropagationStatusTOs().get(0).getResource());
+ assertNotNull(userTO.getPropagationStatusTOs().get(0).getFailureReason());
+ assertEquals(PropagationTaskExecStatus.UNSUBMITTED, userTO.getPropagationStatusTOs().get(0).getStatus());
+ }
+
+ @Test
+ public void issueSYNCOPE122() {
+ // 1. create user on testdb and testdb2
+ UserTO userTO = getUniqueSampleTO("syncope122@apache.org");
+ userTO.getResources().clear();
+
+ userTO.getResources().add(RESOURCE_NAME_TESTDB);
+ userTO.getResources().add(RESOURCE_NAME_TESTDB2);
+
+ userTO = createUser(userTO);
+ assertNotNull(userTO);
+ assertTrue(userTO.getResources().contains(RESOURCE_NAME_TESTDB));
+ assertTrue(userTO.getResources().contains(RESOURCE_NAME_TESTDB2));
+
+ final String pwdOnSyncope = userTO.getPassword();
+
+ ConnObjectTO userOnDb = resourceService.readConnObject(
+ RESOURCE_NAME_TESTDB, AnyTypeKind.USER.name(), userTO.getKey());
+ final AttrTO pwdOnTestDbAttr = userOnDb.getPlainAttrMap().get(OperationalAttributes.PASSWORD_NAME);
+ assertNotNull(pwdOnTestDbAttr);
+ assertNotNull(pwdOnTestDbAttr.getValues());
+ assertFalse(pwdOnTestDbAttr.getValues().isEmpty());
+ final String pwdOnTestDb = pwdOnTestDbAttr.getValues().iterator().next();
+
+ ConnObjectTO userOnDb2 = resourceService.readConnObject(
+ RESOURCE_NAME_TESTDB2, AnyTypeKind.USER.name(), userTO.getKey());
+ final AttrTO pwdOnTestDb2Attr = userOnDb2.getPlainAttrMap().get(OperationalAttributes.PASSWORD_NAME);
+ assertNotNull(pwdOnTestDb2Attr);
+ assertNotNull(pwdOnTestDb2Attr.getValues());
+ assertFalse(pwdOnTestDb2Attr.getValues().isEmpty());
+ final String pwdOnTestDb2 = pwdOnTestDb2Attr.getValues().iterator().next();
+
+ // 2. request to change password only on testdb (no Syncope, no testdb2)
+ UserMod userMod = new UserMod();
+ userMod.setKey(userTO.getKey());
+ userMod.setPassword(getUUIDString());
+ StatusMod pwdPropRequest = new StatusMod();
+ pwdPropRequest.setOnSyncope(false);
- pwdPropRequest.getResourceNames().add(RESOURCE_NAME_TESTDB);
++ pwdPropRequest.getResources().add(RESOURCE_NAME_TESTDB);
+ userMod.setPwdPropRequest(pwdPropRequest);
+
+ userTO = updateUser(userMod);
+
+ // 3a. Chech that only a single propagation took place
+ assertNotNull(userTO.getPropagationStatusTOs());
+ assertEquals(1, userTO.getPropagationStatusTOs().size());
+ assertEquals(RESOURCE_NAME_TESTDB, userTO.getPropagationStatusTOs().iterator().next().getResource());
+
+ // 3b. verify that password hasn't changed on Syncope
+ assertEquals(pwdOnSyncope, userTO.getPassword());
+
+ // 3c. verify that password *has* changed on testdb
+ userOnDb = resourceService.readConnObject(RESOURCE_NAME_TESTDB, AnyTypeKind.USER.name(), userTO.getKey());
+ final AttrTO pwdOnTestDbAttrAfter = userOnDb.getPlainAttrMap().get(OperationalAttributes.PASSWORD_NAME);
+ assertNotNull(pwdOnTestDbAttrAfter);
+ assertNotNull(pwdOnTestDbAttrAfter.getValues());
+ assertFalse(pwdOnTestDbAttrAfter.getValues().isEmpty());
+ assertNotEquals(pwdOnTestDb, pwdOnTestDbAttrAfter.getValues().iterator().next());
+
+ // 3d. verify that password hasn't changed on testdb2
+ userOnDb2 = resourceService.readConnObject(RESOURCE_NAME_TESTDB2, AnyTypeKind.USER.name(), userTO.getKey());
+ final AttrTO pwdOnTestDb2AttrAfter = userOnDb2.getPlainAttrMap().get(OperationalAttributes.PASSWORD_NAME);
+ assertNotNull(pwdOnTestDb2AttrAfter);
+ assertNotNull(pwdOnTestDb2AttrAfter.getValues());
+ assertFalse(pwdOnTestDb2AttrAfter.getValues().isEmpty());
+ assertEquals(pwdOnTestDb2, pwdOnTestDb2AttrAfter.getValues().iterator().next());
+ }
+
+ @Test
+ public void isseSYNCOPE136AES() {
+ // 1. read configured cipher algorithm in order to be able to restore it at the end of test
+ AttrTO pwdCipherAlgo = configurationService.get("password.cipher.algorithm");
+ final String origpwdCipherAlgo = pwdCipherAlgo.getValues().get(0);
+
+ // 2. set AES password cipher algorithm
+ pwdCipherAlgo.getValues().set(0, "AES");
+ configurationService.set(pwdCipherAlgo);
+
- // 3. create user with no resources
- UserTO userTO = getUniqueSampleTO("syncope136_AES@apache.org");
- userTO.getResources().clear();
-
- userTO = createUser(userTO);
- assertNotNull(userTO);
-
- // 4. update user, assign a propagation primary resource but don't provide any password
- UserMod userMod = new UserMod();
- userMod.setKey(userTO.getKey());
- userMod.getResourcesToAdd().add(RESOURCE_NAME_WS1);
++ try {
++ // 3. create user with no resources
++ UserTO userTO = getUniqueSampleTO("syncope136_AES@apache.org");
++ userTO.getResources().clear();
+
- final StatusMod st = new StatusMod();
- st.setOnSyncope(false);
- st.getResourceNames().add(RESOURCE_NAME_WS1);
- userMod.setPwdPropRequest(st);
++ userTO = createUser(userTO);
++ assertNotNull(userTO);
+
- userTO = updateUser(userMod);
- assertNotNull(userTO);
++ // 4. update user, assign a propagation primary resource but don't provide any password
++ UserMod userMod = new UserMod();
++ userMod.setKey(userTO.getKey());
++ userMod.getResourcesToAdd().add(RESOURCE_NAME_WS1);
+
- // 5. verify that propagation was successful
- List<PropagationStatus> props = userTO.getPropagationStatusTOs();
- assertNotNull(props);
- assertEquals(1, props.size());
- PropagationStatus prop = props.iterator().next();
- assertNotNull(prop);
- assertEquals(RESOURCE_NAME_WS1, prop.getResource());
- assertEquals(PropagationTaskExecStatus.SUBMITTED, prop.getStatus());
++ StatusMod st = new StatusMod();
++ st.setOnSyncope(false);
++ st.getResources().add(RESOURCE_NAME_WS1);
++ userMod.setPwdPropRequest(st);
+
- // 6. restore initial cipher algorithm
- pwdCipherAlgo.getValues().set(0, origpwdCipherAlgo);
- configurationService.set(pwdCipherAlgo);
++ userTO = updateUser(userMod);
++ assertNotNull(userTO);
++
++ // 5. verify that propagation was successful
++ List<PropagationStatus> props = userTO.getPropagationStatusTOs();
++ assertNotNull(props);
++ assertEquals(1, props.size());
++ PropagationStatus prop = props.iterator().next();
++ assertNotNull(prop);
++ assertEquals(RESOURCE_NAME_WS1, prop.getResource());
++ assertEquals(PropagationTaskExecStatus.SUBMITTED, prop.getStatus());
++ } finally {
++ // restore initial cipher algorithm
++ pwdCipherAlgo.getValues().set(0, origpwdCipherAlgo);
++ configurationService.set(pwdCipherAlgo);
++ }
+ }
+
+ @Test
+ public void isseSYNCOPE136Random() {
+ // 1. create user with no resources
+ UserTO userTO = getUniqueSampleTO("syncope136_Random@apache.org");
+ userTO.getResources().clear();
+ userTO = createUser(userTO);
+ assertNotNull(userTO);
+
+ // 2. update user, assign a propagation primary resource but don't provide any password
+ UserMod userMod = new UserMod();
+ userMod.setKey(userTO.getKey());
+ userMod.getResourcesToAdd().add(RESOURCE_NAME_LDAP);
+
- final StatusMod st = new StatusMod();
++ StatusMod st = new StatusMod();
+ st.setOnSyncope(false);
- st.getResourceNames().add(RESOURCE_NAME_LDAP);
++ st.getResources().add(RESOURCE_NAME_LDAP);
+ userMod.setPwdPropRequest(st);
+
+ userTO = updateUser(userMod);
+ assertNotNull(userTO);
+
+ // 3. verify that propagation was successful
+ List<PropagationStatus> props = userTO.getPropagationStatusTOs();
+ assertNotNull(props);
+ assertEquals(1, props.size());
+ PropagationStatus prop = props.iterator().next();
+ assertNotNull(prop);
+ assertEquals(RESOURCE_NAME_LDAP, prop.getResource());
+ assertEquals(PropagationTaskExecStatus.SUCCESS, prop.getStatus());
+ }
+
+ @Test
+ public void mappingPurpose() {
+ UserTO userTO = getUniqueSampleTO("mpurpose@apache.org");
+ userTO.getAuxClasses().add("csv");
+
+ AttrTO csvuserid = new AttrTO();
+ csvuserid.setSchema("csvuserid");
+ userTO.getDerAttrs().add(csvuserid);
+
+ userTO.getResources().clear();
+ userTO.getResources().add(RESOURCE_NAME_CSV);
+
+ UserTO actual = createUser(userTO);
+ assertNotNull(actual);
+
+ ConnObjectTO connObjectTO =
+ resourceService.readConnObject(RESOURCE_NAME_CSV, AnyTypeKind.USER.name(), actual.getKey());
+ assertNull(connObjectTO.getPlainAttrMap().get("email"));
+ }
+
+ @Test
+ public void issueSYNCOPE265() {
+ for (long key = 1; key <= 5; key++) {
+ UserMod userMod = new UserMod();
+ userMod.setKey(key);
+
+ userMod.getPlainAttrsToRemove().add("type");
+ userMod.getPlainAttrsToUpdate().add(attrMod("type", "a type"));
+
+ UserTO userTO = updateUser(userMod);
+
+ assertEquals("a type", userTO.getPlainAttrMap().get("type").getValues().get(0));
+ }
+ }
+
+ @Test
+ public void bulkActions() {
+ BulkAction bulkAction = new BulkAction();
+
+ for (int i = 0; i < 10; i++) {
+ UserTO userTO = getUniqueSampleTO("bulk_" + i + "@apache.org");
+ bulkAction.getTargets().add(String.valueOf(createUser(userTO).getKey()));
+ }
+
+ // check for a fail
+ bulkAction.getTargets().add(String.valueOf(Long.MAX_VALUE));
+
+ assertEquals(11, bulkAction.getTargets().size());
+
+ bulkAction.setType(BulkAction.Type.SUSPEND);
+ BulkActionResult res = userService.bulk(bulkAction);
+ assertEquals(10, res.getResultByStatus(Status.SUCCESS).size());
+ assertEquals(1, res.getResultByStatus(Status.FAILURE).size());
+ assertEquals("suspended", userService.read(
+ Long.parseLong(res.getResultByStatus(Status.SUCCESS).get(3))).getStatus());
+
+ bulkAction.setType(BulkAction.Type.REACTIVATE);
+ res = userService.bulk(bulkAction);
+ assertEquals(10, res.getResultByStatus(Status.SUCCESS).size());
+ assertEquals(1, res.getResultByStatus(Status.FAILURE).size());
+ assertEquals("active", userService.read(
+ Long.parseLong(res.getResultByStatus(Status.SUCCESS).get(3))).getStatus());
+
+ bulkAction.setType(BulkAction.Type.DELETE);
+ res = userService.bulk(bulkAction);
+ assertEquals(10, res.getResultByStatus(Status.SUCCESS).size());
+ assertEquals(1, res.getResultByStatus(Status.FAILURE).size());
+ }
+
+ @Test
+ public void issueSYNCOPE354() {
+ // change resource-ldap group mapping for including uniqueMember (need for assertions below)
+ ResourceTO ldap = resourceService.read(RESOURCE_NAME_LDAP);
+ for (MappingItemTO item : ldap.getProvision(AnyTypeKind.GROUP.name()).getMapping().getItems()) {
+ if ("description".equals(item.getExtAttrName())) {
+ item.setExtAttrName("uniqueMember");
+ }
+ }
+ resourceService.update(ldap);
+
+ // 1. create group with LDAP resource
+ GroupTO groupTO = new GroupTO();
+ groupTO.setName("SYNCOPE354-" + getUUIDString());
+ groupTO.setRealm("/");
+ groupTO.getResources().add(RESOURCE_NAME_LDAP);
+
+ groupTO = createGroup(groupTO);
+ assertNotNull(groupTO);
+
+ // 2. create user with LDAP resource and membership of the above group
+ UserTO userTO = getUniqueSampleTO("syncope354@syncope.apache.org");
+ userTO.getResources().add(RESOURCE_NAME_LDAP);
+ MembershipTO membershipTO = new MembershipTO();
+ membershipTO.setRightKey(groupTO.getKey());
+ userTO.getMemberships().add(membershipTO);
+
+ userTO = createUser(userTO);
+ assertTrue(userTO.getResources().contains(RESOURCE_NAME_LDAP));
+
+ // 3. read group on resource, check that user DN is included in uniqueMember
+ ConnObjectTO connObj = resourceService.readConnObject(
+ RESOURCE_NAME_LDAP, AnyTypeKind.GROUP.name(), groupTO.getKey());
+ assertNotNull(connObj);
+ assertTrue(connObj.getPlainAttrMap().get("uniqueMember").getValues().
+ contains("uid=" + userTO.getUsername() + ",ou=people,o=isp"));
+
+ // 4. remove membership
+ UserMod userMod = new UserMod();
+ userMod.setKey(userTO.getKey());
+ userMod.getMembershipsToRemove().add(userTO.getMemberships().get(0).getRightKey());
+
+ userTO = updateUser(userMod);
+ assertTrue(userTO.getResources().contains(RESOURCE_NAME_LDAP));
+
+ // 5. read group on resource, check that user DN was removed from uniqueMember
+ connObj = resourceService.readConnObject(RESOURCE_NAME_LDAP, AnyTypeKind.GROUP.name(), groupTO.getKey());
+ assertNotNull(connObj);
+ assertFalse(connObj.getPlainAttrMap().get("uniqueMember").getValues().
+ contains("uid=" + userTO.getUsername() + ",ou=people,o=isp"));
+
+ // 6. restore original resource-ldap group mapping
+ for (MappingItemTO item : ldap.getProvision(AnyTypeKind.GROUP.name()).getMapping().getItems()) {
+ if ("uniqueMember".equals(item.getExtAttrName())) {
+ item.setExtAttrName("description");
+ }
+ }
+ resourceService.update(ldap);
+ }
+
+ @Test
+ public void issueSYNCOPE357() throws IOException {
+ // 1. create group with LDAP resource
+ GroupTO groupTO = new GroupTO();
+ groupTO.setName("SYNCOPE357-" + getUUIDString());
+ groupTO.setRealm("/");
+ groupTO.getResources().add(RESOURCE_NAME_LDAP);
+
+ groupTO = createGroup(groupTO);
+ assertNotNull(groupTO);
+
+ // 2. create user with membership of the above group
+ UserTO userTO = getUniqueSampleTO("syncope357@syncope.apache.org");
+ userTO.getPlainAttrs().add(attrTO("obscure", "valueToBeObscured"));
+ userTO.getPlainAttrs().add(attrTO("photo",
+ Base64Utility.encode(IOUtils.readBytesFromStream(getClass().getResourceAsStream("/favicon.jpg")))));
+ MembershipTO membershipTO = new MembershipTO();
+ membershipTO.setRightKey(groupTO.getKey());
+ userTO.getMemberships().add(membershipTO);
+
+ userTO = createUser(userTO);
+ assertTrue(userTO.getResources().contains(RESOURCE_NAME_LDAP));
+ assertNotNull(userTO.getPlainAttrMap().get("obscure"));
+ assertNotNull(userTO.getPlainAttrMap().get("photo"));
+
+ // 3. read user on resource
+ ConnObjectTO connObj = resourceService.readConnObject(
+ RESOURCE_NAME_LDAP, AnyTypeKind.USER.name(), userTO.getKey());
+ assertNotNull(connObj);
+ AttrTO registeredAddress = connObj.getPlainAttrMap().get("registeredAddress");
+ assertNotNull(registeredAddress);
+ assertEquals(userTO.getPlainAttrMap().get("obscure").getValues(), registeredAddress.getValues());
+ AttrTO jpegPhoto = connObj.getPlainAttrMap().get("jpegPhoto");
+ assertNotNull(jpegPhoto);
+ assertEquals(userTO.getPlainAttrMap().get("photo").getValues(), jpegPhoto.getValues());
+
+ // 4. remove group
+ groupService.delete(groupTO.getKey());
+
+ // 5. try to read user on resource: fail
+ try {
+ resourceService.readConnObject(RESOURCE_NAME_LDAP, AnyTypeKind.USER.name(), userTO.getKey());
+ fail();
+ } catch (SyncopeClientException e) {
+ assertEquals(ClientExceptionType.NotFound, e.getType());
+ }
+ }
+
+ @Test
+ public void issueSYNCOPE383() {
+ // 1. create user without resources
+ UserTO userTO = getUniqueSampleTO("syncope383@apache.org");
+ userTO.getResources().clear();
+ userTO = createUser(userTO);
+ assertNotNull(userTO);
+
+ // 2. assign resource without specifying a new pwd and check propagation failure
+ UserMod userMod = new UserMod();
+ userMod.setKey(userTO.getKey());
+ userMod.getResourcesToAdd().add(RESOURCE_NAME_TESTDB);
+ userTO = updateUser(userMod);
+ assertEquals(RESOURCE_NAME_TESTDB, userTO.getResources().iterator().next());
+ assertFalse(userTO.getPropagationStatusTOs().get(0).getStatus().isSuccessful());
+ assertNotNull(userTO.getPropagationStatusTOs().get(0).getFailureReason());
+
+ // 3. request to change password only on testdb
+ userMod = new UserMod();
+ userMod.setKey(userTO.getKey());
+ userMod.setPassword(getUUIDString() + "abbcbcbddd123");
+ StatusMod pwdPropRequest = new StatusMod();
- pwdPropRequest.getResourceNames().add(RESOURCE_NAME_TESTDB);
++ pwdPropRequest.getResources().add(RESOURCE_NAME_TESTDB);
+ userMod.setPwdPropRequest(pwdPropRequest);
+
+ userTO = updateUser(userMod);
+ assertEquals(RESOURCE_NAME_TESTDB, userTO.getResources().iterator().next());
+ assertTrue(userTO.getPropagationStatusTOs().get(0).getStatus().isSuccessful());
+ }
+
+ @Test
+ public void issueSYNCOPE402() {
+ // 1. create an user with strict mandatory attributes only
+ UserTO userTO = new UserTO();
+ userTO.setRealm(SyncopeConstants.ROOT_REALM);
+ String userId = getUUIDString() + "syncope402@syncope.apache.org";
+ userTO.setUsername(userId);
+ userTO.setPassword("password123");
+
+ userTO.getPlainAttrs().add(attrTO("userId", userId));
+ userTO.getPlainAttrs().add(attrTO("fullname", userId));
+ userTO.getPlainAttrs().add(attrTO("surname", userId));
+
+ userTO = createUser(userTO);
+ assertNotNull(userTO);
+ assertTrue(userTO.getResources().isEmpty());
+
+ // 2. update assigning a resource NOT forcing mandatory constraints
+ // AND primary: must fail with PropagationException
+ UserMod userMod = new UserMod();
+ userMod.setKey(userTO.getKey());
+ userMod.setPassword("newPassword123");
+
+ userMod.getResourcesToAdd().add(RESOURCE_NAME_WS1);
+ userMod.getResourcesToAdd().add(RESOURCE_NAME_TESTDB);
+ userTO = updateUser(userMod);
+
+ List<PropagationStatus> propagationStatuses = userTO.getPropagationStatusTOs();
+ PropagationStatus ws1PropagationStatus = null;
+ if (propagationStatuses != null) {
+ for (PropagationStatus propStatus : propagationStatuses) {
+ if (RESOURCE_NAME_WS1.equals(propStatus.getResource())) {
+ ws1PropagationStatus = propStatus;
+ break;
+ }
+ }
+ }
+ assertNotNull(ws1PropagationStatus);
+ assertEquals(RESOURCE_NAME_WS1, ws1PropagationStatus.getResource());
+ assertNotNull(ws1PropagationStatus.getFailureReason());
+ assertEquals(PropagationTaskExecStatus.UNSUBMITTED, ws1PropagationStatus.getStatus());
+ }
+
+ @Test
+ public void unlink() {
+ UserTO userTO = getUniqueSampleTO("unlink@syncope.apache.org");
+ userTO.getResources().clear();
+ userTO.getMemberships().clear();
+ userTO.getDerAttrs().clear();
+ userTO.getVirAttrs().clear();
+ userTO.getAuxClasses().add("csv");
+ userTO.getDerAttrs().add(attrTO("csvuserid", null));
+ userTO.getResources().add(RESOURCE_NAME_CSV);
+
+ UserTO actual = createUser(userTO);
+ assertNotNull(actual);
+ assertNotNull(resourceService.readConnObject(RESOURCE_NAME_CSV, AnyTypeKind.USER.name(), actual.getKey()));
+
+ assertNotNull(userService.deassociate(actual.getKey(),
+ ResourceDeassociationActionType.UNLINK,
+ CollectionWrapper.wrap(RESOURCE_NAME_CSV, ResourceKey.class)).
+ readEntity(BulkActionResult.class));
+
+ actual = userService.read(actual.getKey());
+ assertNotNull(actual);
+ assertTrue(actual.getResources().isEmpty());
+
+ assertNotNull(resourceService.readConnObject(RESOURCE_NAME_CSV, AnyTypeKind.USER.name(), actual.getKey()));
+ }
+
+ @Test
+ public void link() {
+ UserTO userTO = getUniqueSampleTO("link@syncope.apache.org");
+ userTO.getResources().clear();
+ userTO.getMemberships().clear();
+ userTO.getDerAttrs().clear();
+ userTO.getVirAttrs().clear();
+ userTO.getAuxClasses().add("csv");
+ userTO.getDerAttrs().add(attrTO("csvuserid", null));
+
+ UserTO actual = createUser(userTO);
+ assertNotNull(actual);
+ assertTrue(actual.getResources().isEmpty());
+
+ try {
+ resourceService.readConnObject(RESOURCE_NAME_CSV, AnyTypeKind.USER.name(), actual.getKey());
+ fail();
+ } catch (Exception e) {
+ assertNotNull(e);
+ }
+
+ final ResourceAssociationMod associationMod = new ResourceAssociationMod();
+ associationMod.getTargetResources().addAll(CollectionWrapper.wrap(RESOURCE_NAME_CSV, ResourceKey.class));
+
+ assertNotNull(userService.associate(actual.getKey(), ResourceAssociationAction.LINK, associationMod).readEntity(
+ BulkActionResult.class));
+
+ actual = userService.read(actual.getKey());
+ assertNotNull(actual);
+ assertFalse(actual.getResources().isEmpty());
+
+ try {
+ resourceService.readConnObject(RESOURCE_NAME_CSV, AnyTypeKind.USER.name(), actual.getKey());
+ fail();
+ } catch (Exception e) {
+ assertNotNull(e);
+ }
+ }
+
+ @Test
+ public void unassign() {
+ UserTO userTO = getUniqueSampleTO("unassign@syncope.apache.org");
+ userTO.getResources().clear();
+ userTO.getMemberships().clear();
+ userTO.getDerAttrs().clear();
+ userTO.getVirAttrs().clear();
+ userTO.getAuxClasses().add("csv");
+ userTO.getDerAttrs().add(attrTO("csvuserid", null));
+ userTO.getResources().add(RESOURCE_NAME_CSV);
+
+ UserTO actual = createUser(userTO);
+ assertNotNull(actual);
+ assertNotNull(resourceService.readConnObject(RESOURCE_NAME_CSV, AnyTypeKind.USER.name(), actual.getKey()));
+
+ assertNotNull(userService.deassociate(actual.getKey(),
+ ResourceDeassociationActionType.UNASSIGN,
+ CollectionWrapper.wrap(RESOURCE_NAME_CSV, ResourceKey.class)).
+ readEntity(BulkActionResult.class));
+
+ actual = userService.read(actual.getKey());
+ assertNotNull(actual);
+ assertTrue(actual.getResources().isEmpty());
+
+ try {
+ resourceService.readConnObject(RESOURCE_NAME_CSV, AnyTypeKind.USER.name(), actual.getKey());
+ fail();
+ } catch (Exception e) {
+ assertNotNull(e);
+ }
+ }
+
+ @Test
+ public void assign() {
+ UserTO userTO = getUniqueSampleTO("assign@syncope.apache.org");
+ userTO.getResources().clear();
+ userTO.getMemberships().clear();
+ userTO.getDerAttrs().clear();
+ userTO.getVirAttrs().clear();
+ userTO.getAuxClasses().add("csv");
+ userTO.getDerAttrs().add(attrTO("csvuserid", null));
+
+ UserTO actual = createUser(userTO);
+ assertNotNull(actual);
+ assertTrue(actual.getResources().isEmpty());
+
+ try {
+ resourceService.readConnObject(RESOURCE_NAME_CSV, AnyTypeKind.USER.name(), actual.getKey());
+ fail();
+ } catch (Exception e) {
+ assertNotNull(e);
+ }
+
+ ResourceAssociationMod associationMod = new ResourceAssociationMod();
+ associationMod.getTargetResources().addAll(CollectionWrapper.wrap(RESOURCE_NAME_CSV, ResourceKey.class));
+ associationMod.setChangePwd(true);
+ associationMod.setPassword("password");
+
+ assertNotNull(userService.associate(actual.getKey(), ResourceAssociationAction.ASSIGN, associationMod)
+ .readEntity(BulkActionResult.class));
+
+ actual = userService.read(actual.getKey());
+ assertNotNull(actual);
+ assertFalse(actual.getResources().isEmpty());
+ assertNotNull(resourceService.readConnObject(RESOURCE_NAME_CSV, AnyTypeKind.USER.name(), actual.getKey()));
+ }
+
+ @Test
+ public void deprovision() {
+ UserTO userTO = getUniqueSampleTO("deprovision@syncope.apache.org");
+ userTO.getResources().clear();
+ userTO.getMemberships().clear();
+ userTO.getDerAttrs().clear();
+ userTO.getVirAttrs().clear();
+ userTO.getAuxClasses().add("csv");
+ userTO.getDerAttrs().add(attrTO("csvuserid", null));
+ userTO.getResources().add(RESOURCE_NAME_CSV);
+
+ UserTO actual = createUser(userTO);
+ assertNotNull(actual);
+ assertNotNull(resourceService.readConnObject(RESOURCE_NAME_CSV, AnyTypeKind.USER.name(), actual.getKey()));
+
+ assertNotNull(userService.deassociate(actual.getKey(),
+ ResourceDeassociationActionType.DEPROVISION,
+ CollectionWrapper.wrap(RESOURCE_NAME_CSV, ResourceKey.class)).
+ readEntity(BulkActionResult.class));
+
+ actual = userService.read(actual.getKey());
+ assertNotNull(actual);
+ assertFalse(actual.getResources().isEmpty());
+
+ try {
+ resourceService.readConnObject(RESOURCE_NAME_CSV, AnyTypeKind.USER.name(), actual.getKey());
+ fail();
+ } catch (SyncopeClientException e) {
+ assertEquals(ClientExceptionType.NotFound, e.getType());
+ }
+ }
+
+ @Test
+ public void provision() {
+ UserTO userTO = getUniqueSampleTO("provision@syncope.apache.org");
+ userTO.getResources().clear();
+ userTO.getMemberships().clear();
+ userTO.getDerAttrs().clear();
+ userTO.getVirAttrs().clear();
+ userTO.getAuxClasses().add("csv");
+ userTO.getDerAttrs().add(attrTO("csvuserid", null));
+
+ UserTO actual = createUser(userTO);
+ assertNotNull(actual);
+ assertTrue(actual.getResources().isEmpty());
+
+ try {
+ resourceService.readConnObject(RESOURCE_NAME_CSV, AnyTypeKind.USER.name(), actual.getKey());
+ fail();
+ } catch (Exception e) {
+ assertNotNull(e);
+ }
+
+ ResourceAssociationMod associationMod = new ResourceAssociationMod();
+ associationMod.getTargetResources().addAll(CollectionWrapper.wrap(RESOURCE_NAME_CSV, ResourceKey.class));
+ associationMod.setChangePwd(true);
+ associationMod.setPassword("password");
+
+ assertNotNull(userService.associate(actual.getKey(), ResourceAssociationAction.PROVISION, associationMod).
+ readEntity(BulkActionResult.class));
+
+ actual = userService.read(actual.getKey());
+ assertNotNull(actual);
+ assertTrue(actual.getResources().isEmpty());
+ assertNotNull(resourceService.readConnObject(RESOURCE_NAME_CSV, AnyTypeKind.USER.name(), actual.getKey()));
+ }
+
+ @Test
+ public void deprovisionUnlinked() {
+ UserTO userTO = getUniqueSampleTO("provision@syncope.apache.org");
+ userTO.getResources().clear();
+ userTO.getMemberships().clear();
+ userTO.getDerAttrs().clear();
+ userTO.getVirAttrs().clear();
+ userTO.getAuxClasses().add("csv");
+ userTO.getDerAttrs().add(attrTO("csvuserid", null));
+
+ UserTO actual = createUser(userTO);
+ assertNotNull(actual);
+ assertTrue(actual.getResources().isEmpty());
+
+ try {
+ resourceService.readConnObject(RESOURCE_NAME_CSV, AnyTypeKind.USER.name(), actual.getKey());
+ fail();
+ } catch (Exception e) {
+ assertNotNull(e);
+ }
+
+ final ResourceAssociationMod associationMod = new ResourceAssociationMod();
+ associationMod.getTargetResources().addAll(CollectionWrapper.wrap(RESOURCE_NAME_CSV, ResourceKey.class));
+ associationMod.setChangePwd(true);
+ associationMod.setPassword("password");
+
+ assertNotNull(userService.associate(actual.getKey(), ResourceAssociationAction.PROVISION,
+ associationMod)
+ .readEntity(BulkActionResult.class));
+
+ actual = userService.read(actual.getKey());
+ assertNotNull(actual);
+ assertTrue(actual.getResources().isEmpty());
+ assertNotNull(resourceService.readConnObject(RESOURCE_NAME_CSV, AnyTypeKind.USER.name(), actual.getKey()));
+
+ assertNotNull(userService.deassociate(actual.getKey(),
+ ResourceDeassociationActionType.DEPROVISION,
+ CollectionWrapper.wrap(RESOURCE_NAME_CSV, ResourceKey.class)).
+ readEntity(BulkActionResult.class));
+
+ actual = userService.read(actual.getKey());
+ assertNotNull(actual);
+ assertTrue(actual.getResources().isEmpty());
+
+ try {
+ resourceService.readConnObject(RESOURCE_NAME_CSV, AnyTypeKind.USER.name(), actual.getKey());
+ fail();
+ } catch (Exception e) {
+ assertNotNull(e);
+ }
+ }
+
+ @Test
+ public void issueSYNCOPE420() {
+ UserTO userTO = getUniqueSampleTO("syncope420@syncope.apache.org");
+ userTO.getPlainAttrs().add(attrTO("makeItDouble", "3"));
+
+ userTO = createUser(userTO);
+ assertEquals("6", userTO.getPlainAttrMap().get("makeItDouble").getValues().get(0));
+
+ UserMod userMod = new UserMod();
+ userMod.setKey(userTO.getKey());
+ userMod.getPlainAttrsToRemove().add("makeItDouble");
+ userMod.getPlainAttrsToUpdate().add(attrMod("makeItDouble", "7"));
+
+ userTO = updateUser(userMod);
+ assertEquals("14", userTO.getPlainAttrMap().get("makeItDouble").getValues().get(0));
+ }
+
+ @Test
+ public void issueSYNCOPE426() {
+ UserTO userTO = getUniqueSampleTO("syncope426@syncope.apache.org");
+ userTO = createUser(userTO);
+ assertNotNull(userTO);
+
+ UserMod userMod = new UserMod();
+ userMod.setKey(userTO.getKey());
+ userMod.setPassword("anotherPassword123");
+ userTO = userService.update(userMod).readEntity(UserTO.class);
+ assertNotNull(userTO);
+ }
+
+ @Test
+ public void issueSYNCOPE435() {
+ // 1. create user without password
+ UserTO userTO = getUniqueSampleTO("syncope435@syncope.apache.org");
+ userTO.setPassword(null);
+ userTO = createUser(userTO, false);
+ assertNotNull(userTO);
+
+ // 2. try to update user by subscribing a resource - works
<TRUNCATED>