Java tutorial
/* * Copyright (c) 2010-2015 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.model.test; import com.evolveum.icf.dummy.resource.DummyAccount; import com.evolveum.icf.dummy.resource.DummyGroup; import com.evolveum.icf.dummy.resource.DummyResource; import com.evolveum.midpoint.common.Clock; import com.evolveum.midpoint.common.InternalsConfig; import com.evolveum.midpoint.common.refinery.RefinedAttributeDefinition; import com.evolveum.midpoint.common.refinery.RefinedObjectClassDefinition; import com.evolveum.midpoint.common.refinery.RefinedResourceSchema; import com.evolveum.midpoint.model.api.ModelDiagnosticService; import com.evolveum.midpoint.model.api.ModelExecuteOptions; import com.evolveum.midpoint.model.api.ModelInteractionService; import com.evolveum.midpoint.model.api.ModelService; import com.evolveum.midpoint.model.api.PolicyViolationException; import com.evolveum.midpoint.model.api.RoleSelectionSpecification; import com.evolveum.midpoint.model.api.context.ModelContext; import com.evolveum.midpoint.model.api.context.ModelProjectionContext; import com.evolveum.midpoint.model.api.expr.MidpointFunctions; import com.evolveum.midpoint.model.api.hooks.HookRegistry; import com.evolveum.midpoint.notifications.api.NotificationManager; import com.evolveum.midpoint.notifications.api.transports.Message; import com.evolveum.midpoint.prism.Containerable; import com.evolveum.midpoint.prism.PrismContainer; import com.evolveum.midpoint.prism.PrismContainerDefinition; import com.evolveum.midpoint.prism.PrismContainerValue; import com.evolveum.midpoint.prism.PrismContext; import com.evolveum.midpoint.prism.PrismObject; import com.evolveum.midpoint.prism.PrismObjectDefinition; import com.evolveum.midpoint.prism.PrismProperty; import com.evolveum.midpoint.prism.PrismPropertyDefinition; import com.evolveum.midpoint.prism.PrismReference; import com.evolveum.midpoint.prism.PrismReferenceValue; import com.evolveum.midpoint.prism.crypto.EncryptionException; import com.evolveum.midpoint.prism.delta.ContainerDelta; import com.evolveum.midpoint.prism.delta.ItemDelta; import com.evolveum.midpoint.prism.delta.ObjectDelta; import com.evolveum.midpoint.prism.delta.PropertyDelta; import com.evolveum.midpoint.prism.delta.ReferenceDelta; import com.evolveum.midpoint.prism.match.MatchingRule; import com.evolveum.midpoint.prism.path.IdItemPathSegment; import com.evolveum.midpoint.prism.path.ItemPath; import com.evolveum.midpoint.prism.path.NameItemPathSegment; import com.evolveum.midpoint.prism.query.AndFilter; import com.evolveum.midpoint.prism.query.EqualFilter; import com.evolveum.midpoint.prism.query.ObjectFilter; import com.evolveum.midpoint.prism.query.ObjectQuery; import com.evolveum.midpoint.prism.query.OrgFilter; import com.evolveum.midpoint.prism.query.RefFilter; import com.evolveum.midpoint.prism.util.PrismAsserts; import com.evolveum.midpoint.prism.util.PrismTestUtil; import com.evolveum.midpoint.prism.xml.XmlTypeConverter; import com.evolveum.midpoint.provisioning.api.ProvisioningService; import com.evolveum.midpoint.repo.api.RepositoryService; import com.evolveum.midpoint.schema.GetOperationOptions; import com.evolveum.midpoint.schema.ResultHandler; import com.evolveum.midpoint.schema.SelectorOptions; import com.evolveum.midpoint.schema.constants.ObjectTypes; import com.evolveum.midpoint.schema.constants.SchemaConstants; import com.evolveum.midpoint.schema.processor.ResourceAttribute; import com.evolveum.midpoint.schema.processor.ResourceAttributeContainer; 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.SchemaTestConstants; import com.evolveum.midpoint.schema.util.ShadowUtil; import com.evolveum.midpoint.security.api.Authorization; import com.evolveum.midpoint.security.api.AuthorizationConstants; import com.evolveum.midpoint.security.api.MidPointPrincipal; import com.evolveum.midpoint.security.api.SecurityEnforcer; import com.evolveum.midpoint.security.api.UserProfileService; import com.evolveum.midpoint.task.api.Task; import com.evolveum.midpoint.test.AbstractIntegrationTest; import com.evolveum.midpoint.test.Checker; import com.evolveum.midpoint.test.DummyAuditService; import com.evolveum.midpoint.test.DummyResourceContoller; import com.evolveum.midpoint.test.IntegrationTestTools; import com.evolveum.midpoint.test.util.MidPointAsserts; import com.evolveum.midpoint.test.util.TestUtil; import com.evolveum.midpoint.util.DebugUtil; import com.evolveum.midpoint.util.DisplayableValue; import com.evolveum.midpoint.util.Holder; import com.evolveum.midpoint.util.MiscUtil; import com.evolveum.midpoint.util.QNameUtil; import com.evolveum.midpoint.util.exception.CommunicationException; import com.evolveum.midpoint.util.exception.ConfigurationException; import com.evolveum.midpoint.util.exception.ExpressionEvaluationException; 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.exception.SystemException; import com.evolveum.midpoint.util.logging.Trace; import com.evolveum.midpoint.util.logging.TraceManager; 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.AdminGuiConfigurationType; import com.evolveum.midpoint.xml.ns._public.common.common_3.AssignmentType; import com.evolveum.midpoint.xml.ns._public.common.common_3.AuthorizationPhaseType; import com.evolveum.midpoint.xml.ns._public.common.common_3.AuthorizationType; import com.evolveum.midpoint.xml.ns._public.common.common_3.ConstructionType; import com.evolveum.midpoint.xml.ns._public.common.common_3.CredentialsType; import com.evolveum.midpoint.xml.ns._public.common.common_3.MetadataType; import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectPolicyConfigurationType; import com.evolveum.midpoint.xml.ns._public.common.common_3.FocusType; import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectReferenceType; import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectSynchronizationType; import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectType; 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.ResourceType; import com.evolveum.midpoint.xml.ns._public.common.common_3.RoleType; import com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowKindType; import com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowType; import com.evolveum.midpoint.xml.ns._public.common.common_3.SynchronizationSituationType; import com.evolveum.midpoint.xml.ns._public.common.common_3.SynchronizationType; import com.evolveum.midpoint.xml.ns._public.common.common_3.SystemConfigurationType; import com.evolveum.midpoint.xml.ns._public.common.common_3.SystemObjectsType; import com.evolveum.midpoint.xml.ns._public.common.common_3.TaskExecutionStatusType; import com.evolveum.midpoint.xml.ns._public.common.common_3.TaskType; import com.evolveum.midpoint.xml.ns._public.common.common_3.TriggerType; import com.evolveum.midpoint.xml.ns._public.common.common_3.UserType; import com.evolveum.midpoint.xml.ns._public.model.model_3.ModelPortType; import com.evolveum.prism.xml.ns._public.types_3.ProtectedStringType; import org.apache.commons.lang.StringUtils; import org.opends.server.types.DirectoryException; import org.opends.server.types.Entry; import org.opends.server.types.SearchResultEntry; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.access.ConfigAttribute; import org.springframework.security.access.SecurityConfig; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContext; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.core.context.SecurityContextImpl; import org.springframework.security.web.FilterInvocation; import org.testng.AssertJUnit; import org.testng.annotations.AfterClass; import javax.xml.datatype.XMLGregorianCalendar; import javax.xml.namespace.QName; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.net.ConnectException; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Date; import java.util.List; import java.util.Set; import static com.evolveum.midpoint.test.IntegrationTestTools.display; import static org.testng.AssertJUnit.assertEquals; import static org.testng.AssertJUnit.assertFalse; import static org.testng.AssertJUnit.assertNotNull; import static org.testng.AssertJUnit.assertNull; import static org.testng.AssertJUnit.assertTrue; import static org.testng.AssertJUnit.fail; /** * Abstract framework for an integration test that is placed on top of a model API. * This provides complete environment that the test should need, e.g model service instance, repository, provisionig, * dummy auditing, etc. It also implements lots of useful methods to make writing the tests easier. * * @author Radovan Semancik * */ public abstract class AbstractModelIntegrationTest extends AbstractIntegrationTest { protected static final int DEFAULT_TASK_WAIT_TIMEOUT = 25000; protected static final long DEFAULT_TASK_SLEEP_TIME = 200; protected static final String CONNECTOR_DUMMY_TYPE = "com.evolveum.icf.dummy.connector.DummyConnector"; protected static final String CONNECTOR_DUMMY_VERSION = "2.0"; protected static final String CONNECTOR_DUMMY_NAMESPACE = "http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/bundle/com.evolveum.icf.dummy/com.evolveum.icf.dummy.connector.DummyConnector"; protected static final String CONNECTOR_LDAP_TYPE = "com.evolveum.polygon.connector.ldap.LdapConnector"; protected static final String CONNECTOR_LDAP_NAMESPACE = "http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/bundle/com.evolveum.polygon.connector-ldap/com.evolveum.polygon.connector.ldap.LdapConnector"; protected static final String CONNECTOR_AD_TYPE = "Org.IdentityConnectors.ActiveDirectory.ActiveDirectoryConnector"; protected static final String CONNECTOR_AD_NAMESPACE = "http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/bundle/ActiveDirectory.Connector/Org.IdentityConnectors.ActiveDirectory.ActiveDirectoryConnector"; protected static final ItemPath ACTIVATION_ADMINISTRATIVE_STATUS_PATH = new ItemPath(UserType.F_ACTIVATION, ActivationType.F_ADMINISTRATIVE_STATUS); protected static final ItemPath ACTIVATION_VALID_FROM_PATH = new ItemPath(UserType.F_ACTIVATION, ActivationType.F_VALID_FROM); protected static final ItemPath ACTIVATION_VALID_TO_PATH = new ItemPath(UserType.F_ACTIVATION, ActivationType.F_VALID_TO); @Autowired(required = true) protected ModelService modelService; @Autowired(required = true) protected ModelInteractionService modelInteractionService; @Autowired(required = true) protected ModelDiagnosticService modelDiagnosticService; @Autowired(required = true) protected ModelPortType modelWeb; @Autowired(required = true) protected RepositoryService repositoryService; @Autowired(required = true) protected ProvisioningService provisioningService; @Autowired(required = true) protected HookRegistry hookRegistry; @Autowired(required = true) protected Clock clock; @Autowired(required = true) protected PrismContext prismContext; @Autowired(required = true) protected DummyTransport dummyTransport; @Autowired(required = false) protected NotificationManager notificationManager; @Autowired(required = false) protected UserProfileService userProfileService; @Autowired(required = true) private SecurityEnforcer securityEnforcer; @Autowired(required = true) protected MidpointFunctions libraryMidpointFunctions; protected DummyAuditService dummyAuditService; protected boolean verbose = false; private static final Trace LOGGER = TraceManager.getTrace(AbstractModelIntegrationTest.class); public AbstractModelIntegrationTest() { super(); } @Override public void initSystem(Task initTask, OperationResult initResult) throws Exception { LOGGER.trace("initSystem"); startResources(); dummyAuditService = DummyAuditService.getInstance(); // Make sure the checks are turned on InternalsConfig.turnOnAllChecks(); // By default, notifications are turned off because of performance implications. Individual tests turn them on for themselves. if (notificationManager != null) { notificationManager.setDisabled(true); } } protected void startResources() throws Exception { // Nothing to do by default } @AfterClass protected void cleanUpSecurity() { SecurityContext securityContext = SecurityContextHolder.getContext(); securityContext.setAuthentication(null); } protected void importObjectFromFile(String filename) throws FileNotFoundException { importObjectFromFile(new File(filename)); } protected void importObjectFromFile(File file) throws FileNotFoundException { OperationResult result = new OperationResult( AbstractModelIntegrationTest.class.getName() + ".importObjectFromFile"); importObjectFromFile(file, result); result.computeStatus(); TestUtil.assertSuccess(result); } protected void importObjectFromFile(String filename, OperationResult result) throws FileNotFoundException { importObjectFromFile(new File(filename), result); } protected void importObjectFromFile(File file, OperationResult result) throws FileNotFoundException { OperationResult subResult = result .createSubresult(AbstractModelIntegrationTest.class + ".importObjectFromFile"); subResult.addParam("filename", file); LOGGER.trace("importObjectFromFile: {}", file); Task task = taskManager.createTaskInstance(); importObjectFromFile(file, task, result); subResult.computeStatus(); if (subResult.isError()) { LOGGER.error("Import of file " + file + " failed:\n{}", subResult.debugDump()); Throwable cause = findCause(subResult); throw new SystemException("Import of file " + file + " failed: " + subResult.getMessage(), cause); } } protected void importObjectFromFile(File file, Task task, OperationResult result) throws FileNotFoundException { FileInputStream stream = new FileInputStream(file); modelService.importObjectsFromStream(stream, MiscSchemaUtil.getDefaultImportOptions(), task, result); } protected Throwable findCause(OperationResult result) { if (result.getCause() != null) { return result.getCause(); } for (OperationResult sub : result.getSubresults()) { Throwable cause = findCause(sub); if (cause != null) { return cause; } } return null; } protected <T extends ObjectType> PrismObject<T> importAndGetObjectFromFile(Class<T> type, String filename, String oid, Task task, OperationResult result) throws FileNotFoundException, ObjectNotFoundException, SchemaException, SecurityViolationException, CommunicationException, ConfigurationException { return importAndGetObjectFromFile(type, new File(filename), oid, task, result); } protected <T extends ObjectType> PrismObject<T> importAndGetObjectFromFile(Class<T> type, File file, String oid, Task task, OperationResult result) throws FileNotFoundException, ObjectNotFoundException, SchemaException, SecurityViolationException, CommunicationException, ConfigurationException { importObjectFromFile(file, result); OperationResult importResult = result.getLastSubresult(); TestUtil.assertSuccess("Import of " + file + " has failed", importResult); return modelService.getObject(type, oid, null, task, result); } /** * This is not the real thing. It is just for the tests. */ protected void applyResourceSchema(ShadowType accountType, ResourceType resourceType) throws SchemaException { IntegrationTestTools.applyResourceSchema(accountType, resourceType, prismContext); } protected void assertUsers(int expectedNumberOfUsers) throws SchemaException, ObjectNotFoundException, SecurityViolationException, CommunicationException, ConfigurationException { Task task = taskManager.createTaskInstance(AbstractModelIntegrationTest.class.getName() + ".assertUsers"); OperationResult result = task.getResult(); List<PrismObject<UserType>> users = modelService.searchObjects(UserType.class, null, null, task, result); if (verbose) display("Users", users); assertEquals("Unexpected number of users", expectedNumberOfUsers, users.size()); } protected void assertUserProperty(String userOid, QName propertyName, Object... expectedPropValues) throws ObjectNotFoundException, SchemaException { OperationResult result = new OperationResult("getObject"); PrismObject<UserType> user = repositoryService.getObject(UserType.class, userOid, null, result); assertUserProperty(user, propertyName, expectedPropValues); } protected void assertUserProperty(PrismObject<UserType> user, QName propertyName, Object... expectedPropValues) { PrismProperty<Object> property = user.findProperty(propertyName); assert property != null : "No property " + propertyName + " in " + user; PrismAsserts.assertPropertyValue(property, expectedPropValues); } protected void assertLinked(String userOid, String accountOid) throws ObjectNotFoundException, SchemaException { assertLinked(UserType.class, userOid, accountOid); } protected <F extends FocusType> void assertLinked(Class<F> type, String focusOid, String projectionOid) throws ObjectNotFoundException, SchemaException { OperationResult result = new OperationResult("assertLinked"); PrismObject<F> user = repositoryService.getObject(type, focusOid, null, result); assertLinked(user, projectionOid); } protected <F extends FocusType> void assertLinked(PrismObject<F> focus, PrismObject<ShadowType> projection) throws ObjectNotFoundException, SchemaException { assertLinked(focus, projection.getOid()); } protected <F extends FocusType> void assertLinked(PrismObject<F> focus, String projectionOid) throws ObjectNotFoundException, SchemaException { PrismReference linkRef = focus.findReference(FocusType.F_LINK_REF); assertNotNull("No linkRefs in " + focus, linkRef); boolean found = false; for (PrismReferenceValue val : linkRef.getValues()) { if (val.getOid().equals(projectionOid)) { found = true; } } assertTrue("Focus " + focus + " is not linked to shadow " + projectionOid, found); } protected void assertNotLinked(String userOid, String accountOid) throws ObjectNotFoundException, SchemaException { OperationResult result = new OperationResult("assertLinked"); PrismObject<UserType> user = repositoryService.getObject(UserType.class, userOid, null, result); assertNotLinked(user, accountOid); } protected void assertNotLinked(PrismObject<UserType> user, PrismObject<ShadowType> account) throws ObjectNotFoundException, SchemaException { assertNotLinked(user, account.getOid()); } protected void assertNotLinked(PrismObject<UserType> user, String accountOid) throws ObjectNotFoundException, SchemaException { PrismReference linkRef = user.findReference(UserType.F_LINK_REF); if (linkRef == null) { return; } boolean found = false; for (PrismReferenceValue val : linkRef.getValues()) { if (val.getOid().equals(accountOid)) { found = true; } } assertFalse("User " + user + " IS linked to account " + accountOid + " but not expecting it", found); } protected void assertNoLinkedAccount(PrismObject<UserType> user) { PrismReference accountRef = user.findReference(UserType.F_LINK_REF); if (accountRef == null) { return; } assert accountRef.isEmpty() : "Expected that " + user + " has no linked account but it has " + accountRef.size() + " linked accounts: " + accountRef.getValues(); } protected void assertAccount(PrismObject<UserType> user, String resourceOid) throws ObjectNotFoundException, SchemaException, SecurityViolationException, CommunicationException, ConfigurationException { String accountOid = getLinkRefOid(user, resourceOid); assertNotNull("User " + user + " has no account on resource " + resourceOid, accountOid); } protected void assertAccounts(String userOid, int numAccounts) throws ObjectNotFoundException, SchemaException { OperationResult result = new OperationResult("assertAccounts"); PrismObject<UserType> user = repositoryService.getObject(UserType.class, userOid, null, result); assertLinks(user, numAccounts); } protected <F extends FocusType> void assertLinks(PrismObject<F> focus, int expectedNumLinks) throws ObjectNotFoundException, SchemaException { PrismReference linkRef = focus.findReference(FocusType.F_LINK_REF); if (linkRef == null) { assert expectedNumLinks == 0 : "Expected " + expectedNumLinks + " but " + focus + " has no linkRef"; return; } assertEquals("Wrong number of links in " + focus, expectedNumLinks, linkRef.size()); } protected void assertAdministrativeStatusEnabled(PrismObject<? extends ObjectType> user) { assertAdministrativeStatus(user, ActivationStatusType.ENABLED); } protected void assertAdministrativeStatusDisabled(PrismObject<? extends ObjectType> user) { assertAdministrativeStatus(user, ActivationStatusType.DISABLED); } protected void assertAdministrativeStatus(PrismObject<? extends ObjectType> object, ActivationStatusType expected) { PrismProperty<ActivationStatusType> statusProperty = object .findProperty(ACTIVATION_ADMINISTRATIVE_STATUS_PATH); assert statusProperty != null : "No status property in " + object; ActivationStatusType status = statusProperty.getRealValue(); assert status != null : "No status property is null in " + object; assert status == expected : "status property is " + status + ", expected " + expected + " in " + object; } protected ObjectDelta<UserType> createModifyUserReplaceDelta(String userOid, QName propertyName, Object... newRealValue) { return createModifyUserReplaceDelta(userOid, new ItemPath(propertyName), newRealValue); } protected ObjectDelta<UserType> createModifyUserReplaceDelta(String userOid, ItemPath propertyName, Object... newRealValue) { return ObjectDelta.createModificationReplaceProperty(UserType.class, userOid, propertyName, prismContext, newRealValue); } protected ObjectDelta<UserType> createModifyUserAddDelta(String userOid, ItemPath propertyName, Object... newRealValue) { return ObjectDelta.createModificationAddProperty(UserType.class, userOid, propertyName, prismContext, newRealValue); } protected ObjectDelta<UserType> createModifyUserDeleteDelta(String userOid, ItemPath propertyName, Object... newRealValue) { return ObjectDelta.createModificationDeleteProperty(UserType.class, userOid, propertyName, prismContext, newRealValue); } protected ObjectDelta<UserType> createModifyUserAddAccount(String userOid, PrismObject<ResourceType> resource) throws SchemaException { PrismObject<ShadowType> account = getAccountShadowDefinition().instantiate(); ObjectReferenceType resourceRef = new ObjectReferenceType(); resourceRef.setOid(resource.getOid()); account.asObjectable().setResourceRef(resourceRef); RefinedResourceSchema refinedSchema = RefinedResourceSchema.getRefinedSchema(resource); account.asObjectable().setObjectClass(refinedSchema.getDefaultRefinedDefinition(ShadowKindType.ACCOUNT) .getObjectClassDefinition().getTypeName()); ObjectDelta<UserType> userDelta = ObjectDelta.createEmptyModifyDelta(UserType.class, userOid, prismContext); PrismReferenceValue accountRefVal = new PrismReferenceValue(); accountRefVal.setObject(account); ReferenceDelta accountDelta = ReferenceDelta.createModificationAdd(UserType.F_LINK_REF, getUserDefinition(), accountRefVal); userDelta.addModification(accountDelta); return userDelta; } protected ObjectDelta<UserType> createModifyUserDeleteAccount(String userOid, PrismObject<ResourceType> resource) throws SchemaException, ObjectNotFoundException, SecurityViolationException, CommunicationException, ConfigurationException { String accountOid = getLinkRefOid(userOid, resource.getOid()); PrismObject<ShadowType> account = getShadowModel(accountOid); ObjectDelta<UserType> userDelta = ObjectDelta.createEmptyModifyDelta(UserType.class, userOid, prismContext); PrismReferenceValue accountRefVal = new PrismReferenceValue(); accountRefVal.setObject(account); ReferenceDelta accountDelta = ReferenceDelta.createModificationDelete(UserType.F_LINK_REF, getUserDefinition(), accountRefVal); userDelta.addModification(accountDelta); return userDelta; } protected ObjectDelta<UserType> createModifyUserUnlinkAccount(String userOid, PrismObject<ResourceType> resource) throws SchemaException, ObjectNotFoundException, SecurityViolationException, CommunicationException, ConfigurationException { String accountOid = getLinkRefOid(userOid, resource.getOid()); ObjectDelta<UserType> userDelta = ObjectDelta.createEmptyModifyDelta(UserType.class, userOid, prismContext); PrismReferenceValue accountRefVal = new PrismReferenceValue(); accountRefVal.setOid(accountOid); ReferenceDelta accountDelta = ReferenceDelta.createModificationDelete(UserType.F_LINK_REF, getUserDefinition(), accountRefVal); userDelta.addModification(accountDelta); return userDelta; } protected ObjectDelta<ShadowType> createModifyAccountShadowEmptyDelta(String accountOid) { return ObjectDelta.createEmptyModifyDelta(ShadowType.class, accountOid, prismContext); } protected ObjectDelta<ShadowType> createModifyAccountShadowReplaceAttributeDelta(String accountOid, PrismObject<ResourceType> resource, String attributeName, Object... newRealValue) throws SchemaException, ObjectNotFoundException, CommunicationException, ConfigurationException { return createModifyAccountShadowReplaceAttributeDelta(accountOid, resource, getAttributeQName(resource, attributeName), newRealValue); } protected ObjectDelta<ShadowType> createModifyAccountShadowReplaceAttributeDelta(String accountOid, PrismObject<ResourceType> resource, QName attributeName, Object... newRealValue) throws SchemaException, ObjectNotFoundException, CommunicationException, ConfigurationException { return createModifyAccountShadowReplaceDelta(accountOid, resource, new ItemPath(ShadowType.F_ATTRIBUTES, attributeName), newRealValue); } protected ObjectDelta<ShadowType> createModifyAccountShadowReplaceDelta(String accountOid, PrismObject<ResourceType> resource, ItemPath itemPath, Object... newRealValue) throws SchemaException, ObjectNotFoundException, CommunicationException, ConfigurationException { if (ShadowType.F_ATTRIBUTES.equals(ItemPath.getName(itemPath.first()))) { PropertyDelta<?> attributeDelta = createAttributeReplaceDelta(resource, ((NameItemPathSegment) itemPath.last()).getName(), newRealValue); ObjectDelta<ShadowType> accountDelta = ObjectDelta.createModifyDelta(accountOid, attributeDelta, ShadowType.class, prismContext); return accountDelta; } else { ObjectDelta<ShadowType> accountDelta = ObjectDelta.createModificationReplaceProperty(ShadowType.class, accountOid, itemPath, prismContext, newRealValue); return accountDelta; } } protected <T> PropertyDelta<T> createAttributeReplaceDelta(PrismObject<ResourceType> resource, String attributeLocalName, T... newRealValue) throws SchemaException { return createAttributeReplaceDelta(resource, getAttributeQName(resource, attributeLocalName), newRealValue); } protected <T> PropertyDelta<T> createAttributeReplaceDelta(PrismObject<ResourceType> resource, QName attributeQName, T... newRealValue) throws SchemaException { PrismPropertyDefinition attributeDefinition = getAttributeDefinition(resource, attributeQName); if (attributeDefinition == null) { throw new SchemaException("No definition for attribute " + attributeQName + " in " + resource); } return PropertyDelta.createModificationReplaceProperty( new ItemPath(ShadowType.F_ATTRIBUTES, attributeQName), attributeDefinition, newRealValue); } protected <T> PropertyDelta<T> createAttributeAddDelta(PrismObject<ResourceType> resource, String attributeLocalName, T... newRealValue) throws SchemaException { return createAttributeAddDelta(resource, getAttributeQName(resource, attributeLocalName), newRealValue); } protected <T> PropertyDelta<T> createAttributeAddDelta(PrismObject<ResourceType> resource, QName attributeQName, T... newRealValue) throws SchemaException { PrismPropertyDefinition attributeDefinition = getAttributeDefinition(resource, attributeQName); if (attributeDefinition == null) { throw new SchemaException("No definition for attribute " + attributeQName + " in " + resource); } return PropertyDelta.createModificationAddProperty(new ItemPath(ShadowType.F_ATTRIBUTES, attributeQName), attributeDefinition, newRealValue); } protected <T> PropertyDelta<T> createAttributeDeleteDelta(PrismObject<ResourceType> resource, String attributeLocalName, T... newRealValue) throws SchemaException { return createAttributeDeleteDelta(resource, getAttributeQName(resource, attributeLocalName), newRealValue); } protected <T> PropertyDelta<T> createAttributeDeleteDelta(PrismObject<ResourceType> resource, QName attributeQName, T... newRealValue) throws SchemaException { PrismPropertyDefinition attributeDefinition = getAttributeDefinition(resource, attributeQName); if (attributeDefinition == null) { throw new SchemaException("No definition for attribute " + attributeQName + " in " + resource); } return PropertyDelta.createModificationDeleteProperty(new ItemPath(ShadowType.F_ATTRIBUTES, attributeQName), attributeDefinition, newRealValue); } protected ResourceAttributeDefinition getAttributeDefinition(PrismObject<ResourceType> resource, QName attributeName) throws SchemaException { RefinedResourceSchema refinedSchema = RefinedResourceSchema.getRefinedSchema(resource); if (refinedSchema == null) { throw new SchemaException("No refined schema for " + resource); } RefinedObjectClassDefinition accountDefinition = refinedSchema .getDefaultRefinedDefinition(ShadowKindType.ACCOUNT); return accountDefinition.findAttributeDefinition(attributeName); } protected ObjectDelta<ShadowType> createModifyAccountShadowAddDelta(String accountOid, ItemPath propertyName, Object... newRealValue) { return ObjectDelta.createModificationAddProperty(ShadowType.class, accountOid, propertyName, prismContext, newRealValue); } protected void modifyUserReplace(String userOid, QName propertyName, Task task, OperationResult result, Object... newRealValue) throws ObjectNotFoundException, SchemaException, ExpressionEvaluationException, CommunicationException, ConfigurationException, ObjectAlreadyExistsException, PolicyViolationException, SecurityViolationException { modifyUserReplace(userOid, new ItemPath(propertyName), task, result, newRealValue); } protected void modifyUserReplace(String userOid, ItemPath propertyPath, Task task, OperationResult result, Object... newRealValue) throws ObjectNotFoundException, SchemaException, ExpressionEvaluationException, CommunicationException, ConfigurationException, ObjectAlreadyExistsException, PolicyViolationException, SecurityViolationException { ObjectDelta<UserType> objectDelta = createModifyUserReplaceDelta(userOid, propertyPath, newRealValue); Collection<ObjectDelta<? extends ObjectType>> deltas = MiscSchemaUtil.createCollection(objectDelta); modelService.executeChanges(deltas, null, task, result); } protected <O extends ObjectType> void modifyObjectReplaceProperty(Class<O> type, String oid, QName propertyName, Task task, OperationResult result, Object... newRealValue) throws ObjectNotFoundException, SchemaException, ExpressionEvaluationException, CommunicationException, ConfigurationException, ObjectAlreadyExistsException, PolicyViolationException, SecurityViolationException { modifyObjectReplaceProperty(type, oid, new ItemPath(propertyName), task, result, newRealValue); } protected <O extends ObjectType> void modifyObjectReplaceProperty(Class<O> type, String oid, ItemPath propertyPath, Task task, OperationResult result, Object... newRealValue) throws ObjectNotFoundException, SchemaException, ExpressionEvaluationException, CommunicationException, ConfigurationException, ObjectAlreadyExistsException, PolicyViolationException, SecurityViolationException { ObjectDelta<O> objectDelta = ObjectDelta.createModificationReplaceProperty(type, oid, propertyPath, prismContext, newRealValue); Collection<ObjectDelta<? extends ObjectType>> deltas = MiscSchemaUtil.createCollection(objectDelta); modelService.executeChanges(deltas, null, task, result); } protected <O extends ObjectType> void modifyObjectDeleteProperty(Class<O> type, String oid, ItemPath propertyPath, Task task, OperationResult result, Object... newRealValue) throws ObjectNotFoundException, SchemaException, ExpressionEvaluationException, CommunicationException, ConfigurationException, ObjectAlreadyExistsException, PolicyViolationException, SecurityViolationException { ObjectDelta<O> objectDelta = ObjectDelta.createModificationDeleteProperty(type, oid, propertyPath, prismContext, newRealValue); Collection<ObjectDelta<? extends ObjectType>> deltas = MiscSchemaUtil.createCollection(objectDelta); modelService.executeChanges(deltas, null, task, result); } protected <O extends ObjectType> void modifyObjectAddProperty(Class<O> type, String oid, ItemPath propertyPath, Task task, OperationResult result, Object... newRealValue) throws ObjectNotFoundException, SchemaException, ExpressionEvaluationException, CommunicationException, ConfigurationException, ObjectAlreadyExistsException, PolicyViolationException, SecurityViolationException { ObjectDelta<O> objectDelta = ObjectDelta.createModificationAddProperty(type, oid, propertyPath, prismContext, newRealValue); Collection<ObjectDelta<? extends ObjectType>> deltas = MiscSchemaUtil.createCollection(objectDelta); modelService.executeChanges(deltas, null, task, result); } protected <O extends ObjectType, C extends Containerable> void modifyObjectReplaceContainer(Class<O> type, String oid, ItemPath propertyPath, Task task, OperationResult result, C... newRealValue) throws ObjectNotFoundException, SchemaException, ExpressionEvaluationException, CommunicationException, ConfigurationException, ObjectAlreadyExistsException, PolicyViolationException, SecurityViolationException { ObjectDelta<O> objectDelta = ObjectDelta.createModificationReplaceContainer(type, oid, propertyPath, prismContext, newRealValue); Collection<ObjectDelta<? extends ObjectType>> deltas = MiscSchemaUtil.createCollection(objectDelta); modelService.executeChanges(deltas, null, task, result); } protected <O extends ObjectType, C extends Containerable> void modifyObjectAddContainer(Class<O> type, String oid, ItemPath propertyPath, Task task, OperationResult result, C... newRealValue) throws ObjectNotFoundException, SchemaException, ExpressionEvaluationException, CommunicationException, ConfigurationException, ObjectAlreadyExistsException, PolicyViolationException, SecurityViolationException { ObjectDelta<O> objectDelta = ObjectDelta.createModificationAddContainer(type, oid, propertyPath, prismContext, newRealValue); Collection<ObjectDelta<? extends ObjectType>> deltas = MiscSchemaUtil.createCollection(objectDelta); modelService.executeChanges(deltas, null, task, result); } protected <O extends ObjectType, C extends Containerable> void modifyObjectDeleteContainer(Class<O> type, String oid, ItemPath propertyPath, Task task, OperationResult result, C... newRealValue) throws ObjectNotFoundException, SchemaException, ExpressionEvaluationException, CommunicationException, ConfigurationException, ObjectAlreadyExistsException, PolicyViolationException, SecurityViolationException { ObjectDelta<O> objectDelta = ObjectDelta.createModificationDeleteContainer(type, oid, propertyPath, prismContext, newRealValue); Collection<ObjectDelta<? extends ObjectType>> deltas = MiscSchemaUtil.createCollection(objectDelta); modelService.executeChanges(deltas, null, task, result); } protected void modifyUserAdd(String userOid, QName propertyName, Task task, OperationResult result, Object... newRealValue) throws ObjectNotFoundException, SchemaException, ExpressionEvaluationException, CommunicationException, ConfigurationException, ObjectAlreadyExistsException, PolicyViolationException, SecurityViolationException { modifyUserAdd(userOid, new ItemPath(propertyName), task, result, newRealValue); } protected void modifyUserAdd(String userOid, ItemPath propertyPath, Task task, OperationResult result, Object... newRealValue) throws ObjectNotFoundException, SchemaException, ExpressionEvaluationException, CommunicationException, ConfigurationException, ObjectAlreadyExistsException, PolicyViolationException, SecurityViolationException { ObjectDelta<UserType> objectDelta = createModifyUserAddDelta(userOid, propertyPath, newRealValue); Collection<ObjectDelta<? extends ObjectType>> deltas = MiscSchemaUtil.createCollection(objectDelta); modelService.executeChanges(deltas, null, task, result); } protected void modifyUserDelete(String userOid, QName propertyName, Task task, OperationResult result, Object... newRealValue) throws ObjectNotFoundException, SchemaException, ExpressionEvaluationException, CommunicationException, ConfigurationException, ObjectAlreadyExistsException, PolicyViolationException, SecurityViolationException { modifyUserDelete(userOid, new ItemPath(propertyName), task, result, newRealValue); } protected void modifyUserDelete(String userOid, ItemPath propertyPath, Task task, OperationResult result, Object... newRealValue) throws ObjectNotFoundException, SchemaException, ExpressionEvaluationException, CommunicationException, ConfigurationException, ObjectAlreadyExistsException, PolicyViolationException, SecurityViolationException { ObjectDelta<UserType> objectDelta = createModifyUserDeleteDelta(userOid, propertyPath, newRealValue); Collection<ObjectDelta<? extends ObjectType>> deltas = MiscSchemaUtil.createCollection(objectDelta); modelService.executeChanges(deltas, null, task, result); } protected void modifyAccountShadowReplace(String accountOid, ItemPath propertyPath, Task task, OperationResult result, Object... newRealValue) throws ObjectNotFoundException, SchemaException, ExpressionEvaluationException, CommunicationException, ConfigurationException, ObjectAlreadyExistsException, PolicyViolationException, SecurityViolationException { PrismObject<ShadowType> shadow = repositoryService.getObject(ShadowType.class, accountOid, null, result); String resourceOid = shadow.asObjectable().getResourceRef().getOid(); PrismObject<ResourceType> resource = provisioningService.getObject(ResourceType.class, resourceOid, null, task, result); ObjectDelta<ShadowType> objectDelta = createModifyAccountShadowReplaceDelta(accountOid, resource, propertyPath, newRealValue); Collection<ObjectDelta<? extends ObjectType>> deltas = MiscSchemaUtil.createCollection(objectDelta); modelService.executeChanges(deltas, null, task, result); } protected void recomputeUser(String userOid, Task task, OperationResult result) throws SchemaException, PolicyViolationException, ExpressionEvaluationException, ObjectNotFoundException, ObjectAlreadyExistsException, CommunicationException, ConfigurationException, SecurityViolationException { modelService.recompute(UserType.class, userOid, task, result); } protected void assignRole(String userOid, String roleOid) throws ObjectNotFoundException, SchemaException, ExpressionEvaluationException, CommunicationException, ConfigurationException, ObjectAlreadyExistsException, PolicyViolationException, SecurityViolationException { Task task = taskManager.createTaskInstance(AbstractModelIntegrationTest.class + ".assignRole"); OperationResult result = task.getResult(); assignRole(userOid, roleOid, task, result); result.computeStatus(); TestUtil.assertSuccess(result); } protected void assignRole(String userOid, String roleOid, Task task, OperationResult result) throws ObjectNotFoundException, SchemaException, ExpressionEvaluationException, CommunicationException, ConfigurationException, ObjectAlreadyExistsException, PolicyViolationException, SecurityViolationException { assignRole(userOid, roleOid, (ActivationType) null, task, result); } protected void assignRole(String userOid, String roleOid, ActivationType activationType, Task task, OperationResult result) throws ObjectNotFoundException, SchemaException, ExpressionEvaluationException, CommunicationException, ConfigurationException, ObjectAlreadyExistsException, PolicyViolationException, SecurityViolationException { modifyUserAssignment(userOid, roleOid, RoleType.COMPLEX_TYPE, null, task, null, activationType, true, result); } protected void unassignRole(String userOid, String roleOid) throws ObjectNotFoundException, SchemaException, ExpressionEvaluationException, CommunicationException, ConfigurationException, ObjectAlreadyExistsException, PolicyViolationException, SecurityViolationException { Task task = taskManager.createTaskInstance(AbstractModelIntegrationTest.class + ".unassignRole"); OperationResult result = task.getResult(); unassignRole(userOid, roleOid, task, result); result.computeStatus(); TestUtil.assertSuccess(result); } protected void unassignRole(String userOid, String roleOid, Task task, OperationResult result) throws ObjectNotFoundException, SchemaException, ExpressionEvaluationException, CommunicationException, ConfigurationException, ObjectAlreadyExistsException, PolicyViolationException, SecurityViolationException { modifyUserAssignment(userOid, roleOid, RoleType.COMPLEX_TYPE, null, task, null, false, result); } protected void assignRole(String userOid, String roleOid, PrismContainer<?> extension, Task task, OperationResult result) throws ObjectNotFoundException, SchemaException, ExpressionEvaluationException, CommunicationException, ConfigurationException, ObjectAlreadyExistsException, PolicyViolationException, SecurityViolationException { modifyUserAssignment(userOid, roleOid, RoleType.COMPLEX_TYPE, null, task, extension, true, result); } protected void unassignRole(String userOid, String roleOid, PrismContainer<?> extension, Task task, OperationResult result) throws ObjectNotFoundException, SchemaException, ExpressionEvaluationException, CommunicationException, ConfigurationException, ObjectAlreadyExistsException, PolicyViolationException, SecurityViolationException { modifyUserAssignment(userOid, roleOid, RoleType.COMPLEX_TYPE, null, task, extension, false, result); } protected void unassignAllRoles(String userOid) throws ObjectNotFoundException, SchemaException, ExpressionEvaluationException, CommunicationException, ConfigurationException, ObjectAlreadyExistsException, PolicyViolationException, SecurityViolationException { Task task = taskManager.createTaskInstance(AbstractModelIntegrationTest.class + ".unassignAllRoles"); OperationResult result = task.getResult(); PrismObject<UserType> user = modelService.getObject(UserType.class, userOid, null, task, result); Collection<ItemDelta<?, ?>> modifications = new ArrayList<>(); for (AssignmentType assignment : user.asObjectable().getAssignment()) { ObjectReferenceType targetRef = assignment.getTargetRef(); if (targetRef != null) { if (targetRef.getType().equals(RoleType.COMPLEX_TYPE)) { ContainerDelta<AssignmentType> assignmentDelta = ContainerDelta .createDelta(UserType.F_ASSIGNMENT, getUserDefinition()); PrismContainerValue<AssignmentType> cval = new PrismContainerValue<AssignmentType>( prismContext); cval.setId(assignment.getId()); assignmentDelta.addValueToDelete(cval); modifications.add(assignmentDelta); } } } if (modifications.isEmpty()) { return; } ObjectDelta<UserType> userDelta = ObjectDelta.createModifyDelta(userOid, modifications, UserType.class, prismContext); Collection<ObjectDelta<? extends ObjectType>> deltas = MiscSchemaUtil.createCollection(userDelta); modelService.executeChanges(deltas, null, task, result); result.computeStatus(); TestUtil.assertSuccess(result); } protected void assignOrg(String userOid, String orgOid, Task task, OperationResult result) throws ObjectNotFoundException, SchemaException, ExpressionEvaluationException, CommunicationException, ConfigurationException, ObjectAlreadyExistsException, PolicyViolationException, SecurityViolationException { assignOrg(userOid, orgOid, null, task, result); } protected void assignOrg(String userOid, String orgOid, QName relation, Task task, OperationResult result) throws ObjectNotFoundException, SchemaException, ExpressionEvaluationException, CommunicationException, ConfigurationException, ObjectAlreadyExistsException, PolicyViolationException, SecurityViolationException { modifyUserAssignment(userOid, orgOid, OrgType.COMPLEX_TYPE, relation, task, null, true, result); } protected void unassignOrg(String userOid, String orgOid, Task task, OperationResult result) throws ObjectNotFoundException, SchemaException, ExpressionEvaluationException, CommunicationException, ConfigurationException, ObjectAlreadyExistsException, PolicyViolationException, SecurityViolationException { unassignOrg(userOid, orgOid, null, task, result); } protected void unassignOrg(String userOid, String orgOid, QName relation, Task task, OperationResult result) throws ObjectNotFoundException, SchemaException, ExpressionEvaluationException, CommunicationException, ConfigurationException, ObjectAlreadyExistsException, PolicyViolationException, SecurityViolationException { modifyUserAssignment(userOid, orgOid, OrgType.COMPLEX_TYPE, relation, task, null, false, result); } protected void modifyUserAssignment(String userOid, String roleOid, QName refType, QName relation, Task task, PrismContainer<?> extension, boolean add, OperationResult result) throws ObjectNotFoundException, SchemaException, ExpressionEvaluationException, CommunicationException, ConfigurationException, ObjectAlreadyExistsException, PolicyViolationException, SecurityViolationException { modifyUserAssignment(userOid, roleOid, refType, relation, task, extension, null, add, result); } protected void modifyUserAssignment(String userOid, String roleOid, QName refType, QName relation, Task task, PrismContainer<?> extension, ActivationType activationType, boolean add, OperationResult result) throws ObjectNotFoundException, SchemaException, ExpressionEvaluationException, CommunicationException, ConfigurationException, ObjectAlreadyExistsException, PolicyViolationException, SecurityViolationException { ObjectDelta<UserType> userDelta = createAssignmentUserDelta(userOid, roleOid, refType, relation, extension, activationType, add); Collection<ObjectDelta<? extends ObjectType>> deltas = MiscSchemaUtil.createCollection(userDelta); modelService.executeChanges(deltas, null, task, result); } /** * Executes assignment replace delta with empty values. */ protected void unassignAll(String userOid, Task task, OperationResult result) throws ObjectNotFoundException, SchemaException, ExpressionEvaluationException, CommunicationException, ConfigurationException, ObjectAlreadyExistsException, PolicyViolationException, SecurityViolationException { ObjectDelta<UserType> userDelta = ObjectDelta.createModificationReplaceContainer(UserType.class, userOid, UserType.F_ASSIGNMENT, prismContext, new PrismContainerValue[0]); Collection<ObjectDelta<? extends ObjectType>> deltas = MiscSchemaUtil.createCollection(userDelta); modelService.executeChanges(deltas, null, task, result); } protected ContainerDelta<AssignmentType> createAssignmentModification(String roleOid, QName refType, QName relation, PrismContainer<?> extension, ActivationType activationType, boolean add) throws SchemaException { ContainerDelta<AssignmentType> assignmentDelta = ContainerDelta.createDelta(UserType.F_ASSIGNMENT, getUserDefinition()); PrismContainerValue<AssignmentType> cval = new PrismContainerValue<AssignmentType>(prismContext); if (add) { assignmentDelta.addValueToAdd(cval); } else { assignmentDelta.addValueToDelete(cval); } PrismReference targetRef = cval.findOrCreateReference(AssignmentType.F_TARGET_REF); targetRef.getValue().setOid(roleOid); targetRef.getValue().setTargetType(refType); targetRef.getValue().setRelation(relation); if (extension != null) { cval.add(extension.clone()); } cval.asContainerable().setActivation(activationType); return assignmentDelta; } protected ObjectDelta<UserType> createAssignmentUserDelta(String userOid, String roleOid, QName refType, QName relation, PrismContainer<?> extension, boolean add) throws SchemaException { return createAssignmentUserDelta(userOid, roleOid, refType, relation, extension, null, add); } protected ObjectDelta<UserType> createAssignmentUserDelta(String userOid, String roleOid, QName refType, QName relation, PrismContainer<?> extension, ActivationType activationType, boolean add) throws SchemaException { Collection<ItemDelta<?, ?>> modifications = new ArrayList<>(); modifications .add((createAssignmentModification(roleOid, refType, relation, extension, activationType, add))); ObjectDelta<UserType> userDelta = ObjectDelta.createModifyDelta(userOid, modifications, UserType.class, prismContext); return userDelta; } protected ContainerDelta<AssignmentType> createAccountAssignmentModification(String resourceOid, String intent, boolean add) throws SchemaException { return createAssignmentModification(resourceOid, ShadowKindType.ACCOUNT, intent, add); } protected <V> PropertyDelta<V> createUserPropertyReplaceModification(QName propertyName, V... values) { return PropertyDelta.createReplaceDelta(getUserDefinition(), propertyName, values); } protected ContainerDelta<AssignmentType> createAssignmentModification(String resourceOid, ShadowKindType kind, String intent, boolean add) throws SchemaException { AssignmentType assignmentType = createAssignment(resourceOid, kind, intent); return createAssignmentModification(assignmentType, add); } protected ContainerDelta<AssignmentType> createAssignmentModification(AssignmentType assignmentType, boolean add) throws SchemaException { ContainerDelta<AssignmentType> assignmentDelta = ContainerDelta.createDelta(UserType.F_ASSIGNMENT, getUserDefinition()); if (add) { assignmentDelta.addValueToAdd(assignmentType.asPrismContainerValue()); } else { assignmentDelta.addValueToDelete(assignmentType.asPrismContainerValue()); } PrismContainerDefinition<AssignmentType> assignmentDef = getUserDefinition() .findContainerDefinition(UserType.F_ASSIGNMENT); assignmentDelta.applyDefinition(assignmentDef); return assignmentDelta; } protected AssignmentType createAccountAssignment(String resourceOid, String intent) { return createAssignment(resourceOid, ShadowKindType.ACCOUNT, intent); } protected AssignmentType createAssignment(String resourceOid, ShadowKindType kind, String intent) { AssignmentType assignmentType = new AssignmentType(); ConstructionType constructionType = new ConstructionType(); constructionType.setKind(kind); assignmentType.setConstruction(constructionType); ObjectReferenceType resourceRef = new ObjectReferenceType(); resourceRef.setOid(resourceOid); resourceRef.setType(ResourceType.COMPLEX_TYPE); constructionType.setResourceRef(resourceRef); constructionType.setIntent(intent); return assignmentType; } protected ConstructionType createAccountConstruction(String resourceOid, String intent) throws SchemaException { ConstructionType accountConstructionType = new ConstructionType(); ObjectReferenceType resourceRef = new ObjectReferenceType(); resourceRef.setOid(resourceOid); accountConstructionType.setResourceRef(resourceRef); accountConstructionType.setIntent(intent); return accountConstructionType; } protected ObjectDelta<UserType> createReplaceAccountConstructionUserDelta(String userOid, Long id, ConstructionType newValue) throws SchemaException { PrismContainerDefinition pcd = getAssignmentDefinition() .findContainerDefinition(AssignmentType.F_CONSTRUCTION); ContainerDelta<ConstructionType> acDelta = new ContainerDelta<ConstructionType>( new ItemPath(new NameItemPathSegment(UserType.F_ASSIGNMENT), new IdItemPathSegment(id), new NameItemPathSegment(AssignmentType.F_CONSTRUCTION)), pcd, prismContext); // ContainerDelta.createDelta(prismContext, ConstructionType.class, AssignmentType.F_CONSTRUCTION); acDelta.setValueToReplace(newValue.asPrismContainerValue()); // PropertyDelta.createModificationReplaceProperty( // new ItemPath(new NameItemPathSegment(UserType.F_ASSIGNMENT), new IdItemPathSegment(id), new NameItemPathSegment(AssignmentType.F_CONSTRUCTION)), // ppd, // newValue); Collection<ItemDelta<?, ?>> modifications = new ArrayList<>(); modifications.add(acDelta); ObjectDelta<UserType> userDelta = ObjectDelta.createModifyDelta(userOid, modifications, UserType.class, prismContext); return userDelta; } protected ObjectDelta<UserType> createAccountAssignmentUserDelta(String userOid, String resourceOid, String intent, boolean add) throws SchemaException { return createAssignmentDelta(UserType.class, userOid, resourceOid, ShadowKindType.ACCOUNT, intent, add); } protected <F extends FocusType> ObjectDelta<F> createAssignmentDelta(Class<F> type, String focusOid, String resourceOid, ShadowKindType kind, String intent, boolean add) throws SchemaException { Collection<ItemDelta<?, ?>> modifications = new ArrayList<>(); modifications.add(createAssignmentModification(resourceOid, kind, intent, add)); ObjectDelta<F> userDelta = ObjectDelta.createModifyDelta(focusOid, modifications, type, prismContext); return userDelta; } protected void assignAccount(String userOid, String resourceOid, String intent) throws SchemaException, ObjectAlreadyExistsException, ObjectNotFoundException, ExpressionEvaluationException, CommunicationException, ConfigurationException, PolicyViolationException, SecurityViolationException { Task task = taskManager.createTaskInstance(AbstractModelIntegrationTest.class + ".assignAccount"); OperationResult result = task.getResult(); assignAccount(userOid, resourceOid, intent, task, result); result.computeStatus(); TestUtil.assertSuccess(result); } protected void assignAccount(String userOid, String resourceOid, String intent, Task task, OperationResult result) throws SchemaException, ObjectAlreadyExistsException, ObjectNotFoundException, ExpressionEvaluationException, CommunicationException, ConfigurationException, PolicyViolationException, SecurityViolationException { ObjectDelta<UserType> userDelta = createAccountAssignmentUserDelta(userOid, resourceOid, intent, true); Collection<ObjectDelta<? extends ObjectType>> deltas = MiscSchemaUtil.createCollection(userDelta); modelService.executeChanges(deltas, null, task, result); } protected void unassignAccount(String userOid, String resourceOid, String intent, Task task, OperationResult result) throws SchemaException, ObjectAlreadyExistsException, ObjectNotFoundException, ExpressionEvaluationException, CommunicationException, ConfigurationException, PolicyViolationException, SecurityViolationException { ObjectDelta<UserType> userDelta = createAccountAssignmentUserDelta(userOid, resourceOid, intent, false); Collection<ObjectDelta<? extends ObjectType>> deltas = MiscSchemaUtil.createCollection(userDelta); modelService.executeChanges(deltas, null, task, result); } protected PrismObject<UserType> getUser(String userOid) throws ObjectNotFoundException, SchemaException, SecurityViolationException, CommunicationException, ConfigurationException { Task task = taskManager.createTaskInstance(AbstractModelIntegrationTest.class.getName() + ".getUser"); OperationResult result = task.getResult(); PrismObject<UserType> user = modelService.getObject(UserType.class, userOid, null, task, result); result.computeStatus(); TestUtil.assertSuccess("getObject(User) result not success", result); return user; } protected <O extends ObjectType> PrismObject<O> findObjectByName(Class<O> type, String name) throws SchemaException, ObjectNotFoundException, SecurityViolationException, CommunicationException, ConfigurationException { Task task = taskManager .createTaskInstance(AbstractModelIntegrationTest.class.getName() + ".findObjectByName"); OperationResult result = task.getResult(); List<PrismObject<O>> objects = modelService.searchObjects(type, createNameQuery(name), null, task, result); if (objects.isEmpty()) { return null; } assert objects.size() == 1 : "Too many objects found for name " + name + ": " + objects; return objects.iterator().next(); } protected ObjectQuery createNameQuery(String name) throws SchemaException { return ObjectQueryUtil.createNameQuery(PrismTestUtil.createPolyString(name), prismContext); } protected PrismObject<UserType> findUserByUsername(String username) throws SchemaException, ObjectNotFoundException, SecurityViolationException, CommunicationException, ConfigurationException { return findObjectByName(UserType.class, username); } protected PrismObject<RoleType> getRole(String oid) throws ObjectNotFoundException, SchemaException, SecurityViolationException, CommunicationException, ConfigurationException { Task task = taskManager.createTaskInstance(AbstractModelIntegrationTest.class.getName() + ".getRole"); OperationResult result = task.getResult(); PrismObject<RoleType> role = modelService.getObject(RoleType.class, oid, null, task, result); result.computeStatus(); TestUtil.assertSuccess("getObject(Role) result not success", result); return role; } protected PrismObject<ShadowType> findAccountByUsername(String username, PrismObject<ResourceType> resource) throws SchemaException, ObjectNotFoundException, SecurityViolationException, CommunicationException, ConfigurationException { Task task = taskManager .createTaskInstance(AbstractModelIntegrationTest.class.getName() + ".findAccountByUsername"); OperationResult result = task.getResult(); return findAccountByUsername(username, resource, task, result); } protected PrismObject<ShadowType> findAccountByUsername(String username, PrismObject<ResourceType> resource, Task task, OperationResult result) throws SchemaException, ObjectNotFoundException, SecurityViolationException, CommunicationException, ConfigurationException { ObjectQuery query = createAccountShadowQuery(username, resource); List<PrismObject<ShadowType>> accounts = modelService.searchObjects(ShadowType.class, query, null, task, result); if (accounts.isEmpty()) { return null; } assert accounts.size() == 1 : "Too many accounts found for username " + username + " on " + resource + ": " + accounts; return accounts.iterator().next(); } protected Collection<PrismObject<ShadowType>> listAccounts(PrismObject<ResourceType> resource, Task task, OperationResult result) throws SchemaException, ObjectNotFoundException, SecurityViolationException, CommunicationException, ConfigurationException { RefinedResourceSchema rSchema = RefinedResourceSchema.getRefinedSchema(resource); RefinedObjectClassDefinition rAccount = rSchema.getDefaultRefinedDefinition(ShadowKindType.ACCOUNT); Collection<? extends ResourceAttributeDefinition> identifierDefs = rAccount.getIdentifiers(); assert identifierDefs.size() == 1 : "Unexpected identifier set in " + resource + " refined schema: " + identifierDefs; ResourceAttributeDefinition identifierDef = identifierDefs.iterator().next(); EqualFilter ocFilter = EqualFilter.createEqual(ShadowType.F_OBJECT_CLASS, ShadowType.class, prismContext, null, rAccount.getObjectClassDefinition().getTypeName()); RefFilter resourceRefFilter = RefFilter.createReferenceEqual(ShadowType.F_RESOURCE_REF, ShadowType.class, resource); AndFilter filter = AndFilter.createAnd(ocFilter, resourceRefFilter); ObjectQuery query = ObjectQuery.createObjectQuery(filter); List<PrismObject<ShadowType>> accounts = modelService.searchObjects(ShadowType.class, query, null, task, result); return accounts; } protected PrismObject<ShadowType> getShadowModel(String accountOid) throws ObjectNotFoundException, SchemaException, SecurityViolationException, CommunicationException, ConfigurationException { return getShadowModel(accountOid, false, true); } protected PrismObject<ShadowType> getShadowModelNoFetch(String accountOid) throws ObjectNotFoundException, SchemaException, SecurityViolationException, CommunicationException, ConfigurationException { return getShadowModel(accountOid, true, true); } protected PrismObject<ShadowType> getShadowModel(String accountOid, boolean noFetch, boolean assertSuccess) throws ObjectNotFoundException, SchemaException, SecurityViolationException, CommunicationException, ConfigurationException { Task task = taskManager.createTaskInstance(AbstractModelIntegrationTest.class.getName() + ".getAccount"); OperationResult result = task.getResult(); Collection<SelectorOptions<GetOperationOptions>> opts = null; if (noFetch) { GetOperationOptions rootOpts = new GetOperationOptions(); rootOpts.setNoFetch(true); opts = SelectorOptions.createCollection(rootOpts); } PrismObject<ShadowType> account = modelService.getObject(ShadowType.class, accountOid, opts, task, result); result.computeStatus(); if (assertSuccess) { TestUtil.assertSuccess("getObject(Account) result not success", result); } return account; } protected <O extends ObjectType> void assertNoObject(Class<O> type, String oid, Task task, OperationResult result) throws SchemaException, SecurityViolationException, CommunicationException, ConfigurationException { try { PrismObject<O> object = modelService.getObject(type, oid, null, task, result); AssertJUnit.fail("Expected that " + object + " does not exist, but it does"); } catch (ObjectNotFoundException e) { // This is expected return; } } protected void assertNoShadow(String username, PrismObject<ResourceType> resource, Task task, OperationResult result) throws SchemaException, ObjectNotFoundException, SecurityViolationException, CommunicationException, ConfigurationException { ObjectQuery query = createAccountShadowQuery(username, resource); List<PrismObject<ShadowType>> accounts = repositoryService.searchObjects(ShadowType.class, query, null, result); if (accounts.isEmpty()) { return; } LOGGER.error("Found shadow for " + username + " on " + resource + " while not expecting it:\n" + accounts.get(0).debugDump()); assert false : "Found shadow for " + username + " on " + resource + " while not expecting it: " + accounts; } protected void assertHasShadow(String username, PrismObject<ResourceType> resource, Task task, OperationResult result) throws SchemaException, ObjectNotFoundException, SecurityViolationException, CommunicationException, ConfigurationException { ObjectQuery query = createAccountShadowQuery(username, resource); List<PrismObject<ShadowType>> accounts = repositoryService.searchObjects(ShadowType.class, query, null, result); if (accounts.isEmpty()) { AssertJUnit.fail("No shadow for " + username + " on " + resource); } else if (accounts.size() > 1) { AssertJUnit.fail("Too many shadows for " + username + " on " + resource + " (" + accounts.size() + "): " + accounts); } } protected ObjectQuery createAccountShadowQuery(String username, PrismObject<ResourceType> resource) throws SchemaException { RefinedResourceSchema rSchema = RefinedResourceSchema.getRefinedSchema(resource); RefinedObjectClassDefinition rAccount = rSchema.getDefaultRefinedDefinition(ShadowKindType.ACCOUNT); Collection<? extends ResourceAttributeDefinition> identifierDefs = rAccount.getIdentifiers(); assert identifierDefs.size() == 1 : "Unexpected identifier set in " + resource + " refined schema: " + identifierDefs; ResourceAttributeDefinition identifierDef = identifierDefs.iterator().next(); //TODO: set matching rule instead of null EqualFilter idFilter = EqualFilter.createEqual( new ItemPath(ShadowType.F_ATTRIBUTES, identifierDef.getName()), identifierDef, username); EqualFilter ocFilter = EqualFilter.createEqual(ShadowType.F_OBJECT_CLASS, ShadowType.class, prismContext, rAccount.getObjectClassDefinition().getTypeName()); RefFilter resourceRefFilter = RefFilter.createReferenceEqual(ShadowType.F_RESOURCE_REF, ShadowType.class, resource); AndFilter filter = AndFilter.createAnd(idFilter, ocFilter, resourceRefFilter); return ObjectQuery.createObjectQuery(filter); } protected <F extends FocusType> String getSingleLinkOid(PrismObject<F> focus) { PrismReferenceValue accountRefValue = getSingleLinkRef(focus); assertNull("Unexpected object in linkRefValue", accountRefValue.getObject()); return accountRefValue.getOid(); } protected <F extends FocusType> PrismReferenceValue getSingleLinkRef(PrismObject<F> focus) { F focusType = focus.asObjectable(); assertEquals("Unexpected number of linkRefs", 1, focusType.getLinkRef().size()); ObjectReferenceType linkRefType = focusType.getLinkRef().get(0); String accountOid = linkRefType.getOid(); assertFalse("No linkRef oid", StringUtils.isBlank(accountOid)); PrismReferenceValue accountRefValue = linkRefType.asReferenceValue(); assertEquals("OID mismatch in linkRefValue", accountOid, accountRefValue.getOid()); return accountRefValue; } protected String getLinkRefOid(String userOid, String resourceOid) throws ObjectNotFoundException, SchemaException, SecurityViolationException, CommunicationException, ConfigurationException { return getLinkRefOid(getUser(userOid), resourceOid); } protected <F extends FocusType> String getLinkRefOid(PrismObject<F> focus, String resourceOid) throws ObjectNotFoundException, SchemaException, SecurityViolationException, CommunicationException, ConfigurationException { PrismReferenceValue linkRef = getLinkRef(focus, resourceOid); if (linkRef == null) { return null; } return linkRef.getOid(); } protected <F extends FocusType> PrismReferenceValue getLinkRef(PrismObject<F> focus, String resourceOid) throws ObjectNotFoundException, SchemaException, SecurityViolationException, CommunicationException, ConfigurationException { F focusType = focus.asObjectable(); for (ObjectReferenceType linkRefType : focusType.getLinkRef()) { String linkTargetOid = linkRefType.getOid(); assertFalse("No linkRef oid", StringUtils.isBlank(linkTargetOid)); PrismObject<ShadowType> account = getShadowModel(linkTargetOid, true, false); if (resourceOid.equals(account.asObjectable().getResourceRef().getOid())) { // This is noFetch. Therefore there is no fetchResult return linkRefType.asReferenceValue(); } } AssertJUnit.fail("Account for resource " + resourceOid + " not found in " + focus); return null; // Never reached. But compiler complains about missing return } protected <F extends FocusType> String getLinkRefOid(PrismObject<F> focus, String resourceOid, ShadowKindType kind, String intent) throws ObjectNotFoundException, SchemaException, SecurityViolationException, CommunicationException, ConfigurationException { F focusType = focus.asObjectable(); for (ObjectReferenceType linkRefType : focusType.getLinkRef()) { String linkTargetOid = linkRefType.getOid(); assertFalse("No linkRef oid", StringUtils.isBlank(linkTargetOid)); PrismObject<ShadowType> account = getShadowModel(linkTargetOid, true, false); ShadowType shadowType = account.asObjectable(); if (kind != null && !kind.equals(shadowType.getKind())) { continue; } if (!MiscUtil.equals(intent, shadowType.getIntent())) { continue; } if (resourceOid.equals(shadowType.getResourceRef().getOid())) { // This is noFetch. Therefore there is no fetchResult return linkTargetOid; } } AssertJUnit.fail("Linked shadow for resource " + resourceOid + ", kind " + kind + " and intent " + intent + " not found in " + focus); return null; // Never reached. But compiler complains about missing return } protected void assertUserNoAccountRefs(PrismObject<UserType> user) { UserType userJackType = user.asObjectable(); assertEquals("Unexpected number of accountRefs", 0, userJackType.getLinkRef().size()); } protected void assertNoShadow(String shadowOid) throws SchemaException { OperationResult result = new OperationResult( AbstractModelIntegrationTest.class.getName() + ".assertNoShadow"); // Check is shadow is gone try { PrismObject<ShadowType> accountShadow = repositoryService.getObject(ShadowType.class, shadowOid, null, result); AssertJUnit.fail("Shadow " + shadowOid + " still exists"); } catch (ObjectNotFoundException e) { // This is OK } } protected AssignmentType getUserAssignment(String userOid, String roleOid) throws ObjectNotFoundException, SchemaException, SecurityViolationException, CommunicationException, ConfigurationException { PrismObject<UserType> user = getUser(userOid); List<AssignmentType> assignments = user.asObjectable().getAssignment(); for (AssignmentType assignment : assignments) { ObjectReferenceType targetRef = assignment.getTargetRef(); if (targetRef != null && roleOid.equals(targetRef.getOid())) { return assignment; } } return null; } protected <F extends FocusType> void assertNoAssignments(PrismObject<F> user) { MidPointAsserts.assertNoAssignments(user); } protected void assertNoAssignments(String userOid, OperationResult result) throws ObjectNotFoundException, SchemaException { PrismObject<UserType> user = repositoryService.getObject(UserType.class, userOid, null, result); assertNoAssignments(user); } protected void assertNoAssignments(String userOid) throws ObjectNotFoundException, SchemaException { OperationResult result = new OperationResult( AbstractModelIntegrationTest.class.getName() + ".assertNoShadow"); assertNoAssignments(userOid, result); } protected void assertAssignedRole(String userOid, String roleOid, Task task, OperationResult result) throws ObjectNotFoundException, SchemaException { PrismObject<UserType> user = repositoryService.getObject(UserType.class, userOid, null, result); assertAssignedRole(user, roleOid); } protected <F extends FocusType> void assertAssignedRole(PrismObject<F> focus, String roleOid, Task task, OperationResult result) throws ObjectNotFoundException, SchemaException { assertAssignedRole(focus, roleOid); } protected <F extends FocusType> void assertAssignedRole(PrismObject<F> user, String roleOid) { MidPointAsserts.assertAssignedRole(user, roleOid); } protected <F extends FocusType> void assertRoleMembershipRef(PrismObject<F> focus, String... roleOids) { List<String> refOids = new ArrayList<String>(); for (ObjectReferenceType ref : focus.asObjectable().getRoleMembershipRef()) { refOids.add(ref.getOid()); assertNotNull("Missing type in roleMembershipRef " + ref.getOid() + " in " + focus, ref.getType()); // Name is not stored now // assertNotNull("Missing name in roleMembershipRef "+ref.getOid()+" in "+focus, ref.getTargetName()); } PrismAsserts.assertSets("Wrong values in roleMembershipRef in " + focus, refOids, roleOids); } protected <F extends FocusType> void assertNotAssignedRole(PrismObject<F> focus, String roleOid, Task task, OperationResult result) throws ObjectNotFoundException, SchemaException { MidPointAsserts.assertNotAssignedRole(focus, roleOid); } protected void assertNotAssignedRole(String userOid, String roleOid, Task task, OperationResult result) throws ObjectNotFoundException, SchemaException { PrismObject<UserType> user = repositoryService.getObject(UserType.class, userOid, null, result); MidPointAsserts.assertNotAssignedRole(user, roleOid); } protected void assertNotAssignedResource(String userOid, String resourceOid, Task task, OperationResult result) throws ObjectNotFoundException, SchemaException { PrismObject<UserType> user = repositoryService.getObject(UserType.class, userOid, null, result); MidPointAsserts.assertNotAssignedResource(user, resourceOid); } protected void assertAssignedResource(String userOid, String resourceOid, Task task, OperationResult result) throws ObjectNotFoundException, SchemaException { PrismObject<UserType> user = repositoryService.getObject(UserType.class, userOid, null, result); MidPointAsserts.assertAssignedResource(user, resourceOid); } protected <F extends FocusType> void assertNotAssignedRole(PrismObject<F> user, String roleOid) { MidPointAsserts.assertNotAssignedRole(user, roleOid); } protected <F extends FocusType> void assertNotAssignedOrg(PrismObject<F> user, String orgOid, QName relation) { MidPointAsserts.assertNotAssignedOrg(user, orgOid, relation); } protected void assertAssignedOrg(String userOid, String orgOid, Task task, OperationResult result) throws ObjectNotFoundException, SchemaException { PrismObject<UserType> user = repositoryService.getObject(UserType.class, userOid, null, result); assertAssignedOrg(user, orgOid); } protected void assertAssignedOrg(PrismObject<? extends FocusType> focus, String orgOid, QName relation) { MidPointAsserts.assertAssignedOrg(focus, orgOid, relation); } protected void assertAssignedOrg(PrismObject<? extends FocusType> focus, String orgOid) { MidPointAsserts.assertAssignedOrg(focus, orgOid); } protected void assertAssignedOrg(PrismObject<UserType> user, PrismObject<OrgType> org) { MidPointAsserts.assertAssignedOrg(user, org.getOid()); } protected void assertHasOrg(String userOid, String orgOid, Task task, OperationResult result) throws ObjectNotFoundException, SchemaException { PrismObject<UserType> user = repositoryService.getObject(UserType.class, userOid, null, result); assertAssignedOrg(user, orgOid); } protected <O extends ObjectType> void assertHasOrg(PrismObject<O> focus, String orgOid) { MidPointAsserts.assertHasOrg(focus, orgOid); } protected <O extends ObjectType> void assertHasOrg(PrismObject<O> user, String orgOid, QName relation) { MidPointAsserts.assertHasOrg(user, orgOid, relation); } protected <O extends ObjectType> void assertHasNoOrg(PrismObject<O> user) { MidPointAsserts.assertHasNoOrg(user); } protected <O extends ObjectType> void assertHasOrgs(PrismObject<O> user, int expectedNumber) { MidPointAsserts.assertHasOrgs(user, expectedNumber); } protected void assertSubOrgs(String baseOrgOid, int expected) throws SchemaException, ObjectNotFoundException, SecurityViolationException, CommunicationException, ConfigurationException { Task task = taskManager.createTaskInstance(AbstractModelIntegrationTest.class + ".assertSubOrgs"); OperationResult result = task.getResult(); List<PrismObject<OrgType>> subOrgs = getSubOrgs(baseOrgOid, task, result); result.computeStatus(); TestUtil.assertSuccess(result); assertEquals("Unexpected number of suborgs of org " + baseOrgOid + ", has suborgs " + subOrgs, expected, subOrgs.size()); } protected void assertSubOrgs(PrismObject<OrgType> baseOrg, int expected) throws SchemaException, ObjectNotFoundException, SecurityViolationException, CommunicationException, ConfigurationException { Task task = taskManager.createTaskInstance(AbstractModelIntegrationTest.class + ".assertSubOrgs"); OperationResult result = task.getResult(); List<PrismObject<OrgType>> subOrgs = getSubOrgs(baseOrg.getOid(), task, result); result.computeStatus(); TestUtil.assertSuccess(result); assertEquals("Unexpected number of suborgs of" + baseOrg + ", has suborgs " + subOrgs, expected, subOrgs.size()); } protected List<PrismObject<OrgType>> getSubOrgs(String baseOrgOid, Task task, OperationResult result) throws SchemaException, ObjectNotFoundException, SecurityViolationException, CommunicationException, ConfigurationException { ObjectQuery query = new ObjectQuery(); PrismReferenceValue baseOrgRef = new PrismReferenceValue(baseOrgOid); ObjectFilter filter = OrgFilter.createOrg(baseOrgRef, OrgFilter.Scope.ONE_LEVEL); query.setFilter(filter); return modelService.searchObjects(OrgType.class, query, null, task, result); } protected String dumpOrgTree(String topOrgOid) throws SchemaException, ObjectNotFoundException, SecurityViolationException, CommunicationException, ConfigurationException { Task task = taskManager.createTaskInstance(AbstractModelIntegrationTest.class + ".assertSubOrgs"); OperationResult result = task.getResult(); PrismObject<OrgType> topOrg = modelService.getObject(OrgType.class, topOrgOid, null, task, result); String dump = dumpOrgTree(topOrg, task, result); result.computeStatus(); TestUtil.assertSuccess(result); return dump; } protected String dumpOrgTree(PrismObject<OrgType> topOrg, Task task, OperationResult result) throws SchemaException, ObjectNotFoundException, SecurityViolationException, CommunicationException, ConfigurationException { StringBuilder sb = new StringBuilder(); dumpOrg(sb, topOrg, 0); sb.append("\n"); dumpSubOrgs(sb, topOrg.getOid(), 1, task, result); return sb.toString(); } private void dumpSubOrgs(StringBuilder sb, String baseOrgOid, int indent, Task task, OperationResult result) throws SchemaException, ObjectNotFoundException, SecurityViolationException, CommunicationException, ConfigurationException { List<PrismObject<OrgType>> subOrgs = getSubOrgs(baseOrgOid, task, result); for (PrismObject<OrgType> suborg : subOrgs) { dumpOrg(sb, suborg, indent); sb.append("\n"); dumpSubOrgs(sb, suborg.getOid(), indent + 1, task, result); } } private void dumpOrg(StringBuilder sb, PrismObject<OrgType> org, int indent) { DebugUtil.indentDebugDump(sb, indent); sb.append(org); List<ObjectReferenceType> linkRefs = org.asObjectable().getLinkRef(); sb.append(": ").append(linkRefs.size()).append(" links"); } protected void displayUsers() throws SchemaException, ObjectNotFoundException, SecurityViolationException, CommunicationException, ConfigurationException { Task task = taskManager.createTaskInstance(AbstractModelIntegrationTest.class + ".displayUsers"); OperationResult result = task.getResult(); ResultHandler<UserType> handler = new ResultHandler<UserType>() { @Override public boolean handle(PrismObject<UserType> user, OperationResult parentResult) { display("User", user); return true; } }; modelService.searchObjectsIterative(UserType.class, null, handler, null, task, result); result.computeStatus(); TestUtil.assertSuccess(result); } protected <F extends FocusType> void assertAssignments(PrismObject<F> user, int expectedNumber) { MidPointAsserts.assertAssignments(user, expectedNumber); } protected <F extends FocusType> void assertAssignments(PrismObject<F> user, Class expectedType, int expectedNumber) { MidPointAsserts.assertAssignments(user, expectedType, expectedNumber); } protected <F extends FocusType> void assertAssigned(PrismObject<F> user, String targetOid, QName refType) { MidPointAsserts.assertAssigned(user, targetOid, refType); } protected void assertAssignedNoOrg(String userOid, Task task, OperationResult result) throws ObjectNotFoundException, SchemaException { PrismObject<UserType> user = repositoryService.getObject(UserType.class, userOid, null, result); assertAssignedNoOrg(user); } protected void assertAssignedNoOrg(PrismObject<UserType> user) { assertAssignedNo(user, OrgType.COMPLEX_TYPE); } protected <F extends FocusType> void assertAssignedNoRole(PrismObject<F> focus, Task task, OperationResult result) throws ObjectNotFoundException, SchemaException { assertAssignedNoRole(focus); } protected void assertAssignedNoRole(String userOid, Task task, OperationResult result) throws ObjectNotFoundException, SchemaException { PrismObject<UserType> user = repositoryService.getObject(UserType.class, userOid, null, result); assertAssignedNoRole(user); } protected <F extends FocusType> void assertAssignedNoRole(PrismObject<F> user) { assertAssignedNo(user, RoleType.COMPLEX_TYPE); } protected <F extends FocusType> void assertAssignedNo(PrismObject<F> user, QName refType) { F userType = user.asObjectable(); for (AssignmentType assignmentType : userType.getAssignment()) { ObjectReferenceType targetRef = assignmentType.getTargetRef(); if (targetRef != null) { if (refType.equals(targetRef.getType())) { AssertJUnit.fail(user + " has role " + targetRef.getOid() + " while expected no roles"); } } } } protected void assertAssignedAccount(String userOid, String resourceOid, Task task, OperationResult result) throws ObjectNotFoundException, SchemaException { PrismObject<UserType> user = repositoryService.getObject(UserType.class, userOid, null, result); assertAssignedAccount(user, resourceOid); } protected void assertAssignedAccount(PrismObject<UserType> user, String resourceOid) throws ObjectNotFoundException, SchemaException { UserType userType = user.asObjectable(); for (AssignmentType assignmentType : userType.getAssignment()) { ConstructionType construction = assignmentType.getConstruction(); if (construction != null) { if (construction.getKind() != null && construction.getKind() != ShadowKindType.ACCOUNT) { continue; } if (resourceOid.equals(construction.getResourceRef().getOid())) { return; } } } AssertJUnit.fail(user.toString() + " does not have account assignment for resource " + resourceOid); } protected void assertAssignedNoAccount(PrismObject<UserType> user, String resourceOid) throws ObjectNotFoundException, SchemaException { UserType userType = user.asObjectable(); for (AssignmentType assignmentType : userType.getAssignment()) { ConstructionType construction = assignmentType.getConstruction(); if (construction != null) { if (construction.getKind() != null && construction.getKind() != ShadowKindType.ACCOUNT) { continue; } if (resourceOid.equals(construction.getResourceRef().getOid())) { AssertJUnit.fail(user.toString() + " has account assignment for resource " + resourceOid + " while expecting no such assignment"); } } } } protected PrismObjectDefinition<RoleType> getRoleDefinition() { return prismContext.getSchemaRegistry().findObjectDefinitionByCompileTimeClass(RoleType.class); } protected PrismObjectDefinition<ShadowType> getShadowDefinition() { return prismContext.getSchemaRegistry().findObjectDefinitionByCompileTimeClass(ShadowType.class); } protected PrismContainerDefinition<AssignmentType> getAssignmentDefinition() { return prismContext.getSchemaRegistry().findContainerDefinitionByType(AssignmentType.COMPLEX_TYPE); } protected PrismContainerDefinition<?> getAssignmentExtensionDefinition() { PrismContainerDefinition<AssignmentType> assignmentDefinition = getAssignmentDefinition(); return assignmentDefinition.findContainerDefinition(AssignmentType.F_EXTENSION); } protected PrismContainer<?> getAssignmentExtensionInstance() { return getAssignmentExtensionDefinition().instantiate(); } protected PrismObjectDefinition<ResourceType> getResourceDefinition() { return prismContext.getSchemaRegistry().findObjectDefinitionByCompileTimeClass(ResourceType.class); } protected PrismObjectDefinition<ShadowType> getAccountShadowDefinition() { return prismContext.getSchemaRegistry().findObjectDefinitionByCompileTimeClass(ShadowType.class); } protected PrismObject<UserType> createUser(String name, String fullName) throws SchemaException { return createUser(name, fullName, null); } protected PrismObject<UserType> createUser(String name, String fullName, Boolean enabled) throws SchemaException { PrismObject<UserType> user = getUserDefinition().instantiate(); UserType userType = user.asObjectable(); userType.setName(PrismTestUtil.createPolyStringType(name)); userType.setFullName(PrismTestUtil.createPolyStringType(fullName)); if (enabled != null) { ActivationType activation = new ActivationType(); userType.setActivation(activation); if (enabled) { activation.setAdministrativeStatus(ActivationStatusType.ENABLED); } else { activation.setAdministrativeStatus(ActivationStatusType.DISABLED); } } return user; } protected PrismObject<UserType> createUser(String name, String givenName, String familyName, Boolean enabled) throws SchemaException { PrismObject<UserType> user = getUserDefinition().instantiate(); UserType userType = user.asObjectable(); userType.setName(PrismTestUtil.createPolyStringType(name)); userType.setGivenName(PrismTestUtil.createPolyStringType(givenName)); userType.setFamilyName(PrismTestUtil.createPolyStringType(familyName)); userType.setFullName(PrismTestUtil.createPolyStringType(givenName + " " + familyName)); if (enabled != null) { ActivationType activation = new ActivationType(); userType.setActivation(activation); if (enabled) { activation.setAdministrativeStatus(ActivationStatusType.ENABLED); } else { activation.setAdministrativeStatus(ActivationStatusType.DISABLED); } } return user; } protected void fillinUser(PrismObject<UserType> user, String name, String fullName) { user.asObjectable().setName(PrismTestUtil.createPolyStringType(name)); user.asObjectable().setFullName(PrismTestUtil.createPolyStringType(fullName)); } protected void fillinUserAssignmentAccountConstruction(PrismObject<UserType> user, String resourceOid) { AssignmentType assignmentType = new AssignmentType(); ConstructionType accountConstruntion = new ConstructionType(); ObjectReferenceType resourceRef = new ObjectReferenceType(); resourceRef.setOid(resourceOid); resourceRef.setType(ResourceType.COMPLEX_TYPE); accountConstruntion.setResourceRef(resourceRef); accountConstruntion.setKind(ShadowKindType.ACCOUNT); assignmentType.setConstruction(accountConstruntion); user.asObjectable().getAssignment().add(assignmentType); } protected PrismObject<ShadowType> createAccount(PrismObject<ResourceType> resource, String name, boolean enabled) throws SchemaException { PrismObject<ShadowType> shadow = getShadowDefinition().instantiate(); ShadowType shadowType = shadow.asObjectable(); ObjectReferenceType resourceRef = new ObjectReferenceType(); resourceRef.setOid(resource.getOid()); shadowType.setResourceRef(resourceRef); RefinedResourceSchema refinedSchema = RefinedResourceSchema.getRefinedSchema(resource); RefinedObjectClassDefinition objectClassDefinition = refinedSchema .getDefaultRefinedDefinition(ShadowKindType.ACCOUNT); shadowType.setObjectClass(objectClassDefinition.getTypeName()); shadowType.setKind(ShadowKindType.ACCOUNT); ResourceAttributeContainer attrCont = ShadowUtil.getOrCreateAttributesContainer(shadow, objectClassDefinition); RefinedAttributeDefinition idSecondaryDef = objectClassDefinition.getSecondaryIdentifiers().iterator() .next(); ResourceAttribute icfsNameAttr = idSecondaryDef.instantiate(); icfsNameAttr.setRealValue(name); attrCont.add(icfsNameAttr); ActivationType activation = new ActivationType(); shadowType.setActivation(activation); if (enabled) { activation.setAdministrativeStatus(ActivationStatusType.ENABLED); } else { activation.setAdministrativeStatus(ActivationStatusType.DISABLED); } return shadow; } protected <T> void addAttributeToShadow(PrismObject<ShadowType> shadow, PrismObject<ResourceType> resource, String attrName, T attrValue) throws SchemaException { ResourceAttributeContainer attrs = ShadowUtil.getAttributesContainer(shadow); ResourceAttributeDefinition attrSnDef = attrs.getDefinition() .findAttributeDefinition(new QName(ResourceTypeUtil.getResourceNamespace(resource), attrName)); ResourceAttribute<T> attr = attrSnDef.instantiate(); attr.setRealValue(attrValue); attrs.add(attr); } protected void setDefaultUserTemplate(String userTemplateOid) throws ObjectNotFoundException, SchemaException, ObjectAlreadyExistsException { setDefaultObjectTemplate(UserType.COMPLEX_TYPE, userTemplateOid); } protected void setDefaultObjectTemplate(QName objectType, String userTemplateOid) throws ObjectNotFoundException, SchemaException, ObjectAlreadyExistsException { OperationResult result = new OperationResult( AbstractModelIntegrationTest.class.getName() + ".setDefaultObjectTemplate"); setDefaultObjectTemplate(objectType, userTemplateOid, result); // display("Aplying default user template result", result); result.computeStatus(); TestUtil.assertSuccess("Aplying default object template failed (result)", result); } protected void setDefaultObjectTemplate(QName objectType, String userTemplateOid, OperationResult parentResult) throws ObjectNotFoundException, SchemaException, ObjectAlreadyExistsException { PrismObject<SystemConfigurationType> systemConfig = repositoryService.getObject( SystemConfigurationType.class, SystemObjectsType.SYSTEM_CONFIGURATION.value(), null, parentResult); PrismContainerValue<ObjectPolicyConfigurationType> oldValue = null; for (ObjectPolicyConfigurationType focusPolicyType : systemConfig.asObjectable() .getDefaultObjectPolicyConfiguration()) { if (QNameUtil.match(objectType, focusPolicyType.getType())) { oldValue = focusPolicyType.asPrismContainerValue(); } } Collection<? extends ItemDelta> modifications = new ArrayList<ItemDelta>(); if (oldValue != null) { ContainerDelta<ObjectPolicyConfigurationType> deleteDelta = ContainerDelta.createModificationDelete( SystemConfigurationType.F_DEFAULT_OBJECT_POLICY_CONFIGURATION, SystemConfigurationType.class, prismContext, oldValue.clone()); ((Collection) modifications).add(deleteDelta); } ObjectPolicyConfigurationType newFocusPolicyType; ContainerDelta<ObjectPolicyConfigurationType> addDelta; if (oldValue == null) { newFocusPolicyType = new ObjectPolicyConfigurationType(); newFocusPolicyType.setType(objectType); addDelta = ContainerDelta.createModificationAdd( SystemConfigurationType.F_DEFAULT_OBJECT_POLICY_CONFIGURATION, SystemConfigurationType.class, prismContext, newFocusPolicyType); } else { PrismContainerValue<ObjectPolicyConfigurationType> newValue = oldValue.clone(); addDelta = ContainerDelta.createModificationAdd( SystemConfigurationType.F_DEFAULT_OBJECT_POLICY_CONFIGURATION, SystemConfigurationType.class, prismContext, newValue); newFocusPolicyType = newValue.asContainerable(); } ObjectReferenceType templateRef = new ObjectReferenceType(); templateRef.setOid(userTemplateOid); newFocusPolicyType.setObjectTemplateRef(templateRef); ((Collection) modifications).add(addDelta); repositoryService.modifyObject(SystemConfigurationType.class, SystemObjectsType.SYSTEM_CONFIGURATION.value(), modifications, parentResult); } protected ItemPath getIcfsNameAttributePath() { return new ItemPath(ShadowType.F_ATTRIBUTES, SchemaTestConstants.ICFS_NAME); } protected <F extends ObjectType> void assertResolvedResourceRefs(ModelContext<F> context) { for (ModelProjectionContext projectionContext : context.getProjectionContexts()) { assertResolvedResourceRefs(projectionContext.getObjectOld(), "objectOld in " + projectionContext); assertResolvedResourceRefs(projectionContext.getObjectNew(), "objectNew in " + projectionContext); assertResolvedResourceRefs(projectionContext.getPrimaryDelta(), "primaryDelta in " + projectionContext); assertResolvedResourceRefs(projectionContext.getSecondaryDelta(), "secondaryDelta in " + projectionContext); } } private void assertResolvedResourceRefs(ObjectDelta<ShadowType> delta, String desc) { if (delta == null) { return; } if (delta.isAdd()) { assertResolvedResourceRefs(delta.getObjectToAdd(), desc); } else if (delta.isModify()) { ReferenceDelta referenceDelta = delta.findReferenceModification(ShadowType.F_RESOURCE_REF); if (referenceDelta != null) { assertResolvedResourceRefs(referenceDelta.getValuesToAdd(), "valuesToAdd in " + desc); assertResolvedResourceRefs(referenceDelta.getValuesToDelete(), "valuesToDelete in " + desc); assertResolvedResourceRefs(referenceDelta.getValuesToReplace(), "valuesToReplace in " + desc); } } } private void assertResolvedResourceRefs(PrismObject<ShadowType> shadow, String desc) { if (shadow == null) { return; } PrismReference resourceRef = shadow.findReference(ShadowType.F_RESOURCE_REF); if (resourceRef == null) { AssertJUnit.fail("No resourceRef in " + desc); } assertResolvedResourceRefs(resourceRef.getValues(), desc); } private void assertResolvedResourceRefs(Collection<PrismReferenceValue> values, String desc) { if (values == null) { return; } for (PrismReferenceValue pval : values) { assertNotNull("resourceRef in " + desc + " does not contain object", pval.getObject()); } } /** * Breaks user assignment delta in the context by inserting some empty value. This may interfere with comparing the values to * existing user values. */ protected void breakAssignmentDelta(Collection<ObjectDelta<? extends ObjectType>> deltas) throws SchemaException { breakAssignmentDelta((ObjectDelta<? extends FocusType>) deltas.iterator().next()); } /** * Breaks user assignment delta in the context by inserting some empty value. This may interfere with comparing the values to * existing user values. */ protected <F extends FocusType> void breakAssignmentDelta(ObjectDelta<F> userDelta) throws SchemaException { ContainerDelta<?> assignmentDelta = userDelta.findContainerDelta(UserType.F_ASSIGNMENT); PrismContainerValue<?> assignmentDeltaValue = null; if (assignmentDelta.getValuesToAdd() != null) { assignmentDeltaValue = assignmentDelta.getValuesToAdd().iterator().next(); } if (assignmentDelta.getValuesToDelete() != null) { assignmentDeltaValue = assignmentDelta.getValuesToDelete().iterator().next(); } PrismContainer<ActivationType> activationContainer = assignmentDeltaValue .findOrCreateContainer(AssignmentType.F_ACTIVATION); PrismContainerValue<ActivationType> emptyValue = new PrismContainerValue<ActivationType>(prismContext); activationContainer.add(emptyValue); } protected void purgeResourceSchema(String resourceOid) throws ObjectAlreadyExistsException, ObjectNotFoundException, SchemaException, ExpressionEvaluationException, CommunicationException, ConfigurationException, PolicyViolationException, SecurityViolationException { Task task = taskManager .createTaskInstance(AbstractModelIntegrationTest.class.getName() + ".purgeResourceSchema"); OperationResult result = task.getResult(); ObjectDelta<ResourceType> resourceDelta = ObjectDelta.createModificationReplaceContainer(ResourceType.class, resourceOid, ResourceType.F_SCHEMA, prismContext, new PrismContainerValue[0]); Collection<ObjectDelta<? extends ObjectType>> deltas = MiscSchemaUtil.createCollection(resourceDelta); modelService.executeChanges(deltas, null, task, result); result.computeStatus(); TestUtil.assertSuccess(result); } protected List<PrismObject<OrgType>> searchOrg(String baseOrgOid, OrgFilter.Scope scope, Task task, OperationResult result) throws SchemaException, ObjectNotFoundException, SecurityViolationException, CommunicationException, ConfigurationException { ObjectFilter filter = OrgFilter.createOrg(baseOrgOid, scope); ObjectQuery query = ObjectQuery.createObjectQuery(filter); return modelService.searchObjects(OrgType.class, query, null, task, result); } protected <T extends ObjectType> PrismObject<T> searchObjectByName(Class<T> type, String name) throws SchemaException, ObjectNotFoundException, SecurityViolationException, CommunicationException, ConfigurationException { Task task = taskManager .createTaskInstance(AbstractModelIntegrationTest.class.getName() + ".searchObjectByName"); OperationResult result = task.getResult(); PrismObject<T> out = searchObjectByName(type, name, task, result); result.computeStatus(); TestUtil.assertSuccess(result); return out; } protected <T extends ObjectType> PrismObject<T> searchObjectByName(Class<T> type, String name, Task task, OperationResult result) throws SchemaException, ObjectNotFoundException, SecurityViolationException, CommunicationException, ConfigurationException { ObjectQuery query = ObjectQueryUtil.createNameQuery(name, prismContext); List<PrismObject<T>> foundObjects = modelService.searchObjects(type, query, null, task, result); if (foundObjects.isEmpty()) { return null; } if (foundObjects.size() > 1) { throw new IllegalStateException( "More than one object found for type " + type + " and name '" + name + "'"); } return foundObjects.iterator().next(); } protected void assertAccountShadowModel(PrismObject<ShadowType> accountShadow, String oid, String username, ResourceType resourceType) throws SchemaException { assertShadowModel(accountShadow, oid, username, resourceType, getAccountObjectClass(resourceType), null); } protected void assertAccountShadowModel(PrismObject<ShadowType> accountShadow, String oid, String username, ResourceType resourceType, MatchingRule<String> matchingRule) throws SchemaException { assertShadowModel(accountShadow, oid, username, resourceType, getAccountObjectClass(resourceType), matchingRule); } protected void assertShadowModel(PrismObject<ShadowType> accountShadow, String oid, String username, ResourceType resourceType, QName objectClass) throws SchemaException { assertShadowModel(accountShadow, oid, username, resourceType, objectClass, null); } protected void assertShadowModel(PrismObject<ShadowType> accountShadow, String oid, String username, ResourceType resourceType, QName objectClass, MatchingRule<String> nameMatchingRule) throws SchemaException { assertShadowCommon(accountShadow, oid, username, resourceType, objectClass, nameMatchingRule); IntegrationTestTools.assertProvisioningShadow(accountShadow, resourceType, RefinedAttributeDefinition.class, objectClass); } protected QName getAttributeQName(PrismObject<ResourceType> resource, String attributeLocalName) { String resourceNamespace = ResourceTypeUtil.getResourceNamespace(resource); return new QName(resourceNamespace, attributeLocalName); } protected ItemPath getAttributePath(PrismObject<ResourceType> resource, String attributeLocalName) { return new ItemPath(ShadowType.F_ATTRIBUTES, getAttributeQName(resource, attributeLocalName)); } // TASKS protected void waitForTaskFinish(Task task, boolean checkSubresult) throws Exception { waitForTaskFinish(task, checkSubresult, DEFAULT_TASK_WAIT_TIMEOUT); } protected void waitForTaskFinish(Task task, boolean checkSubresult, final int timeout) throws Exception { waitForTaskFinish(task, checkSubresult, timeout, DEFAULT_TASK_SLEEP_TIME); } protected void waitForTaskFinish(final Task task, final boolean checkSubresult, final int timeout, long sleepTime) throws Exception { final OperationResult waitResult = new OperationResult( AbstractIntegrationTest.class + ".waitForTaskFinish"); Checker checker = new Checker() { @Override public boolean check() throws Exception { task.refresh(waitResult); waitResult.summarize(); // Task freshTask = taskManager.getTask(task.getOid(), waitResult); OperationResult result = task.getResult(); if (verbose) display("Check result", result); assert !isError(result, checkSubresult) : "Error in " + task + ": " + TestUtil.getErrorMessage(result); assert !isUknown(result, checkSubresult) : "Unknown result in " + task + ": " + TestUtil.getErrorMessage(result); return !isInProgress(result, checkSubresult); } @Override public void timeout() { try { task.refresh(waitResult); } catch (ObjectNotFoundException e) { LOGGER.error("Exception during task refresh: {}", e, e); } catch (SchemaException e) { LOGGER.error("Exception during task refresh: {}", e, e); } OperationResult result = task.getResult(); LOGGER.debug("Result of timed-out task:\n{}", result.debugDump()); assert false : "Timeout (" + timeout + ") while waiting for " + task + " to finish. Last result " + result; } }; IntegrationTestTools.waitFor("Waiting for " + task + " finish", checker, timeout, sleepTime); } protected void waitForTaskFinish(String taskOid, boolean checkSubresult) throws Exception { waitForTaskFinish(taskOid, checkSubresult, DEFAULT_TASK_WAIT_TIMEOUT); } protected void waitForTaskFinish(final String taskOid, final boolean checkSubresult, final int timeout) throws Exception { waitForTaskFinish(taskOid, checkSubresult, timeout, false); } protected void waitForTaskFinish(final String taskOid, final boolean checkSubresult, final int timeout, final boolean errorOk) throws Exception { final OperationResult waitResult = new OperationResult( AbstractIntegrationTest.class + ".waitForTaskFinish"); Checker checker = new Checker() { @Override public boolean check() throws Exception { Task freshTask = taskManager.getTask(taskOid, waitResult); OperationResult result = freshTask.getResult(); if (verbose) display("Check result", result); if (isError(result, checkSubresult)) { if (errorOk) { return true; } else { AssertJUnit.fail("Error in " + freshTask + ": " + TestUtil.getErrorMessage(result)); } } if (isUknown(result, checkSubresult)) { return false; } // assert !isUknown(result, checkSubresult) : "Unknown result in "+freshTask+": "+IntegrationTestTools.getErrorMessage(result); return !isInProgress(result, checkSubresult); } @Override public void timeout() { try { Task freshTask = taskManager.getTask(taskOid, waitResult); OperationResult result = freshTask.getResult(); LOGGER.debug("Result of timed-out task:\n{}", result.debugDump()); assert false : "Timeout (" + timeout + ") while waiting for " + freshTask + " to finish. Last result " + result; } catch (ObjectNotFoundException e) { LOGGER.error("Exception during task refresh: {}", e, e); } catch (SchemaException e) { LOGGER.error("Exception during task refresh: {}", e, e); } } }; IntegrationTestTools.waitFor("Waiting for task " + taskOid + " finish", checker, timeout, DEFAULT_TASK_SLEEP_TIME); } protected void waitForTaskStart(String taskOid, boolean checkSubresult) throws Exception { waitForTaskStart(taskOid, checkSubresult, DEFAULT_TASK_WAIT_TIMEOUT); } protected void waitForTaskStart(final String taskOid, final boolean checkSubresult, final int timeout) throws Exception { final OperationResult waitResult = new OperationResult(AbstractIntegrationTest.class + ".waitForTaskStart"); Checker checker = new Checker() { @Override public boolean check() throws Exception { Task freshTask = taskManager.getTask(taskOid, waitResult); OperationResult result = freshTask.getResult(); if (verbose) display("Check result", result); assert !isError(result, checkSubresult) : "Error in " + freshTask + ": " + TestUtil.getErrorMessage(result); if (isUknown(result, checkSubresult)) { return false; } return freshTask.getLastRunStartTimestamp() != null; } @Override public void timeout() { try { Task freshTask = taskManager.getTask(taskOid, waitResult); OperationResult result = freshTask.getResult(); LOGGER.debug("Result of timed-out task:\n{}", result.debugDump()); assert false : "Timeout (" + timeout + ") while waiting for " + freshTask + " to start. Last result " + result; } catch (ObjectNotFoundException e) { LOGGER.error("Exception during task refresh: {}", e, e); } catch (SchemaException e) { LOGGER.error("Exception during task refresh: {}", e, e); } } }; IntegrationTestTools.waitFor("Waiting for task " + taskOid + " start", checker, timeout, DEFAULT_TASK_SLEEP_TIME); } protected OperationResult waitForTaskNextRunAssertSuccess(String taskOid, boolean checkSubresult) throws Exception { return waitForTaskNextRunAssertSuccess(taskOid, checkSubresult, DEFAULT_TASK_WAIT_TIMEOUT); } protected OperationResult waitForTaskNextRunAssertSuccess(final String taskOid, final boolean checkSubresult, final int timeout) throws Exception { OperationResult taskResult = waitForTaskNextRun(taskOid, checkSubresult, timeout); if (isError(taskResult, checkSubresult)) { assert false : "Error in task " + taskOid + ": " + TestUtil.getErrorMessage(taskResult) + "\n\n" + taskResult.debugDump(); } return taskResult; } protected OperationResult waitForTaskNextRun(final String taskOid, final boolean checkSubresult, final int timeout) throws Exception { final OperationResult waitResult = new OperationResult( AbstractIntegrationTest.class + ".waitForTaskNextRun"); Task origTask = taskManager.getTask(taskOid, waitResult); final Long origLastRunStartTimestamp = origTask.getLastRunStartTimestamp(); final Long origLastRunFinishTimestamp = origTask.getLastRunFinishTimestamp(); final Holder<OperationResult> taskResultHolder = new Holder<>(); Checker checker = new Checker() { @Override public boolean check() throws Exception { Task freshTask = taskManager.getTask(taskOid, waitResult); OperationResult taskResult = freshTask.getResult(); // display("Times", longTimeToString(origLastRunStartTimestamp) + "-" + longTimeToString(origLastRunStartTimestamp) // + " : " + longTimeToString(freshTask.getLastRunStartTimestamp()) + "-" + longTimeToString(freshTask.getLastRunFinishTimestamp())); if (verbose) display("Check result", taskResult); taskResultHolder.setValue(taskResult); if (isError(taskResult, checkSubresult)) { return true; } if (isUknown(taskResult, checkSubresult)) { return false; } if (freshTask.getLastRunFinishTimestamp() == null) { return false; } if (freshTask.getLastRunStartTimestamp() == null) { return false; } return !freshTask.getLastRunStartTimestamp().equals(origLastRunStartTimestamp) && !freshTask.getLastRunFinishTimestamp().equals(origLastRunFinishTimestamp) && freshTask.getLastRunStartTimestamp() < freshTask.getLastRunFinishTimestamp(); } @Override public void timeout() { try { Task freshTask = taskManager.getTask(taskOid, waitResult); OperationResult result = freshTask.getResult(); LOGGER.debug("Result of timed-out task:\n{}", result.debugDump()); assert false : "Timeout (" + timeout + ") while waiting for " + freshTask + " next run. Last result " + result; } catch (ObjectNotFoundException e) { LOGGER.error("Exception during task refresh: {}", e, e); } catch (SchemaException e) { LOGGER.error("Exception during task refresh: {}", e, e); } } }; IntegrationTestTools.waitFor("Waiting for task " + taskOid + " next run", checker, timeout, DEFAULT_TASK_SLEEP_TIME); return taskResultHolder.getValue(); } private String longTimeToString(Long longTime) { if (longTime == null) { return "null"; } return longTime.toString(); } private boolean isError(OperationResult result, boolean checkSubresult) { OperationResult subresult = getSubresult(result, checkSubresult); return subresult != null ? subresult.isError() : false; } private boolean isUknown(OperationResult result, boolean checkSubresult) { OperationResult subresult = getSubresult(result, checkSubresult); return subresult != null ? subresult.isUnknown() : false; // TODO or return true? } private boolean isInProgress(OperationResult result, boolean checkSubresult) { OperationResult subresult = getSubresult(result, checkSubresult); return subresult != null ? subresult.isInProgress() : true; // "true" if there are no subresults } private OperationResult getSubresult(OperationResult result, boolean checkSubresult) { if (checkSubresult) { return result.getLastSubresult(); } return result; } protected void restartTask(String taskOid) throws ObjectNotFoundException, SchemaException, ObjectAlreadyExistsException { final OperationResult result = new OperationResult(AbstractIntegrationTest.class + ".restartTask"); ObjectDelta<TaskType> taskDelta = ObjectDelta.createModificationReplaceProperty(TaskType.class, taskOid, TaskType.F_EXECUTION_STATUS, prismContext, TaskExecutionStatusType.RUNNABLE); taskDelta.addModificationReplaceProperty(TaskType.F_RESULT_STATUS); taskDelta.addModificationReplaceProperty(TaskType.F_RESULT); LOGGER.info("Restarting task {}", taskOid); taskManager.modifyTask(taskOid, taskDelta.getModifications(), result); } protected void setSecurityContextUser(String userOid) throws ObjectNotFoundException, SchemaException, SecurityViolationException, CommunicationException, ConfigurationException { Task task = taskManager.createTaskInstance("get administrator"); PrismObject<UserType> object = modelService.getObject(UserType.class, userOid, null, task, task.getResult()); assertNotNull("User " + userOid + " is null", object.asObjectable()); SecurityContextHolder.getContext().setAuthentication( new UsernamePasswordAuthenticationToken(new MidPointPrincipal(object.asObjectable()), null)); } protected <F extends FocusType> void assertSideEffectiveDeltasOnly(String desc, ObjectDelta<F> focusDelta) { if (focusDelta == null) { return; } int expectedModifications = 0; // There may be metadata modification, we tolerate that Collection<? extends ItemDelta<?, ?>> metadataDelta = focusDelta .findItemDeltasSubPath(new ItemPath(UserType.F_METADATA)); if (metadataDelta != null && !metadataDelta.isEmpty()) { expectedModifications += metadataDelta.size(); } if (focusDelta .findItemDelta(new ItemPath(FocusType.F_ACTIVATION, ActivationType.F_ENABLE_TIMESTAMP)) != null) { expectedModifications++; } if (focusDelta .findItemDelta(new ItemPath(FocusType.F_ACTIVATION, ActivationType.F_DISABLE_TIMESTAMP)) != null) { expectedModifications++; } if (focusDelta .findItemDelta(new ItemPath(FocusType.F_ACTIVATION, ActivationType.F_ARCHIVE_TIMESTAMP)) != null) { expectedModifications++; } PropertyDelta<ActivationStatusType> effectiveStatusDelta = focusDelta .findPropertyDelta(new ItemPath(UserType.F_ACTIVATION, ActivationType.F_EFFECTIVE_STATUS)); if (effectiveStatusDelta != null) { expectedModifications++; } if (focusDelta.findItemDelta(new ItemPath(FocusType.F_ITERATION)) != null) { expectedModifications++; } if (focusDelta.findItemDelta(new ItemPath(FocusType.F_ROLE_MEMBERSHIP_REF)) != null) { expectedModifications++; } if (focusDelta.findItemDelta(new ItemPath(FocusType.F_ITERATION_TOKEN)) != null) { expectedModifications++; } assertEquals("Unexpected modifications in " + desc + ": " + focusDelta, expectedModifications, focusDelta.getModifications().size()); } protected <F extends FocusType> void assertSideEffectiveDeltasOnly(ObjectDelta<F> focusDelta, String desc, ActivationStatusType expectedEfficientActivation) { assertEffectualDeltas(focusDelta, desc, expectedEfficientActivation, 0); } protected <F extends FocusType> void assertEffectualDeltas(ObjectDelta<F> focusDelta, String desc, ActivationStatusType expectedEfficientActivation, int expectedEffectualModifications) { if (focusDelta == null) { return; } int expectedModifications = expectedEffectualModifications; // There may be metadata modification, we tolerate that for (ItemDelta<?, ?> modification : focusDelta.getModifications()) { if (modification.getPath().containsName(ObjectType.F_METADATA)) { expectedModifications++; } } if (focusDelta .findItemDelta(new ItemPath(FocusType.F_ACTIVATION, ActivationType.F_ENABLE_TIMESTAMP)) != null) { expectedModifications++; } if (focusDelta .findItemDelta(new ItemPath(FocusType.F_ACTIVATION, ActivationType.F_DISABLE_TIMESTAMP)) != null) { expectedModifications++; } if (focusDelta .findItemDelta(new ItemPath(FocusType.F_ACTIVATION, ActivationType.F_ARCHIVE_TIMESTAMP)) != null) { expectedModifications++; } PropertyDelta<ActivationStatusType> effectiveStatusDelta = focusDelta .findPropertyDelta(new ItemPath(UserType.F_ACTIVATION, ActivationType.F_EFFECTIVE_STATUS)); if (effectiveStatusDelta != null) { expectedModifications++; PrismAsserts.assertReplace(effectiveStatusDelta, expectedEfficientActivation); } if (focusDelta.findItemDelta(new ItemPath(FocusType.F_ROLE_MEMBERSHIP_REF)) != null) { expectedModifications++; } if (focusDelta.findItemDelta(new ItemPath(FocusType.F_ITERATION)) != null) { expectedModifications++; } if (focusDelta.findItemDelta(new ItemPath(FocusType.F_ITERATION_TOKEN)) != null) { expectedModifications++; } assertEquals("Unexpected modifications in " + desc + ": " + focusDelta, expectedModifications, focusDelta.getModifications().size()); } protected void assertValidFrom(PrismObject<? extends ObjectType> obj, Date expectedDate) { assertEquals("Wrong validFrom in " + obj, XmlTypeConverter.createXMLGregorianCalendar(expectedDate), getActivation(obj).getValidFrom()); } protected void assertValidTo(PrismObject<? extends ObjectType> obj, Date expectedDate) { assertEquals("Wrong validTo in " + obj, XmlTypeConverter.createXMLGregorianCalendar(expectedDate), getActivation(obj).getValidTo()); } private ActivationType getActivation(PrismObject<? extends ObjectType> obj) { ObjectType objectType = obj.asObjectable(); ActivationType activation; if (objectType instanceof ShadowType) { activation = ((ShadowType) objectType).getActivation(); } else if (objectType instanceof UserType) { activation = ((UserType) objectType).getActivation(); } else { throw new IllegalArgumentException("Cannot get activation from " + obj); } assertNotNull("No activation in " + obj, activation); return activation; } protected PrismObject<TaskType> getTask(String taskOid) throws ObjectNotFoundException, SchemaException, SecurityViolationException, CommunicationException, ConfigurationException { Task task = taskManager.createTaskInstance(AbstractModelIntegrationTest.class.getName() + ".getTask"); OperationResult result = task.getResult(); PrismObject<TaskType> retTask = modelService.getObject(TaskType.class, taskOid, null, task, result); result.computeStatus(); TestUtil.assertSuccess("getObject(Task) result not success", result); return retTask; } protected <O extends ObjectType> PrismObject<O> getObject(Class<O> type, String oid) throws ObjectNotFoundException, SchemaException, SecurityViolationException, CommunicationException, ConfigurationException { Task task = taskManager.createTaskInstance(AbstractModelIntegrationTest.class.getName() + ".getObject"); OperationResult result = task.getResult(); PrismObject<O> object = modelService.getObject(type, oid, null, task, result); result.computeStatus(); TestUtil.assertSuccess(result); return object; } protected <O extends ObjectType> void addObjects(File... files) throws ObjectAlreadyExistsException, ObjectNotFoundException, SchemaException, ExpressionEvaluationException, CommunicationException, ConfigurationException, PolicyViolationException, SecurityViolationException, IOException { for (File file : files) { addObject(file); } } protected <O extends ObjectType> void addObject(File file) throws ObjectAlreadyExistsException, ObjectNotFoundException, SchemaException, ExpressionEvaluationException, CommunicationException, ConfigurationException, PolicyViolationException, SecurityViolationException, IOException { PrismObject<O> object = PrismTestUtil.parseObject(file); addObject(object); } protected <O extends ObjectType> void addObject(File file, Task task, OperationResult result) throws ObjectAlreadyExistsException, ObjectNotFoundException, SchemaException, ExpressionEvaluationException, CommunicationException, ConfigurationException, PolicyViolationException, SecurityViolationException, IOException { PrismObject<O> object = PrismTestUtil.parseObject(file); addObject(object, task, result); } protected <O extends ObjectType> void addObject(PrismObject<O> object) throws ObjectAlreadyExistsException, ObjectNotFoundException, SchemaException, ExpressionEvaluationException, CommunicationException, ConfigurationException, PolicyViolationException, SecurityViolationException { Task task = taskManager.createTaskInstance(AbstractModelIntegrationTest.class.getName() + ".addObject"); OperationResult result = task.getResult(); addObject(object, task, result); result.computeStatus(); TestUtil.assertSuccess(result); } protected <O extends ObjectType> void addObject(PrismObject<O> object, Task task, OperationResult result) throws ObjectAlreadyExistsException, ObjectNotFoundException, SchemaException, ExpressionEvaluationException, CommunicationException, ConfigurationException, PolicyViolationException, SecurityViolationException { ObjectDelta<O> addDelta = object.createAddDelta(); modelService.executeChanges(MiscSchemaUtil.createCollection(addDelta), null, task, result); object.setOid(addDelta.getOid()); } protected <O extends ObjectType> void deleteObject(Class<O> type, String oid, Task task, OperationResult result) throws ObjectAlreadyExistsException, ObjectNotFoundException, SchemaException, ExpressionEvaluationException, CommunicationException, ConfigurationException, PolicyViolationException, SecurityViolationException { ObjectDelta<O> delta = ObjectDelta.createDeleteDelta(type, oid, prismContext); modelService.executeChanges(MiscSchemaUtil.createCollection(delta), null, task, result); } protected void addTrigger(String oid, XMLGregorianCalendar timestamp, String uri) throws SchemaException, ObjectAlreadyExistsException, ObjectNotFoundException, ExpressionEvaluationException, CommunicationException, ConfigurationException, PolicyViolationException, SecurityViolationException { Task task = taskManager.createTaskInstance(AbstractModelIntegrationTest.class.getName() + ".addTrigger"); OperationResult result = task.getResult(); TriggerType triggerType = new TriggerType(); triggerType.setTimestamp(timestamp); triggerType.setHandlerUri(uri); ObjectDelta<ObjectType> delta = ObjectDelta.createModificationAddContainer(ObjectType.class, oid, new ItemPath(ObjectType.F_TRIGGER), prismContext, triggerType); modelService.executeChanges(MiscSchemaUtil.createCollection(delta), null, task, result); result.computeStatus(); TestUtil.assertSuccess(result); } protected <O extends ObjectType> void assertTrigger(PrismObject<O> object, String handlerUri, XMLGregorianCalendar start, XMLGregorianCalendar end) throws ObjectNotFoundException, SchemaException { for (TriggerType trigger : object.asObjectable().getTrigger()) { if (handlerUri.equals(trigger.getHandlerUri()) && MiscUtil.isBetween(trigger.getTimestamp(), start, end)) { return; } } AssertJUnit.fail("Expected that " + object + " will have a trigger but it has not"); } protected <O extends ObjectType> void assertTrigger(PrismObject<O> object, String handlerUri, XMLGregorianCalendar mid, long tolerance) throws ObjectNotFoundException, SchemaException { XMLGregorianCalendar start = XmlTypeConverter.addMillis(mid, -tolerance); XMLGregorianCalendar end = XmlTypeConverter.addMillis(mid, tolerance); for (TriggerType trigger : object.asObjectable().getTrigger()) { if (handlerUri.equals(trigger.getHandlerUri()) && MiscUtil.isBetween(trigger.getTimestamp(), start, end)) { return; } } AssertJUnit.fail("Expected that " + object + " will have a trigger but it has not"); } protected <O extends ObjectType> void assertNoTrigger(Class<O> type, String oid) throws ObjectNotFoundException, SchemaException { OperationResult result = new OperationResult( AbstractModelIntegrationTest.class.getName() + ".assertNoTrigger"); PrismObject<O> object = repositoryService.getObject(type, oid, null, result); result.computeStatus(); TestUtil.assertSuccess(result); assertNoTrigger(object); } protected <O extends ObjectType> void assertNoTrigger(PrismObject<O> object) throws ObjectNotFoundException, SchemaException { List<TriggerType> triggers = object.asObjectable().getTrigger(); if (triggers != null && !triggers.isEmpty()) { AssertJUnit.fail("Expected that " + object + " will have no triggers but it has " + triggers.size() + " trigger: " + triggers); } } protected void prepareNotifications() { notificationManager.setDisabled(false); dummyTransport.clearMessages(); } protected void checkDummyTransportMessages(String name, int expectedCount) { List<Message> messages = dummyTransport.getMessages("dummy:" + name); if (expectedCount == 0) { if (messages != null && !messages.isEmpty()) { LOGGER.error(messages.size() + " unexpected message(s) recorded in dummy transport '" + name + "'"); logNotifyMessages(messages); assertFalse(messages.size() + " unexpected message(s) recorded in dummy transport '" + name + "'", true); } } else { assertNotNull("No messages recorded in dummy transport '" + name + "'", messages); if (expectedCount != messages.size()) { LOGGER.error("Invalid number of messages recorded in dummy transport '" + name + "', expected: " + expectedCount + ", actual: " + messages.size()); logNotifyMessages(messages); assertEquals("Invalid number of messages recorded in dummy transport '" + name + "'", expectedCount, messages.size()); } } } private void logNotifyMessages(List<Message> messages) { for (Message message : messages) { LOGGER.debug("Notification message:\n{}", message.getBody()); } } protected void checkDummyTransportMessagesAtLeast(String name, int expectedCount) { if (expectedCount == 0) { return; } List<Message> messages = dummyTransport.getMessages("dummy:" + name); assertNotNull("No messages recorded in dummy transport '" + name + "'", messages); assertTrue("Number of messages recorded in dummy transport '" + name + "' (" + messages.size() + ") is not at least " + expectedCount, messages.size() >= expectedCount); } protected DummyAccount getDummyAccount(String dummyInstanceName, String username) { DummyResource dummyResource = DummyResource.getInstance(dummyInstanceName); try { return dummyResource.getAccountByUsername(username); } catch (ConnectException e) { throw new IllegalStateException(e.getMessage(), e); } catch (FileNotFoundException e) { throw new IllegalStateException(e.getMessage(), e); } } protected DummyAccount getDummyAccountById(String dummyInstanceName, String id) { DummyResource dummyResource = DummyResource.getInstance(dummyInstanceName); try { return dummyResource.getAccountById(id); } catch (ConnectException e) { throw new IllegalStateException(e.getMessage(), e); } catch (FileNotFoundException e) { throw new IllegalStateException(e.getMessage(), e); } } protected void assertDefaultDummyAccount(String username, String fullname, boolean active) { assertDummyAccount(null, username, fullname, active); } protected DummyAccount assertDummyAccount(String dummyInstanceName, String username, String fullname, boolean active) { DummyAccount account = getDummyAccount(dummyInstanceName, username); assertNotNull("No dummy(" + dummyInstanceName + ") account for username " + username, account); assertEquals("Wrong fullname for dummy(" + dummyInstanceName + ") account " + username, fullname, account.getAttributeValue("fullname")); assertEquals("Wrong activation for dummy(" + dummyInstanceName + ") account " + username, active, account.isEnabled()); return account; } protected void assertDummyAccount(String dummyInstanceName, String username) { DummyAccount account = getDummyAccount(dummyInstanceName, username); assertNotNull("No dummy(" + dummyInstanceName + ") account for username " + username, account); } protected void assertDummyAccountById(String dummyInstanceName, String id) { DummyAccount account = getDummyAccountById(dummyInstanceName, id); assertNotNull("No dummy(" + dummyInstanceName + ") account for id " + id, account); } protected void assertNoDummyAccountById(String dummyInstanceName, String id) { DummyAccount account = getDummyAccountById(dummyInstanceName, id); assertNull("Dummy(" + dummyInstanceName + ") account for id " + id + " exists while not expecting it", account); } protected void assertDummyAccountActivation(String dummyInstanceName, String username, boolean active) { DummyAccount account = getDummyAccount(dummyInstanceName, username); assertNotNull("No dummy(" + dummyInstanceName + ") account for username " + username, account); assertEquals("Wrong activation for dummy(" + dummyInstanceName + ") account " + username, active, account.isEnabled()); } protected void assertNoDummyAccount(String username) { assertNoDummyAccount(null, username); } protected void assertNoDummyAccount(String dummyInstanceName, String username) { DummyAccount account = getDummyAccount(dummyInstanceName, username); assertNull("Dummy account for username " + username + " exists while not expecting it (" + dummyInstanceName + ")", account); } protected void assertDefaultDummyAccountAttribute(String username, String attributeName, Object... expectedAttributeValues) { assertDummyAccountAttribute(null, username, attributeName, expectedAttributeValues); } protected void assertDummyAccountAttribute(String dummyInstanceName, String username, String attributeName, Object... expectedAttributeValues) { DummyAccount account = getDummyAccount(dummyInstanceName, username); assertNotNull("No dummy account for username " + username, account); Set<Object> values = account.getAttributeValues(attributeName, Object.class); if ((values == null || values.isEmpty()) && (expectedAttributeValues == null || expectedAttributeValues.length == 0)) { return; } assertNotNull("No values for attribute " + attributeName + " of " + dummyInstanceName + " dummy account " + username, values); assertEquals( "Unexpected number of values for attribute " + attributeName + " of dummy account " + username + ". Expected: " + Arrays.toString(expectedAttributeValues) + ", was: " + values, expectedAttributeValues.length, values.size()); for (Object expectedValue : expectedAttributeValues) { if (!values.contains(expectedValue)) { AssertJUnit.fail("Value '" + expectedValue + "' expected in attribute " + attributeName + " of dummy account " + username + " but not found. Values found: " + values); } } } protected void assertNoDummyAccountAttribute(String dummyInstanceName, String username, String attributeName) { DummyAccount account = getDummyAccount(dummyInstanceName, username); assertNotNull("No dummy account for username " + username, account); Set<Object> values = account.getAttributeValues(attributeName, Object.class); if (values == null || values.isEmpty()) { return; } AssertJUnit.fail("Expected no value in attribute " + attributeName + " of dummy account " + username + ". Values found: " + values); } protected void assertDummyAccountAttributeGenerated(String dummyInstanceName, String username) { DummyAccount account = getDummyAccount(dummyInstanceName, username); assertNotNull("No dummy account for username " + username, account); Integer generated = account.getAttributeValue(DummyAccount.ATTR_INTERNAL_ID, Integer.class); if (generated == null) { AssertJUnit.fail( "No value in generated attribute dir of " + dummyInstanceName + " dummy account " + username); } } protected DummyGroup getDummyGroup(String dummyInstanceName, String name) { DummyResource dummyResource = DummyResource.getInstance(dummyInstanceName); try { return dummyResource.getGroupByName(name); } catch (ConnectException e) { throw new IllegalStateException(e.getMessage(), e); } catch (FileNotFoundException e) { throw new IllegalStateException(e.getMessage(), e); } } protected void assertDummyGroup(String username, String description) { assertDummyGroup(null, username, description, null); } protected void assertDummyGroup(String username, String description, Boolean active) { assertDummyGroup(null, username, description, active); } protected void assertDummyGroup(String dummyInstanceName, String groupname, String description, Boolean active) { DummyGroup group = getDummyGroup(dummyInstanceName, groupname); assertNotNull("No dummy(" + dummyInstanceName + ") group for name " + groupname, group); assertEquals("Wrong fullname for dummy(" + dummyInstanceName + ") group " + groupname, description, group.getAttributeValue(DummyResourceContoller.DUMMY_GROUP_ATTRIBUTE_DESCRIPTION)); if (active != null) { assertEquals("Wrong activation for dummy(" + dummyInstanceName + ") group " + groupname, (boolean) active, group.isEnabled()); } } protected void assertNoDummyGroup(String groupname) { assertNoDummyGroup(null, groupname); } protected void assertNoDummyGroup(String dummyInstanceName, String groupname) { DummyGroup group = getDummyGroup(dummyInstanceName, groupname); assertNull("Dummy group '" + groupname + "' exists while not expecting it (" + dummyInstanceName + ")", group); } protected void assertDummyGroupAttribute(String dummyInstanceName, String groupname, String attributeName, Object... expectedAttributeValues) { DummyGroup group = getDummyGroup(dummyInstanceName, groupname); assertNotNull("No dummy group for groupname " + groupname, group); Set<Object> values = group.getAttributeValues(attributeName, Object.class); if ((values == null || values.isEmpty()) && (expectedAttributeValues == null || expectedAttributeValues.length == 0)) { return; } assertNotNull("No values for attribute " + attributeName + " of " + dummyInstanceName + " dummy group " + groupname, values); assertEquals("Unexpected number of values for attribute " + attributeName + " of dummy group " + groupname + ": " + values, expectedAttributeValues.length, values.size()); for (Object expectedValue : expectedAttributeValues) { if (!values.contains(expectedValue)) { AssertJUnit.fail("Value '" + expectedValue + "' expected in attribute " + attributeName + " of dummy group " + groupname + " but not found. Values found: " + values); } } } protected void assertDummyGroupMember(String dummyInstanceName, String dummyGroupName, String accountId) throws ConnectException, FileNotFoundException { DummyResource dummyResource = DummyResource.getInstance(dummyInstanceName); DummyGroup group = dummyResource.getGroupByName(dummyGroupName); IntegrationTestTools.assertGroupMember(group, accountId); } protected void assertDefaultDummyGroupMember(String dummyGroupName, String accountId) throws ConnectException, FileNotFoundException { assertDummyGroupMember(null, dummyGroupName, accountId); } protected void assertNoDummyGroupMember(String dummyInstanceName, String dummyGroupName, String accountId) throws ConnectException, FileNotFoundException { DummyResource dummyResource = DummyResource.getInstance(dummyInstanceName); DummyGroup group = dummyResource.getGroupByName(dummyGroupName); IntegrationTestTools.assertNoGroupMember(group, accountId); } protected void assertNoDefaultDummyGroupMember(String dummyGroupName, String accountId) throws ConnectException, FileNotFoundException { assertNoDummyGroupMember(null, dummyGroupName, accountId); } protected void assertDummyAccountNoAttribute(String dummyInstanceName, String username, String attributeName) { DummyAccount account = getDummyAccount(dummyInstanceName, username); assertNotNull("No dummy account for username " + username, account); Set<Object> values = account.getAttributeValues(attributeName, Object.class); assertTrue("Unexpected values for attribute " + attributeName + " of dummy account " + username + ": " + values, values == null || values.isEmpty()); } protected Entry assertOpenDjAccount(String uid, String cn, Boolean active) throws DirectoryException { Entry entry = openDJController.searchByUid(uid); assertNotNull("OpenDJ accoun with uid " + uid + " not found", entry); openDJController.assertAttribute(entry, "cn", cn); if (active != null) { openDJController.assertActive(entry, active); } return entry; } protected void assertNoOpenDjAccount(String uid) throws DirectoryException { Entry entry = openDJController.searchByUid(uid); assertNull("Expected that OpenDJ account with uid " + uid + " will be gone, but it is still there", entry); } protected void assertIteration(PrismObject<ShadowType> shadow, Integer expectedIteration, String expectedIterationToken) { PrismAsserts.assertPropertyValue(shadow, ShadowType.F_ITERATION, expectedIteration); PrismAsserts.assertPropertyValue(shadow, ShadowType.F_ITERATION_TOKEN, expectedIterationToken); } protected void assertIterationDelta(ObjectDelta<ShadowType> shadowDelta, Integer expectedIteration, String expectedIterationToken) { PrismAsserts.assertPropertyReplace(shadowDelta, ShadowType.F_ITERATION, expectedIteration); PrismAsserts.assertPropertyReplace(shadowDelta, ShadowType.F_ITERATION_TOKEN, expectedIterationToken); } protected void assertSituation(PrismObject<ShadowType> shadow, SynchronizationSituationType expectedSituation) { if (expectedSituation == null) { PrismAsserts.assertNoItem(shadow, ShadowType.F_SYNCHRONIZATION_SITUATION); } else { PrismAsserts.assertPropertyValue(shadow, ShadowType.F_SYNCHRONIZATION_SITUATION, expectedSituation); } } protected void assertEnableTimestampFocus(PrismObject<? extends FocusType> focus, XMLGregorianCalendar startTime, XMLGregorianCalendar endTime) { XMLGregorianCalendar userDisableTimestamp = focus.asObjectable().getActivation().getEnableTimestamp(); TestUtil.assertBetween("Wrong user enableTimestamp in " + focus, startTime, endTime, userDisableTimestamp); } protected void assertDisableTimestampFocus(PrismObject<? extends FocusType> focus, XMLGregorianCalendar startTime, XMLGregorianCalendar endTime) { XMLGregorianCalendar userDisableTimestamp = focus.asObjectable().getActivation().getDisableTimestamp(); TestUtil.assertBetween("Wrong user disableTimestamp in " + focus, startTime, endTime, userDisableTimestamp); } protected void assertEnableTimestampShadow(PrismObject<? extends ShadowType> shadow, XMLGregorianCalendar startTime, XMLGregorianCalendar endTime) { ActivationType activationType = shadow.asObjectable().getActivation(); assertNotNull("No activation in " + shadow, activationType); XMLGregorianCalendar userDisableTimestamp = activationType.getEnableTimestamp(); TestUtil.assertBetween("Wrong shadow enableTimestamp in " + shadow, startTime, endTime, userDisableTimestamp); } protected void assertDisableTimestampShadow(PrismObject<? extends ShadowType> shadow, XMLGregorianCalendar startTime, XMLGregorianCalendar endTime) { XMLGregorianCalendar userDisableTimestamp = shadow.asObjectable().getActivation().getDisableTimestamp(); TestUtil.assertBetween("Wrong shadow disableTimestamp in " + shadow, startTime, endTime, userDisableTimestamp); } protected void assertDisableReasonShadow(PrismObject<? extends ShadowType> shadow, String expectedReason) { String disableReason = shadow.asObjectable().getActivation().getDisableReason(); assertEquals("Wrong shadow disableReason in " + shadow, expectedReason, disableReason); } protected void assertPassword(PrismObject<UserType> user, String expectedPassword) throws EncryptionException { CredentialsType credentialsType = user.asObjectable().getCredentials(); assertNotNull("No credentials in " + user, credentialsType); PasswordType passwordType = credentialsType.getPassword(); assertNotNull("No password in " + user, passwordType); ProtectedStringType protectedStringType = passwordType.getValue(); assertNotNull("No password value in " + user, protectedStringType); String decryptedUserPassword = protector.decryptString(protectedStringType); assertEquals("Wrong password in " + user, expectedPassword, decryptedUserPassword); } protected void assertUserLdapPassword(PrismObject<UserType> user, String expectedPassword) throws EncryptionException { CredentialsType credentialsType = user.asObjectable().getCredentials(); assertNotNull("No credentials in " + user, credentialsType); PasswordType passwordType = credentialsType.getPassword(); assertNotNull("No password in " + user, passwordType); ProtectedStringType protectedStringType = passwordType.getValue(); assertLdapPassword(protectedStringType, expectedPassword, user); } protected void assertShadowLdapPassword(PrismObject<ShadowType> shadow, String expectedPassword) throws EncryptionException { CredentialsType credentialsType = shadow.asObjectable().getCredentials(); assertNotNull("No credentials in " + shadow, credentialsType); PasswordType passwordType = credentialsType.getPassword(); assertNotNull("No password in " + shadow, passwordType); ProtectedStringType protectedStringType = passwordType.getValue(); assertLdapPassword(protectedStringType, expectedPassword, shadow); } protected <O extends ObjectType> void assertLdapPassword(ProtectedStringType protectedStringType, String expectedPassword, PrismObject<O> source) throws EncryptionException { assertNotNull("No password value in " + source, protectedStringType); String decryptedUserPassword = protector.decryptString(protectedStringType); assertNotNull("Null password in " + source, decryptedUserPassword); if (decryptedUserPassword.startsWith("{") || decryptedUserPassword.contains("}")) { assertTrue( "Wrong password hash in " + source + ": " + decryptedUserPassword + ", expected " + expectedPassword, ldapShaPasswordEncoder.isPasswordValid(decryptedUserPassword, expectedPassword, null)); } else { assertEquals("Wrong password in " + source, expectedPassword, decryptedUserPassword); } } protected void assertGroupMember(DummyGroup group, String accountId) { IntegrationTestTools.assertGroupMember(group, accountId); } protected void assertNoGroupMember(DummyGroup group, String accountId) { IntegrationTestTools.assertNoGroupMember(group, accountId); } protected void assertNoGroupMembers(DummyGroup group) { IntegrationTestTools.assertNoGroupMembers(group); } protected void login(String principalName) throws ObjectNotFoundException { MidPointPrincipal principal = userProfileService.getPrincipal(principalName); login(principal); } protected void login(PrismObject<UserType> user) { MidPointPrincipal principal = userProfileService.getPrincipal(user); login(principal); } protected void login(MidPointPrincipal principal) { SecurityContext securityContext = SecurityContextHolder.getContext(); Authentication authentication = new UsernamePasswordAuthenticationToken(principal, null); securityContext.setAuthentication(authentication); } protected void loginSuperUser(String principalName) throws SchemaException, ObjectNotFoundException { MidPointPrincipal principal = userProfileService.getPrincipal(principalName); loginSuperUser(principal); } protected void loginSuperUser(PrismObject<UserType> user) throws SchemaException { MidPointPrincipal principal = userProfileService.getPrincipal(user); loginSuperUser(principal); } protected void loginSuperUser(MidPointPrincipal principal) throws SchemaException { AuthorizationType superAutzType = new AuthorizationType(); prismContext.adopt(superAutzType, RoleType.class, new ItemPath(RoleType.F_AUTHORIZATION)); superAutzType.getAction().add(AuthorizationConstants.AUTZ_ALL_URL); Authorization superAutz = new Authorization(superAutzType); Collection<Authorization> authorities = principal.getAuthorities(); authorities.add(superAutz); SecurityContext securityContext = SecurityContextHolder.getContext(); Authentication authentication = new UsernamePasswordAuthenticationToken(principal, null); securityContext.setAuthentication(authentication); } protected void assertLoggedInUser(String username) { SecurityContext securityContext = SecurityContextHolder.getContext(); Authentication authentication = securityContext.getAuthentication(); if (authentication == null) { if (username == null) { return; } else { AssertJUnit.fail("Expected logged in user '" + username + "' but there was no authentication in the spring security context"); } } Object principal = authentication.getPrincipal(); if (principal == null) { if (username == null) { return; } else { AssertJUnit.fail("Expected logged in user '" + username + "' but there was no principal in the spring security context"); } } if (principal instanceof MidPointPrincipal) { MidPointPrincipal midPointPrincipal = (MidPointPrincipal) principal; UserType user = midPointPrincipal.getUser(); if (user == null) { if (username == null) { return; } else { AssertJUnit.fail("Expected logged in user '" + username + "' but there was no user in the spring security context"); } } assertEquals("Wrong logged-in user", username, user.getName().getOrig()); } else { AssertJUnit.fail("Expected logged in user '" + username + "' but there was unknown principal in the spring security context: " + principal); } } protected void resetAuthentication() { SecurityContext securityContext = SecurityContextHolder.getContext(); securityContext.setAuthentication(null); } protected void assertNoAuthentication() { SecurityContext securityContext = SecurityContextHolder.getContext(); assertNull("Unexpected authentication", securityContext.getAuthentication()); } protected void displayAllUsers() throws SchemaException, ObjectNotFoundException, CommunicationException, ConfigurationException, SecurityViolationException { Task task = taskManager .createTaskInstance(AbstractModelIntegrationTest.class.getName() + ".displayAllUsers"); OperationResult result = task.getResult(); ResultHandler<UserType> handler = new ResultHandler<UserType>() { @Override public boolean handle(PrismObject<UserType> object, OperationResult parentResult) { display("User", object); return true; } }; modelService.searchObjectsIterative(UserType.class, null, handler, null, task, result); result.computeStatus(); TestUtil.assertSuccess(result); } /** * Returns appropriate object synchronization settings for the class. * Assumes single sync setting for now. */ protected ObjectSynchronizationType determineSynchronization(ResourceType resource, Class<UserType> type, String name) { SynchronizationType synchronization = resource.getSynchronization(); if (synchronization == null) { return null; } List<ObjectSynchronizationType> objectSynchronizations = synchronization.getObjectSynchronization(); if (objectSynchronizations.isEmpty()) { return null; } for (ObjectSynchronizationType objSyncType : objectSynchronizations) { QName focusTypeQName = objSyncType.getFocusType(); if (focusTypeQName == null) { if (type != UserType.class) { continue; } } else { ObjectTypes focusType = ObjectTypes.getObjectTypeFromTypeQName(focusTypeQName); if (type != focusType.getClassDefinition()) { continue; } } if (name == null) { // we got it return objSyncType; } else { if (name.equals(objSyncType.getName())) { return objSyncType; } } } throw new IllegalArgumentException( "Synchronization setting for " + type + " and name " + name + " not found in " + resource); } protected void assertShadowKindIntent(String shadowOid, ShadowKindType expectedKind, String expectedIntent) throws ObjectNotFoundException, SchemaException { OperationResult result = new OperationResult( AbstractIntegrationTest.class.getName() + ".assertShadowKindIntent"); PrismObject<ShadowType> shadow = repositoryService.getObject(ShadowType.class, shadowOid, null, result); result.computeStatus(); TestUtil.assertSuccess(result); assertShadowKindIntent(shadow, expectedKind, expectedIntent); } protected void assertShadowKindIntent(PrismObject<ShadowType> shadow, ShadowKindType expectedKind, String expectedIntent) { assertEquals("Wrong kind in " + shadow, expectedKind, shadow.asObjectable().getKind()); assertEquals("Wrong intent in " + shadow, expectedIntent, shadow.asObjectable().getIntent()); } protected Task createTask(String operationName) { if (!operationName.contains(".")) { operationName = this.getClass().getName() + "." + operationName; } Task task = taskManager.createTaskInstance(operationName); task.setChannel(SchemaConstants.CHANNEL_GUI_USER_URI); return task; } protected void modifyRoleAddConstruction(String roleOid, long inducementId, String resourceOid) throws SchemaException, ObjectAlreadyExistsException, ObjectNotFoundException, ExpressionEvaluationException, CommunicationException, ConfigurationException, PolicyViolationException, SecurityViolationException { Task task = createTask(AbstractModelIntegrationTest.class.getName() + ".modifyRoleAddConstruction"); OperationResult result = task.getResult(); ConstructionType construction = new ConstructionType(); ObjectReferenceType resourceRedRef = new ObjectReferenceType(); resourceRedRef.setOid(resourceOid); construction.setResourceRef(resourceRedRef); ObjectDelta<RoleType> roleDelta = ObjectDelta.createModificationAddContainer(RoleType.class, roleOid, new ItemPath(new NameItemPathSegment(RoleType.F_INDUCEMENT), new IdItemPathSegment(inducementId), new NameItemPathSegment(AssignmentType.F_CONSTRUCTION)), prismContext, construction); modelService.executeChanges(MiscSchemaUtil.createCollection(roleDelta), null, task, result); result.computeStatus(); TestUtil.assertSuccess(result); } protected void modifyRoleAddInducementTarget(String roleOid, String targetOid, boolean reconcileAffected, Task task) throws SchemaException, ObjectAlreadyExistsException, ObjectNotFoundException, ExpressionEvaluationException, CommunicationException, ConfigurationException, PolicyViolationException, SecurityViolationException { if (task == null) { task = createTask(AbstractModelIntegrationTest.class.getName() + ".modifyRoleAddInducementTarget"); } OperationResult result = task.getResult(); AssignmentType inducement = new AssignmentType(); ObjectReferenceType targetRef = new ObjectReferenceType(); targetRef.setOid(targetOid); inducement.setTargetRef(targetRef); ObjectDelta<RoleType> roleDelta = ObjectDelta.createModificationAddContainer(RoleType.class, roleOid, new ItemPath(new NameItemPathSegment(RoleType.F_INDUCEMENT)), prismContext, inducement); ModelExecuteOptions options = new ModelExecuteOptions(); options.setReconcileAffected(reconcileAffected); modelService.executeChanges(MiscSchemaUtil.createCollection(roleDelta), options, task, result); result.computeStatus(); if (reconcileAffected) { TestUtil.assertInProgressOrSuccess(result); } else { TestUtil.assertSuccess(result); } } protected AssignmentType findInducementByTarget(String roleOid, String targetOid) throws SchemaException, ObjectAlreadyExistsException, ObjectNotFoundException, ExpressionEvaluationException, CommunicationException, ConfigurationException, PolicyViolationException, SecurityViolationException { Task task = createTask(AbstractModelIntegrationTest.class.getName() + ".findInducementByTarget"); OperationResult result = task.getResult(); PrismObject<RoleType> role = modelService.getObject(RoleType.class, roleOid, null, task, result); for (AssignmentType inducement : role.asObjectable().getInducement()) { ObjectReferenceType targetRef = inducement.getTargetRef(); if (targetRef != null && targetOid.equals(targetRef.getOid())) { return inducement; } } return null; } protected void modifyRoleDeleteInducementTarget(String roleOid, String targetOid) throws SchemaException, ObjectAlreadyExistsException, ObjectNotFoundException, ExpressionEvaluationException, CommunicationException, ConfigurationException, PolicyViolationException, SecurityViolationException { Task task = createTask(AbstractModelIntegrationTest.class.getName() + ".modifyRoleDeleteInducementTarget"); OperationResult result = task.getResult(); AssignmentType inducement = findInducementByTarget(roleOid, targetOid); ObjectDelta<RoleType> roleDelta = ObjectDelta.createModificationDeleteContainer(RoleType.class, roleOid, new ItemPath(new NameItemPathSegment(RoleType.F_INDUCEMENT)), prismContext, inducement.asPrismContainerValue().clone()); modelService.executeChanges(MiscSchemaUtil.createCollection(roleDelta), null, task, result); result.computeStatus(); TestUtil.assertSuccess(result); } protected void modifyRoleDeleteInducement(String roleOid, long inducementId, boolean reconcileAffected, Task task) throws SchemaException, ObjectAlreadyExistsException, ObjectNotFoundException, ExpressionEvaluationException, CommunicationException, ConfigurationException, PolicyViolationException, SecurityViolationException { if (task == null) { task = createTask(AbstractModelIntegrationTest.class.getName() + ".modifyRoleDeleteInducement"); } OperationResult result = task.getResult(); AssignmentType inducement = new AssignmentType(); inducement.setId(inducementId); ObjectDelta<RoleType> roleDelta = ObjectDelta.createModificationDeleteContainer(RoleType.class, roleOid, RoleType.F_INDUCEMENT, prismContext, inducement); ModelExecuteOptions options = new ModelExecuteOptions(); options.setReconcileAffected(reconcileAffected); modelService.executeChanges(MiscSchemaUtil.createCollection(roleDelta), options, task, result); result.computeStatus(); if (reconcileAffected) { TestUtil.assertInProgressOrSuccess(result); } else { TestUtil.assertSuccess(result); } } protected void modifyUserAddAccount(String userOid, File accountFile, Task task, OperationResult result) throws SchemaException, IOException, ObjectAlreadyExistsException, ObjectNotFoundException, ExpressionEvaluationException, CommunicationException, ConfigurationException, PolicyViolationException, SecurityViolationException { PrismObject<ShadowType> account = PrismTestUtil.parseObject(accountFile); ObjectDelta<UserType> userDelta = ObjectDelta.createEmptyModifyDelta(UserType.class, userOid, prismContext); PrismReferenceValue accountRefVal = new PrismReferenceValue(); accountRefVal.setObject(account); ReferenceDelta accountDelta = ReferenceDelta.createModificationAdd(UserType.F_LINK_REF, getUserDefinition(), accountRefVal); userDelta.addModification(accountDelta); Collection<ObjectDelta<? extends ObjectType>> deltas = (Collection) MiscUtil.createCollection(userDelta); modelService.executeChanges(deltas, null, task, result); } protected void assertAuthorized(MidPointPrincipal principal, String action) throws SchemaException { assertAuthorized(principal, action, null); assertAuthorized(principal, action, AuthorizationPhaseType.REQUEST); assertAuthorized(principal, action, AuthorizationPhaseType.EXECUTION); } protected void assertAuthorized(MidPointPrincipal principal, String action, AuthorizationPhaseType phase) throws SchemaException { SecurityContext origContext = SecurityContextHolder.getContext(); createSecurityContext(principal); try { assertTrue("AuthorizationEvaluator.isAuthorized: Principal " + principal + " NOT authorized for action " + action, securityEnforcer.isAuthorized(action, phase, null, null, null, null)); if (phase == null) { securityEnforcer.decide(SecurityContextHolder.getContext().getAuthentication(), createSecureObject(), createConfigAttributes(action)); } } finally { SecurityContextHolder.setContext(origContext); } } protected void assertNotAuthorized(MidPointPrincipal principal, String action) throws SchemaException { assertNotAuthorized(principal, action, null); assertNotAuthorized(principal, action, AuthorizationPhaseType.REQUEST); assertNotAuthorized(principal, action, AuthorizationPhaseType.EXECUTION); } protected void assertNotAuthorized(MidPointPrincipal principal, String action, AuthorizationPhaseType phase) throws SchemaException { SecurityContext origContext = SecurityContextHolder.getContext(); createSecurityContext(principal); boolean isAuthorized = securityEnforcer.isAuthorized(action, phase, null, null, null, null); SecurityContextHolder.setContext(origContext); assertFalse("AuthorizationEvaluator.isAuthorized: Principal " + principal + " IS authorized for action " + action + " (" + phase + ") but he should not be", isAuthorized); } protected void assertAdminGuiConfigurations(MidPointPrincipal principal, int expectedMenuLinks, int expectedDashboardLinks, int expectedObjectForms) { AdminGuiConfigurationType adminGuiConfiguration = principal.getAdminGuiConfiguration(); display("Admin GUI config for " + principal.getUsername(), adminGuiConfiguration); assertAdminGuiConfigurations(adminGuiConfiguration, expectedMenuLinks, expectedDashboardLinks, expectedObjectForms); } protected void assertAdminGuiConfigurations(AdminGuiConfigurationType adminGuiConfiguration, int expectedMenuLinks, int expectedDashboardLinks, int expectedObjectForms) { assertNotNull("No admin GUI configuration", adminGuiConfiguration); assertEquals("Wrong number of menu links in", expectedMenuLinks, adminGuiConfiguration.getAdditionalMenuLink().size()); assertEquals("Wrong number of menu links in", expectedDashboardLinks, adminGuiConfiguration.getUserDashboardLink().size()); assertEquals("Wrong number of object forms in admin GUI configuration", expectedObjectForms, adminGuiConfiguration.getObjectForms().getObjectForm().size()); } protected void createSecurityContext(MidPointPrincipal principal) { SecurityContext context = new SecurityContextImpl(); Authentication authentication = new UsernamePasswordAuthenticationToken(principal, null); context.setAuthentication(authentication); SecurityContextHolder.setContext(context); } protected Object createSecureObject() { return new FilterInvocation("/midpoint", "whateverServlet", "doSomething"); } protected Collection<ConfigAttribute> createConfigAttributes(String action) { Collection<ConfigAttribute> attrs = new ArrayList<ConfigAttribute>(); attrs.add(new SecurityConfig(action)); return attrs; } protected <O extends ObjectType> PrismObjectDefinition<O> getEditObjectDefinition(PrismObject<O> object) throws SchemaException, ConfigurationException, ObjectNotFoundException { OperationResult result = new OperationResult( AbstractModelIntegrationTest.class + ".getEditObjectDefinition"); PrismObjectDefinition<O> editSchema = modelInteractionService.getEditObjectDefinition(object, null, result); result.computeStatus(); TestUtil.assertSuccess(result); return editSchema; } protected <F extends FocusType> void assertRoleTypes(PrismObject<F> focus, String... expectedRoleTypes) throws ObjectNotFoundException, SchemaException, ConfigurationException { assertRoleTypes(getAssignableRoleSpecification(focus), expectedRoleTypes); } protected <F extends FocusType> RoleSelectionSpecification getAssignableRoleSpecification(PrismObject<F> focus) throws ObjectNotFoundException, SchemaException, ConfigurationException { OperationResult result = new OperationResult( AbstractIntegrationTest.class.getName() + ".getAssignableRoleSpecification"); RoleSelectionSpecification spec = modelInteractionService.getAssignableRoleSpecification(focus, result); result.computeStatus(); TestUtil.assertSuccess(result); return spec; } protected void assertRoleTypes(RoleSelectionSpecification roleSpec, String... expectedRoleTypes) { assertNotNull("Null role spec", roleSpec); display("Role spec", roleSpec); List<? extends DisplayableValue<String>> roleTypes = roleSpec.getRoleTypes(); if ((roleTypes == null || roleTypes.isEmpty()) && expectedRoleTypes.length == 0) { return; } assertNotNull("Null roleTypes in roleSpec " + roleSpec, roleTypes); if (roleTypes.size() != expectedRoleTypes.length) { AssertJUnit.fail("Expected role types " + Arrays.toString(expectedRoleTypes) + " but got " + roleTypes); } for (String expectedRoleType : expectedRoleTypes) { boolean found = false; for (DisplayableValue<String> roleTypeDval : roleTypes) { if (expectedRoleType.equals(roleTypeDval.getValue())) { found = true; break; } } if (!found) { AssertJUnit.fail("Expected role type " + expectedRoleType + " but it was not present (got " + roleTypes + ")"); } } } protected void assertEncryptedPassword(PrismObject<UserType> user, String expectedClearPassword) throws EncryptionException { UserType userType = user.asObjectable(); ProtectedStringType protectedActualPassword = userType.getCredentials().getPassword().getValue(); String actualClearPassword = protector.decryptString(protectedActualPassword); assertEquals("Wrong password for " + user, expectedClearPassword, actualClearPassword); } protected void assertPasswordMetadata(PrismObject<UserType> user, boolean create, XMLGregorianCalendar start, XMLGregorianCalendar end, String actorOid, String channel) { PrismContainer<MetadataType> metadataContainer = user.findContainer( new ItemPath(UserType.F_CREDENTIALS, CredentialsType.F_PASSWORD, PasswordType.F_METADATA)); assertNotNull("No password metadata in " + user, metadataContainer); MetadataType metadataType = metadataContainer.getValue().asContainerable(); if (create) { ObjectReferenceType creatorRef = metadataType.getCreatorRef(); assertNotNull("No creatorRef in password metadata in " + user, creatorRef); assertEquals("Wrong creatorRef OID in password metadata in " + user, actorOid, creatorRef.getOid()); TestUtil.assertBetween("Wrong password create timestamp in password metadata in " + user, start, end, metadataType.getCreateTimestamp()); assertEquals("Wrong create channel", channel, metadataType.getCreateChannel()); } else { ObjectReferenceType modifierRef = metadataType.getModifierRef(); assertNotNull("No modifierRef in password metadata in " + user, modifierRef); assertEquals("Wrong modifierRef OID in password metadata in " + user, actorOid, modifierRef.getOid()); TestUtil.assertBetween("Wrong password modify timestamp in password metadata in " + user, start, end, metadataType.getModifyTimestamp()); assertEquals("Wrong modification channel", channel, metadataType.getModifyChannel()); } } protected void reconcileUser(String oid, Task task, OperationResult result) throws CommunicationException, ObjectAlreadyExistsException, ExpressionEvaluationException, PolicyViolationException, SchemaException, SecurityViolationException, ConfigurationException, ObjectNotFoundException { ObjectDelta<UserType> emptyDelta = ObjectDelta.createEmptyModifyDelta(UserType.class, oid, prismContext); modelService.executeChanges(MiscSchemaUtil.createCollection(emptyDelta), ModelExecuteOptions.createReconcile(), task, result); result.computeStatus(); TestUtil.assertSuccess(result); } protected void assertRefEquals(String message, ObjectReferenceType expected, ObjectReferenceType actual) { if (expected == null && actual == null) { return; } if (expected == null || actual == null) { fail(message + ": expected=" + expected + ", actual=" + actual); } PrismAsserts.assertRefEquivalent(message, expected.asReferenceValue(), actual.asReferenceValue()); } }