Skip to content

Commit

Permalink
adding possibility to define object selector for autoassignments (MID…
Browse files Browse the repository at this point in the history
…-5497, MID-5734)
  • Loading branch information
katkav committed Jun 8, 2020
1 parent 1fd8183 commit 2033b81
Show file tree
Hide file tree
Showing 7 changed files with 226 additions and 40 deletions.
Expand Up @@ -13116,7 +13116,7 @@
(abstract) role.
</p>
<p>
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.
Expand Down Expand Up @@ -13181,6 +13181,15 @@
</xsd:documentation>
</xsd:annotation>
</xsd:element>
<xsd:element name="selector" type="tns:ObjectSelectorType" minOccurs="0" maxOccurs="1">
<xsd:annotation>
<xsd:documentation>
<p>
Restrics autoassignment to concrete focus type.
</p>
</xsd:documentation>
</xsd:annotation>
</xsd:element>
<!-- TODO: later: mapping is too flexible. It is will be difficult for the
role managers to be set from GUI. But we can support most of the policy rule
constraints here (PolicyConstraintsType). -->
Expand Down Expand Up @@ -13621,7 +13630,7 @@
<xsd:attribute name="id" type="xsd:long" use="optional"/>
</xsd:complexType>

<xsd:complexType name="ObjectSelectorType">
<xsd:complexType name="ObjectSelectorType">
<xsd:annotation>
<xsd:documentation>
Selects some objects from all the objects in midPoint.
Expand Down
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -459,6 +440,11 @@ private <AH extends AssignmentHolderType> 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));
Expand All @@ -470,6 +456,19 @@ private <AH extends AssignmentHolderType> void collectAutoassignMappings(LensCon
cacheRepositoryService.searchObjectsIterative(AbstractRoleType.class, query, handler, GetOperationOptions.createReadOnlyCollection(), true, result);
}

private <AH extends AssignmentHolderType> boolean isApplicableFor(ObjectSelectorType selector, LensFocusContext<AH> 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) {
Expand Down
Expand Up @@ -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;
Expand All @@ -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
Expand All @@ -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);
Expand All @@ -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);
}

/**
Expand Down Expand Up @@ -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
Expand Down
@@ -0,0 +1,48 @@
<!--
~ Copyright (c) 2017 Evolveum and contributors
~
~ This work is dual-licensed under the Apache License 2.0
~ and European Union Public License. See LICENSE file for details.
-->
<role oid="9a60cdc6-f2ad-4414-964b-5fd1dfaec157"
xmlns="http://midpoint.evolveum.com/xml/ns/public/common/common-3"
xmlns:c="http://midpoint.evolveum.com/xml/ns/public/common/common-3"
xmlns:t="http://prism.evolveum.com/xml/ns/public/types-3"
xmlns:piracy="http://midpoint.evolveum.com/xml/ns/samples/piracy">
<name>Unit Rider</name>
<inducement>
<construction xmlns:ri="http://midpoint.evolveum.com/xml/ns/public/resource/instance/10000000-0000-0000-0000-000000000004">
<resourceRef oid="10000000-0000-0000-0000-000000000004" type="c:ResourceType"/>
<kind>account</kind>
<attribute>
<ref>ri:title</ref>
<outbound>
<expression>
<value>Rider</value>
</expression>
</outbound>
</attribute>
</construction>
</inducement>
<autoassign>
<enabled>true</enabled>
<focus>
<selector>
<type>UserType</type>
<archetypeRef oid="7135e68c-ee53-11e8-8025-170b77da3fd6" type="c:ArchetypeType"/>
</selector>
<mapping>
<name>autoassign-rider</name>
<trace>true</trace>
<source>
<path>organizationalUnit</path>
</source>
<condition>
<script>
<code>basic.stringify(organizationalUnit) == 'rider'</code>
</script>
</condition>
</mapping>
</focus>
</autoassign>
</role>
Expand Up @@ -27,6 +27,9 @@
<autoassign>
<enabled>true</enabled>
<focus>
<selector>
<type>UserType</type>
</selector>
<mapping>
<name>autoassign-sleeper</name>
<trace>true</trace>
Expand Down
Expand Up @@ -27,6 +27,9 @@
<autoassign>
<enabled>true</enabled>
<focus>
<selector>
<type>UserType</type>
</selector>
<mapping>
<name>autoassign-walker</name>
<trace>true</trace>
Expand Down
Expand Up @@ -27,6 +27,9 @@
<autoassign>
<enabled>true</enabled>
<focus>
<selector>
<type>UserType</type>
</selector>
<mapping>
<name>autoassign-worker</name>
<trace>true</trace>
Expand Down

0 comments on commit 2033b81

Please sign in to comment.