diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/configuration/PageAccounts.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/configuration/PageAccounts.java index f94e63e2412..468e1f27cdd 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/configuration/PageAccounts.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/configuration/PageAccounts.java @@ -486,7 +486,7 @@ private LoadableModel createTotalsModel(final SynchronizationSituationT @Override protected Integer load() { // ObjectFilter resourceFilter = createResourceQueryFilter(); - ObjectFilter resourceFilter = createObjectQuery().getFilter(); + ObjectFilter resourceFilter = createObjectQuery().getFilter(); // leads to invalid filters [e.g. AND(something,null)] if (resourceFilter == null) { return 0; diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/resources/content/dto/AccountContentDataProvider.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/resources/content/dto/AccountContentDataProvider.java index 378488f1475..3a131f39a8e 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/resources/content/dto/AccountContentDataProvider.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/resources/content/dto/AccountContentDataProvider.java @@ -21,6 +21,9 @@ import com.evolveum.midpoint.prism.query.ObjectFilter; import com.evolveum.midpoint.prism.query.ObjectPaging; import com.evolveum.midpoint.prism.query.ObjectQuery; +import com.evolveum.midpoint.schema.GetOperationOptions; +import com.evolveum.midpoint.schema.RetrieveOption; +import com.evolveum.midpoint.schema.SelectorOptions; import com.evolveum.midpoint.schema.processor.ResourceAttribute; import com.evolveum.midpoint.schema.result.OperationResult; import com.evolveum.midpoint.schema.util.ObjectQueryUtil; @@ -102,7 +105,9 @@ public Iterator internalIterator(long first, long count) { LOGGER.trace("Query filter:\n{}", query); } - List> list = getModel().searchObjects(ShadowType.class, query, null, task, result); + Collection> options = + SelectorOptions.createCollection(ShadowType.F_ASSOCIATION, GetOperationOptions.createRetrieve(RetrieveOption.EXCLUDE)); + List> list = getModel().searchObjects(ShadowType.class, query, options, task, result); AccountContentDto dto; for (PrismObject object : list) { diff --git a/infra/schema/src/main/java/com/evolveum/midpoint/schema/SelectorOptions.java b/infra/schema/src/main/java/com/evolveum/midpoint/schema/SelectorOptions.java index 7f44a4cfa5e..dbed0cd67be 100644 --- a/infra/schema/src/main/java/com/evolveum/midpoint/schema/SelectorOptions.java +++ b/infra/schema/src/main/java/com/evolveum/midpoint/schema/SelectorOptions.java @@ -157,15 +157,17 @@ public static boolean hasToLoadPath(ItemPath path, Collection + + + + TODO + + + diff --git a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/EntitlementConverter.java b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/EntitlementConverter.java index d6367cbac65..1e44dae91e8 100644 --- a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/EntitlementConverter.java +++ b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/EntitlementConverter.java @@ -135,7 +135,7 @@ private void postProcessEntitlementSubjectToEntitlement if (associationName == null) { throw new SchemaException("No name in entitlement association "+assocDefType+" in "+resourceType); } - + QName assocAttrName = assocDefType.getResourceObjectAssociationType().getAssociationAttribute(); if (assocAttrName == null) { throw new SchemaException("No association attribute defined in entitlement association '"+associationName+"' in "+resourceType); @@ -149,25 +149,26 @@ private void postProcessEntitlementSubjectToEntitlement // Nothing to do. No attribute to base the association on. return; } - + QName valueAttrName = assocDefType.getResourceObjectAssociationType().getValueAttribute(); if (valueAttrName == null) { throw new SchemaException("No value attribute defined in entitlement association '"+associationName+"' in "+resourceType); } RefinedAttributeDefinition valueAttrDef = entitlementDef.findAttributeDefinition(valueAttrName); - ResourceAttribute valueAttribute = valueAttrDef.instantiate(); - - for (PrismPropertyValue assocAttrPVal: assocAttr.getValues()) { - valueAttribute.add(assocAttrPVal.clone()); - } - - PrismContainerValue associationCVal = associationContainer.createNewValue(); - associationCVal.asContainerable().setName(associationName); - ResourceAttributeContainer identifiersContainer = new ResourceAttributeContainer( - ShadowAssociationType.F_IDENTIFIERS, entitlementDef.toResourceAttributeContainerDefinition(), prismContext); - associationCVal.add(identifiersContainer); - identifiersContainer.add(valueAttribute); - } + + for (PrismPropertyValue assocAttrPVal : assocAttr.getValues()) { + + ResourceAttribute valueAttribute = valueAttrDef.instantiate(); + valueAttribute.add(assocAttrPVal.clone()); + + PrismContainerValue associationCVal = associationContainer.createNewValue(); + associationCVal.asContainerable().setName(associationName); + ResourceAttributeContainer identifiersContainer = new ResourceAttributeContainer( + ShadowAssociationType.F_IDENTIFIERS, entitlementDef.toResourceAttributeContainerDefinition(), prismContext); + associationCVal.add(identifiersContainer); + identifiersContainer.add(valueAttribute); + } + } private void postProcessEntitlementEntitlementToSubject(ConnectorInstance connector, ResourceType resourceType, final PrismObject resourceObject, diff --git a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ResourceObjectConverter.java b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ResourceObjectConverter.java index 2c8386ba42d..477315ad2f0 100644 --- a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ResourceObjectConverter.java +++ b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ResourceObjectConverter.java @@ -34,7 +34,6 @@ import org.springframework.stereotype.Component; import com.evolveum.midpoint.common.ResourceObjectPattern; -import com.evolveum.midpoint.common.refinery.RefinedAssociationDefinition; import com.evolveum.midpoint.common.refinery.RefinedAttributeDefinition; import com.evolveum.midpoint.common.refinery.RefinedObjectClassDefinition; import com.evolveum.midpoint.common.refinery.RefinedResourceSchema; @@ -44,7 +43,6 @@ import com.evolveum.midpoint.prism.PrismContainer; 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.PrismPropertyValue; import com.evolveum.midpoint.prism.delta.ContainerDelta; @@ -78,7 +76,6 @@ import com.evolveum.midpoint.schema.util.ResourceTypeUtil; import com.evolveum.midpoint.schema.util.SchemaDebugUtil; import com.evolveum.midpoint.schema.util.ShadowUtil; -import com.evolveum.midpoint.task.api.Task; import com.evolveum.midpoint.util.Holder; import com.evolveum.midpoint.util.MiscUtil; import com.evolveum.midpoint.util.PrettyPrinter; @@ -100,7 +97,6 @@ import com.evolveum.midpoint.xml.ns._public.common.common_3.ProvisioningOperationTypeType; import com.evolveum.midpoint.xml.ns._public.common.common_3.ResourceType; import com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowAssociationType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowIdentifiersType; 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.resource.capabilities_3.ActivationCapabilityType; @@ -191,8 +187,17 @@ public PrismObject locateResourceObject(ConnectorInstance connector, } final ResourceAttribute finalSecondaryIdentifier = secondaryIdentifier; - - ObjectFilter filter = EqualFilter.createEqual(new ItemPath(ShadowType.F_ATTRIBUTES, secondaryIdentifierDef.getName()), secondaryIdentifierDef, secondaryIdentifier.getValue()); + + List secondaryIdentifierValues = (List) secondaryIdentifier.getValues(); + PrismPropertyValue secondaryIdentifierValue; + if (secondaryIdentifierValues.size() > 1) { + throw new IllegalStateException("Secondary identifier has more than one value: " + secondaryIdentifier.getValues()); + } else if (secondaryIdentifierValues.size() == 1) { + secondaryIdentifierValue = secondaryIdentifierValues.get(0); + } else { + secondaryIdentifierValue = null; + } + ObjectFilter filter = EqualFilter.createEqual(new ItemPath(ShadowType.F_ATTRIBUTES, secondaryIdentifierDef.getName()), secondaryIdentifierDef, secondaryIdentifierValue); ObjectQuery query = ObjectQuery.createObjectQuery(filter); // query.setFilter(filter); final Holder> shadowHolder = new Holder>(); @@ -212,7 +217,7 @@ public boolean handle(PrismObject shadow) { throw new ObjectNotFoundException("No object found for secondary identifier "+secondaryIdentifier); } PrismObject shadow = shadowHolder.getValue(); - return postProcessResourceObjectRead(connector, resource, shadow, objectClassDefinition, parentResult); + return postProcessResourceObjectRead(connector, resource, shadow, objectClassDefinition, true, parentResult); } catch (GenericFrameworkException e) { throw new GenericConnectorException(e.getMessage(), e); } @@ -741,16 +746,17 @@ private void executeEntitlements(ConnectorInstance connector, ResourceType resou public void searchResourceObjects(final ConnectorInstance connector, final ResourceType resourceType, final RefinedObjectClassDefinition objectClassDef, - final ResultHandler resultHandler, ObjectQuery query, final OperationResult parentResult) throws SchemaException, + final ResultHandler resultHandler, ObjectQuery query, final boolean fetchAssociations, + final OperationResult parentResult) throws SchemaException, CommunicationException, ObjectNotFoundException, ConfigurationException { AttributesToReturn attributesToReturn = ProvisioningUtil.createAttributesToReturn(objectClassDef, resourceType); - + ResultHandler innerResultHandler = new ResultHandler() { @Override public boolean handle(PrismObject shadow) { try { - shadow = postProcessResourceObjectRead(connector, resourceType, shadow, objectClassDef, parentResult); + shadow = postProcessResourceObjectRead(connector, resourceType, shadow, objectClassDef, fetchAssociations, parentResult); } catch (SchemaException e) { throw new TunnelException(e); } catch (CommunicationException e) { @@ -834,7 +840,7 @@ private PrismObject fetchResourceObject(ConnectorInstance connector, PrismObject resourceObject = connector.fetchObject(ShadowType.class, objectClassDefinition, identifiers, attributesToReturn, parentResult); - return postProcessResourceObjectRead(connector, resource, resourceObject, objectClassDefinition, parentResult); + return postProcessResourceObjectRead(connector, resource, resourceObject, objectClassDefinition, true, parentResult); // todo consider whether it is always necessary to fetch the entitlements } catch (ObjectNotFoundException e) { parentResult.recordFatalError( "Object not found. Identifiers: " + identifiers + ". Reason: " + e.getMessage(), e); @@ -1213,7 +1219,7 @@ public List> fetchChanges(ConnectorInstance connector, Resour } } else { PrismObject currentShadow = postProcessResourceObjectRead(connector, resource, change.getCurrentShadow(), - objectClass, parentResult); + objectClass, true, parentResult); change.setCurrentShadow(currentShadow); } } @@ -1227,7 +1233,8 @@ public List> fetchChanges(ConnectorInstance connector, Resour * Process simulated activation, credentials and other properties that are added to the object by midPoint. */ private PrismObject postProcessResourceObjectRead(ConnectorInstance connector, ResourceType resourceType, - PrismObject resourceObject, RefinedObjectClassDefinition objectClassDefinition, OperationResult parentResult) throws SchemaException, CommunicationException, GenericFrameworkException { + PrismObject resourceObject, RefinedObjectClassDefinition objectClassDefinition, boolean fetchAssociations, + OperationResult parentResult) throws SchemaException, CommunicationException, GenericFrameworkException { ShadowType resourceObjectType = resourceObject.asObjectable(); setProtectedFlag(resourceType, objectClassDefinition, resourceObject); @@ -1249,7 +1256,9 @@ private PrismObject postProcessResourceObjectRead(ConnectorInstance } // Entitlements - entitlementConverter.postProcessEntitlementsRead(connector, resourceType, resourceObject, objectClassDefinition, parentResult); + if (fetchAssociations) { + entitlementConverter.postProcessEntitlementsRead(connector, resourceType, resourceObject, objectClassDefinition, parentResult); + } return resourceObject; } diff --git a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ShadowCache.java b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ShadowCache.java index 2e4da42a17d..1c2d6bf982e 100644 --- a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ShadowCache.java +++ b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ShadowCache.java @@ -821,7 +821,7 @@ public boolean handle(PrismObject resourceShadow) { applyAttributesDefinition(repoShadow, resourceType); forceRenameIfNeeded(resourceShadow.asObjectable(), repoShadow.asObjectable(), objectClassDef, parentResult); - + resultShadow = completeShadow(connector, resourceShadow, repoShadow, resourceType, objectClassDef, parentResult); @@ -870,8 +870,11 @@ public boolean handle(PrismObject resourceShadow) { } }; + + boolean fetchAssociations = SelectorOptions.hasToLoadPath(ShadowType.F_ASSOCIATION, options); - resouceObjectConverter.searchResourceObjects(connector, resourceType, objectClassDef, resultHandler, attributeQuery, parentResult); + resouceObjectConverter.searchResourceObjects(connector, resourceType, objectClassDef, resultHandler, + attributeQuery, fetchAssociations, parentResult); } @@ -1512,7 +1515,7 @@ private PrismObject completeShadow(ConnectorInstance connector, Pris PrismObject resultShadow = repoShadow.clone(); boolean resultIsResourceShadowClone = false; - if (resultShadow == null) { + if (resultShadow == null) { // todo how could this happen (see above)? [mederly] resultShadow = resourceShadow.clone(); resultIsResourceShadowClone = true; } diff --git a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/ucf/impl/ConnectorFactoryIcfImpl.java b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/ucf/impl/ConnectorFactoryIcfImpl.java index cb79d60a539..bae6710f68f 100644 --- a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/ucf/impl/ConnectorFactoryIcfImpl.java +++ b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/ucf/impl/ConnectorFactoryIcfImpl.java @@ -149,6 +149,7 @@ public class ConnectorFactoryIcfImpl implements ConnectorFactory { "ResultsHandlerConfigurationType"); public static final String CONNECTOR_SCHEMA_RESULTS_HANDLER_CONFIGURATION_ENABLE_NORMALIZING_RESULTS_HANDLER = "enableNormalizingResultsHandler"; public static final String CONNECTOR_SCHEMA_RESULTS_HANDLER_CONFIGURATION_ENABLE_FILTERED_RESULTS_HANDLER = "enableFilteredResultsHandler"; + public static final String CONNECTOR_SCHEMA_RESULTS_HANDLER_CONFIGURATION_FILTERED_RESULTS_HANDLER_IN_VALIDATION_MODE = "filteredResultsHandlerInValidationMode"; public static final String CONNECTOR_SCHEMA_RESULTS_HANDLER_CONFIGURATION_ENABLE_CASE_INSENSITIVE_HANDLER = "enableCaseInsensitiveFilter"; public static final String CONNECTOR_SCHEMA_RESULTS_HANDLER_CONFIGURATION_ENABLE_ATTRIBUTES_TO_GET_SEARCH_RESULTS_HANDLER = "enableAttributesToGetSearchResultsHandler"; diff --git a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/ucf/impl/ConnectorInstanceIcfImpl.java b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/ucf/impl/ConnectorInstanceIcfImpl.java index 091ba056198..4a9ae69bfa5 100644 --- a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/ucf/impl/ConnectorInstanceIcfImpl.java +++ b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/ucf/impl/ConnectorInstanceIcfImpl.java @@ -2449,6 +2449,9 @@ private void transformResultsHandlerConfiguration(ResultsHandlerConfiguration re } else if (ConnectorFactoryIcfImpl.CONNECTOR_SCHEMA_RESULTS_HANDLER_CONFIGURATION_ENABLE_FILTERED_RESULTS_HANDLER .equals(subelementName)) { resultsHandlerConfiguration.setEnableFilteredResultsHandler(parseBoolean(prismProperty)); + } else if (ConnectorFactoryIcfImpl.CONNECTOR_SCHEMA_RESULTS_HANDLER_CONFIGURATION_FILTERED_RESULTS_HANDLER_IN_VALIDATION_MODE + .equals(subelementName)) { + resultsHandlerConfiguration.setFilteredResultsHandlerInValidationMode(parseBoolean(prismProperty)); } else if (ConnectorFactoryIcfImpl.CONNECTOR_SCHEMA_RESULTS_HANDLER_CONFIGURATION_ENABLE_CASE_INSENSITIVE_HANDLER .equals(subelementName)) { resultsHandlerConfiguration.setEnableCaseInsensitiveFilter(parseBoolean(prismProperty)); diff --git a/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/test/impl/AbstractDummyTest.java b/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/test/impl/AbstractDummyTest.java index 1df4de53e8e..7efcfca5840 100644 --- a/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/test/impl/AbstractDummyTest.java +++ b/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/test/impl/AbstractDummyTest.java @@ -136,7 +136,11 @@ public abstract class AbstractDummyTest extends AbstractIntegrationTest { protected static final String PRIVILEGE_PILLAGE_OID = "c0c010c0-d34d-b44f-f11d-3332eeff0000"; protected static final String PRIVILEGE_PILLAGE_NAME = "pillage"; - protected static final String FILENAME_ACCOUNT_SCRIPT = TEST_DIR + "account-script.xml"; + protected static final String PRIVILEGE_BARGAIN_FILENAME = TEST_DIR + "privilege-bargain.xml"; + protected static final String PRIVILEGE_BARGAIN_OID = "c0c010c0-d34d-b44f-f11d-3332eeff0001"; + protected static final String PRIVILEGE_BARGAIN_NAME = "bargain"; + + protected static final String FILENAME_ACCOUNT_SCRIPT = TEST_DIR + "account-script.xml"; protected static final String ACCOUNT_NEW_SCRIPT_OID = "c0c010c0-d34d-b44f-f11d-33322212abcd"; protected static final String FILENAME_ENABLE_ACCOUNT = TEST_DIR + "modify-will-enable.xml"; protected static final String FILENAME_DISABLE_ACCOUNT = TEST_DIR + "modify-will-disable.xml"; diff --git a/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/test/impl/TestDummy.java b/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/test/impl/TestDummy.java index ef0c30f3a6e..1e291482515 100644 --- a/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/test/impl/TestDummy.java +++ b/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/test/impl/TestDummy.java @@ -173,6 +173,7 @@ public class TestDummy extends AbstractDummyTest { private String williamIcfUid; protected String piratesIcfUid; private String pillageIcfUid; + private String bargainIcfUid; private String leChuckIcfUid; private String blackbeardIcfUid; private String drakeIcfUid; @@ -2749,7 +2750,7 @@ public void test210AddPrivilege() throws Exception { checkConsistency(priv); assertSteadyResource(); } - + @Test public void test212GetPriv() throws Exception { final String TEST_NAME = "test212GetPriv"; @@ -2789,8 +2790,75 @@ private void checkPrivPillage(ShadowType shadow, OperationResult result) { assertNull("The _PASSSWORD_ attribute sneaked into shadow", ShadowUtil.getAttributeValues( shadow, new QName(ConnectorFactoryIcfImpl.NS_ICF_SCHEMA, "password"))); } - - @Test + + @Test + public void test214AddPrivilegeBargain() throws Exception { + final String TEST_NAME = "test214AddPrivilegeBargain"; + TestUtil.displayTestTile(TEST_NAME); + // GIVEN + Task task = taskManager.createTaskInstance(TestDummy.class.getName() + "." + TEST_NAME); + OperationResult result = task.getResult(); + syncServiceMock.reset(); + + PrismObject priv = prismContext.parseObject(new File(PRIVILEGE_BARGAIN_FILENAME)); + priv.checkConsistence(); + + display("Adding priv", priv); + + // WHEN + String addedObjectOid = provisioningService.addObject(priv, null, null, task, result); + + // THEN + result.computeStatus(); + display("add object result", result); + TestUtil.assertSuccess("addObject has failed (result)", result); + assertEquals(PRIVILEGE_BARGAIN_OID, addedObjectOid); + + priv.checkConsistence(); + + ShadowType groupRepoType = repositoryService.getObject(ShadowType.class, PRIVILEGE_BARGAIN_OID, null, result) + .asObjectable(); + PrismAsserts.assertEqualsPolyString("Name not equal.", PRIVILEGE_BARGAIN_NAME, groupRepoType.getName()); + assertEquals("Wrong kind (repo)", ShadowKindType.ENTITLEMENT, groupRepoType.getKind()); + + syncServiceMock.assertNotifySuccessOnly(); + + ShadowType privProvisioningType = provisioningService.getObject(ShadowType.class, + PRIVILEGE_BARGAIN_OID, null, task, result).asObjectable(); + display("priv from provisioning", privProvisioningType); + checkPrivBargain(privProvisioningType, result); + bargainIcfUid = getIcfUid(privProvisioningType); + + // Check if the group was created in the dummy resource + + DummyPrivilege dummyPriv = getDummyPrivilegeAssert(PRIVILEGE_BARGAIN_NAME, bargainIcfUid); + assertNotNull("No dummy priv "+PRIVILEGE_BARGAIN_NAME, dummyPriv); + + // Check if the shadow is still in the repo (e.g. that the consistency or sync haven't removed it) + PrismObject shadowFromRepo = repositoryService.getObject(ShadowType.class, + addedObjectOid, null, result); + assertNotNull("Shadow was not created in the repository", shadowFromRepo); + display("Repository shadow", shadowFromRepo.debugDump()); + + ProvisioningTestUtil.checkRepoEntitlementShadow(shadowFromRepo); + + checkConsistency(priv); + assertSteadyResource(); + } + + private void checkPrivBargain(ShadowType shadow, OperationResult result) { + checkEntitlementShadow(shadow, result, OBJECTCLAS_PRIVILEGE_LOCAL_NAME, true); + PrismAsserts.assertEqualsPolyString("Name not equal.", PRIVILEGE_BARGAIN_NAME, shadow.getName()); + assertEquals("Wrong kind (provisioning)", ShadowKindType.ENTITLEMENT, shadow.getKind()); + Collection> attributes = ShadowUtil.getAttributes(shadow); + assertEquals("Unexpected number of attributes", 2, attributes.size()); + + assertNull("The _PASSSWORD_ attribute sneaked into shadow", ShadowUtil.getAttributeValues( + shadow, new QName(ConnectorFactoryIcfImpl.NS_ICF_SCHEMA, "password"))); + } + + + @Test public void test220EntitleAccountWillPirates() throws Exception { final String TEST_NAME = "test220EntitleAccountWillPirates"; TestUtil.displayTestTile(TEST_NAME); @@ -2903,8 +2971,56 @@ public void test222EntitleAccountWillPillage() throws Exception { assertSteadyResource(); } - - /** + + @Test + public void test222bEntitleAccountWillBargain() throws Exception { + final String TEST_NAME = "test222bEntitleAccountWillBargain"; + TestUtil.displayTestTile(TEST_NAME); + + Task task = taskManager.createTaskInstance(TestDummy.class.getName() + + "." + TEST_NAME); + OperationResult result = task.getResult(); + + syncServiceMock.reset(); + + ObjectDelta delta = IntegrationTestTools.createEntitleDelta(ACCOUNT_WILL_OID, + dummyResourceCtl.getAttributeQName(DummyResourceContoller.DUMMY_ENTITLEMENT_PRIVILEGE_NAME), + PRIVILEGE_BARGAIN_OID, prismContext); + display("ObjectDelta", delta); + delta.checkConsistence(); + + // WHEN + provisioningService.modifyObject(ShadowType.class, delta.getOid(), delta.getModifications(), + new OperationProvisioningScriptsType(), null, task, result); + + // THEN + result.computeStatus(); + display("modifyObject result", result); + TestUtil.assertSuccess(result); + + DummyAccount dummyAccount = getDummyAccountAssert(ACCOUNT_WILL_USERNAME, willIcfUid); + assertNotNull("Account will is gone!", dummyAccount); + Set accountProvileges = dummyAccount.getAttributeValues(DummyAccount.ATTR_PRIVILEGES_NAME, String.class); + PrismAsserts.assertSets("account privileges", accountProvileges, PRIVILEGE_PILLAGE_NAME, PRIVILEGE_BARGAIN_NAME); + + // Make sure that privilege object is still there + DummyPrivilege priv = getDummyPrivilegeAssert(PRIVILEGE_PILLAGE_NAME, pillageIcfUid); + assertNotNull("Privilege object (pillage) is gone!", priv); + DummyPrivilege priv2 = getDummyPrivilegeAssert(PRIVILEGE_BARGAIN_NAME, bargainIcfUid); + assertNotNull("Privilege object (bargain) is gone!", priv2); + + delta.checkConsistence(); + + // Make sure that the groups is still there and will is a member + DummyGroup group = getDummyGroupAssert(GROUP_PIRATES_NAME, piratesIcfUid); + assertMember(group, getWillRepoIcfName()); + + syncServiceMock.assertNotifySuccessOnly(); + + assertSteadyResource(); + } + + /** * Reads the will accounts, checks that both entitlements are there. */ @Test @@ -2930,17 +3046,20 @@ public void test223GetPillagingPirateWill() throws Exception { assertEntitlementGroup(account, GROUP_PIRATES_OID); assertEntitlementPriv(account, PRIVILEGE_PILLAGE_OID); - + assertEntitlementPriv(account, PRIVILEGE_BARGAIN_OID); + // Just make sure nothing has changed DummyAccount dummyAccount = getDummyAccountAssert(ACCOUNT_WILL_USERNAME, willIcfUid); assertNotNull("Account will is gone!", dummyAccount); Set accountProvileges = dummyAccount.getAttributeValues(DummyAccount.ATTR_PRIVILEGES_NAME, String.class); - PrismAsserts.assertSets("Wrong account privileges", accountProvileges, PRIVILEGE_PILLAGE_NAME); + PrismAsserts.assertSets("Wrong account privileges", accountProvileges, PRIVILEGE_PILLAGE_NAME, PRIVILEGE_BARGAIN_NAME); // Make sure that privilege object is still there DummyPrivilege priv = getDummyPrivilegeAssert(PRIVILEGE_PILLAGE_NAME, pillageIcfUid); assertNotNull("Privilege object is gone!", priv); - + DummyPrivilege priv2 = getDummyPrivilegeAssert(PRIVILEGE_BARGAIN_NAME, bargainIcfUid); + assertNotNull("Privilege object (bargain) is gone!", priv2); + DummyGroup group = getDummyGroupAssert(GROUP_PIRATES_NAME, piratesIcfUid); assertMember(group, getWillRepoIcfName()); @@ -2984,17 +3103,20 @@ public void test224GetFoolishPirateWill() throws Exception { assertEntitlementGroup(account, GROUP_PIRATES_OID); assertEntitlementGroup(account, foolsShadow.getOid()); assertEntitlementPriv(account, PRIVILEGE_PILLAGE_OID); - + assertEntitlementPriv(account, PRIVILEGE_BARGAIN_OID); + // Just make sure nothing has changed DummyAccount dummyAccount = getDummyAccountAssert(ACCOUNT_WILL_USERNAME, willIcfUid); assertNotNull("Account will is gone!", dummyAccount); Set accountProvileges = dummyAccount.getAttributeValues(DummyAccount.ATTR_PRIVILEGES_NAME, String.class); - PrismAsserts.assertSets("Wrong account privileges", accountProvileges, PRIVILEGE_PILLAGE_NAME); + PrismAsserts.assertSets("Wrong account privileges", accountProvileges, PRIVILEGE_PILLAGE_NAME, PRIVILEGE_BARGAIN_NAME); // Make sure that privilege object is still there DummyPrivilege priv = getDummyPrivilegeAssert(PRIVILEGE_PILLAGE_NAME, pillageIcfUid); assertNotNull("Privilege object is gone!", priv); - + DummyPrivilege priv2 = getDummyPrivilegeAssert(PRIVILEGE_BARGAIN_NAME, bargainIcfUid); + assertNotNull("Privilege object (bargain) is gone!", priv2); + DummyGroup group = getDummyGroupAssert(GROUP_PIRATES_NAME, piratesIcfUid); assertMember(group, getWillRepoIcfName()); @@ -3039,12 +3161,14 @@ public void test228DetitleAccountWillPirates() throws Exception { DummyAccount dummyAccount = getDummyAccountAssert(ACCOUNT_WILL_USERNAME, willIcfUid); assertNotNull("Account will is gone!", dummyAccount); Set accountProvileges = dummyAccount.getAttributeValues(DummyAccount.ATTR_PRIVILEGES_NAME, String.class); - PrismAsserts.assertSets("Wrong account privileges", accountProvileges, PRIVILEGE_PILLAGE_NAME); + PrismAsserts.assertSets("Wrong account privileges", accountProvileges, PRIVILEGE_PILLAGE_NAME, PRIVILEGE_BARGAIN_NAME); // Make sure that privilege object is still there DummyPrivilege priv = getDummyPrivilegeAssert(PRIVILEGE_PILLAGE_NAME, pillageIcfUid); assertNotNull("Privilege object is gone!", priv); - + DummyPrivilege priv2 = getDummyPrivilegeAssert(PRIVILEGE_BARGAIN_NAME, bargainIcfUid); + assertNotNull("Privilege object (bargain) is gone!", priv2); + syncServiceMock.assertNotifySuccessOnly(); assertSteadyResource(); } @@ -3083,7 +3207,7 @@ public void test229DetitleAccountWillPillage() throws Exception { DummyAccount dummyAccount = getDummyAccountAssert(ACCOUNT_WILL_USERNAME, willIcfUid); assertNotNull("Account will is gone!", dummyAccount); Set accountProvileges = dummyAccount.getAttributeValues(DummyAccount.ATTR_PRIVILEGES_NAME, String.class); - assertTrue("Unexpected account privileges: "+accountProvileges, accountProvileges == null || accountProvileges.isEmpty()); + PrismAsserts.assertSets("Wrong account privileges", accountProvileges, PRIVILEGE_BARGAIN_NAME); // Make sure that privilege object is still there DummyPrivilege priv = getDummyPrivilegeAssert(PRIVILEGE_PILLAGE_NAME, pillageIcfUid); @@ -3092,8 +3216,54 @@ public void test229DetitleAccountWillPillage() throws Exception { syncServiceMock.assertNotifySuccessOnly(); assertSteadyResource(); } - - /** + + @Test + public void test229bDetitleAccountWillBargain() throws Exception { + final String TEST_NAME = "test229bDetitleAccountWillBargain"; + TestUtil.displayTestTile(TEST_NAME); + + Task task = taskManager.createTaskInstance(TestDummy.class.getName() + + "." + TEST_NAME); + OperationResult result = task.getResult(); + + syncServiceMock.reset(); + + ObjectDelta delta = IntegrationTestTools.createDetitleDelta(ACCOUNT_WILL_OID, + dummyResourceCtl.getAttributeQName(DummyResourceContoller.DUMMY_ENTITLEMENT_PRIVILEGE_NAME), + PRIVILEGE_BARGAIN_OID, prismContext); + display("ObjectDelta", delta); + delta.checkConsistence(); + + // WHEN + provisioningService.modifyObject(ShadowType.class, delta.getOid(), delta.getModifications(), + new OperationProvisioningScriptsType(), null, task, result); + + // THEN + result.computeStatus(); + display("modifyObject result", result); + TestUtil.assertSuccess(result); + + delta.checkConsistence(); + DummyGroup group = getDummyGroupAssert(GROUP_PIRATES_NAME, piratesIcfUid); + assertNoMember(group, getWillRepoIcfName()); + + // Make sure that account is still there and it has the privilege + DummyAccount dummyAccount = getDummyAccountAssert(ACCOUNT_WILL_USERNAME, willIcfUid); + assertNotNull("Account will is gone!", dummyAccount); + Set accountProvileges = dummyAccount.getAttributeValues(DummyAccount.ATTR_PRIVILEGES_NAME, String.class); + assertTrue("There are still some privileges", accountProvileges == null || accountProvileges.isEmpty()); + + // Make sure that privilege object is still there + DummyPrivilege priv = getDummyPrivilegeAssert(PRIVILEGE_PILLAGE_NAME, pillageIcfUid); + assertNotNull("Privilege object is gone!", priv); + DummyPrivilege priv2 = getDummyPrivilegeAssert(PRIVILEGE_BARGAIN_NAME, bargainIcfUid); + assertNotNull("Privilege object (bargain) is gone!", priv); + + syncServiceMock.assertNotifySuccessOnly(); + assertSteadyResource(); + } + + /** * LeChuck has both group and priv entitlement. Let's add him together with these entitlements. */ @Test diff --git a/provisioning/provisioning-impl/src/test/resources/impl/dummy/privilege-bargain.xml b/provisioning/provisioning-impl/src/test/resources/impl/dummy/privilege-bargain.xml new file mode 100644 index 00000000000..7802a0e9ebd --- /dev/null +++ b/provisioning/provisioning-impl/src/test/resources/impl/dummy/privilege-bargain.xml @@ -0,0 +1,31 @@ + + + + + bargain + + ri:CustomprivilegeObjectClass + entitlement + privilege + + bargain + +