package com.evolveum.midpoint.testing.conntest;
/*
* Copyright (c) 2010-2016 Evolveum
*
* Licensed 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.
*/
import static org.testng.AssertJUnit.assertNull;
import static org.testng.AssertJUnit.assertFalse;
import static org.testng.AssertJUnit.assertTrue;
import static org.testng.AssertJUnit.assertNotNull;
import static com.evolveum.midpoint.test.IntegrationTestTools.display;
import static org.testng.AssertJUnit.assertEquals;
import java.io.File;
import java.io.IOException;
import java.util.Collection;
import java.util.List;
import javax.xml.namespace.QName;
import com.evolveum.midpoint.model.impl.sync.ReconciliationTaskHandler;
import com.evolveum.midpoint.util.MiscUtil;
import com.evolveum.midpoint.util.QNameUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.annotation.DirtiesContext.ClassMode;
import org.springframework.test.context.ContextConfiguration;
import org.testng.AssertJUnit;
import org.testng.annotations.Test;
import org.apache.commons.lang.mutable.MutableInt;
import org.apache.directory.api.ldap.model.entry.Entry;
import com.evolveum.midpoint.prism.PrismObject;
import com.evolveum.midpoint.prism.delta.ObjectDelta;
import com.evolveum.midpoint.prism.delta.PropertyDelta;
import com.evolveum.midpoint.prism.path.ItemPath;
import com.evolveum.midpoint.prism.query.ObjectPaging;
import com.evolveum.midpoint.prism.query.ObjectQuery;
import com.evolveum.midpoint.prism.query.OrderDirection;
import com.evolveum.midpoint.prism.util.PrismTestUtil;
import com.evolveum.midpoint.schema.ResultHandler;
import com.evolveum.midpoint.schema.SearchResultList;
import com.evolveum.midpoint.schema.SearchResultMetadata;
import com.evolveum.midpoint.schema.constants.MidPointConstants;
import com.evolveum.midpoint.schema.processor.ResourceAttribute;
import com.evolveum.midpoint.schema.processor.ResourceAttributeDefinition;
import com.evolveum.midpoint.schema.result.OperationResult;
import com.evolveum.midpoint.schema.util.MiscSchemaUtil;
import com.evolveum.midpoint.schema.util.ObjectQueryUtil;
import com.evolveum.midpoint.schema.util.ShadowUtil;
import com.evolveum.midpoint.task.api.Task;
import com.evolveum.midpoint.test.IntegrationTestTools;
import com.evolveum.midpoint.test.util.TestUtil;
import com.evolveum.midpoint.util.exception.CommunicationException;
import com.evolveum.midpoint.util.exception.ConfigurationException;
import com.evolveum.midpoint.util.exception.ObjectAlreadyExistsException;
import com.evolveum.midpoint.util.exception.ObjectNotFoundException;
import com.evolveum.midpoint.util.exception.SchemaException;
import com.evolveum.midpoint.util.exception.SecurityViolationException;
import com.evolveum.midpoint.util.logging.Trace;
import com.evolveum.midpoint.util.logging.TraceManager;
import com.evolveum.midpoint.xml.ns._public.common.common_3.AssignmentType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.CredentialsType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.PasswordType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.RoleType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowAssociationType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.UserType;
import com.evolveum.prism.xml.ns._public.types_3.ProtectedStringType;
/**
* @author Radovan Semancik
*
*/
@ContextConfiguration(locations = {"classpath:ctx-conntest-test-main.xml"})
@DirtiesContext(classMode = ClassMode.AFTER_CLASS)
public abstract class AbstractLdapConnTest extends AbstractLdapSynchronizationTest {
private static final Trace LOGGER = TraceManager.getTrace(AbstractLdapConnTest.class);
protected static final String ACCOUNT_IDM_DN = "uid=idm,ou=Administrators,dc=example,dc=com";
protected static final String ACCOUNT_0_UID = "u00000000";
protected static final String ACCOUNT_19_UID = "u00000019";
protected static final String ACCOUNT_20_UID = "u00000020";
protected static final String ACCOUNT_68_UID = "u00000068";
protected static final String ACCOUNT_69_UID = "u00000069";
protected static final String ACCOUNT_240_UID = "u00000240";
protected static final String ACCOUNT_241_UID = "u00000241";
protected static final int NUMBER_OF_GENERATED_ACCOUNTS = 4000;
protected static final String ACCOUNT_HT_UID = "ht";
protected static final String ACCOUNT_HT_CN = "Herman Toothrot";
protected static final String ACCOUNT_HT_GIVENNAME = "Herman";
protected static final String ACCOUNT_HT_SN = "Toothrot";
private static final String USER_LARGO_NAME = "LarGO";
private static final String USER_LARGO_GIVEN_NAME = "Largo";
private static final String USER_LARGO_FAMILY_NAME = "LaGrande";
protected static final File ROLE_UNDEAD_FILE = new File (COMMON_DIR, "role-undead.xml");
protected static final String ROLE_UNDEAD_OID = "54885c40-ffcc-11e5-b782-63b3e4e2a69d";
protected static final File ROLE_EVIL_FILE = new File (COMMON_DIR, "role-evil.xml");
protected static final String ROLE_EVIL_OID = "624b43ec-ffcc-11e5-8297-f392afa54704";
protected static final String GROUP_UNDEAD_CN = "undead";
protected static final String GROUP_UNDEAD_DESCRIPTION = "Death is for loosers";
protected static final String GROUP_EVIL_CN = "evil";
protected static final String GROUP_EVIL_DESCRIPTION = "No pain no gain";
private static final String REGEXP_RESOURCE_OID_PLACEHOLDER = "%%%RESOURCE%%%";
protected String account0Oid;
protected String accountBarbossaOid;
protected String accountBarbossaDn;
protected String accountBarbossaEntryId;
protected String accountLechuckOid;
protected String accountLechuckDn;
protected String groupEvilShadowOid;
@Autowired
protected ReconciliationTaskHandler reconciliationTaskHandler;
protected boolean isIdmAdminInteOrgPerson() {
return false;
}
protected File getResourceFile() {
return new File(getBaseDir(), "resource.xml");
}
protected abstract String getAccount0Cn();
protected int getNumberOfAllAccounts() {
return NUMBER_OF_GENERATED_ACCOUNTS + (isIdmAdminInteOrgPerson()?1:0);
}
protected boolean hasAssociationShortcut() {
return true;
}
protected boolean isVlvSearchBeyondEndResurnsLastEntry() {
return false;
}
@Override
public void initSystem(Task initTask, OperationResult initResult) throws Exception {
super.initSystem(initTask, initResult);
// Users
repoAddObjectFromFile(USER_BARBOSSA_FILE, initResult);
repoAddObjectFromFile(USER_GUYBRUSH_FILE, initResult);
repoAddObjectFromFile(USER_LECHUCK_FILE, initResult);
// Roles
repoAddObjectFromFileReplaceResource(ROLE_UNDEAD_FILE, RoleType.class, initResult);
repoAddObjectFromFileReplaceResource(ROLE_EVIL_FILE, RoleType.class, initResult);
}
protected <O extends ObjectType> void repoAddObjectFromFileReplaceResource(File file, Class<O> type, OperationResult result) throws IOException, SchemaException, ObjectAlreadyExistsException {
String fileContent = MiscUtil.readFile(file);
String xmlString = fileContent.replaceAll(REGEXP_RESOURCE_OID_PLACEHOLDER, getResourceOid());
PrismObject<O> object = PrismTestUtil.parseObject(xmlString);
repositoryService.addObject(object, null, result);
}
@Test
public void test000Sanity() throws Exception {
super.test000Sanity();
cleanupDelete(toAccountDn(USER_BARBOSSA_USERNAME));
cleanupDelete(toAccountDn(USER_CPTBARBOSSA_USERNAME));
cleanupDelete(toGroupDn(GROUP_UNDEAD_CN));
cleanupDelete(toGroupDn(GROUP_EVIL_CN));
if (needsGroupFakeMemeberEntry()) {
addLdapGroup(GROUP_UNDEAD_CN, GROUP_UNDEAD_DESCRIPTION, "uid=fake,"+getPeopleLdapSuffix());
addLdapGroup(GROUP_EVIL_CN, GROUP_EVIL_DESCRIPTION, "uid=fake,"+getPeopleLdapSuffix());
} else {
addLdapGroup(GROUP_UNDEAD_CN, GROUP_UNDEAD_DESCRIPTION);
addLdapGroup(GROUP_EVIL_CN, GROUP_EVIL_DESCRIPTION);
}
}
@Test
public void test100SeachAccount0ByLdapUid() throws Exception {
final String TEST_NAME = "test100SeachAccount0ByLdapUid";
TestUtil.displayTestTile(this, TEST_NAME);
// GIVEN
Task task = taskManager.createTaskInstance(this.getClass().getName() + "." + TEST_NAME);
OperationResult result = task.getResult();
ObjectQuery query = createUidQuery(ACCOUNT_0_UID);
rememberConnectorOperationCount();
rememberConnectorSimulatedPagingSearchCount();
// WHEN
TestUtil.displayWhen(TEST_NAME);
SearchResultList<PrismObject<ShadowType>> shadows = modelService.searchObjects(ShadowType.class, query, null, task, result);
assertEquals("Unexpected search result: "+shadows, 1, shadows.size());
PrismObject<ShadowType> shadow = shadows.get(0);
assertAccountShadow(shadow, toAccountDn(ACCOUNT_0_UID));
assertConnectorOperationIncrement(1, 2);
assertConnectorSimulatedPagingSearchIncrement(0);
SearchResultMetadata metadata = shadows.getMetadata();
if (metadata != null) {
assertFalse(metadata.isPartialResults());
}
assertLdapConnectorInstances(1);
}
/**
* No paging. It should return all accounts.
*/
@Test
public void test150SeachAllAccounts() throws Exception {
final String TEST_NAME = "test150SeachAllAccounts";
TestUtil.displayTestTile(this, TEST_NAME);
// GIVEN
Task task = taskManager.createTaskInstance(this.getClass().getName() + "." + TEST_NAME);
OperationResult result = task.getResult();
ObjectQuery query = ObjectQueryUtil.createResourceAndObjectClassQuery(getResourceOid(), getAccountObjectClass(), prismContext);
SearchResultList<PrismObject<ShadowType>> searchResultList = doSearch(TEST_NAME, query, getNumberOfAllAccounts(), task, result);
assertConnectorOperationIncrement(1, getNumberOfAllAccounts() + 1);
assertConnectorSimulatedPagingSearchIncrement(0);
SearchResultMetadata metadata = searchResultList.getMetadata();
if (metadata != null) {
assertFalse(metadata.isPartialResults());
}
assertLdapConnectorInstances(1, 2);
}
/**
* Blocksize is 100, so this is in one block.
*/
@Test
public void test152SeachFirst50Accounts() throws Exception {
final String TEST_NAME = "test152SeachFirst50Accounts";
TestUtil.displayTestTile(this, TEST_NAME);
// GIVEN
Task task = taskManager.createTaskInstance(this.getClass().getName() + "." + TEST_NAME);
OperationResult result = task.getResult();
ObjectQuery query = ObjectQueryUtil.createResourceAndObjectClassQuery(getResourceOid(), getAccountObjectClass(), prismContext);
ObjectPaging paging = ObjectPaging.createEmptyPaging();
paging.setMaxSize(50);
query.setPaging(paging);
SearchResultList<PrismObject<ShadowType>> searchResultList = doSearch(TEST_NAME, query, 50, task, result);
assertConnectorOperationIncrement(1, 51);
assertConnectorSimulatedPagingSearchIncrement(0);
SearchResultMetadata metadata = searchResultList.getMetadata();
if (metadata != null) {
assertFalse(metadata.isPartialResults());
}
assertLdapConnectorInstances(1, 2);
}
/**
* Blocksize is 100, so this gets more than two blocks.
*/
@Test
public void test154SeachFirst222Accounts() throws Exception {
final String TEST_NAME = "test154SeachFirst222Accounts";
TestUtil.displayTestTile(this, TEST_NAME);
// GIVEN
Task task = taskManager.createTaskInstance(this.getClass().getName() + "." + TEST_NAME);
OperationResult result = task.getResult();
ObjectQuery query = ObjectQueryUtil.createResourceAndObjectClassQuery(getResourceOid(), getAccountObjectClass(), prismContext);
ObjectPaging paging = ObjectPaging.createEmptyPaging();
paging.setMaxSize(222);
query.setPaging(paging);
SearchResultList<PrismObject<ShadowType>> searchResultList = doSearch(TEST_NAME, query, 222, task, result);
assertConnectorOperationIncrement(1, 223);
assertConnectorSimulatedPagingSearchIncrement(0);
SearchResultMetadata metadata = searchResultList.getMetadata();
if (metadata != null) {
assertFalse(metadata.isPartialResults());
}
assertLdapConnectorInstances(1, 2);
}
/**
* Make a search that starts in the list of all accounts but goes beyond the end.
*/
@Test
public void test156SeachThroughEnd() throws Exception {
final String TEST_NAME = "test156SeachBeyondEnd";
TestUtil.displayTestTile(this, TEST_NAME);
// GIVEN
Task task = taskManager.createTaskInstance(this.getClass().getName() + "." + TEST_NAME);
OperationResult result = task.getResult();
ObjectQuery query = ObjectQueryUtil.createResourceAndObjectClassQuery(getResourceOid(), getAccountObjectClass(), prismContext);
ObjectPaging paging = ObjectPaging.createEmptyPaging();
paging.setOffset(getNumberOfAllAccounts() - 150);
paging.setMaxSize(333);
query.setPaging(paging);
SearchResultList<PrismObject<ShadowType>> searchResultList = doSearch(TEST_NAME, query, 150, task, result);
assertConnectorOperationIncrement(1, 151);
assertConnectorSimulatedPagingSearchIncrement(0);
SearchResultMetadata metadata = searchResultList.getMetadata();
if (metadata != null) {
assertFalse(metadata.isPartialResults());
}
assertLdapConnectorInstances(1, 2);
}
/**
* Make a search that goes beyond the end of the list of all accounts.
*/
@Test
public void test158SeachBeyondEnd() throws Exception {
final String TEST_NAME = "test158SeachBeyondEnd";
TestUtil.displayTestTile(this, TEST_NAME);
// GIVEN
Task task = taskManager.createTaskInstance(this.getClass().getName() + "." + TEST_NAME);
OperationResult result = task.getResult();
ObjectQuery query = ObjectQueryUtil.createResourceAndObjectClassQuery(getResourceOid(), getAccountObjectClass(), prismContext);
ObjectPaging paging = ObjectPaging.createEmptyPaging();
paging.setOffset(getNumberOfAllAccounts() + 50);
paging.setMaxSize(123);
query.setPaging(paging);
int expectedEntries = 0;
if (isVlvSearchBeyondEndResurnsLastEntry()) {
expectedEntries = 1;
}
SearchResultList<PrismObject<ShadowType>> searchResultList = doSearch(TEST_NAME, query, expectedEntries, task, result);
// Fails for 389ds tests. For some unknown reason. And this is not that important. There are similar asserts in other tests that are passing.
// assertConnectorOperationIncrement(1);
assertConnectorSimulatedPagingSearchIncrement(0);
SearchResultMetadata metadata = searchResultList.getMetadata();
if (metadata != null) {
assertFalse(metadata.isPartialResults());
}
assertLdapConnectorInstances(1, 2);
}
@Test
public void test162SeachFirst50AccountsOffset0() throws Exception {
final String TEST_NAME = "test152SeachFirst50Accounts";
TestUtil.displayTestTile(this, TEST_NAME);
// GIVEN
Task task = taskManager.createTaskInstance(this.getClass().getName() + "." + TEST_NAME);
OperationResult result = task.getResult();
ObjectQuery query = ObjectQueryUtil.createResourceAndObjectClassQuery(getResourceOid(), getAccountObjectClass(), prismContext);
ObjectPaging paging = ObjectPaging.createEmptyPaging();
paging.setOffset(0);
paging.setMaxSize(50);
query.setPaging(paging);
SearchResultList<PrismObject<ShadowType>> searchResultList = doSearch(TEST_NAME, query, 50, task, result);
assertConnectorOperationIncrement(1, 51);
assertConnectorSimulatedPagingSearchIncrement(0);
SearchResultMetadata metadata = searchResultList.getMetadata();
if (metadata != null) {
assertFalse(metadata.isPartialResults());
}
assertLdapConnectorInstances(1, 2);
}
/**
* Blocksize is 100, so this is in one block.
* There is offset, so VLV should be used.
* No explicit sorting.
*/
@Test
public void test172Search50AccountsOffset20() throws Exception {
final String TEST_NAME = "test172Search50AccountsOffset20";
TestUtil.displayTestTile(this, TEST_NAME);
// GIVEN
Task task = taskManager.createTaskInstance(this.getClass().getName() + "." + TEST_NAME);
OperationResult result = task.getResult();
ObjectQuery query = ObjectQueryUtil.createResourceAndObjectClassQuery(getResourceOid(), getAccountObjectClass(), prismContext);
ObjectPaging paging = ObjectPaging.createPaging(20, 50);
query.setPaging(paging);
SearchResultList<PrismObject<ShadowType>> searchResultList = doSearch(TEST_NAME, query, 50, task, result);
assertConnectorOperationIncrement(1, 51);
assertConnectorSimulatedPagingSearchIncrement(0);
SearchResultMetadata metadata = searchResultList.getMetadata();
if (metadata != null) {
assertFalse(metadata.isPartialResults());
}
assertLdapConnectorInstances(1, 2);
}
/**
* Blocksize is 100, so this gets more than two blocks.
* There is offset, so VLV should be used.
* No explicit sorting.
*/
@Test
public void test174SeachFirst222AccountsOffset20() throws Exception {
final String TEST_NAME = "test174SeachFirst222AccountsOffset20";
TestUtil.displayTestTile(this, TEST_NAME);
// GIVEN
Task task = taskManager.createTaskInstance(this.getClass().getName() + "." + TEST_NAME);
OperationResult result = task.getResult();
ObjectQuery query = ObjectQueryUtil.createResourceAndObjectClassQuery(getResourceOid(), getAccountObjectClass(), prismContext);
ObjectPaging paging = ObjectPaging.createPaging(20, 222);
query.setPaging(paging);
SearchResultList<PrismObject<ShadowType>> searchResultList = doSearch(TEST_NAME, query, 222, task, result);
assertConnectorOperationIncrement(1, 223);
assertConnectorSimulatedPagingSearchIncrement(0);
SearchResultMetadata metadata = searchResultList.getMetadata();
if (metadata != null) {
assertFalse(metadata.isPartialResults());
}
assertLdapConnectorInstances(1, 2);
}
/**
* Blocksize is 100, so this is in one block.
* There is offset, so VLV should be used.
* Explicit sorting.
*/
@Test
public void test182Search50AccountsOffset20SortUid() throws Exception {
final String TEST_NAME = "test182Search50AccountsOffset20SortUid";
TestUtil.displayTestTile(this, TEST_NAME);
// GIVEN
Task task = taskManager.createTaskInstance(this.getClass().getName() + "." + TEST_NAME);
OperationResult result = task.getResult();
ObjectQuery query = ObjectQueryUtil.createResourceAndObjectClassQuery(getResourceOid(), getAccountObjectClass(), prismContext);
ObjectPaging paging = ObjectPaging.createPaging(20, 50);
paging.setOrdering(getAttributePath(resource, "uid"), OrderDirection.ASCENDING);
query.setPaging(paging);
SearchResultList<PrismObject<ShadowType>> shadows = doSearch(TEST_NAME, query, 50, task, result);
assertAccountShadow(shadows.get(0), toAccountDn(isIdmAdminInteOrgPerson()?ACCOUNT_19_UID:ACCOUNT_20_UID));
assertAccountShadow(shadows.get(49), toAccountDn(isIdmAdminInteOrgPerson()?ACCOUNT_68_UID:ACCOUNT_69_UID));
assertConnectorOperationIncrement(1, 51);
assertConnectorSimulatedPagingSearchIncrement(0);
SearchResultMetadata metadata = shadows.getMetadata();
if (metadata != null) {
assertFalse(metadata.isPartialResults());
}
assertLdapConnectorInstances(1, 2);
}
/**
* Blocksize is 100, so this gets more than two blocks.
* There is offset, so VLV should be used.
* No explicit sorting.
*/
@Test
public void test184SearchFirst222AccountsOffset20SortUid() throws Exception {
final String TEST_NAME = "test184SeachFirst222AccountsOffset20SortUid";
TestUtil.displayTestTile(this, TEST_NAME);
// GIVEN
Task task = taskManager.createTaskInstance(this.getClass().getName() + "." + TEST_NAME);
OperationResult result = task.getResult();
ObjectQuery query = ObjectQueryUtil.createResourceAndObjectClassQuery(getResourceOid(), getAccountObjectClass(), prismContext);
ObjectPaging paging = ObjectPaging.createPaging(20, 222);
paging.setOrdering(getAttributePath(resource, "uid"), OrderDirection.ASCENDING);
query.setPaging(paging);
SearchResultList<PrismObject<ShadowType>> shadows = doSearch(TEST_NAME, query, 222, task, result);
assertAccountShadow(shadows.get(0), toAccountDn(isIdmAdminInteOrgPerson()?ACCOUNT_19_UID:ACCOUNT_20_UID));
assertAccountShadow(shadows.get(221), toAccountDn(isIdmAdminInteOrgPerson()?ACCOUNT_240_UID:ACCOUNT_241_UID));
assertConnectorOperationIncrement(1, 223);
assertConnectorSimulatedPagingSearchIncrement(0);
SearchResultMetadata metadata = shadows.getMetadata();
if (metadata != null) {
assertFalse(metadata.isPartialResults());
}
assertLdapConnectorInstances(1, 2);
}
/**
* No paging. Allow incomplete results. This should violate sizelimit, but some results should
* be returned anyway.
*/
@Test
public void test190SeachAllAccountsSizelimit() throws Exception {
final String TEST_NAME = "test190SeachAllAccountsSizelimit";
TestUtil.displayTestTile(this, TEST_NAME);
// GIVEN
Task task = taskManager.createTaskInstance(this.getClass().getName() + "." + TEST_NAME);
OperationResult result = task.getResult();
ObjectQuery query = ObjectQueryUtil.createResourceAndObjectClassQuery(getResourceOid(), getAccountObjectClass(), prismContext);
query.setAllowPartialResults(true);
SearchResultList<PrismObject<ShadowType>> resultList = doSearch(TEST_NAME, query, getSearchSizeLimit(), task, result);
assertConnectorOperationIncrement(1, getSearchSizeLimit() + 1);
assertConnectorSimulatedPagingSearchIncrement(0);
SearchResultMetadata metadata = resultList.getMetadata();
assertNotNull("No search metadata", metadata);
assertTrue("Partial results not indicated", metadata.isPartialResults());
assertLdapConnectorInstances(1, 2);
}
/**
* Do many searches with different sorting and paging options. This test is designed
* to deplete SSS/VLV resources on the LDAP server side, so the server may reach with
* an error. Make sure that the connector transparently handles the error and that
* we can sustain a large number of searches.
*/
@Test
public void test195SearchInferno() throws Exception {
final String TEST_NAME = "test195SearchInferno";
TestUtil.displayTestTile(this, TEST_NAME);
// GIVEN
Task task = taskManager.createTaskInstance(this.getClass().getName() + "." + TEST_NAME);
OperationResult result = task.getResult();
ObjectQuery query = ObjectQueryUtil.createResourceAndObjectClassQuery(getResourceOid(), getAccountObjectClass(), prismContext);
// WHEN
TestUtil.displayWhen(TEST_NAME);
singleInfernoSearch(query, 30, 10, 30, "uid", task, result);
singleInfernoSearch(query, 40, 5, 40, "cn", task, result);
singleInfernoSearch(query, 15, 2, 15, "sn", task, result);
singleInfernoSearch(query, 42, 200, 42, "uid", task, result);
singleInfernoSearch(query, 200, 30, 200, "sn", task, result);
assertConnectorOperationIncrement(5, 332);
assertConnectorSimulatedPagingSearchIncrement(0);
assertLdapConnectorInstances(1, 2);
}
private void singleInfernoSearch(ObjectQuery query, int expectedNumberOfResults, Integer offset, Integer maxSize, String sortAttrName, Task task, OperationResult result) throws SchemaException, ObjectNotFoundException, CommunicationException, ConfigurationException, SecurityViolationException {
ObjectPaging paging = ObjectPaging.createPaging(offset, maxSize);
paging.setOrdering(getAttributePath(resource, sortAttrName), OrderDirection.ASCENDING);
query.setPaging(paging);
final MutableInt count = new MutableInt();
ResultHandler<ShadowType> handler = new ResultHandler<ShadowType>() {
@Override
public boolean handle(PrismObject<ShadowType> object, OperationResult parentResult) {
count.increment();
return true;
}
};
modelService.searchObjectsIterative(ShadowType.class, query, handler, null, task, result);
assertEquals("Unexpected number of search results", expectedNumberOfResults, count.intValue());
}
// TODO: scoped search
// TODO: count shadows
@Test
public void test200AssignAccountToBarbossa() throws Exception {
final String TEST_NAME = "test200AssignAccountToBarbossa";
TestUtil.displayTestTile(this, TEST_NAME);
// GIVEN
Task task = taskManager.createTaskInstance(this.getClass().getName() + "." + TEST_NAME);
OperationResult result = task.getResult();
long tsStart = System.currentTimeMillis();
// WHEN
TestUtil.displayWhen(TEST_NAME);
assignAccount(USER_BARBOSSA_OID, getResourceOid(), null, task, result);
// THEN
TestUtil.displayThen(TEST_NAME);
result.computeStatus();
TestUtil.assertSuccess(result);
long tsEnd = System.currentTimeMillis();
assertLdapConnectorInstances(1, 2);
Entry entry = assertLdapAccount(USER_BARBOSSA_USERNAME, USER_BARBOSSA_FULL_NAME);
assertAttribute(entry, "title", null);
PrismObject<UserType> user = getUser(USER_BARBOSSA_OID);
String shadowOid = getSingleLinkOid(user);
PrismObject<ShadowType> shadow = getShadowModel(shadowOid);
display("Shadow (model)", shadow);
accountBarbossaOid = shadow.getOid();
Collection<ResourceAttribute<?>> identifiers = ShadowUtil.getPrimaryIdentifiers(shadow);
accountBarbossaEntryId = (String) identifiers.iterator().next().getRealValue();
assertNotNull("No identifier in "+shadow, accountBarbossaEntryId);
assertEquals("Wrong ICFS UID", getAttributeAsString(entry, getPrimaryIdentifierAttributeName()), accountBarbossaEntryId);
assertLdapPassword(USER_BARBOSSA_USERNAME, USER_BARBOSSA_PASSWORD);
ResourceAttribute<Long> createTimestampAttribute = ShadowUtil.getAttribute(shadow, new QName(MidPointConstants.NS_RI, "createTimestamp"));
assertNotNull("No createTimestamp in "+shadow, createTimestampAttribute);
Long createTimestamp = createTimestampAttribute.getRealValue();
// LDAP server may be on a different host. Allow for some clock offset.
TestUtil.assertBetween("Wrong createTimestamp in "+shadow, roundTsDown(tsStart)-1000, roundTsUp(tsEnd)+1000, createTimestamp);
assertLdapConnectorInstances(1, 2);
}
@Test
public void test210ModifyAccountBarbossaReplaceTitle() throws Exception {
final String TEST_NAME = "test210ModifyAccountBarbossaReplaceTitle";
TestUtil.displayTestTile(this, TEST_NAME);
// GIVEN
Task task = taskManager.createTaskInstance(this.getClass().getName() + "." + TEST_NAME);
OperationResult result = task.getResult();
ObjectDelta<ShadowType> delta = ObjectDelta.createEmptyModifyDelta(ShadowType.class, accountBarbossaOid, prismContext);
QName attrQName = new QName(MidPointConstants.NS_RI, "title");
ResourceAttributeDefinition<String> attrDef = accountObjectClassDefinition.findAttributeDefinition(attrQName);
PropertyDelta<String> attrDelta = PropertyDelta.createModificationReplaceProperty(
new ItemPath(ShadowType.F_ATTRIBUTES, attrQName), attrDef, "Captain");
delta.addModification(attrDelta);
// WHEN
TestUtil.displayWhen(TEST_NAME);
modelService.executeChanges(MiscSchemaUtil.createCollection(delta), null, task, result);
// THEN
TestUtil.displayThen(TEST_NAME);
result.computeStatus();
TestUtil.assertSuccess(result);
Entry entry = assertLdapAccount(USER_BARBOSSA_USERNAME, USER_BARBOSSA_FULL_NAME);
assertAttribute(entry, "title", "Captain");
PrismObject<UserType> user = getUser(USER_BARBOSSA_OID);
String shadowOid = getSingleLinkOid(user);
assertEquals("Shadows have moved", accountBarbossaOid, shadowOid);
assertLdapConnectorInstances(1, 2);
}
/**
* Make a duplicate modification. Add a title value that is already there.
* Normal LDAP should fail. So check that connector and midPoint handles that.
*/
@Test
public void test212ModifyAccountBarbossaAddTitleDuplicate() throws Exception {
final String TEST_NAME = "test212ModifyAccountBarbossaAddTitleDuplicate";
TestUtil.displayTestTile(this, TEST_NAME);
// GIVEN
Task task = taskManager.createTaskInstance(this.getClass().getName() + "." + TEST_NAME);
OperationResult result = task.getResult();
ObjectDelta<ShadowType> delta = ObjectDelta.createEmptyModifyDelta(ShadowType.class, accountBarbossaOid, prismContext);
QName attrQName = new QName(MidPointConstants.NS_RI, "title");
ResourceAttributeDefinition<String> attrDef = accountObjectClassDefinition.findAttributeDefinition(attrQName);
PropertyDelta<String> attrDelta = PropertyDelta.createModificationAddProperty(
new ItemPath(ShadowType.F_ATTRIBUTES, attrQName), attrDef, "Captain");
delta.addModification(attrDelta);
// WHEN
TestUtil.displayWhen(TEST_NAME);
modelService.executeChanges(MiscSchemaUtil.createCollection(delta), null, task, result);
// THEN
TestUtil.displayThen(TEST_NAME);
result.computeStatus();
TestUtil.assertSuccess(result);
Entry entry = assertLdapAccount(USER_BARBOSSA_USERNAME, USER_BARBOSSA_FULL_NAME);
assertAttribute(entry, "title", "Captain");
PrismObject<UserType> user = getUser(USER_BARBOSSA_OID);
String shadowOid = getSingleLinkOid(user);
assertEquals("Shadows have moved", accountBarbossaOid, shadowOid);
assertLdapConnectorInstances(1, 2);
}
/**
* Make another duplicate modification. Add a title value that is already there,
* but with a different capitalization.
*/
@Test
public void test213ModifyAccountBarbossaAddTitleDuplicateCapitalized() throws Exception {
final String TEST_NAME = "test213ModifyAccountBarbossaAddTitleDuplicateCapitalized";
TestUtil.displayTestTile(this, TEST_NAME);
// GIVEN
Task task = taskManager.createTaskInstance(this.getClass().getName() + "." + TEST_NAME);
OperationResult result = task.getResult();
ObjectDelta<ShadowType> delta = ObjectDelta.createEmptyModifyDelta(ShadowType.class, accountBarbossaOid, prismContext);
QName attrQName = new QName(MidPointConstants.NS_RI, "title");
ResourceAttributeDefinition<String> attrDef = accountObjectClassDefinition.findAttributeDefinition(attrQName);
PropertyDelta<String> attrDelta = PropertyDelta.createModificationAddProperty(
new ItemPath(ShadowType.F_ATTRIBUTES, attrQName), attrDef, "CAPTAIN");
delta.addModification(attrDelta);
// WHEN
TestUtil.displayWhen(TEST_NAME);
modelService.executeChanges(MiscSchemaUtil.createCollection(delta), null, task, result);
// THEN
TestUtil.displayThen(TEST_NAME);
result.computeStatus();
TestUtil.assertSuccess(result);
Entry entry = assertLdapAccount(USER_BARBOSSA_USERNAME, USER_BARBOSSA_FULL_NAME);
assertAttribute(entry, "title", "Captain");
PrismObject<UserType> user = getUser(USER_BARBOSSA_OID);
String shadowOid = getSingleLinkOid(user);
assertEquals("Shadows have moved", accountBarbossaOid, shadowOid);
assertLdapConnectorInstances(1, 2);
}
@Test
public void test220ModifyUserBarbossaPassword() throws Exception {
final String TEST_NAME = "test220ModifyUserBarbossaPassword";
TestUtil.displayTestTile(this, TEST_NAME);
// GIVEN
Task task = taskManager.createTaskInstance(this.getClass().getName() + "." + TEST_NAME);
OperationResult result = task.getResult();
ProtectedStringType userPasswordPs = new ProtectedStringType();
userPasswordPs.setClearValue(USER_BARBOSSA_PASSWORD_2);
// WHEN
TestUtil.displayWhen(TEST_NAME);
modifyUserReplace(USER_BARBOSSA_OID,
new ItemPath(UserType.F_CREDENTIALS, CredentialsType.F_PASSWORD, PasswordType.F_VALUE),
task, result, userPasswordPs);
// THEN
TestUtil.displayThen(TEST_NAME);
result.computeStatus();
TestUtil.assertSuccess(result);
Entry entry = assertLdapAccount(USER_BARBOSSA_USERNAME, USER_BARBOSSA_FULL_NAME);
assertAttribute(entry, "title", "Captain");
assertLdapPassword(USER_BARBOSSA_USERNAME, USER_BARBOSSA_PASSWORD_2);
PrismObject<UserType> user = getUser(USER_BARBOSSA_OID);
String shadowOid = getSingleLinkOid(user);
assertEquals("Shadows have moved", accountBarbossaOid, shadowOid);
assertLdapConnectorInstances(1, 2);
}
@Test
public void test230ModifyUserBarbossaEmployeeType() throws Exception {
final String TEST_NAME = "test230ModifyUserBarbossaEmployeeType";
TestUtil.displayTestTile(this, TEST_NAME);
// GIVEN
Task task = taskManager.createTaskInstance(this.getClass().getName() + "." + TEST_NAME);
OperationResult result = task.getResult();
// WHEN
TestUtil.displayWhen(TEST_NAME);
modifyUserReplace(USER_BARBOSSA_OID, UserType.F_EMPLOYEE_TYPE, task, result, "Pirate");
// THEN
TestUtil.displayThen(TEST_NAME);
result.computeStatus();
TestUtil.assertSuccess(result);
Entry entry = assertLdapAccount(USER_BARBOSSA_USERNAME, USER_BARBOSSA_FULL_NAME);
assertAttribute(entry, "employeeType", "Pirate");
PrismObject<UserType> user = getUser(USER_BARBOSSA_OID);
String shadowOid = getSingleLinkOid(user);
assertEquals("Shadows have moved", accountBarbossaOid, shadowOid);
assertLdapConnectorInstances(1, 2);
}
@Test
public void test232ModifyUserBarbossaEmployeeTypeAgain() throws Exception {
final String TEST_NAME = "test232ModifyUserBarbossaEmployeeTypeAgain";
TestUtil.displayTestTile(this, TEST_NAME);
// GIVEN
Task task = taskManager.createTaskInstance(this.getClass().getName() + "." + TEST_NAME);
OperationResult result = task.getResult();
// WHEN
TestUtil.displayWhen(TEST_NAME);
modifyUserReplace(USER_BARBOSSA_OID, UserType.F_EMPLOYEE_TYPE, task, result, "Pirate");
// THEN
TestUtil.displayThen(TEST_NAME);
result.computeStatus();
TestUtil.assertSuccess(result);
Entry entry = assertLdapAccount(USER_BARBOSSA_USERNAME, USER_BARBOSSA_FULL_NAME);
assertAttribute(entry, "employeeType", "Pirate");
PrismObject<UserType> user = getUser(USER_BARBOSSA_OID);
String shadowOid = getSingleLinkOid(user);
assertEquals("Shadows have moved", accountBarbossaOid, shadowOid);
assertLdapConnectorInstances(1, 2);
}
@Test
public void test234ModifyUserBarbossaEmployeeTypeAgainCapitalized() throws Exception {
final String TEST_NAME = "test234ModifyUserBarbossaEmployeeTypeAgainCapitalized";
TestUtil.displayTestTile(this, TEST_NAME);
// GIVEN
Task task = taskManager.createTaskInstance(this.getClass().getName() + "." + TEST_NAME);
OperationResult result = task.getResult();
// WHEN
TestUtil.displayWhen(TEST_NAME);
modifyUserReplace(USER_BARBOSSA_OID, UserType.F_EMPLOYEE_TYPE, task, result, "PIRATE");
// THEN
TestUtil.displayThen(TEST_NAME);
result.computeStatus();
TestUtil.assertSuccess(result);
Entry entry = assertLdapAccount(USER_BARBOSSA_USERNAME, USER_BARBOSSA_FULL_NAME);
assertAttribute(entry, "employeeType", "Pirate");
PrismObject<UserType> user = getUser(USER_BARBOSSA_OID);
String shadowOid = getSingleLinkOid(user);
assertEquals("Shadows have moved", accountBarbossaOid, shadowOid);
assertLdapConnectorInstances(1, 2);
}
@Test
public void test290ModifyUserBarbossaRename() throws Exception {
final String TEST_NAME = "test290ModifyUserBarbossaRename";
TestUtil.displayTestTile(this, TEST_NAME);
// GIVEN
Task task = taskManager.createTaskInstance(this.getClass().getName() + "." + TEST_NAME);
OperationResult result = task.getResult();
// WHEN
TestUtil.displayWhen(TEST_NAME);
modifyUserReplace(USER_BARBOSSA_OID, UserType.F_NAME, task, result, PrismTestUtil.createPolyString(USER_CPTBARBOSSA_USERNAME));
// THEN
TestUtil.displayThen(TEST_NAME);
result.computeStatus();
TestUtil.assertSuccess(result);
Entry entry = assertLdapAccount(USER_CPTBARBOSSA_USERNAME, USER_BARBOSSA_FULL_NAME);
display("LDAP entry after", entry);
assertEquals("Wrong DN", toAccountDn(USER_CPTBARBOSSA_USERNAME), entry.getDn().toString());
assertAttribute(entry, "title", "Captain");
PrismObject<UserType> user = getUser(USER_BARBOSSA_OID);
String shadowOid = getSingleLinkOid(user);
assertEquals("Shadows have moved", accountBarbossaOid, shadowOid);
PrismObject<ShadowType> repoShadow = repositoryService.getObject(ShadowType.class, shadowOid, null, result);
display("Repo shadow after rename", repoShadow);
String repoPrimaryIdentifier = ShadowUtil.getAttributeValue(repoShadow, getPrimaryIdentifierAttributeQName());
if ("dn".equals(getPrimaryIdentifierAttributeName())) {
assertEquals("Entry DN (primary identifier) was not updated in the shadow", toAccountDn(USER_CPTBARBOSSA_USERNAME).toLowerCase(), repoPrimaryIdentifier);
} else {
assertEquals("Entry ID changed after rename", accountBarbossaEntryId, repoPrimaryIdentifier);
}
assertLdapConnectorInstances(1, 2);
}
/**
* Try the rename again. This time just as a capitalization of the original name.
* The DN should not change.
*/
@Test
public void test292ModifyUserBarbossaRenameCapitalized() throws Exception {
final String TEST_NAME = "test292ModifyUserBarbossaRenameCapitalized";
TestUtil.displayTestTile(this, TEST_NAME);
// GIVEN
Task task = taskManager.createTaskInstance(this.getClass().getName() + "." + TEST_NAME);
OperationResult result = task.getResult();
rememberConnectorOperationCount();
// WHEN
TestUtil.displayWhen(TEST_NAME);
modifyUserReplace(USER_BARBOSSA_OID, UserType.F_NAME, task, result,
PrismTestUtil.createPolyString(USER_CPTBARBOSSA_USERNAME.toUpperCase()));
// THEN
TestUtil.displayThen(TEST_NAME);
result.computeStatus();
TestUtil.assertSuccess(result);
Entry entry = assertLdapAccount(USER_CPTBARBOSSA_USERNAME, USER_BARBOSSA_FULL_NAME);
display("LDAP entry after", entry);
assertAttribute(entry, "title", "Captain");
assertEquals("Wrong DN", toAccountDn(USER_CPTBARBOSSA_USERNAME), entry.getDn().toString());
assertConnectorOperationIncrement(1, 2); // Just account read, no modify
PrismObject<UserType> user = getUser(USER_BARBOSSA_OID);
String shadowOid = getSingleLinkOid(user);
assertEquals("Shadows have moved", accountBarbossaOid, shadowOid);
PrismObject<ShadowType> repoShadow = repositoryService.getObject(ShadowType.class, shadowOid, null, result);
display("Repo shadow after rename", repoShadow);
String repoPrimaryIdentifier = ShadowUtil.getAttributeValue(repoShadow, getPrimaryIdentifierAttributeQName());
if ("dn".equals(getPrimaryIdentifierAttributeName())) {
assertEquals("Entry DN (primary identifier) was not updated in the shadow", toAccountDn(USER_CPTBARBOSSA_USERNAME).toLowerCase(), repoPrimaryIdentifier);
} else {
assertEquals("Entry ID changed after rename", accountBarbossaEntryId, repoPrimaryIdentifier);
}
assertLdapConnectorInstances(1, 2);
}
@Test
public void test299UnAssignAccountBarbossa() throws Exception {
final String TEST_NAME = "test299UnAssignAccountBarbossa";
TestUtil.displayTestTile(this, TEST_NAME);
// GIVEN
Task task = taskManager.createTaskInstance(this.getClass().getName() + "." + TEST_NAME);
OperationResult result = task.getResult();
// WHEN
TestUtil.displayWhen(TEST_NAME);
unassignAccount(USER_BARBOSSA_OID, getResourceOid(), null, task, result);
// THEN
TestUtil.displayThen(TEST_NAME);
result.computeStatus();
TestUtil.assertSuccess(result);
assertNoLdapAccount(USER_BARBOSSA_USERNAME);
assertNoLdapAccount(USER_CPTBARBOSSA_USERNAME);
PrismObject<UserType> user = getUser(USER_BARBOSSA_OID);
assertNoLinkedAccount(user);
assertLdapConnectorInstances(1, 2);
}
/**
* MID-2853: Unexpected association behaviour - removing roles does not always remove from groups
*/
@Test
public void test300AssignRoleEvilToLechuck() throws Exception {
final String TEST_NAME = "test300AssignRoleEvilToLechuck";
TestUtil.displayTestTile(this, TEST_NAME);
// GIVEN
Task task = createTask(TEST_NAME);
OperationResult result = task.getResult();
// WHEN
TestUtil.displayWhen(TEST_NAME);
assignRole(USER_LECHUCK_OID, ROLE_EVIL_OID, task, result);
// THEN
TestUtil.displayThen(TEST_NAME);
result.computeStatus();
TestUtil.assertSuccess(result);
Entry entry = assertLdapAccount(USER_LECHUCK_USERNAME, USER_LECHUCK_FULL_NAME);
PrismObject<UserType> user = getUser(USER_LECHUCK_OID);
String shadowOid = getSingleLinkOid(user);
PrismObject<ShadowType> shadow = getShadowModel(shadowOid);
display("Shadow (model)", shadow);
accountLechuckOid = shadow.getOid();
accountLechuckDn = entry.getDn().toString();
assertNotNull(accountLechuckDn);
assertLdapGroupMember(entry, GROUP_EVIL_CN);
assertLdapNoGroupMember(entry, GROUP_UNDEAD_CN);
Entry ldapEntryEvil = getLdapEntry(toGroupDn(GROUP_EVIL_CN));
display("Evil group", ldapEntryEvil);
Entry ldapEntryUndead = getLdapEntry(toGroupDn(GROUP_UNDEAD_CN));
display("Undead group", ldapEntryUndead);
assertLdapConnectorInstances(1, 2);
}
/**
* MID-2853: Unexpected association behaviour - removing roles does not always remove from groups
*/
@Test
public void test302AssignRoleUndeadToLechuck() throws Exception {
final String TEST_NAME = "test302AssignRoleUndeadToLechuck";
TestUtil.displayTestTile(this, TEST_NAME);
// GIVEN
Task task = taskManager.createTaskInstance(this.getClass().getName() + "." + TEST_NAME);
OperationResult result = task.getResult();
// WHEN
TestUtil.displayWhen(TEST_NAME);
assignRole(USER_LECHUCK_OID, ROLE_UNDEAD_OID, task, result);
// THEN
TestUtil.displayThen(TEST_NAME);
result.computeStatus();
TestUtil.assertSuccess(result);
Entry entry = assertLdapAccount(USER_LECHUCK_USERNAME, USER_LECHUCK_FULL_NAME);
PrismObject<UserType> user = getUser(USER_LECHUCK_OID);
String shadowOid = getSingleLinkOid(user);
PrismObject<ShadowType> shadow = getShadowModel(shadowOid);
display("Shadow (model)", shadow);
assertLdapGroupMember(entry, GROUP_EVIL_CN);
assertLdapGroupMember(entry, GROUP_UNDEAD_CN);
Entry ldapEntryEvil = getLdapEntry(toGroupDn(GROUP_EVIL_CN));
display("Evil group", ldapEntryEvil);
Entry ldapEntryUndead = getLdapEntry(toGroupDn(GROUP_UNDEAD_CN));
display("Undead group", ldapEntryUndead);
assertLdapConnectorInstances(1, 2);
}
/**
* MID-2853: Unexpected association behaviour - removing roles does not always remove from groups
*/
@Test
public void test306UnassignRoleEvilFromLechuck() throws Exception {
final String TEST_NAME = "test306UnassignRoleEvilFromLechuck";
TestUtil.displayTestTile(this, TEST_NAME);
// GIVEN
Task task = taskManager.createTaskInstance(this.getClass().getName() + "." + TEST_NAME);
OperationResult result = task.getResult();
// WHEN
TestUtil.displayWhen(TEST_NAME);
unassignRole(USER_LECHUCK_OID, ROLE_EVIL_OID, task, result);
// THEN
TestUtil.displayThen(TEST_NAME);
result.computeStatus();
TestUtil.assertSuccess(result);
Entry entry = assertLdapAccount(USER_LECHUCK_USERNAME, USER_LECHUCK_FULL_NAME);
PrismObject<UserType> user = getUser(USER_LECHUCK_OID);
String shadowOid = getSingleLinkOid(user);
PrismObject<ShadowType> shadow = getShadowModel(shadowOid);
display("Shadow (model)", shadow);
assertLdapNoGroupMember(entry, GROUP_EVIL_CN);
assertLdapGroupMember(entry, GROUP_UNDEAD_CN);
Entry ldapEntryEvil = getLdapEntry(toGroupDn(GROUP_EVIL_CN));
display("Evil group", ldapEntryEvil);
Entry ldapEntryUndead = getLdapEntry(toGroupDn(GROUP_UNDEAD_CN));
display("Undead group", ldapEntryUndead);
assertLdapConnectorInstances(1, 2);
}
/**
* MID-2853: Unexpected association behaviour - removing roles does not always remove from groups
*/
@Test
public void test309UnassignRoleUndeadFromLechuck() throws Exception {
final String TEST_NAME = "test309UnassignRoleUndeadFromLechuck";
TestUtil.displayTestTile(this, TEST_NAME);
// GIVEN
Task task = taskManager.createTaskInstance(this.getClass().getName() + "." + TEST_NAME);
OperationResult result = task.getResult();
// WHEN
TestUtil.displayWhen(TEST_NAME);
unassignRole(USER_LECHUCK_OID, ROLE_UNDEAD_OID, task, result);
// THEN
TestUtil.displayThen(TEST_NAME);
result.computeStatus();
TestUtil.assertSuccess(result);
PrismObject<UserType> user = getUser(USER_LECHUCK_OID);
assertNoLinkedAccount(user);
assertNoEntry(accountLechuckDn);
assertNoObject(ShadowType.class, accountLechuckOid, task, result);
assertLdapNoGroupMember(accountLechuckDn, GROUP_EVIL_CN);
assertLdapNoGroupMember(accountLechuckDn, GROUP_UNDEAD_CN);
Entry ldapEntryEvil = getLdapEntry(toGroupDn(GROUP_EVIL_CN));
display("Evil group", ldapEntryEvil);
Entry ldapEntryUndead = getLdapEntry(toGroupDn(GROUP_UNDEAD_CN));
display("Undead group", ldapEntryUndead);
assertLdapConnectorInstances(1, 2);
}
@Test
public void test310SeachGroupEvilByCn() throws Exception {
final String TEST_NAME = "test310SeachGroupEvilByCn";
TestUtil.displayTestTile(this, TEST_NAME);
// GIVEN
Task task = taskManager.createTaskInstance(this.getClass().getName() + "." + TEST_NAME);
OperationResult result = task.getResult();
ObjectQuery query = ObjectQueryUtil.createResourceAndObjectClassQuery(getResourceOid(), getGroupObjectClass(), prismContext);
ObjectQueryUtil.filterAnd(query.getFilter(), createAttributeFilter("cn", GROUP_EVIL_CN));
rememberConnectorOperationCount();
rememberConnectorSimulatedPagingSearchCount();
// WHEN
TestUtil.displayWhen(TEST_NAME);
SearchResultList<PrismObject<ShadowType>> shadows = modelService.searchObjects(ShadowType.class, query, null, task, result);
assertEquals("Unexpected search result: "+shadows, 1, shadows.size());
PrismObject<ShadowType> shadow = shadows.get(0);
assertGroupShadow(shadow, toGroupDn(GROUP_EVIL_CN));
groupEvilShadowOid = shadow.getOid();
assertNotNull(groupEvilShadowOid);
assertConnectorOperationIncrement(1, 1);
assertConnectorSimulatedPagingSearchIncrement(0);
SearchResultMetadata metadata = shadows.getMetadata();
if (metadata != null) {
assertFalse(metadata.isPartialResults());
}
assertLdapConnectorInstances(1, 2);
}
/**
* MID-3209: Rename does not change group membership for associations, when resource does not implement its own referential integrity
*/
@Test
public void test312AssignRoleEvilToBarbossa() throws Exception {
final String TEST_NAME = "test312AssignRoleEvilToBarbossa";
TestUtil.displayTestTile(this, TEST_NAME);
// GIVEN
Task task = taskManager.createTaskInstance(this.getClass().getName() + "." + TEST_NAME);
OperationResult result = task.getResult();
// WHEN
TestUtil.displayWhen(TEST_NAME);
assignRole(USER_BARBOSSA_OID, ROLE_EVIL_OID, task, result);
// THEN
TestUtil.displayThen(TEST_NAME);
result.computeStatus();
TestUtil.assertSuccess(result);
Entry entry = assertLdapAccount(USER_CPTBARBOSSA_USERNAME, USER_BARBOSSA_FULL_NAME);
display("Account LDAP entry", entry);
PrismObject<UserType> user = getUser(USER_BARBOSSA_OID);
String shadowOid = getSingleLinkOid(user);
PrismObject<ShadowType> shadow = getShadowModel(shadowOid);
display("Shadow (model)", shadow);
accountBarbossaOid = shadow.getOid();
accountBarbossaDn = entry.getDn().toString();
assertNotNull(accountBarbossaDn);
Collection<ResourceAttribute<?>> identifiers = ShadowUtil.getPrimaryIdentifiers(shadow);
accountBarbossaEntryId = (String) identifiers.iterator().next().getRealValue();
assertNotNull("No identifier in "+shadow, accountBarbossaEntryId);
Entry ldapEntryEvil = getLdapEntry(toGroupDn(GROUP_EVIL_CN));
display("Evil group", ldapEntryEvil);
Entry ldapEntryUndead = getLdapEntry(toGroupDn(GROUP_UNDEAD_CN));
display("Undead group", ldapEntryUndead);
assertLdapGroupMember(entry, GROUP_EVIL_CN);
assertLdapNoGroupMember(entry, GROUP_UNDEAD_CN);
IntegrationTestTools.assertAssociation(shadow, getAssociationGroupName(), groupEvilShadowOid);
assertLdapConnectorInstances(1, 2);
}
/**
* MID-3209: Rename does not change group membership for associations, when resource does not implement its own referential integrity
*/
@Test
public void test314ModifyUserBarbossaRenameBack() throws Exception {
final String TEST_NAME = "test314ModifyUserBarbossaRenameBack";
TestUtil.displayTestTile(this, TEST_NAME);
// GIVEN
Task task = taskManager.createTaskInstance(this.getClass().getName() + "." + TEST_NAME);
OperationResult result = task.getResult();
PrismObject<UserType> userBefore = getUser(USER_BARBOSSA_OID);
display("user defore", userBefore);
assertNotNull(userBefore);
// WHEN
TestUtil.displayWhen(TEST_NAME);
modifyUserReplace(USER_BARBOSSA_OID, UserType.F_NAME, task, result, PrismTestUtil.createPolyString(USER_BARBOSSA_USERNAME));
// THEN
TestUtil.displayThen(TEST_NAME);
result.computeStatus();
TestUtil.assertSuccess(result);
Entry entry = assertLdapAccount(USER_BARBOSSA_USERNAME, USER_BARBOSSA_FULL_NAME);
display("LDAP entry after", entry);
assertEquals("Wrong DN", toAccountDn(USER_BARBOSSA_USERNAME), entry.getDn().toString());
PrismObject<UserType> user = getUser(USER_BARBOSSA_OID);
String shadowOid = getSingleLinkOid(user);
assertEquals("Shadows have moved", accountBarbossaOid, shadowOid);
PrismObject<ShadowType> repoShadow = repositoryService.getObject(ShadowType.class, shadowOid, null, result);
display("Repo shadow after rename", repoShadow);
String repoPrimaryIdentifier = ShadowUtil.getAttributeValue(repoShadow, getPrimaryIdentifierAttributeQName());
if ("dn".equals(getPrimaryIdentifierAttributeName())) {
assertEquals("Entry DN (primary identifier) was not updated in the shadow", toAccountDn(USER_BARBOSSA_USERNAME).toLowerCase(), repoPrimaryIdentifier);
} else {
assertEquals("Entry ID changed after rename", accountBarbossaEntryId, repoPrimaryIdentifier);
}
Entry ldapEntryEvil = getLdapEntry(toGroupDn(GROUP_EVIL_CN));
display("Evil group", ldapEntryEvil);
Entry ldapEntryUndead = getLdapEntry(toGroupDn(GROUP_UNDEAD_CN));
display("Undead group", ldapEntryUndead);
assertLdapGroupMember(entry, GROUP_EVIL_CN);
assertLdapNoGroupMember(accountBarbossaDn, GROUP_EVIL_CN);
assertLdapNoGroupMember(entry, GROUP_UNDEAD_CN);
assertLdapConnectorInstances(1, 2);
}
/**
* Add user that has role evil, check association. Use mixed lower/upper chars in the username.
* MID-3713
*/
@Test
public void test320AddEvilUserLargo() throws Exception {
final String TEST_NAME = "test320AddEvilUserLargo";
TestUtil.displayTestTile(this, TEST_NAME);
// GIVEN
Task task = createTask(TEST_NAME);
OperationResult result = task.getResult();
PrismObject<UserType> userBefore = createUser(USER_LARGO_NAME, USER_LARGO_GIVEN_NAME, USER_LARGO_FAMILY_NAME, true);
AssignmentType assignmentType = createTargetAssignment(ROLE_EVIL_OID, RoleType.COMPLEX_TYPE);
userBefore.asObjectable().getAssignment().add(assignmentType);
display("user before", userBefore);
// WHEN
TestUtil.displayWhen(TEST_NAME);
addObject(userBefore, task, result);
// THEN
TestUtil.displayThen(TEST_NAME);
result.computeStatus();
TestUtil.assertSuccess(result);
PrismObject<UserType> userAfter = findUserByUsername(USER_LARGO_NAME);
display("user after", userAfter);
assertAssignedRole(userAfter, ROLE_EVIL_OID);
assertAssignments(userAfter, 1);
String shadowOid = getSingleLinkOid(userAfter);
PrismObject<ShadowType> shadow = getShadowModel(shadowOid);
display("Shadow (model)", shadow);
Entry entry = assertLdapAccount(USER_LARGO_NAME, userAfter.asObjectable().getFullName().getOrig());
display("account after", entry);
assertLdapGroupMember(entry, GROUP_EVIL_CN);
assertLdapNoGroupMember(entry, GROUP_UNDEAD_CN);
Entry ldapEntryEvil = getLdapEntry(toGroupDn(GROUP_EVIL_CN));
display("Evil group", ldapEntryEvil);
Entry ldapEntryUndead = getLdapEntry(toGroupDn(GROUP_UNDEAD_CN));
display("Undead group", ldapEntryUndead);
assertAssociation(shadow, ASSOCIATION_GROUP_NAME, groupEvilShadowOid);
assertLdapConnectorInstances(1, 2);
}
private void assertAssociation(PrismObject<ShadowType> shadow, QName assocName, String entitlementOid) {
for (ShadowAssociationType association: shadow.asObjectable().getAssociation()) {
if (QNameUtil.match(assocName, association.getName())) {
assertEquals("Wrong association shadow ref in "+shadow, entitlementOid,
association.getShadowRef().getOid());
return;
}
}
AssertJUnit.fail("Association "+assocName+" not found in "+shadow);
}
protected void assertConnectorOperationIncrement(int shortcutIncrement, int noShortcutIncrement) {
if (hasAssociationShortcut()) {
assertConnectorOperationIncrement(shortcutIncrement);
} else {
assertConnectorOperationIncrement(noShortcutIncrement);
}
}
}