diff --git a/infra/schema/src/main/resources/xml/ns/public/common/common-core-3.xsd b/infra/schema/src/main/resources/xml/ns/public/common/common-core-3.xsd index baec7735e0d..1e6140b320c 100755 --- a/infra/schema/src/main/resources/xml/ns/public/common/common-core-3.xsd +++ b/infra/schema/src/main/resources/xml/ns/public/common/common-core-3.xsd @@ -13116,7 +13116,7 @@ (abstract) role.

- Use with care. MidPoint will will have to process all the roles that + Use with care. MidPoint will have to process all the roles that have this flag set to true. All the roles will be looked up, autoassign specification will be processed to see if the focus is matching. This will happen all the time for all modification operations. @@ -13181,6 +13181,15 @@ + + + +

+ Restrics autoassignment to concrete focus type. +

+ + + @@ -13621,7 +13630,7 @@ - + Selects some objects from all the objects in midPoint. diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/focus/ObjectTemplateProcessor.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/focus/ObjectTemplateProcessor.java index 316ccc949c6..91bcaa88589 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/focus/ObjectTemplateProcessor.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/focus/ObjectTemplateProcessor.java @@ -24,6 +24,11 @@ import com.evolveum.midpoint.prism.delta.*; import com.evolveum.midpoint.prism.equivalence.EquivalenceStrategy; import com.evolveum.midpoint.prism.path.ItemPathCollectionsUtil; +import com.evolveum.midpoint.schema.ObjectSelector; +import com.evolveum.midpoint.util.QNameUtil; +import com.evolveum.midpoint.util.exception.*; +import com.evolveum.midpoint.xml.ns._public.common.common_3.*; + import org.apache.commons.lang.BooleanUtils; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -57,32 +62,8 @@ import com.evolveum.midpoint.schema.result.OperationResult; import com.evolveum.midpoint.task.api.Task; import com.evolveum.midpoint.util.DebugUtil; -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.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.util.logging.Trace; import com.evolveum.midpoint.util.logging.TraceManager; -import com.evolveum.midpoint.xml.ns._public.common.common_3.AbstractRoleType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.AssignmentHolderType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.AutoassignMappingType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.AutoassignSpecificationType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.FocalAutoassignSpecificationType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.FocusType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.MappingStrengthType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.MappingType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectReferenceType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectTemplateItemDefinitionType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectTemplateMappingEvaluationPhaseType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectTemplateMappingType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectTemplateType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.RoleManagementConfigurationType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.SystemConfigurationType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.VariableBindingDefinitionType; import com.evolveum.prism.xml.ns._public.types_3.ItemPathType; import static com.evolveum.midpoint.model.impl.lens.projector.util.SkipWhenFocusDeleted.PRIMARY; @@ -459,6 +440,11 @@ private void collectAutoassignMappings(LensCon if (focalAutoassignSpec == null) { return true; } + + if (!isApplicableFor(focalAutoassignSpec.getSelector(), context.getFocusContext(), objectResult)) { + return true; + } + for (AutoassignMappingType autoMapping: focalAutoassignSpec.getMapping()) { AutoassignMappingType mapping = autoMapping.clone(); setMappingTarget(mapping, new ItemPathType(SchemaConstants.PATH_ASSIGNMENT)); @@ -470,6 +456,19 @@ private void collectAutoassignMappings(LensCon cacheRepositoryService.searchObjectsIterative(AbstractRoleType.class, query, handler, GetOperationOptions.createReadOnlyCollection(), true, result); } + private boolean isApplicableFor(ObjectSelectorType selector, LensFocusContext focusContext, OperationResult result) { + if (selector == null) { + return true; + } + try { + return cacheRepositoryService.selectorMatches(selector, focusContext.getObjectAny(), null, LOGGER, ""); + } catch (SchemaException | SecurityViolationException | ExpressionEvaluationException | CommunicationException | ObjectNotFoundException | ConfigurationException e) { + LOGGER.error("Failed to evaluate selector constraints, selector {}, focusContext {}\nReason: {}", selector, focusContext, e.getMessage(), e); + result.recordFatalError("Failed to evaluate selector constrains, selector: " + selector + ", focusContext: " + focusContext + "\nReason: " + e.getMessage(), e); + throw new SystemException(e); + } + } + private void setMappingTarget(MappingType mapping, ItemPathType path) { VariableBindingDefinitionType target = mapping.getTarget(); if (target == null) { diff --git a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/rbac/TestAutoassign.java b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/rbac/TestAutoassign.java index 08232a4986f..a772a2bfaae 100644 --- a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/rbac/TestAutoassign.java +++ b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/rbac/TestAutoassign.java @@ -10,6 +10,10 @@ import javax.xml.datatype.XMLGregorianCalendar; +import com.evolveum.midpoint.prism.path.ItemPath; + +import com.evolveum.midpoint.xml.ns._public.common.common_3.*; + import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.annotation.DirtiesContext.ClassMode; import org.springframework.test.context.ContextConfiguration; @@ -20,11 +24,6 @@ import com.evolveum.midpoint.schema.result.OperationResult; import com.evolveum.midpoint.task.api.Task; import com.evolveum.midpoint.test.DummyResourceContoller; -import com.evolveum.midpoint.xml.ns._public.common.common_3.RoleManagementConfigurationType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.RoleType; -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; /** * @author semancik @@ -47,9 +46,14 @@ public class TestAutoassign extends AbstractRbacTest { protected static final String ROLE_UNIT_WALKER_OID = "a2bc45fc-bfec-11e7-bdfd-af4b3e689502"; protected static final String ROLE_UNIT_WALKER_TITLE = "Walker"; + protected static final File ROLE_UNIT_RIDER_FILE = new File(AUTOASSIGN_DIR, "role-unit-rider.xml"); + protected static final String ROLE_UNIT_RIDER_OID = "9a60cdc6-f2ad-4414-964b-5fd1dfaec157"; + protected static final String ROLE_UNIT_RIDER_TITLE = "Rider"; + protected static final String UNIT_WORKER = "worker"; protected static final String UNIT_SLEEPER = "sleeper"; protected static final String UNIT_WALKER = "walker"; + protected static final String UNIT_RIDER = "rider"; private static final XMLGregorianCalendar ROLE_SLEEPER_AUTOASSIGN_VALID_TO = XmlTypeConverter.createXMLGregorianCalendar(2222, 1, 2, 3, 4, 5); @@ -62,16 +66,13 @@ public void initSystem(Task initTask, OperationResult initResult) repoAddObjectFromFile(ROLE_UNIT_WORKER_FILE, RoleType.class, initResult); repoAddObjectFromFile(ROLE_UNIT_SLEEPER_FILE, RoleType.class, initResult); repoAddObjectFromFile(ROLE_UNIT_WALKER_FILE, RoleType.class, initResult); + repoAddObjectFromFile(ROLE_UNIT_RIDER_FILE, RoleType.class, initResult); + + repoAddObjectFromFile(ARCHETYPE_EMPLOYEE_FILE, ArchetypeType.class, initResult); - // Temporarily using repository service because of MID-5497 - repositoryService.modifyObject(SystemConfigurationType.class, SystemObjectsType.SYSTEM_CONFIGURATION.value(), - prismContext.deltaFor(SystemConfigurationType.class) - .item(SystemConfigurationType.F_ROLE_MANAGEMENT, RoleManagementConfigurationType.F_AUTOASSIGN_ENABLED) - .replace(true) - .asItemDeltas(), initResult); -// modifyObjectReplaceProperty(SystemConfigurationType.class, SystemObjectsType.SYSTEM_CONFIGURATION.value(), -// ItemPath.create(SystemConfigurationType.F_ROLE_MANAGEMENT, RoleManagementConfigurationType.F_AUTOASSIGN_ENABLED), -// initTask, initResult, Boolean.TRUE); + modifyObjectReplaceProperty(SystemConfigurationType.class, SystemObjectsType.SYSTEM_CONFIGURATION.value(), + ItemPath.create(SystemConfigurationType.F_ROLE_MANAGEMENT, RoleManagementConfigurationType.F_AUTOASSIGN_ENABLED), + initTask, initResult, Boolean.TRUE); } /** @@ -239,6 +240,126 @@ public void test114ModifyUnitAddSleeper() throws Exception { ROLE_UNIT_WORKER_TITLE, ROLE_UNIT_WALKER_TITLE, ROLE_UNIT_SLEEPER_TITLE); } + @Test + public void test115ModifyUnitAddRider() throws Exception { + // GIVEN + Task task = getTestTask(); + OperationResult result = task.getResult(); + + // WHEN + modifyUserAdd(USER_JACK_OID, UserType.F_ORGANIZATIONAL_UNIT, task, result, + createPolyString(UNIT_RIDER)); + + // THEN + assertSuccess(result); + + assertUserAfter(USER_JACK_OID) + .assertOrganizationalUnits(UNIT_WORKER, UNIT_WALKER, UNIT_SLEEPER, UNIT_RIDER) + .assignments() + .assertAssignments(3) + .assertRole(ROLE_UNIT_WORKER_OID) + .assertRole(ROLE_UNIT_WALKER_OID) + .assertRole(ROLE_UNIT_SLEEPER_OID) + .assertNoRole(ROLE_UNIT_RIDER_OID) + .end() + .links() + .single(); + + assertDummyAccountByUsername(null, USER_JACK_USERNAME) + .assertAttribute(DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_TITLE_NAME, + ROLE_UNIT_WORKER_TITLE, ROLE_UNIT_WALKER_TITLE, ROLE_UNIT_SLEEPER_TITLE); + } + + /** + * Prepare user guybrush for autoassignment + */ + @Test + public void test200assignArchetypeGuybrush() throws Exception { + // GIVEN + Task task = getTestTask(); + OperationResult result = task.getResult(); + + //WHEN + assignArchetype(USER_GUYBRUSH_OID, ARCHETYPE_EMPLOYEE_OID, task, result); + + //THEN + assertUserAfter(USER_GUYBRUSH_OID) + .assertArchetypeRef(ARCHETYPE_EMPLOYEE_OID) + .assignments() + .assertAssignments(1) + .assertArchetype(ARCHETYPE_EMPLOYEE_OID) + .end(); + + } + + @Test + public void test201addUnitRiderGuybrush() throws Exception { + //GIVEN + Task task = getTestTask(); + OperationResult result = task.getResult(); + + //WHEN + modifyUserAdd(USER_GUYBRUSH_OID, UserType.F_ORGANIZATIONAL_UNIT, task, result, createPolyString(UNIT_RIDER)); + + //THEN + assertUserAfter(USER_GUYBRUSH_OID) + .assertOrganizationalUnits(UNIT_RIDER) + .assertArchetypeRef(ARCHETYPE_EMPLOYEE_OID) + .assignments() + .assertAssignments(2) + .assertArchetype(ARCHETYPE_EMPLOYEE_OID) + .assertRole(ROLE_UNIT_RIDER_OID) + .end() + .links() + .single(); + } + + @Test + public void test202addUnitSleeperGuybrush() throws Exception { + //GIVEN + Task task = getTestTask(); + OperationResult result = task.getResult(); + + //WHEN + modifyUserAdd(USER_GUYBRUSH_OID, UserType.F_ORGANIZATIONAL_UNIT, task, result, createPolyString(UNIT_SLEEPER)); + + //THEN + assertUserAfter(USER_GUYBRUSH_OID) + .assertOrganizationalUnits(UNIT_RIDER, UNIT_SLEEPER) + .assertArchetypeRef(ARCHETYPE_EMPLOYEE_OID) + .assignments() + .assertAssignments(3) + .assertArchetype(ARCHETYPE_EMPLOYEE_OID) + .assertRole(ROLE_UNIT_RIDER_OID) + .assertRole(ROLE_UNIT_SLEEPER_OID) + .end() + .links() + .single(); + } + + @Test + public void test203removeUnitRiderGuybrush() throws Exception { + //GIVEN + Task task = getTestTask(); + OperationResult result = task.getResult(); + + //WHEN + modifyUserDelete(USER_GUYBRUSH_OID, UserType.F_ORGANIZATIONAL_UNIT, task, result, createPolyString(UNIT_RIDER)); + + //THEN + assertUserAfter(USER_GUYBRUSH_OID) + .assertArchetypeRef(ARCHETYPE_EMPLOYEE_OID) + .assignments() + .assertAssignments(2) + .assertArchetype(ARCHETYPE_EMPLOYEE_OID) + .assertNoRole(ROLE_UNIT_RIDER_OID) + .assertRole(ROLE_UNIT_SLEEPER_OID) + .end() + .links() + .single(); + } + + // TODO: org and relation // TODO: combine autoassign with object template role assign diff --git a/model/model-intest/src/test/resources/rbac/autoassign/role-unit-rider.xml b/model/model-intest/src/test/resources/rbac/autoassign/role-unit-rider.xml new file mode 100644 index 00000000000..a25c84fe6ee --- /dev/null +++ b/model/model-intest/src/test/resources/rbac/autoassign/role-unit-rider.xml @@ -0,0 +1,48 @@ + + + Unit Rider + + + + account + + ri:title + + + Rider + + + + + + + true + + + UserType + + + + autoassign-rider + true + + organizationalUnit + + + + + + + + diff --git a/model/model-intest/src/test/resources/rbac/autoassign/role-unit-sleeper.xml b/model/model-intest/src/test/resources/rbac/autoassign/role-unit-sleeper.xml index bb2f8d1b9f5..51784033504 100644 --- a/model/model-intest/src/test/resources/rbac/autoassign/role-unit-sleeper.xml +++ b/model/model-intest/src/test/resources/rbac/autoassign/role-unit-sleeper.xml @@ -27,6 +27,9 @@ true + + UserType + autoassign-sleeper true diff --git a/model/model-intest/src/test/resources/rbac/autoassign/role-unit-walker.xml b/model/model-intest/src/test/resources/rbac/autoassign/role-unit-walker.xml index fac2063254c..56d4bbb0878 100644 --- a/model/model-intest/src/test/resources/rbac/autoassign/role-unit-walker.xml +++ b/model/model-intest/src/test/resources/rbac/autoassign/role-unit-walker.xml @@ -27,6 +27,9 @@ true + + UserType + autoassign-walker true diff --git a/model/model-intest/src/test/resources/rbac/autoassign/role-unit-worker.xml b/model/model-intest/src/test/resources/rbac/autoassign/role-unit-worker.xml index c0befb16a17..9f079d52252 100644 --- a/model/model-intest/src/test/resources/rbac/autoassign/role-unit-worker.xml +++ b/model/model-intest/src/test/resources/rbac/autoassign/role-unit-worker.xml @@ -27,6 +27,9 @@ true + + UserType + autoassign-worker true