/*
* 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;
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.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.naming.NamingException;
import javax.sql.DataSource;
import javax.ws.rs.core.GenericType;
import org.apache.commons.lang3.tuple.Pair;
import org.apache.cxf.common.util.Base64Utility;
import org.apache.cxf.helpers.IOUtils;
import org.apache.syncope.common.lib.SyncopeClientException;
import org.apache.syncope.common.lib.SyncopeConstants;
import org.apache.syncope.common.lib.patch.MembershipPatch;
import org.apache.syncope.common.lib.patch.PasswordPatch;
import org.apache.syncope.common.lib.patch.StringPatchItem;
import org.apache.syncope.common.lib.patch.StringReplacePatchItem;
import org.apache.syncope.common.lib.patch.UserPatch;
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.ConnObjectTO;
import org.apache.syncope.common.lib.to.GroupTO;
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.PropagationStatus;
import org.apache.syncope.common.lib.to.ProvisioningResult;
import org.apache.syncope.common.lib.to.RealmTO;
import org.apache.syncope.common.lib.to.ResourceTO;
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.PatchOperation;
import org.apache.syncope.common.lib.types.PropagationTaskExecStatus;
import org.apache.syncope.core.provisioning.java.propagation.DBPasswordPropagationActions;
import org.apache.syncope.core.provisioning.java.propagation.LDAPPasswordPropagationActions;
import org.apache.syncope.core.spring.security.Encryptor;
import org.apache.syncope.fit.AbstractITCase;
import org.apache.syncope.fit.core.reference.DoubleValueLogicActions;
import org.identityconnectors.framework.common.objects.Name;
import org.identityconnectors.framework.common.objects.OperationalAttributes;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "classpath:testJDBCEnv.xml" })
public class UserIssuesITCase extends AbstractITCase {
@Autowired
private DataSource testDataSource;
@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).getEntity();
assertNotNull(userTO);
assertTrue(userTO.getResources().isEmpty());
// 2. update assigning a resource forcing mandatory constraints: must fail with RequiredValuesMissing
UserPatch userPatch = new UserPatch();
userPatch.setKey(userTO.getKey());
userPatch.setPassword(new PasswordPatch.Builder().value("newPassword123").build());
userPatch.getResources().add(new StringPatchItem.Builder().
operation(PatchOperation.ADD_REPLACE).value(RESOURCE_NAME_WS2).build());
try {
userTO = updateUser(userPatch).getEntity();
fail();
} catch (SyncopeClientException e) {
assertEquals(ClientExceptionType.RequiredValuesMissing, e.getType());
}
// 3. update assigning a resource NOT forcing mandatory constraints
// AND priority: must fail with PropagationException
userPatch = new UserPatch();
userPatch.setKey(userTO.getKey());
userPatch.setPassword(new PasswordPatch.Builder().value("newPassword123").build());
userPatch.getResources().add(new StringPatchItem.Builder().
operation(PatchOperation.ADD_REPLACE).value(RESOURCE_NAME_WS1).build());
ProvisioningResult<UserTO> result = updateUser(userPatch);
assertNotNull(result.getPropagationStatuses().get(0).getFailureReason());
userTO = result.getEntity();
// 4. update assigning a resource NOT forcing mandatory constraints
// BUT not priority: must succeed
userPatch = new UserPatch();
userPatch.setKey(userTO.getKey());
userPatch.setPassword(new PasswordPatch.Builder().value("newPassword123456").build());
userPatch.getResources().add(new StringPatchItem.Builder().
operation(PatchOperation.ADD_REPLACE).value(RESOURCE_NAME_CSV).build());
updateUser(userPatch);
}
@Test
public void issue213() {
UserTO userTO = UserITCase.getUniqueSampleTO("issue213@syncope.apache.org");
userTO.getResources().add(RESOURCE_NAME_TESTDB);
userTO = createUser(userTO).getEntity();
assertNotNull(userTO);
assertEquals(1, userTO.getResources().size());
JdbcTemplate jdbcTemplate = new JdbcTemplate(testDataSource);
String username = queryForObject(
jdbcTemplate, 50, "SELECT id FROM test WHERE id=?", String.class, userTO.getUsername());
assertEquals(userTO.getUsername(), username);
UserPatch userPatch = new UserPatch();
userPatch.setKey(userTO.getKey());
userPatch.getResources().add(
new StringPatchItem.Builder().operation(PatchOperation.DELETE).value(RESOURCE_NAME_TESTDB).build());
userTO = updateUser(userPatch).getEntity();
assertTrue(userTO.getResources().isEmpty());
Exception exception = null;
try {
jdbcTemplate.queryForObject("SELECT id FROM test WHERE id=?", String.class, userTO.getUsername());
} catch (EmptyResultDataAccessException e) {
exception = e;
}
assertNotNull(exception);
}
@Test
public void issue234() {
UserTO inUserTO = UserITCase.getUniqueSampleTO("issue234@syncope.apache.org");
inUserTO.getResources().add(RESOURCE_NAME_LDAP);
UserTO userTO = createUser(inUserTO).getEntity();
assertNotNull(userTO);
UserPatch userPatch = new UserPatch();
userPatch.setKey(userTO.getKey());
userPatch.setUsername(new StringReplacePatchItem.Builder().value("1" + userTO.getUsername()).build());
userTO = updateUser(userPatch).getEntity();
assertNotNull(userTO);
assertEquals("1" + inUserTO.getUsername(), userTO.getUsername());
}
@Test
public final void issue280() {
UserTO userTO = UserITCase.getUniqueSampleTO("issue280@syncope.apache.org");
userTO.getResources().clear();
userTO.getMemberships().clear();
userTO.getDerAttrs().clear();
userTO = createUser(userTO).getEntity();
assertNotNull(userTO);
UserPatch userPatch = new UserPatch();
userPatch.setKey(userTO.getKey());
userPatch.setPassword(new PasswordPatch.Builder().onSyncope(false).
resource(RESOURCE_NAME_TESTDB).value("123password").build());
userPatch.getResources().add(new StringPatchItem.Builder().
operation(PatchOperation.ADD_REPLACE).value(RESOURCE_NAME_TESTDB).build());
ProvisioningResult<UserTO> result = updateUser(userPatch);
assertNotNull(result);
List<PropagationStatus> propagations = result.getPropagationStatuses();
assertNotNull(propagations);
assertEquals(1, propagations.size());
assertEquals(PropagationTaskExecStatus.SUCCESS, propagations.get(0).getStatus());
String resource = propagations.get(0).getResource();
assertEquals(RESOURCE_NAME_TESTDB, resource);
}
@Test
public void issue281() {
UserTO userTO = UserITCase.getUniqueSampleTO("issue281@syncope.apache.org");
userTO.getResources().clear();
userTO.getMemberships().clear();
userTO.getDerAttrs().clear();
userTO.getResources().add(RESOURCE_NAME_CSV);
ProvisioningResult<UserTO> result = createUser(userTO);
assertNotNull(result);
List<PropagationStatus> propagations = result.getPropagationStatuses();
assertNotNull(propagations);
assertEquals(1, propagations.size());
assertNotEquals(PropagationTaskExecStatus.SUCCESS, propagations.get(0).getStatus());
String resource = propagations.get(0).getResource();
assertEquals(RESOURCE_NAME_CSV, resource);
}
@Test
public void issue288() {
UserTO userTO = UserITCase.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 issueSYNCOPE108() {
UserTO userTO = UserITCase.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));
userTO.getMemberships().add(new MembershipTO.Builder().
group("0626100b-a4ba-4e00-9971-86fad52a6216").build());
userTO.getMemberships().add(new MembershipTO.Builder().
group("ba9ed509-b1f5-48ab-a334-c8530a6422dc").build());
userTO.getResources().add(RESOURCE_NAME_CSV);
userTO = createUser(userTO).getEntity();
assertNotNull(userTO);
assertEquals(2, userTO.getMemberships().size());
assertEquals(1, userTO.getResources().size());
ConnObjectTO connObjectTO =
resourceService.readConnObject(RESOURCE_NAME_CSV, AnyTypeKind.USER.name(), userTO.getKey());
assertNotNull(connObjectTO);
// -----------------------------------
// Remove the first membership: de-provisioning shouldn't happen
// -----------------------------------
UserPatch userPatch = new UserPatch();
userPatch.setKey(userTO.getKey());
userPatch.getMemberships().add(new MembershipPatch.Builder().
operation(PatchOperation.DELETE).group(userTO.getMemberships().get(0).getGroupKey()).build());
userTO = updateUser(userPatch).getEntity();
assertNotNull(userTO);
assertEquals(1, userTO.getMemberships().size());
connObjectTO = resourceService.readConnObject(RESOURCE_NAME_CSV, AnyTypeKind.USER.name(), userTO.getKey());
assertNotNull(connObjectTO);
// -----------------------------------
// -----------------------------------
// Remove the resource assigned directly: de-provisioning shouldn't happen
// -----------------------------------
userPatch = new UserPatch();
userPatch.setKey(userTO.getKey());
userPatch.getResources().add(new StringPatchItem.Builder().operation(PatchOperation.DELETE).
value(userTO.getResources().iterator().next()).build());
userTO = updateUser(userPatch).getEntity();
assertNotNull(userTO);
assertEquals(1, userTO.getMemberships().size());
assertFalse(userTO.getResources().isEmpty());
connObjectTO = resourceService.readConnObject(RESOURCE_NAME_CSV, AnyTypeKind.USER.name(), userTO.getKey());
assertNotNull(connObjectTO);
// -----------------------------------
// -----------------------------------
// Remove the first membership: de-provisioning should happen
// -----------------------------------
userPatch = new UserPatch();
userPatch.setKey(userTO.getKey());
userPatch.getMemberships().add(new MembershipPatch.Builder().
operation(PatchOperation.DELETE).group(userTO.getMemberships().get(0).getGroupKey()).build());
userTO = updateUser(userPatch).getEntity();
assertNotNull(userTO);
assertTrue(userTO.getMemberships().isEmpty());
assertTrue(userTO.getResources().isEmpty());
try {
resourceService.readConnObject(RESOURCE_NAME_CSV, AnyTypeKind.USER.name(), userTO.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 = UserITCase.getSampleTO("syncope185@syncope.apache.org");
userTO.getVirAttrs().clear();
userTO.getResources().add(RESOURCE_NAME_LDAP);
ProvisioningResult<UserTO> result = createUser(userTO);
assertNotNull(result);
assertFalse(result.getPropagationStatuses().isEmpty());
assertEquals(RESOURCE_NAME_LDAP, result.getPropagationStatuses().get(0).getResource());
assertEquals(PropagationTaskExecStatus.SUCCESS, result.getPropagationStatuses().get(0).getStatus());
userTO = result.getEntity();
// 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 = UserITCase.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 = UserITCase.getUniqueSampleTO("syncope267@apache.org");
userTO.getVirAttrs().add(attrTO("virtualdata", "virtualvalue"));
userTO.getResources().clear();
userTO.getResources().add(RESOURCE_NAME_DBVIRATTR);
ProvisioningResult<UserTO> result = createUser(userTO);
assertNotNull(result);
assertFalse(result.getPropagationStatuses().isEmpty());
assertEquals(RESOURCE_NAME_DBVIRATTR, result.getPropagationStatuses().get(0).getResource());
assertEquals(PropagationTaskExecStatus.SUCCESS, result.getPropagationStatuses().get(0).getStatus());
userTO = result.getEntity();
ConnObjectTO connObjectTO =
resourceService.readConnObject(RESOURCE_NAME_DBVIRATTR, AnyTypeKind.USER.name(), userTO.getKey());
assertNotNull(connObjectTO);
assertEquals("virtualvalue", connObjectTO.getAttrMap().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 = UserITCase.getUniqueSampleTO("syncope266@apache.org");
userTO.getResources().clear();
userTO = createUser(userTO).getEntity();
assertNotNull(userTO);
UserPatch userPatch = new UserPatch();
userPatch.setKey(userTO.getKey());
// this resource has not a mapping for Password
userPatch.getResources().add(new StringPatchItem.Builder().
operation(PatchOperation.ADD_REPLACE).value(RESOURCE_NAME_UPDATE).build());
userTO = updateUser(userPatch).getEntity();
assertNotNull(userTO);
}
@Test
public void issueSYNCOPE279() {
UserTO userTO = UserITCase.getUniqueSampleTO("syncope279@apache.org");
userTO.getResources().clear();
userTO.getResources().add(RESOURCE_NAME_TIMEOUT);
ProvisioningResult<UserTO> result = createUser(userTO);
assertEquals(RESOURCE_NAME_TIMEOUT, result.getPropagationStatuses().get(0).getResource());
assertNotNull(result.getPropagationStatuses().get(0).getFailureReason());
assertEquals(PropagationTaskExecStatus.FAILURE, result.getPropagationStatuses().get(0).getStatus());
}
@Test
public void issueSYNCOPE122() {
// 1. create user on testdb and testdb2
UserTO userTO = UserITCase.getUniqueSampleTO("syncope122@apache.org");
userTO.getResources().clear();
userTO.getResources().add(RESOURCE_NAME_TESTDB);
userTO.getResources().add(RESOURCE_NAME_TESTDB2);
userTO = createUser(userTO).getEntity();
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.getAttrMap().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.getAttrMap().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)
UserPatch userPatch = new UserPatch();
userPatch.setKey(userTO.getKey());
userPatch.setPassword(new PasswordPatch.Builder().value(getUUIDString()).onSyncope(false).
resource(RESOURCE_NAME_TESTDB).build());
ProvisioningResult<UserTO> result = updateUser(userPatch);
userTO = result.getEntity();
// 3a. Chech that only a single propagation took place
assertNotNull(result.getPropagationStatuses());
assertEquals(1, result.getPropagationStatuses().size());
assertEquals(RESOURCE_NAME_TESTDB, result.getPropagationStatuses().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.getAttrMap().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.getAttrMap().get(OperationalAttributes.PASSWORD_NAME);
assertNotNull(pwdOnTestDb2AttrAfter);
assertNotNull(pwdOnTestDb2AttrAfter.getValues());
assertFalse(pwdOnTestDb2AttrAfter.getValues().isEmpty());
assertEquals(pwdOnTestDb2, pwdOnTestDb2AttrAfter.getValues().iterator().next());
}
@Test
public void issueSYNCOPE136AES() {
// 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);
UserTO userTO = null;
try {
// 3. create user with no resources
userTO = UserITCase.getUniqueSampleTO("syncope136_AES@apache.org");
userTO.getResources().clear();
userTO = createUser(userTO).getEntity();
assertNotNull(userTO);
// 4. update user, assign a propagation priority resource but don't provide any password
UserPatch userPatch = new UserPatch();
userPatch.setKey(userTO.getKey());
userPatch.getResources().add(new StringPatchItem.Builder().
operation(PatchOperation.ADD_REPLACE).value(RESOURCE_NAME_LDAP).build());
userPatch.setPassword(new PasswordPatch.Builder().onSyncope(false).resource(RESOURCE_NAME_LDAP).build());
ProvisioningResult<UserTO> result = updateUser(userPatch);
assertNotNull(result);
userTO = result.getEntity();
assertNotNull(userTO);
// 5. verify that propagation was successful
List<PropagationStatus> props = result.getPropagationStatuses();
assertNotNull(props);
assertEquals(1, props.size());
PropagationStatus prop = props.iterator().next();
assertNotNull(prop);
assertEquals(RESOURCE_NAME_LDAP, prop.getResource());
assertEquals(PropagationTaskExecStatus.SUCCESS, prop.getStatus());
} finally {
// restore initial cipher algorithm
pwdCipherAlgo.getValues().set(0, origpwdCipherAlgo);
configurationService.set(pwdCipherAlgo);
if (userTO != null) {
deleteUser(userTO.getKey());
}
}
}
@Test
public void isseSYNCOPE136Random() {
// 1. create user with no resources
UserTO userTO = UserITCase.getUniqueSampleTO("syncope136_Random@apache.org");
userTO.getResources().clear();
userTO = createUser(userTO).getEntity();
assertNotNull(userTO);
// 2. update user, assign a propagation priority resource but don't provide any password
UserPatch userPatch = new UserPatch();
userPatch.setKey(userTO.getKey());
userPatch.getResources().add(new StringPatchItem.Builder().
operation(PatchOperation.ADD_REPLACE).value(RESOURCE_NAME_LDAP).build());
userPatch.setPassword(new PasswordPatch.Builder().onSyncope(false).resource(RESOURCE_NAME_LDAP).build());
ProvisioningResult<UserTO> result = updateUser(userPatch);
assertNotNull(result);
// 3. verify that propagation was successful
List<PropagationStatus> props = result.getPropagationStatuses();
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 issueSYNCOPE265() {
String[] userKeys = new String[] {
"1417acbe-cbf6-4277-9372-e75e04f97000",
"74cd8ece-715a-44a4-a736-e17b46c4e7e6",
"b3cbc78d-32e6-4bd4-92e0-bbe07566a2ee",
"c9b2dec2-00a7-4855-97c0-d854842b4b24",
"823074dc-d280-436d-a7dd-07399fae48ec" };
for (String userKey : userKeys) {
UserPatch userPatch = new UserPatch();
userPatch.setKey(userKey);
userPatch.getPlainAttrs().add(attrAddReplacePatch("ctype", "a type"));
UserTO userTO = updateUser(userPatch).getEntity();
assertEquals("a type", userTO.getPlainAttrMap().get("ctype").getValues().get(0));
}
}
@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).getEntity();
assertNotNull(groupTO);
// 2. create user with LDAP resource and membership of the above group
UserTO userTO = UserITCase.getUniqueSampleTO("syncope354@syncope.apache.org");
userTO.getResources().add(RESOURCE_NAME_LDAP);
userTO.getMemberships().add(new MembershipTO.Builder().group(groupTO.getKey()).build());
userTO = createUser(userTO).getEntity();
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.getAttrMap().get("uniqueMember").getValues().
contains("uid=" + userTO.getUsername() + ",ou=people,o=isp"));
// 4. remove membership
UserPatch userPatch = new UserPatch();
userPatch.setKey(userTO.getKey());
userPatch.getMemberships().add(new MembershipPatch.Builder().operation(PatchOperation.DELETE).
group(userTO.getMemberships().get(0).getGroupKey()).build());
userTO = updateUser(userPatch).getEntity();
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.getAttrMap().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).getEntity();
assertNotNull(groupTO);
// 2. create user with membership of the above group
UserTO userTO = UserITCase.getUniqueSampleTO("syncope357@syncope.apache.org");
userTO.getPlainAttrs().add(attrTO("obscure", "valueToBeObscured"));
userTO.getPlainAttrs().add(attrTO("photo",
Base64Utility.encode(IOUtils.readBytesFromStream(getClass().getResourceAsStream("/favicon.jpg")))));
userTO.getMemberships().add(new MembershipTO.Builder().group(groupTO.getKey()).build());
userTO = createUser(userTO).getEntity();
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.getAttrMap().get("registeredAddress");
assertNotNull(registeredAddress);
assertEquals(userTO.getPlainAttrMap().get("obscure").getValues(), registeredAddress.getValues());
AttrTO jpegPhoto = connObj.getAttrMap().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 = UserITCase.getUniqueSampleTO("syncope383@apache.org");
userTO.getResources().clear();
userTO = createUser(userTO).getEntity();
assertNotNull(userTO);
// 2. assign resource without specifying a new pwd and check propagation failure
UserPatch userPatch = new UserPatch();
userPatch.setKey(userTO.getKey());
userPatch.getResources().add(new StringPatchItem.Builder().
operation(PatchOperation.ADD_REPLACE).value(RESOURCE_NAME_TESTDB).build());
ProvisioningResult<UserTO> result = updateUser(userPatch);
assertNotNull(result);
userTO = result.getEntity();
assertEquals(RESOURCE_NAME_TESTDB, userTO.getResources().iterator().next());
assertNotEquals(PropagationTaskExecStatus.SUCCESS, result.getPropagationStatuses().get(0).getStatus());
assertNotNull(result.getPropagationStatuses().get(0).getFailureReason());
userTO = result.getEntity();
// 3. request to change password only on testdb
userPatch = new UserPatch();
userPatch.setKey(userTO.getKey());
userPatch.setPassword(
new PasswordPatch.Builder().value(getUUIDString() + "abbcbcbddd123").resource(RESOURCE_NAME_TESTDB).
build());
result = updateUser(userPatch);
assertEquals(RESOURCE_NAME_TESTDB, userTO.getResources().iterator().next());
assertEquals(PropagationTaskExecStatus.SUCCESS, result.getPropagationStatuses().get(0).getStatus());
}
@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).getEntity();
assertNotNull(userTO);
assertTrue(userTO.getResources().isEmpty());
// 2. update assigning a resource NOT forcing mandatory constraints
// AND priority: must fail with PropagationException
UserPatch userPatch = new UserPatch();
userPatch.setKey(userTO.getKey());
userPatch.setPassword(new PasswordPatch.Builder().value("newPassword123").build());
userPatch.getResources().add(new StringPatchItem.Builder().
operation(PatchOperation.ADD_REPLACE).value(RESOURCE_NAME_WS1).build());
userPatch.getResources().add(new StringPatchItem.Builder().
operation(PatchOperation.ADD_REPLACE).value(RESOURCE_NAME_TESTDB).build());
ProvisioningResult<UserTO> result = updateUser(userPatch);
List<PropagationStatus> propagationStatuses = result.getPropagationStatuses();
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.FAILURE, ws1PropagationStatus.getStatus());
}
@Test
public void issueSYNCOPE420() {
RealmTO realm = realmService.list("/even/two").iterator().next();
assertNotNull(realm);
realm.getActionsClassNames().add(DoubleValueLogicActions.class.getName());
realmService.update(realm);
UserTO userTO = UserITCase.getUniqueSampleTO("syncope420@syncope.apache.org");
userTO.setRealm(realm.getFullPath());
userTO.getPlainAttrs().add(attrTO("makeItDouble", "3"));
userTO = createUser(userTO).getEntity();
assertEquals("6", userTO.getPlainAttrMap().get("makeItDouble").getValues().get(0));
UserPatch userPatch = new UserPatch();
userPatch.setKey(userTO.getKey());
userPatch.getPlainAttrs().add(attrAddReplacePatch("makeItDouble", "7"));
userTO = updateUser(userPatch).getEntity();
assertEquals("14", userTO.getPlainAttrMap().get("makeItDouble").getValues().get(0));
}
@Test
public void issueSYNCOPE426() {
UserTO userTO = UserITCase.getUniqueSampleTO("syncope426@syncope.apache.org");
userTO = createUser(userTO).getEntity();
assertNotNull(userTO);
UserPatch userPatch = new UserPatch();
userPatch.setKey(userTO.getKey());
userPatch.setPassword(new PasswordPatch.Builder().value("anotherPassword123").build());
userTO = userService.update(userPatch).readEntity(new GenericType<ProvisioningResult<UserTO>>() {
}).getEntity();
assertNotNull(userTO);
}
@Test
public void issueSYNCOPE435() {
// 1. create user without password
UserTO userTO = UserITCase.getUniqueSampleTO("syncope435@syncope.apache.org");
userTO.setPassword(null);
userTO = createUser(userTO, false).getEntity();
assertNotNull(userTO);
// 2. try to update user by subscribing a resource - works but propagation is not even attempted
UserPatch userPatch = new UserPatch();
userPatch.setKey(userTO.getKey());
userPatch.getResources().add(new StringPatchItem.Builder().
operation(PatchOperation.ADD_REPLACE).value(RESOURCE_NAME_WS1).build());
ProvisioningResult<UserTO> result = updateUser(userPatch);
assertNotNull(result);
userTO = result.getEntity();
assertEquals(Collections.singleton(RESOURCE_NAME_WS1), userTO.getResources());
assertNotEquals(PropagationTaskExecStatus.SUCCESS, result.getPropagationStatuses().get(0).getStatus());
assertTrue(result.getPropagationStatuses().get(0).getFailureReason().
startsWith("Not attempted because there are mandatory attributes without value(s): [__PASSWORD__]"));
}
@Test
public void issueSYNCOPE454() throws NamingException {
// 1. create user with LDAP resource (with 'Generate password if missing' enabled)
UserTO userTO = UserITCase.getUniqueSampleTO("syncope454@syncope.apache.org");
userTO.getResources().add(RESOURCE_NAME_LDAP);
userTO = createUser(userTO).getEntity();
assertNotNull(userTO);
// 2. read resource configuration for LDAP binding
ConnObjectTO connObject =
resourceService.readConnObject(RESOURCE_NAME_LDAP, AnyTypeKind.USER.name(), userTO.getKey());
// 3. try (and succeed) to perform simple LDAP binding with provided password ('password123')
assertNotNull(getLdapRemoteObject(
connObject.getAttrMap().get(Name.NAME).getValues().get(0),
"password123",
connObject.getAttrMap().get(Name.NAME).getValues().get(0)));
// 4. update user without any password change request
UserPatch userPatch = new UserPatch();
userPatch.setKey(userTO.getKey());
userPatch.setPassword(new PasswordPatch());
userPatch.getPlainAttrs().add(attrAddReplacePatch("surname", "surname2"));
userService.update(userPatch);
// 5. try (and succeed again) to perform simple LDAP binding: password has not changed
assertNotNull(getLdapRemoteObject(
connObject.getAttrMap().get(Name.NAME).getValues().get(0),
"password123",
connObject.getAttrMap().get(Name.NAME).getValues().get(0)));
}
@Test
public void issueSYNCOPE493() {
// 1. create user and check that firstname is not propagated on resource with mapping for firstname set to NONE
UserTO userTO = UserITCase.getUniqueSampleTO("493@test.org");
userTO.getResources().add(RESOURCE_NAME_WS1);
ProvisioningResult<UserTO> result = createUser(userTO);
assertNotNull(userTO);
assertEquals(1, result.getPropagationStatuses().size());
assertEquals(PropagationTaskExecStatus.SUCCESS, result.getPropagationStatuses().get(0).getStatus());
userTO = result.getEntity();
ConnObjectTO actual =
resourceService.readConnObject(RESOURCE_NAME_WS1, AnyTypeKind.USER.name(), userTO.getKey());
assertNotNull(actual);
// check if mapping attribute with purpose NONE really hasn't been propagated
assertNull(actual.getAttrMap().get("NAME"));
// 2. update resource ws-target-resource-1
ResourceTO ws1 = resourceService.read(RESOURCE_NAME_WS1);
assertNotNull(ws1);
MappingTO ws1NewUMapping = ws1.getProvision(AnyTypeKind.USER.name()).getMapping();
// change purpose from NONE to BOTH
for (MappingItemTO itemTO : ws1NewUMapping.getItems()) {
if ("firstname".equals(itemTO.getIntAttrName())) {
itemTO.setPurpose(MappingPurpose.BOTH);
}
}
ws1.getProvision(AnyTypeKind.USER.name()).setMapping(ws1NewUMapping);
resourceService.update(ws1);
ResourceTO newWs1 = resourceService.read(ws1.getKey());
assertNotNull(newWs1);
// check for existence
Collection<MappingItemTO> mapItems = newWs1.getProvision(AnyTypeKind.USER.name()).getMapping().getItems();
assertNotNull(mapItems);
assertEquals(7, mapItems.size());
// 3. update user and check firstname propagation
UserPatch userPatch = new UserPatch();
userPatch.setKey(userTO.getKey());
userPatch.setPassword(new PasswordPatch());
userPatch.getPlainAttrs().add(attrAddReplacePatch("firstname", "firstnameNew"));
result = updateUser(userPatch);
assertNotNull(userTO);
assertEquals(1, result.getPropagationStatuses().size());
assertEquals(PropagationTaskExecStatus.SUCCESS, result.getPropagationStatuses().get(0).getStatus());
userTO = result.getEntity();
ConnObjectTO newUser =
resourceService.readConnObject(RESOURCE_NAME_WS1, AnyTypeKind.USER.name(), userTO.getKey());
assertNotNull(newUser.getAttrMap().get("NAME"));
assertEquals("firstnameNew", newUser.getAttrMap().get("NAME").getValues().get(0));
// 4. restore resource ws-target-resource-1 mapping
ws1NewUMapping = newWs1.getProvision(AnyTypeKind.USER.name()).getMapping();
// restore purpose from BOTH to NONE
for (MappingItemTO itemTO : ws1NewUMapping.getItems()) {
if ("firstname".equals(itemTO.getIntAttrName())) {
itemTO.setPurpose(MappingPurpose.NONE);
}
}
newWs1.getProvision(AnyTypeKind.USER.name()).setMapping(ws1NewUMapping);
resourceService.update(newWs1);
}
@Test
public void issueSYNCOPE505DB() throws Exception {
// 1. create user
UserTO user = UserITCase.getUniqueSampleTO("syncope505-db@syncope.apache.org");
user.setPassword("security123");
user = createUser(user).getEntity();
assertNotNull(user);
assertTrue(user.getResources().isEmpty());
// 2. Add DBPasswordPropagationActions
ResourceTO resourceTO = resourceService.read(RESOURCE_NAME_TESTDB);
assertNotNull(resourceTO);
resourceTO.getPropagationActionsClassNames().add(DBPasswordPropagationActions.class.getName());
resourceService.update(resourceTO);
// 3. Add a db resource to the User
UserPatch userPatch = new UserPatch();
userPatch.setKey(user.getKey());
userPatch.getResources().add(new StringPatchItem.Builder().
operation(PatchOperation.ADD_REPLACE).value(RESOURCE_NAME_TESTDB).build());
userPatch.setPassword(new PasswordPatch.Builder().onSyncope(false).resource(RESOURCE_NAME_TESTDB).build());
user = updateUser(userPatch).getEntity();
assertNotNull(user);
assertEquals(1, user.getResources().size());
// 4. Check that the DB resource has the correct password
final JdbcTemplate jdbcTemplate = new JdbcTemplate(testDataSource);
String value = jdbcTemplate.queryForObject(
"SELECT PASSWORD FROM test WHERE ID=?", String.class, user.getUsername());
assertEquals(Encryptor.getInstance().encode("security123", CipherAlgorithm.SHA1), value.toUpperCase());
// 5. Remove DBPasswordPropagationActions
resourceTO = resourceService.read(RESOURCE_NAME_TESTDB);
assertNotNull(resourceTO);
resourceTO.getPropagationActionsClassNames().remove(DBPasswordPropagationActions.class.getName());
resourceService.update(resourceTO);
}
@Test
public void issueSYNCOPE505LDAP() throws Exception {
// 1. create user
UserTO user = UserITCase.getUniqueSampleTO("syncope505-ldap@syncope.apache.org");
user.setPassword("security123");
user = createUser(user).getEntity();
assertNotNull(user);
assertTrue(user.getResources().isEmpty());
// 2. Add LDAPPasswordPropagationActions
ResourceTO resourceTO = resourceService.read(RESOURCE_NAME_LDAP);
assertNotNull(resourceTO);
resourceTO.getPropagationActionsClassNames().add(LDAPPasswordPropagationActions.class.getName());
resourceTO.setRandomPwdIfNotProvided(false);
resourceService.update(resourceTO);
// 3. Add a resource to the User
UserPatch userPatch = new UserPatch();
userPatch.setKey(user.getKey());
userPatch.getResources().add(new StringPatchItem.Builder().
operation(PatchOperation.ADD_REPLACE).value(RESOURCE_NAME_LDAP).build());
userPatch.setPassword(new PasswordPatch.Builder().onSyncope(false).resource(RESOURCE_NAME_LDAP).build());
user = updateUser(userPatch).getEntity();
assertNotNull(user);
assertEquals(1, user.getResources().size());
// 4. Check that the LDAP resource has the correct password
ConnObjectTO connObject =
resourceService.readConnObject(RESOURCE_NAME_LDAP, AnyTypeKind.USER.name(), user.getKey());
assertNotNull(getLdapRemoteObject(
connObject.getAttrMap().get(Name.NAME).getValues().get(0),
"security123",
connObject.getAttrMap().get(Name.NAME).getValues().get(0)));
// 5. Remove LDAPPasswordPropagationActions
resourceTO = resourceService.read(RESOURCE_NAME_LDAP);
assertNotNull(resourceTO);
resourceTO.getPropagationActionsClassNames().remove(LDAPPasswordPropagationActions.class.getName());
resourceTO.setRandomPwdIfNotProvided(true);
resourceService.update(resourceTO);
}
@Test
public void issueSYNCOPE391() {
// 1. create user on Syncope with null password
UserTO userTO = UserITCase.getUniqueSampleTO("syncope391@syncope.apache.org");
userTO.setPassword(null);
userTO = createUser(userTO, false).getEntity();
assertNotNull(userTO);
assertNull(userTO.getPassword());
// 2. create existing user on csv and check that password on Syncope is null and that password on resource
// doesn't change
userTO = new UserTO();
userTO.setRealm(SyncopeConstants.ROOT_REALM);
userTO.setPassword(null);
userTO.setUsername("syncope391@syncope.apache.org");
userTO.getPlainAttrs().add(attrTO("fullname", "fullname"));
userTO.getPlainAttrs().add(attrTO("firstname", "nome0"));
userTO.getPlainAttrs().add(attrTO("surname", "cognome0"));
userTO.getPlainAttrs().add(attrTO("userId", "syncope391@syncope.apache.org"));
userTO.getPlainAttrs().add(attrTO("email", "syncope391@syncope.apache.org"));
userTO.getDerAttrs().add(attrTO("csvuserid", null));
userTO.getAuxClasses().add("csv");
userTO.getResources().add(RESOURCE_NAME_CSV);
userTO = createUser(userTO, false).getEntity();
assertNotNull(userTO);
ConnObjectTO connObjectTO =
resourceService.readConnObject(RESOURCE_NAME_CSV, AnyTypeKind.USER.name(), userTO.getKey());
assertNotNull(connObjectTO);
// check if password has not changed
assertEquals("password0", connObjectTO.getAttrMap().
get(OperationalAttributes.PASSWORD_NAME).getValues().get(0));
assertNull(userTO.getPassword());
// 3. create user with not null password and propagate onto resource-csv, specify not to save password on
// Syncope local storage
userTO = UserITCase.getUniqueSampleTO("syncope391@syncope.apache.org");
userTO.setPassword("passwordTESTNULL1");
userTO.getDerAttrs().clear();
userTO.getVirAttrs().clear();
userTO.getAuxClasses().add("csv");
userTO.getDerAttrs().add(attrTO("csvuserid", null));
userTO.getResources().add(RESOURCE_NAME_CSV);
userTO = createUser(userTO, false).getEntity();
assertNotNull(userTO);
connObjectTO =
resourceService.readConnObject(RESOURCE_NAME_CSV, AnyTypeKind.USER.name(), userTO.getKey());
assertNotNull(connObjectTO);
// check if password has been propagated and that saved userTO's password is null
assertEquals("passwordTESTNULL1", connObjectTO.getAttrMap().
get(OperationalAttributes.PASSWORD_NAME).getValues().get(0));
assertNull(userTO.getPassword());
// 4. create user and propagate password on resource-csv and on Syncope local storage
userTO = UserITCase.getUniqueSampleTO("syncope391@syncope.apache.org");
userTO.setPassword("passwordTESTNULL1");
userTO.getDerAttrs().clear();
userTO.getVirAttrs().clear();
userTO.getAuxClasses().add("csv");
userTO.getDerAttrs().add(attrTO("csvuserid", null));
userTO.getResources().add(RESOURCE_NAME_CSV);
// storePassword true by default
userTO = createUser(userTO).getEntity();
assertNotNull(userTO);
connObjectTO = resourceService.readConnObject(RESOURCE_NAME_CSV, AnyTypeKind.USER.name(), userTO.getKey());
assertNotNull(connObjectTO);
// check if password has been correctly propagated on Syncope and resource-csv as usual
assertEquals("passwordTESTNULL1", connObjectTO.getAttrMap().
get(OperationalAttributes.PASSWORD_NAME).getValues().get(0));
Pair<Map<String, Set<String>>, UserTO> self =
clientFactory.create(userTO.getUsername(), "passwordTESTNULL1").self();
assertNotNull(self);
// 4. add password policy to resource with passwordNotStore to false --> must store password
ResourceTO csv = resourceService.read(RESOURCE_NAME_CSV);
assertNotNull(csv);
try {
csv.setPasswordPolicy("55e5de0b-c79c-4e66-adda-251b6fb8579a");
resourceService.update(csv);
csv = resourceService.read(RESOURCE_NAME_CSV);
assertEquals("55e5de0b-c79c-4e66-adda-251b6fb8579a", csv.getPasswordPolicy());
userTO = UserITCase.getUniqueSampleTO("syncope391@syncope.apache.org");
userTO.setPassword(null);
userTO.getDerAttrs().clear();
userTO.getVirAttrs().clear();
userTO.getAuxClasses().add("csv");
userTO.getDerAttrs().add(attrTO("csvuserid", null));
userTO.getResources().add(RESOURCE_NAME_CSV);
createUser(userTO, false);
fail();
} catch (SyncopeClientException e) {
assertEquals(ClientExceptionType.InvalidUser, e.getType());
assertTrue(e.getMessage().contains("Password mandatory"));
} finally {
// resource csv with null password policy
csv.setPasswordPolicy(null);
resourceService.update(csv);
}
}
@Test
public void issueSYNCOPE647() {
UserTO userTO = UserITCase.getUniqueSampleTO("syncope647@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.getAuxClasses().add("generic membership");
userTO.getPlainAttrs().add(attrTO("postalAddress", "postalAddress"));
userTO.getResources().add(RESOURCE_NAME_LDAP);
UserTO actual = createUser(userTO).getEntity();
assertNotNull(actual);
assertNotNull(actual.getDerAttrMap().get("csvuserid"));
ConnObjectTO connObjectTO =
resourceService.readConnObject(RESOURCE_NAME_LDAP, AnyTypeKind.USER.name(), actual.getKey());
assertNotNull(connObjectTO);
assertEquals("postalAddress", connObjectTO.getAttrMap().get("postalAddress").getValues().get(0));
UserPatch userPatch = new UserPatch();
userPatch.setKey(actual.getKey());
userPatch.getPlainAttrs().add(attrAddReplacePatch("postalAddress", "newPostalAddress"));
actual = updateUser(userPatch).getEntity();
connObjectTO = resourceService.readConnObject(RESOURCE_NAME_LDAP, AnyTypeKind.USER.name(), actual.getKey());
assertNotNull(connObjectTO);
assertEquals("newPostalAddress", connObjectTO.getAttrMap().get("postalAddress").getValues().get(0));
}
@Test
public void issueSYNCOPE626() {
PasswordPolicyTO passwordPolicy = new PasswordPolicyTO();
passwordPolicy.setDescription("Password Policy for SYNCOPE-626");
DefaultPasswordRuleConf ruleConf = new DefaultPasswordRuleConf();
ruleConf.setUsernameAllowed(false);
passwordPolicy.getRuleConfs().add(ruleConf);
passwordPolicy = createPolicy(passwordPolicy);
assertNotNull(passwordPolicy);
RealmTO realm = realmService.list("/even/two").get(0);
String oldPasswordPolicy = realm.getPasswordPolicy();
realm.setPasswordPolicy(passwordPolicy.getKey());
realmService.update(realm);
try {
UserTO user = UserITCase.getUniqueSampleTO("syncope626@syncope.apache.org");
user.setRealm(realm.getFullPath());
user.setPassword(user.getUsername());
try {
createUser(user);
fail();
} catch (SyncopeClientException e) {
assertEquals(ClientExceptionType.InvalidUser, e.getType());
assertTrue(e.getElements().iterator().next().startsWith("InvalidPassword"));
}
user.setPassword("password123");
user = createUser(user).getEntity();
assertNotNull(user);
} finally {
realm.setPasswordPolicy(oldPasswordPolicy);
realmService.update(realm);
policyService.delete(passwordPolicy.getKey());
}
}
@Test
public void issueSYNCOPE686() {
// 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");
String origpwdCipherAlgo = pwdCipherAlgo.getValues().get(0);
// 2. set AES password cipher algorithm
pwdCipherAlgo.getValues().set(0, "AES");
configurationService.set(pwdCipherAlgo);
try {
// 3. create group with LDAP resource assigned
GroupTO group = GroupITCase.getBasicSampleTO("syncope686");
group.getResources().add(RESOURCE_NAME_LDAP);
group = createGroup(group).getEntity();
assertNotNull(group);
// 4. create user with no resources
UserTO userTO = UserITCase.getUniqueSampleTO("syncope686@apache.org");
userTO.getResources().clear();
userTO = createUser(userTO).getEntity();
assertNotNull(userTO);
// 5. update user with the new group, and don't provide any password
UserPatch userPatch = new UserPatch();
userPatch.setKey(userTO.getKey());
userPatch.getMemberships().add(new MembershipPatch.Builder().operation(PatchOperation.ADD_REPLACE).
group(group.getKey()).build());
ProvisioningResult<UserTO> result = updateUser(userPatch);
assertNotNull(result);
// 5. verify that propagation was successful
List<PropagationStatus> props = result.getPropagationStatuses();
assertNotNull(props);
assertEquals(1, props.size());
PropagationStatus prop = props.iterator().next();
assertNotNull(prop);
assertEquals(RESOURCE_NAME_LDAP, prop.getResource());
assertEquals(PropagationTaskExecStatus.SUCCESS, prop.getStatus());
} finally {
// restore initial cipher algorithm
pwdCipherAlgo.getValues().set(0, origpwdCipherAlgo);
configurationService.set(pwdCipherAlgo);
}
}
@Test
public void issueSYNCOPE710() {
// 1. create groups for indirect resource assignment
GroupTO ldapGroup = GroupITCase.getBasicSampleTO("syncope710.ldap");
ldapGroup.getResources().add(RESOURCE_NAME_LDAP);
ldapGroup = createGroup(ldapGroup).getEntity();
GroupTO dbGroup = GroupITCase.getBasicSampleTO("syncope710.db");
dbGroup.getResources().add(RESOURCE_NAME_TESTDB);
dbGroup = createGroup(dbGroup).getEntity();
// 2. create user with memberships for the groups created above
UserTO userTO = UserITCase.getUniqueSampleTO("syncope710@syncope.apache.org");
userTO.getResources().clear();
userTO.getMemberships().clear();
userTO.getMemberships().add(new MembershipTO.Builder().group(ldapGroup.getKey()).build());
userTO.getMemberships().add(new MembershipTO.Builder().group(dbGroup.getKey()).build());
ProvisioningResult<UserTO> result = createUser(userTO);
assertEquals(2, result.getPropagationStatuses().size());
userTO = result.getEntity();
// 3. request to propagate passwod only to db
UserPatch userPatch = new UserPatch();
userPatch.setKey(userTO.getKey());
userPatch.setPassword(new PasswordPatch.Builder().
onSyncope(false).resource(RESOURCE_NAME_TESTDB).value("newpassword123").build());
result = updateUser(userPatch);
assertEquals(1, result.getPropagationStatuses().size());
assertEquals(RESOURCE_NAME_TESTDB, result.getPropagationStatuses().get(0).getResource());
}
@Test
public void issueSYNCOPE881() {
// 1. create group and assign LDAP
GroupTO group = GroupITCase.getSampleTO("syncope881G");
group.getVirAttrs().add(attrTO("rvirtualdata", "rvirtualvalue"));
group = createGroup(group).getEntity();
assertNotNull(group);
assertNotNull(resourceService.readConnObject(RESOURCE_NAME_LDAP, AnyTypeKind.GROUP.name(), group.getKey()));
// 2. create user and assign such group
UserTO user = UserITCase.getUniqueSampleTO("syncope881U@apache.org");
user.getMemberships().clear();
user.getMemberships().add(new MembershipTO.Builder().group(group.getKey()).build());
user = createUser(user).getEntity();
assertNotNull(user);
// 3. verify that user is in LDAP
ConnObjectTO connObject =
resourceService.readConnObject(RESOURCE_NAME_LDAP, AnyTypeKind.USER.name(), user.getKey());
assertNotNull(connObject);
AttrTO userDn = connObject.getAttrMap().get(Name.NAME);
assertNotNull(userDn);
assertEquals(1, userDn.getValues().size());
assertNotNull(getLdapRemoteObject(RESOURCE_LDAP_ADMIN_DN, RESOURCE_LDAP_ADMIN_PWD, userDn.getValues().get(0)));
// 4. remove user
userService.delete(user.getKey());
// 5. verify that user is not in LDAP anynmore
assertNull(getLdapRemoteObject(RESOURCE_LDAP_ADMIN_DN, RESOURCE_LDAP_ADMIN_PWD, userDn.getValues().get(0)));
}
}