/**
* Copyright (c) 2015-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.
*/
package com.evolveum.midpoint.testing.conntest;
import static org.testng.AssertJUnit.assertNotNull;
import static com.evolveum.midpoint.test.IntegrationTestTools.display;
import static org.testng.AssertJUnit.assertTrue;
import static org.testng.AssertJUnit.assertEquals;
import static org.testng.AssertJUnit.assertFalse;
import java.io.File;
import java.io.IOException;
import java.util.Collection;
import javax.xml.namespace.QName;
import org.apache.directory.api.ldap.model.cursor.CursorException;
import org.apache.directory.api.ldap.model.entry.Entry;
import org.apache.directory.api.ldap.model.exception.LdapException;
import org.apache.directory.ldap.client.api.LdapNetworkConnection;
import org.testng.AssertJUnit;
import org.testng.annotations.Listeners;
import org.testng.annotations.Test;
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.ObjectQuery;
import com.evolveum.midpoint.prism.util.PrismTestUtil;
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.ResourceTypeUtil;
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.MidPointTestConstants;
import com.evolveum.midpoint.test.util.TestUtil;
import com.evolveum.midpoint.util.MiscUtil;
import com.evolveum.midpoint.util.exception.SchemaException;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ActivationStatusType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ActivationType;
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.LockoutStatusType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectReferenceType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.OrgType;
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.ShadowType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.UserType;
import com.evolveum.prism.xml.ns._public.types_3.PolyStringType;
import com.evolveum.prism.xml.ns._public.types_3.ProtectedStringType;
/**
* @author semancik
*
*/
@Listeners({com.evolveum.midpoint.tools.testng.AlphabeticalMethodInterceptor.class})
public abstract class AbstractEDirTest extends AbstractLdapTest {
protected static final File TEST_DIR = new File(MidPointTestConstants.TEST_RESOURCES_DIR, "edir");
protected static final File ROLE_PIRATES_FILE = new File(TEST_DIR, "role-pirate.xml");
protected static final String ROLE_PIRATES_OID = "5dd034e8-41d2-11e5-a123-001e8c717e5b";
protected static final File ROLE_META_ORG_FILE = new File(TEST_DIR, "role-meta-org.xml");
protected static final String ROLE_META_ORG_OID = "f2ad0ace-45d7-11e5-af54-001e8c717e5b";
public static final String ATTRIBUTE_LOCKOUT_LOCKED_NAME = "lockedByIntruder";
public static final String ATTRIBUTE_LOCKOUT_RESET_TIME_NAME = "loginIntruderResetTime";
public static final String ATTRIBUTE_GROUP_MEMBERSHIP_NAME = "groupMembership";
public static final String ATTRIBUTE_EQUIVALENT_TO_ME_NAME = "equivalentToMe";
public static final String ATTRIBUTE_SECURITY_EQUALS_NAME = "securityEquals";
protected static final String ACCOUNT_JACK_UID = "jack";
protected static final String ACCOUNT_JACK_PASSWORD = "qwe123";
private static final String GROUP_PIRATES_NAME = "pirates";
private static final String GROUP_MELEE_ISLAND_NAME = "Mêlée Island";
private static final String GROUP_MELA_NOVA_NAME = "Mela Nova";
protected static final int NUMBER_OF_ACCOUNTS = 4;
protected static final int LOCKOUT_EXPIRATION_SECONDS = 65;
private static final String ASSOCIATION_GROUP_NAME = "group";
protected String jackAccountOid;
protected String groupPiratesOid;
protected long jackLockoutTimestamp;
private String accountBarbossaOid;
private String orgMeleeIslandOid;
protected String groupMeleeOid;
@Override
public String getStartSystemCommand() {
return null;
}
@Override
public String getStopSystemCommand() {
return null;
}
@Override
protected File getBaseDir() {
return TEST_DIR;
}
@Override
protected String getSyncTaskOid() {
return null;
}
@Override
protected boolean useSsl() {
return true;
}
@Override
protected String getLdapSuffix() {
return "o=example";
}
@Override
protected String getLdapBindDn() {
return "cn=admin,o=example";
}
@Override
protected String getLdapBindPassword() {
return "secret";
}
@Override
protected int getSearchSizeLimit() {
return -1;
}
@Override
public String getPrimaryIdentifierAttributeName() {
return "GUID";
}
@Override
protected String getLdapGroupObjectClass() {
return "groupOfNames";
}
@Override
protected String getLdapGroupMemberAttribute() {
return "member";
}
private QName getAssociationGroupQName() {
return new QName(MidPointConstants.NS_RI, ASSOCIATION_GROUP_NAME);
}
protected String getOrgGroupsLdapSuffix() {
return "ou=orggroups,"+getLdapSuffix();
}
@Override
public void initSystem(Task initTask, OperationResult initResult) throws Exception {
super.initSystem(initTask, initResult);
binaryAttributeDetector.addBinaryAttribute("GUID");
// Users
repoAddObjectFromFile(USER_BARBOSSA_FILE, initResult);
repoAddObjectFromFile(USER_GUYBRUSH_FILE, initResult);
// Roles
repoAddObjectFromFile(ROLE_PIRATES_FILE, initResult);
repoAddObjectFromFile(ROLE_META_ORG_FILE, initResult);
}
@Test
public void test000Sanity() throws Exception {
final String TEST_NAME = "test000Sanity";
TestUtil.displayTestTile(this, TEST_NAME);
assertLdapPassword(ACCOUNT_JACK_UID, ACCOUNT_JACK_PASSWORD);
assertEDirGroupMember(ACCOUNT_JACK_UID, GROUP_PIRATES_NAME);
cleanupDelete(toAccountDn(USER_BARBOSSA_USERNAME));
cleanupDelete(toAccountDn(USER_CPTBARBOSSA_USERNAME));
cleanupDelete(toAccountDn(USER_GUYBRUSH_USERNAME));
cleanupDelete(toOrgGroupDn(GROUP_MELEE_ISLAND_NAME));
cleanupDelete(toOrgGroupDn(GROUP_MELA_NOVA_NAME));
}
@Test
public void test050Capabilities() throws Exception {
final String TEST_NAME = "test050Capabilities";
TestUtil.displayTestTile(this, TEST_NAME);
Collection<Object> nativeCapabilitiesCollection = ResourceTypeUtil.getNativeCapabilitiesCollection(resourceType);
display("Native capabilities", nativeCapabilitiesCollection);
assertTrue("No native activation capability", ResourceTypeUtil.hasResourceNativeActivationCapability(resourceType));
assertTrue("No native activation status capability", ResourceTypeUtil.hasResourceNativeActivationStatusCapability(resourceType));
assertTrue("No native lockout capability", ResourceTypeUtil.hasResourceNativeActivationLockoutCapability(resourceType));
assertTrue("No native credentias capability", ResourceTypeUtil.isCredentialsCapabilityEnabled(resourceType));
}
@Test
public void test100SeachJackByLdapUid() throws Exception {
final String TEST_NAME = "test100SeachJackByLdapUid";
TestUtil.displayTestTile(this, TEST_NAME);
// GIVEN
Task task = taskManager.createTaskInstance(this.getClass().getName() + "." + TEST_NAME);
OperationResult result = task.getResult();
ObjectQuery query = createUidQuery(ACCOUNT_JACK_UID);
rememberConnectorOperationCount();
rememberConnectorSimulatedPagingSearchCount();
// WHEN
TestUtil.displayWhen(TEST_NAME);
SearchResultList<PrismObject<ShadowType>> shadows = modelService.searchObjects(ShadowType.class, query, null, task, result);
// THEN
result.computeStatus();
TestUtil.assertSuccess(result);
assertEquals("Unexpected search result: "+shadows, 1, shadows.size());
PrismObject<ShadowType> shadow = shadows.get(0);
display("Shadow", shadow);
assertAccountShadow(shadow, toAccountDn(ACCOUNT_JACK_UID));
assertShadowLockout(shadow, LockoutStatusType.NORMAL);
jackAccountOid = shadow.getOid();
assertNotNull("Null OID in "+shadow, jackAccountOid);
assertConnectorOperationIncrement(2);
assertConnectorSimulatedPagingSearchIncrement(0);
SearchResultMetadata metadata = shadows.getMetadata();
if (metadata != null) {
assertFalse(metadata.isPartialResults());
}
}
@Test
public void test105SeachPiratesByCn() throws Exception {
final String TEST_NAME = "test105SeachPiratesByCn";
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_PIRATES_NAME));
rememberConnectorOperationCount();
rememberConnectorSimulatedPagingSearchCount();
// WHEN
TestUtil.displayWhen(TEST_NAME);
SearchResultList<PrismObject<ShadowType>> shadows = modelService.searchObjects(ShadowType.class, query, null, task, result);
// THEN
result.computeStatus();
TestUtil.assertSuccess(result);
assertEquals("Unexpected search result: "+shadows, 1, shadows.size());
PrismObject<ShadowType> shadow = shadows.get(0);
display("Shadow", shadow);
groupPiratesOid = shadow.getOid();
assertConnectorOperationIncrement(2);
assertConnectorSimulatedPagingSearchIncrement(0);
SearchResultMetadata metadata = shadows.getMetadata();
if (metadata != null) {
assertFalse(metadata.isPartialResults());
}
}
@Test
public void test110GetJack() throws Exception {
final String TEST_NAME = "test110GetJack";
TestUtil.displayTestTile(this, TEST_NAME);
// GIVEN
Task task = taskManager.createTaskInstance(this.getClass().getName() + "." + TEST_NAME);
OperationResult result = task.getResult();
ObjectQuery query = createUidQuery(ACCOUNT_JACK_UID);
rememberConnectorOperationCount();
rememberConnectorSimulatedPagingSearchCount();
// WHEN
TestUtil.displayWhen(TEST_NAME);
PrismObject<ShadowType> shadow = modelService.getObject(ShadowType.class, jackAccountOid, null, task, result);
// THEN
result.computeStatus();
TestUtil.assertSuccess(result);
display("Shadow", shadow);
assertAccountShadow(shadow, toAccountDn(ACCOUNT_JACK_UID));
assertShadowLockout(shadow, LockoutStatusType.NORMAL);
assertPasswordAllowChange(shadow, null);
jackAccountOid = shadow.getOid();
IntegrationTestTools.assertAssociation(shadow, getAssociationGroupQName(), groupPiratesOid);
assertConnectorOperationIncrement(1);
assertConnectorSimulatedPagingSearchIncrement(0);
}
@Test
public void test120JackLockout() throws Exception {
final String TEST_NAME = "test120JackLockout";
TestUtil.displayTestTile(this, TEST_NAME);
// GIVEN
Task task = taskManager.createTaskInstance(this.getClass().getName() + "." + TEST_NAME);
OperationResult result = task.getResult();
makeBadLoginAttempt(ACCOUNT_JACK_UID);
makeBadLoginAttempt(ACCOUNT_JACK_UID);
makeBadLoginAttempt(ACCOUNT_JACK_UID);
makeBadLoginAttempt(ACCOUNT_JACK_UID);
jackLockoutTimestamp = System.currentTimeMillis();
ObjectQuery query = createUidQuery(ACCOUNT_JACK_UID);
rememberConnectorOperationCount();
rememberConnectorSimulatedPagingSearchCount();
// WHEN
TestUtil.displayWhen(TEST_NAME);
SearchResultList<PrismObject<ShadowType>> shadows = modelService.searchObjects(ShadowType.class, query, null, task, result);
// THEN
TestUtil.displayThen(TEST_NAME);
result.computeStatus();
TestUtil.assertSuccess(result);
assertEquals("Unexpected search result: "+shadows, 1, shadows.size());
PrismObject<ShadowType> shadow = shadows.get(0);
display("Shadow", shadow);
assertAccountShadow(shadow, toAccountDn(ACCOUNT_JACK_UID));
assertShadowLockout(shadow, LockoutStatusType.LOCKED);
assertConnectorOperationIncrement(1);
assertConnectorSimulatedPagingSearchIncrement(0);
SearchResultMetadata metadata = shadows.getMetadata();
if (metadata != null) {
assertFalse(metadata.isPartialResults());
}
}
/**
* 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, NUMBER_OF_ACCOUNTS, task, result);
assertConnectorOperationIncrement(1);
assertConnectorSimulatedPagingSearchIncrement(0);
SearchResultMetadata metadata = searchResultList.getMetadata();
if (metadata != null) {
assertFalse(metadata.isPartialResults());
}
}
@Test
public void test190SeachLockedAccounts() throws Exception {
final String TEST_NAME = "test190SeachLockedAccounts";
TestUtil.displayTestTile(this, TEST_NAME);
// GIVEN
Task task = taskManager.createTaskInstance(this.getClass().getName() + "." + TEST_NAME);
OperationResult result = task.getResult();
ObjectQuery query = ObjectQueryUtil.createResourceAndObjectClassFilterPrefix(getResourceOid(), getAccountObjectClass(), prismContext)
.and().item(ShadowType.F_ACTIVATION, ActivationType.F_LOCKOUT_STATUS).eq(LockoutStatusType.LOCKED)
.build();
SearchResultList<PrismObject<ShadowType>> searchResultList = doSearch(TEST_NAME, query, 1, task, result);
assertConnectorOperationIncrement(1);
assertConnectorSimulatedPagingSearchIncrement(0);
PrismObject<ShadowType> shadow = searchResultList.get(0);
display("Shadow", shadow);
assertAccountShadow(shadow, toAccountDn(ACCOUNT_JACK_UID));
assertShadowLockout(shadow, LockoutStatusType.LOCKED);
SearchResultMetadata metadata = searchResultList.getMetadata();
if (metadata != null) {
assertFalse(metadata.isPartialResults());
}
}
@Test
public void test200AssignAccountBarbossa() throws Exception {
final String TEST_NAME = "test200AssignAccountBarbossa";
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();
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);
String accountBarbossaIcfUid = (String) identifiers.iterator().next().getRealValue();
assertNotNull("No identifier in "+shadow, accountBarbossaIcfUid);
assertEquals("Wrong ICFS UID", MiscUtil.binaryToHex(entry.get(getPrimaryIdentifierAttributeName()).getBytes()), accountBarbossaIcfUid);
assertLdapPassword(USER_BARBOSSA_USERNAME, USER_BARBOSSA_PASSWORD);
assertPasswordAllowChange(shadow, null);
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);
}
@Test
public void test210ModifyAccountBarbossaTitle() throws Exception {
final String TEST_NAME = "test210ModifyAccountBarbossaTitle";
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);
}
@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("hereThereBeMonsters");
// 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, "hereThereBeMonsters");
PrismObject<UserType> user = getUser(USER_BARBOSSA_OID);
String shadowOid = getSingleLinkOid(user);
assertEquals("Shadows have moved", accountBarbossaOid, shadowOid);
}
@Test
public void test230DisableBarbossa() throws Exception {
final String TEST_NAME = "test230DisableBarbossa";
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,
new ItemPath(UserType.F_ACTIVATION, ActivationType.F_ADMINISTRATIVE_STATUS),
task, result, ActivationStatusType.DISABLED);
// THEN
TestUtil.displayThen(TEST_NAME);
result.computeStatus();
TestUtil.assertSuccess(result);
PrismObject<UserType> user = getUser(USER_BARBOSSA_OID);
assertAdministrativeStatus(user, ActivationStatusType.DISABLED);
Entry entry = assertLdapAccount(USER_BARBOSSA_USERNAME, USER_BARBOSSA_FULL_NAME);
assertAttribute(entry, "loginDisabled", "TRUE");
String shadowOid = getSingleLinkOid(user);
PrismObject<ShadowType> shadow = getObject(ShadowType.class, shadowOid);
assertAdministrativeStatus(shadow, ActivationStatusType.DISABLED);
}
@Test
public void test239EnableBarbossa() throws Exception {
final String TEST_NAME = "test239EnableBarbossa";
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,
new ItemPath(UserType.F_ACTIVATION, ActivationType.F_ADMINISTRATIVE_STATUS),
task, result, ActivationStatusType.ENABLED);
// THEN
TestUtil.displayThen(TEST_NAME);
result.computeStatus();
TestUtil.assertSuccess(result);
PrismObject<UserType> user = getUser(USER_BARBOSSA_OID);
assertAdministrativeStatus(user, ActivationStatusType.ENABLED);
Entry entry = assertLdapAccount(USER_BARBOSSA_USERNAME, USER_BARBOSSA_FULL_NAME);
assertAttribute(entry, "loginDisabled", "FALSE");
String shadowOid = getSingleLinkOid(user);
PrismObject<ShadowType> shadow = getObject(ShadowType.class, shadowOid);
assertAdministrativeStatus(shadow, ActivationStatusType.ENABLED);
}
/**
* passwordAllowChange is a boolean attribute
*/
@Test
public void test240ModifyAccountBarbossaPasswordAllowChangeFalse() throws Exception {
final String TEST_NAME = "test240ModifyAccountBarbossaPasswordAllowChangeFalse";
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, "passwordAllowChange");
ResourceAttributeDefinition<Boolean> attrDef = accountObjectClassDefinition.findAttributeDefinition(attrQName);
PropertyDelta<Boolean> attrDelta = PropertyDelta.createModificationReplaceProperty(
new ItemPath(ShadowType.F_ATTRIBUTES, attrQName), attrDef, Boolean.FALSE);
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, "passwordAllowChange", "FALSE");
PrismObject<UserType> user = getUser(USER_BARBOSSA_OID);
String shadowOid = getSingleLinkOid(user);
assertEquals("Shadows have moved", accountBarbossaOid, shadowOid);
PrismObject<ShadowType> shadow = getObject(ShadowType.class, shadowOid);
display("Shadow after", shadow);
assertPasswordAllowChange(shadow, false);
}
/**
* This should create account with a group. And disabled.
*/
@Test
public void test250AssignGuybrushPirates() throws Exception {
final String TEST_NAME = "test250AssignGuybrushPirates";
TestUtil.displayTestTile(this, TEST_NAME);
// GIVEN
Task task = taskManager.createTaskInstance(this.getClass().getName() + "." + TEST_NAME);
OperationResult result = task.getResult();
modifyUserReplace(USER_GUYBRUSH_OID,
new ItemPath(UserType.F_ACTIVATION, ActivationType.F_ADMINISTRATIVE_STATUS),
task, result, ActivationStatusType.DISABLED);
// WHEN
TestUtil.displayWhen(TEST_NAME);
assignRole(USER_GUYBRUSH_OID, ROLE_PIRATES_OID, task, result);
// THEN
TestUtil.displayThen(TEST_NAME);
result.computeStatus();
TestUtil.assertSuccess(result);
Entry entry = assertLdapAccount(USER_GUYBRUSH_USERNAME, USER_GUYBRUSH_FULL_NAME);
display("Entry", entry);
assertAttribute(entry, "loginDisabled", "TRUE");
assertEDirGroupMember(entry, GROUP_PIRATES_NAME);
PrismObject<UserType> user = getUser(USER_GUYBRUSH_OID);
assertAdministrativeStatus(user, ActivationStatusType.DISABLED);
String shadowOid = getSingleLinkOid(user);
PrismObject<ShadowType> shadow = getObject(ShadowType.class, shadowOid);
IntegrationTestTools.assertAssociation(shadow, getAssociationGroupQName(), groupPiratesOid);
assertAdministrativeStatus(shadow, ActivationStatusType.DISABLED);
}
@Test
public void test260EnableGyubrush() throws Exception {
final String TEST_NAME = "test260EnableGyubrush";
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_GUYBRUSH_OID,
new ItemPath(UserType.F_ACTIVATION, ActivationType.F_ADMINISTRATIVE_STATUS),
task, result, ActivationStatusType.ENABLED);
// THEN
TestUtil.displayThen(TEST_NAME);
result.computeStatus();
TestUtil.assertSuccess(result);
PrismObject<UserType> user = getUser(USER_GUYBRUSH_OID);
assertAdministrativeStatus(user, ActivationStatusType.ENABLED);
Entry entry = assertLdapAccount(USER_GUYBRUSH_USERNAME, USER_GUYBRUSH_FULL_NAME);
assertAttribute(entry, "loginDisabled", "FALSE");
String shadowOid = getSingleLinkOid(user);
PrismObject<ShadowType> shadow = getObject(ShadowType.class, shadowOid);
assertAdministrativeStatus(shadow, ActivationStatusType.ENABLED);
}
// TODO: search for disabled accounts
@Test
public void test300AssignBarbossaPirates() throws Exception {
final String TEST_NAME = "test300AssignBarbossaPirates";
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_PIRATES_OID, task, result);
// THEN
TestUtil.displayThen(TEST_NAME);
result.computeStatus();
TestUtil.assertSuccess(result);
Entry entry = assertLdapAccount(USER_BARBOSSA_USERNAME, USER_BARBOSSA_FULL_NAME);
display("Entry", entry);
assertAttribute(entry, "title", "Captain");
Entry groupEntry = assertEDirGroupMember(entry, GROUP_PIRATES_NAME);
display("Group entry", groupEntry);
PrismObject<UserType> user = getUser(USER_BARBOSSA_OID);
String shadowOid = getSingleLinkOid(user);
assertEquals("Shadows have moved", accountBarbossaOid, shadowOid);
PrismObject<ShadowType> shadow = getObject(ShadowType.class, shadowOid);
IntegrationTestTools.assertAssociation(shadow, getAssociationGroupQName(), groupPiratesOid);
}
@Test
public void test390ModifyUserBarbossaRename() throws Exception {
final String TEST_NAME = "test390ModifyUserBarbossaRename";
TestUtil.displayTestTile(this, TEST_NAME);
// GIVEN
Task task = taskManager.createTaskInstance(this.getClass().getName() + "." + TEST_NAME);
OperationResult result = task.getResult();
// WHEN
TestUtil.displayWhen(TEST_NAME);
renameObject(UserType.class, USER_BARBOSSA_OID, USER_CPTBARBOSSA_USERNAME, task, result);
// THEN
TestUtil.displayThen(TEST_NAME);
result.computeStatus();
TestUtil.assertSuccess(result);
Entry entry = assertLdapAccount(USER_CPTBARBOSSA_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);
PrismObject<ShadowType> shadow = getObject(ShadowType.class, shadowOid);
display("Shadow after rename (model)", shadow);
PrismObject<ShadowType> repoShadow = repositoryService.getObject(ShadowType.class, shadowOid, null, result);
display("Shadow after rename (repo)", repoShadow);
assertNoLdapAccount(USER_BARBOSSA_USERNAME);
}
// TODO: create account with a group membership
@Test
public void test500AddOrgMeleeIsland() throws Exception {
final String TEST_NAME = "test500AddOrgMeleeIsland";
TestUtil.displayTestTile(this, TEST_NAME);
// GIVEN
Task task = taskManager.createTaskInstance(this.getClass().getName() + "." + TEST_NAME);
OperationResult result = task.getResult();
PrismObject<OrgType> org = prismContext.getSchemaRegistry().findObjectDefinitionByCompileTimeClass(OrgType.class).instantiate();
OrgType orgType = org.asObjectable();
orgType.setName(new PolyStringType(GROUP_MELEE_ISLAND_NAME));
AssignmentType metaroleAssignment = new AssignmentType();
ObjectReferenceType metaroleRef = new ObjectReferenceType();
metaroleRef.setOid(ROLE_META_ORG_OID);
metaroleRef.setType(RoleType.COMPLEX_TYPE);
metaroleAssignment.setTargetRef(metaroleRef);
orgType.getAssignment().add(metaroleAssignment);
// WHEN
TestUtil.displayWhen(TEST_NAME);
addObject(org, task, result);
// THEN
TestUtil.displayThen(TEST_NAME);
result.computeStatus();
TestUtil.assertSuccess(result);
orgMeleeIslandOid = org.getOid();
Entry entry = assertLdapGroup(GROUP_MELEE_ISLAND_NAME);
org = getObject(OrgType.class, orgMeleeIslandOid);
groupMeleeOid = getSingleLinkOid(org);
PrismObject<ShadowType> shadow = getShadowModel(groupMeleeOid);
display("Shadow (model)", shadow);
}
@Test
public void test510AssignGuybrushMeleeIsland() throws Exception {
final String TEST_NAME = "test510AssignGuybrushMeleeIsland";
TestUtil.displayTestTile(this, TEST_NAME);
// GIVEN
Task task = taskManager.createTaskInstance(this.getClass().getName() + "." + TEST_NAME);
OperationResult result = task.getResult();
// WHEN
TestUtil.displayWhen(TEST_NAME);
assignOrg(USER_GUYBRUSH_OID, orgMeleeIslandOid, task, result);
// THEN
TestUtil.displayThen(TEST_NAME);
result.computeStatus();
TestUtil.assertSuccess(result);
Entry entry = assertLdapAccount(USER_GUYBRUSH_USERNAME, USER_GUYBRUSH_FULL_NAME);
PrismObject<UserType> user = getUser(USER_GUYBRUSH_OID);
String shadowOid = getSingleLinkOid(user);
PrismObject<ShadowType> shadow = getShadowModel(shadowOid);
display("Shadow (model)", shadow);
assertEDirGroupMember(entry, GROUP_MELEE_ISLAND_NAME);
IntegrationTestTools.assertAssociation(shadow, getAssociationGroupQName(), groupMeleeOid);
}
@Test
public void test520RenameOrgMeleeIsland() throws Exception {
final String TEST_NAME = "test520RenameOrgMeleeIsland";
TestUtil.displayTestTile(this, TEST_NAME);
// GIVEN
Task task = taskManager.createTaskInstance(this.getClass().getName() + "." + TEST_NAME);
OperationResult result = task.getResult();
// WHEN
TestUtil.displayWhen(TEST_NAME);
renameObject(OrgType.class, orgMeleeIslandOid, GROUP_MELA_NOVA_NAME, task, result);
// THEN
TestUtil.displayThen(TEST_NAME);
result.computeStatus();
TestUtil.assertSuccess(result);
Entry entry = assertLdapGroup(GROUP_MELA_NOVA_NAME);
PrismObject<OrgType> org = getObject(OrgType.class, orgMeleeIslandOid);
String groupMeleeOidAfter = getSingleLinkOid(org);
PrismObject<ShadowType> shadow = getShadowModel(groupMeleeOidAfter);
display("Shadow (model)", shadow);
}
// Wait until the lockout of Jack expires, check status
@Test
public void test800JackLockoutExpires() throws Exception {
final String TEST_NAME = "test800JackLockoutExpires";
TestUtil.displayTestTile(this, TEST_NAME);
// GIVEN
Task task = taskManager.createTaskInstance(this.getClass().getName() + "." + TEST_NAME);
OperationResult result = task.getResult();
long now = System.currentTimeMillis();
long lockoutExpires = jackLockoutTimestamp + LOCKOUT_EXPIRATION_SECONDS*1000;
if (now < lockoutExpires) {
display("Sleeping for "+(lockoutExpires-now)+"ms (waiting for lockout expiration)");
Thread.sleep(lockoutExpires-now);
}
now = System.currentTimeMillis();
display("Time is now "+now);
ObjectQuery query = createUidQuery(ACCOUNT_JACK_UID);
rememberConnectorOperationCount();
rememberConnectorSimulatedPagingSearchCount();
// WHEN
TestUtil.displayWhen(TEST_NAME);
SearchResultList<PrismObject<ShadowType>> shadows = modelService.searchObjects(ShadowType.class, query, null, task, result);
// THEN
TestUtil.displayThen(TEST_NAME);
result.computeStatus();
TestUtil.assertSuccess(result);
assertEquals("Unexpected search result: "+shadows, 1, shadows.size());
PrismObject<ShadowType> shadow = shadows.get(0);
display("Shadow", shadow);
assertAccountShadow(shadow, toAccountDn(ACCOUNT_JACK_UID));
assertShadowLockout(shadow, LockoutStatusType.NORMAL);
assertConnectorOperationIncrement(1);
assertConnectorSimulatedPagingSearchIncrement(0);
SearchResultMetadata metadata = shadows.getMetadata();
if (metadata != null) {
assertFalse(metadata.isPartialResults());
}
}
@Test
public void test810SeachLockedAccounts() throws Exception {
final String TEST_NAME = "test810SeachLockedAccounts";
TestUtil.displayTestTile(this, TEST_NAME);
// GIVEN
Task task = taskManager.createTaskInstance(this.getClass().getName() + "." + TEST_NAME);
OperationResult result = task.getResult();
ObjectQuery query = ObjectQueryUtil.createResourceAndObjectClassFilterPrefix(getResourceOid(), getAccountObjectClass(), prismContext)
.and().item(ShadowType.F_ACTIVATION, ActivationType.F_LOCKOUT_STATUS).eq(LockoutStatusType.LOCKED)
.build();
SearchResultList<PrismObject<ShadowType>> searchResultList = doSearch(TEST_NAME, query, 0, task, result);
assertConnectorOperationIncrement(1);
assertConnectorSimulatedPagingSearchIncrement(0);
}
@Test
public void test820JackLockoutAndUnlock() throws Exception {
final String TEST_NAME = "test820JackLockoutAndUnlock";
TestUtil.displayTestTile(this, TEST_NAME);
// GIVEN
Task task = taskManager.createTaskInstance(this.getClass().getName() + "." + TEST_NAME);
OperationResult result = task.getResult();
makeBadLoginAttempt(ACCOUNT_JACK_UID);
makeBadLoginAttempt(ACCOUNT_JACK_UID);
makeBadLoginAttempt(ACCOUNT_JACK_UID);
makeBadLoginAttempt(ACCOUNT_JACK_UID);
jackLockoutTimestamp = System.currentTimeMillis();
ObjectQuery query = createUidQuery(ACCOUNT_JACK_UID);
// precondition
SearchResultList<PrismObject<ShadowType>> shadows = modelService.searchObjects(ShadowType.class, query, null, task, result);
result.computeStatus();
TestUtil.assertSuccess(result);
assertEquals("Unexpected search result: "+shadows, 1, shadows.size());
PrismObject<ShadowType> shadowLocked = shadows.get(0);
display("Locked shadow", shadowLocked);
assertAccountShadow(shadowLocked, toAccountDn(ACCOUNT_JACK_UID));
assertShadowLockout(shadowLocked, LockoutStatusType.LOCKED);
rememberConnectorOperationCount();
rememberConnectorSimulatedPagingSearchCount();
// WHEN
TestUtil.displayWhen(TEST_NAME);
modifyObjectReplaceProperty(ShadowType.class, shadowLocked.getOid(),
new ItemPath(ShadowType.F_ACTIVATION, ActivationType.F_LOCKOUT_STATUS), task, result,
LockoutStatusType.NORMAL);
// THEN
TestUtil.displayThen(TEST_NAME);
result.computeStatus();
TestUtil.assertSuccess(result);
assertConnectorOperationIncrement(1);
assertConnectorSimulatedPagingSearchIncrement(0);
PrismObject<ShadowType> shadowAfter = getObject(ShadowType.class, shadowLocked.getOid());
display("Shadow after", shadowAfter);
assertAccountShadow(shadowAfter, toAccountDn(ACCOUNT_JACK_UID));
assertShadowLockout(shadowAfter, LockoutStatusType.NORMAL);
assertLdapPassword(ACCOUNT_JACK_UID, ACCOUNT_JACK_PASSWORD);
SearchResultMetadata metadata = shadows.getMetadata();
if (metadata != null) {
assertFalse(metadata.isPartialResults());
}
}
// Let's do this at the very end.
// We need to wait after rename, otherwise the delete fail with:
// NDS error: previous move in progress (-637)
// So ... let's give some time to eDirectory to sort the things out
@Test
public void test890UnAssignBarbossaPirates() throws Exception {
final String TEST_NAME = "test890UnAssignBarbossaPirates";
TestUtil.displayTestTile(this, TEST_NAME);
// TODO: do this on another account. There is a bad interference with rename.
// GIVEN
Task task = taskManager.createTaskInstance(this.getClass().getName() + "." + TEST_NAME);
OperationResult result = task.getResult();
// WHEN
TestUtil.displayWhen(TEST_NAME);
unassignRole(USER_BARBOSSA_OID, ROLE_PIRATES_OID, task, result);
// THEN
TestUtil.displayThen(TEST_NAME);
result.computeStatus();
TestUtil.assertSuccess(result);
Entry entry = assertLdapAccount(USER_CPTBARBOSSA_USERNAME, USER_BARBOSSA_FULL_NAME);
display("Entry", entry);
assertAttribute(entry, "title", "Captain");
assertEDirNoGroupMember(entry, GROUP_PIRATES_NAME);
PrismObject<UserType> user = getUser(USER_BARBOSSA_OID);
String shadowOid = getSingleLinkOid(user);
assertEquals("Shadows have moved", accountBarbossaOid, shadowOid);
PrismObject<ShadowType> shadow = getObject(ShadowType.class, shadowOid);
IntegrationTestTools.assertNoAssociation(shadow, getAssociationGroupQName(), groupPiratesOid);
}
@Test
public void test899UnAssignAccountBarbossa() throws Exception {
final String TEST_NAME = "test899UnAssignAccountBarbossa";
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);
}
// TODO: lock out jack again, explicitly reset the lock, see that he can login
@Override
protected void assertAccountShadow(PrismObject<ShadowType> shadow, String dn) throws SchemaException {
super.assertAccountShadow(shadow, dn);
ResourceAttribute<String> primaryIdAttr = ShadowUtil.getAttribute(shadow, getPrimaryIdentifierAttributeQName());
assertNotNull("No primary identifier ("+getPrimaryIdentifierAttributeQName()+" in "+shadow, primaryIdAttr);
String primaryId = primaryIdAttr.getRealValue();
assertTrue("Unexpected chars in primary ID: '"+primaryId+"'", primaryId.matches("[a-z0-9]+"));
}
protected void assertPasswordAllowChange(PrismObject<ShadowType> shadow, Boolean expected) throws SchemaException {
Boolean passwordAllowChange = ShadowUtil.getAttributeValue(shadow, new QName(MidPointConstants.NS_RI, "passwordAllowChange"));
assertEquals("Wrong passwordAllowChange in "+shadow, expected, passwordAllowChange);
}
private void makeBadLoginAttempt(String uid) throws LdapException, IOException {
try {
LdapNetworkConnection conn = ldapConnect(toAccountDn(uid), "thisIsAwRoNgPASSW0RD");
if (conn.isAuthenticated()) {
AssertJUnit.fail("Bad authentication went good for "+uid);
}
} catch (SecurityException e) {
// this is expected
}
}
private void assertEDirGroupMember(String accountUid, String groupName) throws LdapException, IOException, CursorException, SchemaException {
Entry accountEntry = getLdapAccountByUid(accountUid);
assertEDirGroupMember(accountEntry, groupName);
}
private Entry assertEDirGroupMember(Entry accountEntry, String groupName) throws LdapException, IOException, CursorException, SchemaException {
Entry groupEntry = getLdapGroupByName(groupName);
assertAttributeContains(groupEntry, getLdapGroupMemberAttribute(), accountEntry.getDn().toString());
assertAttributeContains(groupEntry, ATTRIBUTE_EQUIVALENT_TO_ME_NAME, accountEntry.getDn().toString());
assertAttributeContains(accountEntry, ATTRIBUTE_GROUP_MEMBERSHIP_NAME, groupEntry.getDn().toString());
assertAttributeContains(accountEntry, ATTRIBUTE_SECURITY_EQUALS_NAME, groupEntry.getDn().toString());
return groupEntry;
}
private void assertEDirNoGroupMember(Entry accountEntry, String groupName) throws LdapException, IOException, CursorException, SchemaException {
Entry groupEntry = getLdapGroupByName(groupName);
assertAttributeNotContains(groupEntry, getLdapGroupMemberAttribute(), accountEntry.getDn().toString());
assertAttributeNotContains(groupEntry, ATTRIBUTE_EQUIVALENT_TO_ME_NAME, accountEntry.getDn().toString());
assertAttributeNotContains(accountEntry, ATTRIBUTE_GROUP_MEMBERSHIP_NAME, groupEntry.getDn().toString());
assertAttributeNotContains(accountEntry, ATTRIBUTE_SECURITY_EQUALS_NAME, groupEntry.getDn().toString());
}
protected String toOrgGroupDn(String cn) {
return "cn="+cn+","+getOrgGroupsLdapSuffix();
}
}