package com.evolveum.midpoint.testing.story; /* * Copyright (c) 2014-2016 Evolveum * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import static org.testng.AssertJUnit.assertTrue; 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 java.io.File; import java.util.Collection; import javax.xml.namespace.QName; import com.evolveum.midpoint.notifications.api.transports.Message; import org.apache.commons.io.IOUtils; import org.apache.commons.lang.StringUtils; import org.opends.server.types.DirectoryException; import org.opends.server.types.Entry; import org.opends.server.types.LDIFImportConfig; import org.opends.server.types.SearchResultEntry; import org.opends.server.util.LDIFException; import org.opends.server.util.LDIFReader; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.annotation.DirtiesContext.ClassMode; import org.springframework.test.context.ContextConfiguration; import org.testng.AssertJUnit; import org.testng.annotations.AfterClass; import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; import com.evolveum.icf.dummy.resource.DummyAccount; import com.evolveum.icf.dummy.resource.DummyObjectClass; import com.evolveum.icf.dummy.resource.DummyResource; import com.evolveum.icf.dummy.resource.DummySyncStyle; import com.evolveum.midpoint.common.refinery.RefinedObjectClassDefinition; import com.evolveum.midpoint.common.refinery.RefinedResourceSchema; import com.evolveum.midpoint.common.refinery.ShadowDiscriminatorObjectDelta; import com.evolveum.midpoint.model.api.ModelExecuteOptions; import com.evolveum.midpoint.model.api.context.ModelContext; import com.evolveum.midpoint.model.common.expression.evaluator.LiteralExpressionEvaluatorFactory; import com.evolveum.midpoint.model.test.AbstractModelIntegrationTest; import com.evolveum.midpoint.prism.Containerable; import com.evolveum.midpoint.prism.PrismContainer; import com.evolveum.midpoint.prism.PrismObject; import com.evolveum.midpoint.prism.PrismProperty; import com.evolveum.midpoint.prism.PrismPropertyDefinition; import com.evolveum.midpoint.prism.PrismPropertyValue; import com.evolveum.midpoint.prism.PrismReferenceValue; import com.evolveum.midpoint.prism.delta.ChangeType; 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.match.MatchingRuleRegistry; import com.evolveum.midpoint.prism.match.StringIgnoreCaseMatchingRule; import com.evolveum.midpoint.prism.path.ItemPath; import com.evolveum.midpoint.prism.polystring.PolyString; import com.evolveum.midpoint.prism.util.PrismAsserts; import com.evolveum.midpoint.prism.util.PrismTestUtil; import com.evolveum.midpoint.schema.GetOperationOptions; import com.evolveum.midpoint.schema.SelectorOptions; import com.evolveum.midpoint.schema.constants.MidPointConstants; 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.result.OperationResultStatus; import com.evolveum.midpoint.schema.util.MiscSchemaUtil; import com.evolveum.midpoint.schema.util.ResourceTypeUtil; import com.evolveum.midpoint.schema.util.ShadowUtil; import com.evolveum.midpoint.task.api.Task; import com.evolveum.midpoint.test.DummyResourceContoller; import com.evolveum.midpoint.test.IntegrationTestTools; import com.evolveum.midpoint.test.ProvisioningScriptSpec; import com.evolveum.midpoint.test.util.MidPointTestConstants; import com.evolveum.midpoint.test.util.TestUtil; import com.evolveum.midpoint.util.DOMUtil; import com.evolveum.midpoint.util.MiscUtil; import com.evolveum.midpoint.util.exception.CommunicationException; import com.evolveum.midpoint.util.exception.ConfigurationException; import com.evolveum.midpoint.util.exception.ObjectAlreadyExistsException; import com.evolveum.midpoint.util.exception.ObjectNotFoundException; import com.evolveum.midpoint.util.exception.PolicyViolationException; import com.evolveum.midpoint.util.exception.SchemaException; import com.evolveum.midpoint.util.exception.SecurityViolationException; 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.AssignmentPolicyEnforcementType; import com.evolveum.midpoint.xml.ns._public.common.common_3.AssignmentType; import com.evolveum.midpoint.xml.ns._public.common.common_3.ConnectorConfigurationType; import com.evolveum.midpoint.xml.ns._public.common.common_3.ConstructionType; import com.evolveum.midpoint.xml.ns._public.common.common_3.ExpressionType; import com.evolveum.midpoint.xml.ns._public.common.common_3.MappingType; import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectFactory; import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectReferenceType; 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.ResourceAttributeDefinitionType; 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.SystemConfigurationType; import com.evolveum.midpoint.xml.ns._public.common.common_3.SystemObjectsType; import com.evolveum.midpoint.xml.ns._public.common.common_3.UserType; import com.evolveum.prism.xml.ns._public.types_3.PolyStringType; /** * @author Radovan Semancik * */ @ContextConfiguration(locations = {"classpath:ctx-story-test-main.xml"}) @DirtiesContext(classMode = ClassMode.AFTER_CLASS) public class TestUuid extends AbstractStoryTest { public static final File TEST_DIR = new File(MidPointTestConstants.TEST_RESOURCES_DIR, "uuid"); public static final File SYSTEM_CONFIGURATION_FILE = new File(TEST_DIR, "system-configuration.xml"); public static final File OBJECT_TEMPLATE_USER_FILE = new File(TEST_DIR, "object-template-user.xml"); public static final String OBJECT_TEMPLATE_USER_OID = "10000000-0000-0000-0000-000000000222"; protected static final File RESOURCE_OPENDJ_FILE = new File(TEST_DIR, "resource-opendj.xml"); protected static final String RESOURCE_OPENDJ_OID = "10000000-0000-0000-0000-000000000003"; protected static final String RESOURCE_OPENDJ_NAMESPACE = MidPointConstants.NS_RI; public static final File ROLE_CLIENT_FILE = new File(TEST_DIR, "role-client.xml"); public static final String ROLE_CLIENT_OID = "10000000-0000-0000-0000-000000000601"; public static final String ROLE_CLIENT_NAME = "Client"; private static final File OU_CLIENTS_LDIF_FILE = new File(TEST_DIR, "ou-clients.ldif"); private static final String USER_RAPP_GIVEN_NAME = "Rapp"; private static final String USER_RAPP_FAMILY_NAME = "Scallion"; private static final String USER_MANCOMB_GIVEN_NAME = "Mancomb"; private static final String USER_MANCOMB_FAMILY_NAME = "Seepgood"; private static final String USER_KATE_NAME = "c0c010c0-d34d-b33f-f00d-11111aa00001"; private static final String USER_KATE_GIVEN_NAME = "Kate"; private static final String USER_KATE_FAMILY_NAME = "Capsize"; private static final String USER_WALLY_OID = "c0c010c0-d34d-b33f-f00d-11111aa00002"; private static final String USER_WALLY_GIVEN_NAME = "Wally"; private static final String USER_WALLY_FAMILY_NAME = "Feed"; private static final String USER_ROGERS_OID = "c0c010c0-d34d-b33f-f00d-11111aa00003"; private static final String USER_ROGERS_GIVEN_NAME = "Rum"; private static final String USER_ROGERS_FAMILY_NAME = "Rogers"; private static final String USER_MARTY_OID = "c0c010c0-d34d-b33f-f00d-11111aa00004"; private static final String USER_MARTY_NAME = "marty"; private static final String USER_MARTY_GIVEN_NAME = "Mad"; private static final String USER_MARTY_FAMILY_NAME = "Marty"; protected ResourceType resourceOpenDjType; protected PrismObject<ResourceType> resourceOpenDj; protected String userRappOid; protected String userMancombOid; @Override protected void startResources() throws Exception { openDJController.startCleanServer(); } @AfterClass public static void stopResources() throws Exception { openDJController.stop(); } @Override public void initSystem(Task initTask, OperationResult initResult) throws Exception { super.initSystem(initTask, initResult); // Resources resourceOpenDj = importAndGetObjectFromFile(ResourceType.class, RESOURCE_OPENDJ_FILE, RESOURCE_OPENDJ_OID, initTask, initResult); resourceOpenDjType = resourceOpenDj.asObjectable(); openDJController.setResource(resourceOpenDj); // Object Templates importObjectFromFile(OBJECT_TEMPLATE_USER_FILE, initResult); // Role importObjectFromFile(ROLE_CLIENT_FILE, initResult); // LDAP content openDJController.addEntryFromLdifFile(OU_CLIENTS_LDIF_FILE); } @Override protected File getSystemConfigurationFile() { return SYSTEM_CONFIGURATION_FILE; } @Test public void test000Sanity() throws Exception { final String TEST_NAME = "test000Sanity"; TestUtil.displayTestTile(this, TEST_NAME); Task task = taskManager.createTaskInstance(TestTrafo.class.getName() + "." + TEST_NAME); OperationResult testResultOpenDj = modelService.testResource(RESOURCE_OPENDJ_OID, task); TestUtil.assertSuccess(testResultOpenDj); waitForTaskStart(TASK_TRIGGER_SCANNER_OID, true); waitForTaskStart(TASK_VALIDITY_SCANNER_OID, true); } @Test public void test100AddUserRapp() throws Exception { final String TEST_NAME = "test100AddUserRapp"; TestUtil.displayTestTile(this, TEST_NAME); Task task = taskManager.createTaskInstance(TestTrafo.class.getName() + "." + TEST_NAME); OperationResult result = task.getResult(); PrismObject<UserType> user = createNoNameUser(USER_RAPP_GIVEN_NAME, USER_RAPP_FAMILY_NAME, true); // WHEN addObject(user, task, result); // THEN result.computeStatus(); TestUtil.assertSuccess(result); userRappOid = user.getOid(); user = getUser(userRappOid); assertUser(user, USER_RAPP_GIVEN_NAME, USER_RAPP_FAMILY_NAME); } @Test public void test101RappAssignRoleClient() throws Exception { final String TEST_NAME = "test101RappAssignRoleClient"; TestUtil.displayTestTile(this, TEST_NAME); Task task = taskManager.createTaskInstance(TestTrafo.class.getName() + "." + TEST_NAME); OperationResult result = task.getResult(); // WHEN assignRole(userRappOid, ROLE_CLIENT_OID, task, result); // THEN result.computeStatus(); TestUtil.assertSuccess(result); PrismObject<UserType> userAfter = getUser(userRappOid); assertUser(userAfter, USER_RAPP_GIVEN_NAME, USER_RAPP_FAMILY_NAME); assertLdapClient(userAfter, USER_RAPP_GIVEN_NAME, USER_RAPP_FAMILY_NAME); } // TODO: modify user, account should be modified @Test public void test107RappUnAssignRoleClient() throws Exception { final String TEST_NAME = "test107RappUnAssignRoleClient"; TestUtil.displayTestTile(this, TEST_NAME); Task task = taskManager.createTaskInstance(TestTrafo.class.getName() + "." + TEST_NAME); // WHEN unassignRole(userRappOid, ROLE_CLIENT_OID); // THEN PrismObject<UserType> userAfter = getUser(userRappOid); assertUser(userAfter, USER_RAPP_GIVEN_NAME, USER_RAPP_FAMILY_NAME); assertNoLdapClient(userAfter); } @Test public void test110AddMancombWithRoleClient() throws Exception { final String TEST_NAME = "test110AddMancombWithRoleClient"; TestUtil.displayTestTile(this, TEST_NAME); Task task = taskManager.createTaskInstance(TestTrafo.class.getName() + "." + TEST_NAME); OperationResult result = task.getResult(); PrismObject<UserType> user = createClientUser(null, null, USER_MANCOMB_GIVEN_NAME, USER_MANCOMB_FAMILY_NAME, true); // WHEN addObject(user, task, result); // THEN result.computeStatus(); TestUtil.assertSuccess(result); userMancombOid = user.getOid(); PrismObject<UserType> userAfter = getUser(userMancombOid); assertUser(userAfter, USER_MANCOMB_GIVEN_NAME, USER_MANCOMB_FAMILY_NAME); assertLdapClient(userAfter, USER_MANCOMB_GIVEN_NAME, USER_MANCOMB_FAMILY_NAME); } /** * Test user rename. Name is bound to OID and OID cannot be changed therefore * an attempt to rename should fail. */ @Test public void test112RenameMancomb() throws Exception { final String TEST_NAME = "test112RenameMancomb"; TestUtil.displayTestTile(this, TEST_NAME); Task task = taskManager.createTaskInstance(TestTrafo.class.getName() + "." + TEST_NAME); OperationResult result = task.getResult(); try { // WHEN modifyUserReplace(userMancombOid, UserType.F_NAME, task, result, PrismTestUtil.createPolyString("whatever")); AssertJUnit.fail("Unexpected success"); } catch (PolicyViolationException e) { // This is expected result.computeStatus(); TestUtil.assertFailure(result); } PrismObject<UserType> userAfter = getUser(userMancombOid); assertUser(userAfter, USER_MANCOMB_GIVEN_NAME, USER_MANCOMB_FAMILY_NAME); assertLdapClient(userAfter, USER_MANCOMB_GIVEN_NAME, USER_MANCOMB_FAMILY_NAME); } @Test public void test119MancombDelete() throws Exception { final String TEST_NAME = "test119MancombDelete"; TestUtil.displayTestTile(this, TEST_NAME); Task task = taskManager.createTaskInstance(TestTrafo.class.getName() + "." + TEST_NAME); OperationResult result = task.getResult(); // WHEN deleteObject(UserType.class, userMancombOid, task, result); // THEN result.computeStatus(); TestUtil.assertSuccess(result); assertNoObject(UserType.class, userMancombOid, task, result); openDJController.assertNoEntry("uid="+userMancombOid+",ou=clients,dc=example,dc=com"); } /** * Kate nas a name. But no OID. */ @Test public void test120AddKateWithRoleClient() throws Exception { final String TEST_NAME = "test120AddKateWithRoleClient"; TestUtil.displayTestTile(this, TEST_NAME); Task task = taskManager.createTaskInstance(TestTrafo.class.getName() + "." + TEST_NAME); OperationResult result = task.getResult(); PrismObject<UserType> user = createClientUser(null, USER_KATE_NAME, USER_KATE_GIVEN_NAME, USER_KATE_FAMILY_NAME, true); // WHEN addObject(user, task, result); // THEN result.computeStatus(); TestUtil.assertSuccess(result); PrismObject<UserType> userAfter = getUser(USER_KATE_NAME); assertUser(userAfter, USER_WALLY_GIVEN_NAME, USER_WALLY_FAMILY_NAME); assertLdapClient(userAfter, USER_WALLY_GIVEN_NAME, USER_WALLY_FAMILY_NAME); } /** * Wally already has OID. But no name. */ @Test public void test122AddWallyWithRoleClient() throws Exception { final String TEST_NAME = "test122AddWallyWithRoleClient"; TestUtil.displayTestTile(this, TEST_NAME); Task task = taskManager.createTaskInstance(TestTrafo.class.getName() + "." + TEST_NAME); OperationResult result = task.getResult(); PrismObject<UserType> user = createClientUser(USER_WALLY_OID, null, USER_WALLY_GIVEN_NAME, USER_WALLY_FAMILY_NAME, true); // WHEN addObject(user, task, result); // THEN result.computeStatus(); TestUtil.assertSuccess(result); PrismObject<UserType> userAfter = getUser(USER_WALLY_OID); assertUser(userAfter, USER_WALLY_GIVEN_NAME, USER_WALLY_FAMILY_NAME); assertLdapClient(userAfter, USER_WALLY_GIVEN_NAME, USER_WALLY_FAMILY_NAME); } /** * rogers has both OID and name and they do match. */ @Test public void test124AddRogersWithRoleClient() throws Exception { final String TEST_NAME = "test124AddMartyWithRoleClient"; TestUtil.displayTestTile(this, TEST_NAME); Task task = taskManager.createTaskInstance(TestTrafo.class.getName() + "." + TEST_NAME); OperationResult result = task.getResult(); PrismObject<UserType> user = createClientUser(USER_ROGERS_OID, USER_ROGERS_OID, USER_ROGERS_GIVEN_NAME, USER_ROGERS_FAMILY_NAME, true); // WHEN addObject(user, task, result); // THEN result.computeStatus(); TestUtil.assertSuccess(result); PrismObject<UserType> userAfter = getUser(USER_ROGERS_OID); assertUser(userAfter, USER_ROGERS_GIVEN_NAME, USER_ROGERS_FAMILY_NAME); assertLdapClient(userAfter, USER_ROGERS_GIVEN_NAME, USER_ROGERS_FAMILY_NAME); } /** * marty has both OID and name and they do NOT match. */ @Test public void test126AddMartyWithRoleClient() throws Exception { final String TEST_NAME = "test124AddMartyWithRoleClient"; TestUtil.displayTestTile(this, TEST_NAME); Task task = taskManager.createTaskInstance(TestTrafo.class.getName() + "." + TEST_NAME); OperationResult result = task.getResult(); PrismObject<UserType> user = createClientUser(USER_MARTY_OID, USER_MARTY_NAME, USER_MARTY_GIVEN_NAME, USER_MARTY_FAMILY_NAME, true); try { // WHEN addObject(user, task, result); AssertJUnit.fail("Unexpected success"); } catch (PolicyViolationException e) { // This is expected result.computeStatus(); TestUtil.assertFailure(result); } // THEN assertNoObject(UserType.class, USER_MARTY_OID, task, result); openDJController.assertNoEntry("uid="+USER_MARTY_OID+",ou=clients,dc=example,dc=com"); } private void assertUser(PrismObject<UserType> user, String firstName, String lastName) { display("User", user); String oid = user.getOid(); PolyStringType name = user.asObjectable().getName(); assertEquals("User name-OID mismatch", oid, name.getOrig()); // TODO } private void assertLdapClient(PrismObject<UserType> user, String firstName, String lastName) throws ObjectNotFoundException, SchemaException, SecurityViolationException, CommunicationException, ConfigurationException { assertLinks(user, 1); assertAssignments(user, RoleType.class, 1); assertAssignedRole(user, ROLE_CLIENT_OID); assertAccount(user, RESOURCE_OPENDJ_OID); PrismReferenceValue linkRef = getLinkRef(user, RESOURCE_OPENDJ_OID); PrismObject<ShadowType> shadow = getShadowModel(linkRef.getOid()); display("OpenDJ shadow linked to "+user, shadow); IntegrationTestTools.assertSecondaryIdentifier(shadow, "uid="+user.getOid()+",ou=clients,dc=example,dc=com"); // TODO: cn, sn, givenName } private void assertNoLdapClient(PrismObject<UserType> user) throws ObjectNotFoundException, SchemaException, SecurityViolationException, CommunicationException, ConfigurationException, DirectoryException { assertLinks(user, 0); assertAssignments(user, RoleType.class, 0); assertNotAssignedRole(user, ROLE_CLIENT_OID); openDJController.assertNoEntry("uid="+user.getOid()+",ou=clients,dc=example,dc=com"); } protected PrismObject<UserType> createNoNameUser(String givenName, String familyName, Boolean enabled) throws SchemaException { PrismObject<UserType> user = getUserDefinition().instantiate(); UserType userType = user.asObjectable(); userType.setGivenName(PrismTestUtil.createPolyStringType(givenName)); userType.setFamilyName(PrismTestUtil.createPolyStringType(familyName)); if (enabled != null) { ActivationType activation = new ActivationType(); userType.setActivation(activation); if (enabled) { activation.setAdministrativeStatus(ActivationStatusType.ENABLED); } else { activation.setAdministrativeStatus(ActivationStatusType.DISABLED); } } return user; } private PrismObject<UserType> createClientUser(String oid, String name, String givenName, String familyName, boolean enabled) throws SchemaException { PrismObject<UserType> user = createNoNameUser(givenName, familyName, enabled); AssignmentType roleAssignment = new AssignmentType(); ObjectReferenceType targetRef = new ObjectReferenceType(); targetRef.setOid(ROLE_CLIENT_OID); targetRef.setType(RoleType.COMPLEX_TYPE); roleAssignment.setTargetRef(targetRef); user.asObjectable().getAssignment().add(roleAssignment); user.setOid(oid); if (name != null) { user.asObjectable().setName(PrismTestUtil.createPolyStringType(name)); } return user; } }