Skip to content

Commit

Permalink
MID-4270 (modification constraint ignores some modifications) + imple…
Browse files Browse the repository at this point in the history
…mented subtype for object selector
  • Loading branch information
mederly committed Nov 21, 2017
1 parent 5ee99d4 commit 5456e76
Show file tree
Hide file tree
Showing 9 changed files with 124 additions and 10 deletions.
Expand Up @@ -47,6 +47,7 @@
import com.evolveum.prism.xml.ns._public.types_3.ItemDeltaType;
import com.evolveum.prism.xml.ns._public.types_3.ModificationTypeType;
import org.apache.commons.collections4.CollectionUtils;
import org.jetbrains.annotations.NotNull;

/**
* @author Radovan Semancik
Expand Down Expand Up @@ -2008,4 +2009,13 @@ public static <V extends PrismValue, D extends ItemDefinition> ItemDelta<V, D> c
return rv;
}

public static boolean pathMatches(@NotNull Collection<? extends ItemDelta<?, ?>> deltas, @NotNull ItemPath path, int segmentsToSkip) {
for (ItemDelta<?, ?> delta : deltas) {
ItemPath modifiedPath = delta.getPath().tail(segmentsToSkip).removeIdentifiers(); // because of extension/cities[2]/name (in delta) vs. extension/cities/name (in spec)
if (path.isSubPathOrEquivalent(modifiedPath)) {
return true;
}
}
return false;
}
}
Expand Up @@ -256,10 +256,13 @@ public ItemPath head() {
*/
@NotNull
public ItemPath tail(int n) {
if (segments.size() < n) {
if (n == 0) {
return this;
} else if (segments.size() < n) {
return EMPTY_PATH;
} else {
return new ItemPath(segments.subList(n, segments.size()));
}
return new ItemPath(segments.subList(n, segments.size()));
}

@NotNull
Expand Down
Expand Up @@ -48,6 +48,8 @@
import java.util.Collections;
import java.util.List;

import static java.util.Collections.emptySet;
import static java.util.Collections.singleton;
import static org.apache.commons.collections4.CollectionUtils.emptyIfNull;

/**
Expand Down Expand Up @@ -797,4 +799,20 @@ public static LocalizableMessage createTypeDisplayInformation(String objectClass
.fallbackMessage(objectClassName)
.build();
}

@NotNull
public static <O extends ObjectType> Collection<String> getSubtypeValues(@NotNull PrismObject<O> object) {
O o = object.asObjectable();
if (o instanceof UserType) {
return ((UserType) o).getEmployeeType();
} else if (o instanceof RoleType) {
return singleton(((RoleType) o).getRoleType());
} else if (o instanceof OrgType) {
return ((OrgType) o).getOrgType();
} else if (o instanceof ServiceType) {
return ((ServiceType) o).getServiceType();
} else {
return emptySet();
}
}
}
Expand Up @@ -166,12 +166,6 @@ private boolean pathMatches(AssignmentType assignment, ItemPath path) throws Sch
}

private boolean pathMatches(Collection<? extends ItemDelta<?, ?>> deltas, ItemPath path) {
for (ItemDelta<?, ?> delta : emptyIfNull(deltas)) {
// TODO what about changes like extension/cities[2]/name (in delta) vs. extension/cities/name (in spec)
if (path.isSubPathOrEquivalent(delta.getPath().tail(2))) {
return true;
}
}
return false;
return ItemDelta.pathMatches(emptyIfNull(deltas), path, 2);
}
}
Expand Up @@ -22,6 +22,7 @@
import com.evolveum.midpoint.model.impl.lens.projector.policy.ObjectPolicyRuleEvaluationContext;
import com.evolveum.midpoint.model.impl.lens.projector.policy.PolicyRuleEvaluationContext;
import com.evolveum.midpoint.prism.PrismObject;
import com.evolveum.midpoint.prism.delta.ItemDelta;
import com.evolveum.midpoint.prism.delta.ObjectDelta;
import com.evolveum.midpoint.prism.path.ItemPath;
import com.evolveum.midpoint.schema.constants.SchemaConstants;
Expand All @@ -48,6 +49,8 @@
import javax.xml.bind.JAXBElement;
import java.util.List;

import static org.apache.commons.collections4.CollectionUtils.emptyIfNull;

/**
* @author semancik
* @author mederly
Expand Down Expand Up @@ -142,7 +145,7 @@ private <F extends FocusType> boolean pathMatches(ObjectDelta<?> delta, PrismObj
} else if (delta.isDelete()) {
return objectOld != null && objectOld.containsItem(path, false);
} else {
return delta.findItemDelta(path) != null;
return ItemDelta.pathMatches(emptyIfNull(delta.getModifications()), path, 0);
}
}

Expand Down
Expand Up @@ -36,6 +36,7 @@
import com.evolveum.midpoint.test.util.TestUtil;
import com.evolveum.midpoint.util.DebugUtil;
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.xml.ns._public.common.common_3.*;
import org.springframework.test.annotation.DirtiesContext;
Expand Down Expand Up @@ -74,6 +75,7 @@ public class TestPolicyRules2 extends AbstractLensTest {
protected static final File ROLE_CYCLIC_REFERENCES_FILE = new File(TEST_DIR, "role-cyclic-references.xml");
protected static final File ROLE_UNRESOLVABLE_REFERENCES_FILE = new File(TEST_DIR, "role-unresolvable-references.xml");
protected static final File ROLE_AMBIGUOUS_REFERENCE_FILE = new File(TEST_DIR, "role-ambiguous-reference.xml");
protected static final File ROLE_IMMUTABLE_INDUCEMENTS_FILE = new File(TEST_DIR, "role-immutable-inducements.xml");

private static final int STUDENT_TARGET_RULES = 6; // one is global
private static final int STUDENT_FOCUS_RULES = 21;
Expand All @@ -82,6 +84,7 @@ public class TestPolicyRules2 extends AbstractLensTest {

private String rolePersonOid;
private String roleTemporaryOid;
private String roleImmutableInducementsOid;
private String roleStudentOid;
private String userJoeOid;
private String userFrankOid;
Expand All @@ -91,6 +94,7 @@ public void initSystem(Task initTask, OperationResult initResult) throws Excepti
super.initSystem(initTask, initResult);
setDefaultUserTemplate(USER_TEMPLATE_OID);

roleImmutableInducementsOid = repoAddObjectFromFile(ROLE_IMMUTABLE_INDUCEMENTS_FILE, initResult).getOid(); // using repo because the inducement is present in the object
rolePersonOid = addAndRecompute(ROLE_PERSON_FILE, initTask, initResult);
roleTemporaryOid = addAndRecompute(ROLE_TEMPORARY_FILE, initTask, initResult);
roleStudentOid = addAndRecompute(ROLE_STUDENT_FILE, initTask, initResult);
Expand Down Expand Up @@ -814,5 +818,39 @@ public void test230AddAmbiguous() throws Exception {
}
}

// MID-4270
@Test
public void test300ModifyInducement() throws Exception {
final String TEST_NAME = "test300ModifyInducement";
TestUtil.displayTestTitle(this, TEST_NAME);

// GIVEN
Task task = taskManager.createTaskInstance(TestPolicyRules2.class.getName() + "." + TEST_NAME);
OperationResult result = task.getResult();

ObjectDelta<RoleType> delta = DeltaBuilder.deltaFor(RoleType.class, prismContext)
.item(RoleType.F_INDUCEMENT, 1L, AssignmentType.F_DESCRIPTION).replace("hi")
.asObjectDeltaCast(roleImmutableInducementsOid);
LensContext<RoleType> context = createLensContext(RoleType.class);
context.createFocusContext().setPrimaryDelta(delta);
display("Input context", context);

assertFocusModificationSanity(context);

// WHEN
TestUtil.displayWhen(TEST_NAME);
try {
clockwork.run(context, task, result);
TestUtil.displayThen(TEST_NAME);
fail("unexpected success");
} catch (PolicyViolationException e) {
TestUtil.displayThen(TEST_NAME);
System.out.println("Expected exception: " + e);
e.printStackTrace(System.out);
if (!e.getMessage().contains("Role \"Immutable inducements\" is to be modified")) {
fail("Exception message was not as expected: " + e.getMessage());
}
}
}

}
Expand Up @@ -106,6 +106,21 @@
</expression>
</condition>
</globalPolicyRule>
<globalPolicyRule>
<name>Immutable inducements</name>
<policyConstraints>
<modification>
<item>inducement</item>
</modification>
</policyConstraints>
<policyActions>
<enforcement/>
</policyActions>
<focusSelector>
<type>RoleType</type>
<subtype>immutable-inducements</subtype>
</focusSelector>
</globalPolicyRule>
<adminGuiConfiguration>
<userDashboardLink>
<targetUrl>/foo</targetUrl>
Expand Down
@@ -0,0 +1,23 @@
<!--
~ Copyright (c) 2010-2017 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.
-->
<role oid="cfdac6b8-f6e2-4bee-8c3e-97a377257d4b"
xmlns="http://midpoint.evolveum.com/xml/ns/public/common/common-3">
<name>Immutable inducements</name>
<inducement id="1">
<targetRef type="RoleType" oid="00000000-0000-0000-0000-000000000004" />
</inducement>
<roleType>immutable-inducements</roleType>
</role>
Expand Up @@ -1005,6 +1005,16 @@ public <O extends ObjectType> boolean selectorMatches(ObjectSelectorType objectS
return false;
}

// Subtype
String specSubtype = objectSelector.getSubtype();
if (specSubtype != null) {
Collection<String> actualSubtypeValues = ObjectTypeUtil.getSubtypeValues(object);
if (!actualSubtypeValues.contains(specSubtype)) {
logger.trace("{} subtype mismatch, expected {}, was {}", logMessagePrefix, specSubtype, actualSubtypeValues);
return false;
}
}

// Filter
if (specFilterType != null) {
ObjectFilter specFilter = QueryJaxbConvertor.createObjectFilter(object.getCompileTimeClass(), specFilterType, object.getPrismContext());
Expand Down

0 comments on commit 5456e76

Please sign in to comment.