Skip to content

Commit

Permalink
Merge branch 'master' of github.com:Evolveum/midpoint
Browse files Browse the repository at this point in the history
  • Loading branch information
1azyman committed Feb 28, 2023
2 parents f1a71dd + c419185 commit 0953dd4
Show file tree
Hide file tree
Showing 31 changed files with 358 additions and 267 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1079,7 +1079,7 @@ public static boolean hasAttributeModifications(
.collect(Collectors.toList());
}

private static boolean isResourceModification(ItemDelta<?, ?> modification) {
public static boolean isResourceModification(ItemDelta<?, ?> modification) {
QName firstPathName = modification.getPath().firstName();
return isAttributeModification(firstPathName) || isNonAttributeResourceModification(firstPathName);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*
* Copyright (C) 2010-2023 Evolveum and contributors
*
* This work is dual-licensed under the Apache License 2.0
* and European Union Public License. See LICENSE file for details.
*/

package com.evolveum.midpoint.schema.util.expression;

import com.evolveum.midpoint.xml.ns._public.common.common_3.ExpressionType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectFactory;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ScriptExpressionEvaluatorType;

import org.jetbrains.annotations.NotNull;

/**
* Various methods to assist in creating (maybe later parsing?) objects of {@link ExpressionType}.
*/
public class ExpressionUtil {

public static @NotNull ExpressionType forGroovyCode(String code) {
ExpressionType expression = new ExpressionType();
expression.getExpressionEvaluator().add(
new ObjectFactory().createScript(
new ScriptExpressionEvaluatorType().code(code)));
return expression;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15944,6 +15944,34 @@
</xsd:appinfo>
</xsd:annotation>
</xsd:enumeration>
<xsd:enumeration value="00000000-0000-0000-0000-000000000801">
<xsd:annotation>
<xsd:appinfo>
<jaxb:typesafeEnumMember name="MARK_DECOMMISSION_LATER"/>
</xsd:appinfo>
</xsd:annotation>
</xsd:enumeration>
<xsd:enumeration value="00000000-0000-0000-0000-000000000802">
<xsd:annotation>
<xsd:appinfo>
<jaxb:typesafeEnumMember name="MARK_CORRELATE_LATER"/>
</xsd:appinfo>
</xsd:annotation>
</xsd:enumeration>
<xsd:enumeration value="00000000-0000-0000-0000-000000000803">
<xsd:annotation>
<xsd:appinfo>
<jaxb:typesafeEnumMember name="MARK_DO_NOT_TOUCH"/>
</xsd:appinfo>
</xsd:annotation>
</xsd:enumeration>
<xsd:enumeration value="00000000-0000-0000-0000-000000000804">
<xsd:annotation>
<xsd:appinfo>
<jaxb:typesafeEnumMember name="MARK_INVALID_DATA"/>
</xsd:appinfo>
</xsd:annotation>
</xsd:enumeration>
<xsd:enumeration value="00000000-0000-0000-0000-000000001005">
<xsd:annotation>
<xsd:appinfo>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3457,17 +3457,6 @@
</xsd:appinfo>
</xsd:annotation>
</xsd:enumeration>
<xsd:enumeration value="policySituation">
<xsd:annotation>
<xsd:documentation>
Resource object was excluded from synchronization because of a (unspecified) policy situation.
<!-- We may add more specific reasons here later. Or will we report that in a different way? -->
</xsd:documentation>
<xsd:appinfo>
<jaxb:typesafeEnumMember name="POLICY_SITUATION"/>
</xsd:appinfo>
</xsd:annotation>
</xsd:enumeration>
<xsd:enumeration value="noSynchronizationPolicy">
<xsd:annotation>
<xsd:documentation>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1928,6 +1928,11 @@ public boolean isVisible() throws SchemaException, ConfigurationException {
return SimulationUtil.isVisible(resource, getStructuralObjectDefinition(), getTaskExecutionMode());
}

public boolean hasResourceAndIsVisible() throws SchemaException, ConfigurationException {
return resource != null
&& SimulationUtil.isVisible(resource, getStructuralObjectDefinition(), getTaskExecutionMode());
}

private @NotNull TaskExecutionMode getTaskExecutionMode() {
return lensContext.getTaskExecutionMode();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ class LinkUpdater<F extends FocusType> {
this.clock = beans.clock;
}

void updateLinks(OperationResult parentResult) throws SchemaException, ObjectNotFoundException {
void updateLinks(OperationResult parentResult) throws SchemaException, ObjectNotFoundException, ConfigurationException {

OperationResult result = parentResult.subresult(OP_UPDATE_LINKS)
.setMinor()
Expand Down Expand Up @@ -355,7 +355,7 @@ private void setLinkRefInFocus(QName relation, OperationResult result)
executeFocusDelta(delta, OP_LINK_ACCOUNT, result);
}

private boolean checkOidPresent() {
private boolean checkOidPresent() throws SchemaException, ConfigurationException {
if (projCtx.getOid() != null) {
return false;
}
Expand All @@ -365,6 +365,11 @@ private boolean checkOidPresent() {
projCtx.toHumanReadableString());
return true;
}
if (!projCtx.isVisible()) {
LOGGER.trace("Shadow OID not present in invisible account -> not updating links. In: {}",
projCtx.toHumanReadableString());
return true;
}
LOGGER.error("Projection {} has null OID, this should not happen, context:\n{}", projCtx.toHumanReadableString(),
projCtx.debugDump());
throw new IllegalStateException("Projection " + projCtx.toHumanReadableString() + " has null OID, this should not happen");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@

import java.util.Collection;

import com.evolveum.midpoint.schema.util.ShadowUtil;

import org.jetbrains.annotations.NotNull;

import com.evolveum.midpoint.model.api.ProgressInformation;
Expand Down Expand Up @@ -89,21 +91,29 @@ public void execute(OperationResult parentResult) throws SchemaException, Object
try {
LOGGER.trace("Executing projection context {}", projCtx.toHumanReadableString());

// We want to execute the changes for no-resource contexts e.g. to remove dead links
if (projCtx.hasResource() && !projCtx.isVisible()) {
LOGGER.trace("Resource object definition is not visible; skipping change execution (if there's any)");
result.recordNotApplicable("Not visible");
return;
}

context.reportProgress(new ProgressInformation(RESOURCE_OBJECT_OPERATION, projCtx.getKey(), ENTERING));

ScriptExecutor<O> scriptExecutor = new ScriptExecutor<>(context, projCtx, task, b);
scriptExecutor.executeReconciliationScripts(BeforeAfterType.BEFORE, result);

projectionDelta = projCtx.getExecutableDelta();

emptyToDeleteDeltaIfNeeded();
if (projCtx.hasResourceAndIsVisible()) {
emptyToDeleteDeltaIfNeeded();
} else if (projectionDelta != null) {
if (projectionDelta.isAdd() || projectionDelta.isDelete()) {
LOGGER.trace("Resource object definition is not visible -> skipping application of ADD/DELETE deltas");
projectionDelta = null;
} else {
assert projectionDelta.isModify();
if (ShadowUtil.hasResourceModifications(projectionDelta.getModifications())) {
LOGGER.trace("Resource object definition is not visible -> deleting on-resource modifications from it");
projectionDelta = projectionDelta.clone();
projectionDelta.getModifications().removeIf( // not very nice -> TODO add support for such op into delta
mod -> ShadowUtil.isResourceModification(mod));
}
}
}

if (deletingHigherOrderContextWithLowerAlreadyDeleted()) {
result.recordNotApplicable();
Expand All @@ -113,7 +123,7 @@ public void execute(OperationResult parentResult) throws SchemaException, Object
boolean skipDeltaExecution;
if (projCtx.isBroken() && !ObjectDelta.isDelete(projectionDelta)) {
LOGGER.trace("Ignoring non-delete delta for broken context {}", projCtx.getKey());
skipDeltaExecution = true;
skipDeltaExecution = true; // TODO what about repo-only deltas (e.g. setting policy statements)?
} else {
skipDeltaExecution = ObjectDelta.isEmpty(projectionDelta);
}
Expand Down Expand Up @@ -316,7 +326,7 @@ private boolean isEquivalentAddDelta(PrismObject<ShadowType> object1, PrismObjec
/**
* Make sure that the account is linked (or unlinked) as needed.
*/
private void updateLinks(OperationResult result) throws ObjectNotFoundException, SchemaException {
private void updateLinks(OperationResult result) throws ObjectNotFoundException, SchemaException, ConfigurationException {
LensFocusContext<O> focusContext = context.getFocusContext();
if (focusContext == null || !focusContext.represents(FocusType.class)) {
LOGGER.trace("Missing or non-FocusType focus context, not updating the links");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
package com.evolveum.midpoint.model.impl.sync;

import java.util.Collection;
import java.util.List;

import com.evolveum.midpoint.schema.processor.ResourceObjectDefinition;
import com.evolveum.midpoint.schema.processor.ResourceObjectTypeIdentification;
Expand Down Expand Up @@ -194,12 +193,12 @@ boolean isSynchronizationEnabled() {
&& synchronizationPolicy.isSynchronizationEnabled();
}

public boolean isMarkedSkipSynchronization() {
boolean isMarkedSkipSynchronization(OperationResult result) {
var policy = shadowedResourceObject.getEffectiveOperationPolicy();
// Policy should not be null if was provided by provisioning-impl, but sometimes in tests
// provisioning is skipped, so we need to ensure policy is computed.
if (policy == null) {
policy = ObjectOperationPolicyHelper.get().computeEffectivePolicy(shadowedResourceObject, new OperationResult("markedSkipSynchronization"));
policy = ObjectOperationPolicyHelper.get().computeEffectivePolicy(shadowedResourceObject, result);
}
return !policy.getSynchronize().getInbound().isEnabled();
}
Expand Down Expand Up @@ -517,15 +516,6 @@ public boolean isVisible() {
return SimulationUtil.isVisible(resource, resourceObjectDefinition, task.getExecutionMode());
}

/**
* TEMPORARY IMPLEMENTATION
*
* Later, we will have a dictionary of those situations with the information how they affect the synchronization process.
*/
boolean isSynchronizationPreventedByShadowPolicySituation() {
return !shadowedResourceObject.getPolicySituation().isEmpty();
}

/**
* Synchronization context ready for the synchronization, i.e. it has type identification and synchronization policy present.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,7 @@ private boolean shouldSkipSynchronization(SynchronizationContext<?> syncCtx, Ope
return true;
}

if (syncCtx.isMarkedSkipSynchronization()) {
if (syncCtx.isMarkedSkipSynchronization(result)) {
String message = String.format(
"SYNCHRONIZATION is skipped for marked shadow %s, ignoring change from channel %s", shadow, channel);
LOGGER.debug(message);
Expand All @@ -242,7 +242,6 @@ private boolean shouldSkipSynchronization(SynchronizationContext<?> syncCtx, Ope
return true;
}


if (syncCtx.isProtected()) {
String message = String.format(
"SYNCHRONIZATION is skipped for protected shadow %s, ignoring change from channel %s", shadow, channel);
Expand All @@ -255,18 +254,6 @@ private boolean shouldSkipSynchronization(SynchronizationContext<?> syncCtx, Ope
return true;
}

if (syncCtx.isSynchronizationPreventedByShadowPolicySituation()) {
String message = String.format(
"SYNCHRONIZATION is skipped for %s because of the policy situation %s, ignoring change from channel %s",
shadow, shadow.getPolicySituation(), channel);
LOGGER.debug(message);
syncCtx.getUpdater()
.updateAllSyncMetadataRespectingMode();
result.recordNotApplicable(message);
syncCtx.recordSyncExclusionInTask(POLICY_SITUATION);
return true;
}

return false;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
package com.evolveum.midpoint.model.intest;

import static com.evolveum.midpoint.test.util.MidPointTestConstants.TEST_RESOURCES_DIR;
import static org.testng.Assert.assertNotNull;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNotNull;

import static com.evolveum.midpoint.test.util.MidPointTestConstants.TEST_RESOURCES_DIR;

import java.io.File;

Expand All @@ -20,26 +21,8 @@
import com.evolveum.midpoint.schema.result.OperationResult;
import com.evolveum.midpoint.task.api.Task;
import com.evolveum.midpoint.test.DummyTestResource;
import com.evolveum.midpoint.test.TestResource;
import com.evolveum.midpoint.util.exception.CommonException;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ArchetypeType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.AssignmentType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.GlobalPolicyRuleType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.MarkType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectOperationPolicyType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectReferenceType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectSelectorType;
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.OperationPolicyConfigurationType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.PolicyConstraintsType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.PolicyRuleEvaluationTargetType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.PolicyStatementType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.PolicyStatementTypeType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.SynchronizeOperationPolicyConfigurationType;
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.midpoint.test.TestObject;
import com.evolveum.midpoint.xml.ns._public.common.common_3.*;

@ContextConfiguration(locations = {"classpath:ctx-model-intest-test-main.xml"})
@DirtiesContext(classMode = ClassMode.AFTER_CLASS)
Expand All @@ -55,7 +38,7 @@ public class TestShadowMarks extends AbstractEmptyModelIntegrationTest {
private static final ItemName ENT_PERSONAL_NUMBER = new ItemName(NS_ENT, "personalNumber");
private static final ItemPath PATH_PERSONAL_NUMBER = ItemPath.create(ObjectType.F_EXTENSION, ENT_PERSONAL_NUMBER);

public static final DummyTestResource RESOURCE_SINGLE = new DummyTestResource(
private static final DummyTestResource RESOURCE_SINGLE = new DummyTestResource(
TEST_DIR, "resource-single-outbound.xml", "157796ed-d4f2-429d-84f3-00ce4164263b", "single",
controller -> {
controller.addAttrDef(controller.getDummyResource().getAccountObjectClass(),
Expand All @@ -66,9 +49,9 @@ public class TestShadowMarks extends AbstractEmptyModelIntegrationTest {
ATTR_PERSONAL_NUMBER, String.class, false, false);
});

private static final TestResource<ArchetypeType> ARCHETYPE_PERSON = new TestResource<>(
private static final TestObject<ArchetypeType> ARCHETYPE_PERSON = TestObject.file(
TEST_DIR, "archetype-person.xml", "3a6f3ddd-ac72-4656-abac-0e306cd29645");
private static final TestResource<ObjectTemplateType> OBJECT_TEMPLATE_PERSON = new TestResource<>(
private static final TestObject<ObjectTemplateType> OBJECT_TEMPLATE_PERSON = TestObject.file(
TEST_DIR, "object-template-person.xml", "c0d96ed0-bec7-4c6e-9a69-133b0301bdb8");

private String markNoSyncOid;
Expand All @@ -84,7 +67,7 @@ public void initSystem(Task initTask, OperationResult initResult) throws Excepti
addObject(ARCHETYPE_PERSON, initTask, initResult);
initAndTestDummyResource(RESOURCE_SINGLE, initTask, initResult);
addObject(CommonInitialObjects.ARCHETYPE_OBJECT_MARK, initTask, initResult);
addObject(CommonInitialObjects.MARK_PROTECTED_SHADOW, initTask, initResult);
addObject(CommonInitialObjects.MARK_PROTECTED, initTask, initResult);

markNoSyncOid = addObject(new MarkType()
.name("Skip Synchronization")
Expand Down Expand Up @@ -123,9 +106,6 @@ public void initSystem(Task initTask, OperationResult initResult) throws Excepti
.outbound(new OperationPolicyConfigurationType().enabled(false))
)
), initTask, initResult);



}

@Test
Expand Down Expand Up @@ -237,7 +217,6 @@ public void test200ImportUserAndMarkReadOnly() throws Exception {
@Test
void test300importUserWithBrokenMapping() throws Exception {
var result = createOperationResult();
var task = createTask();
DummyAccount account1 = RESOURCE_SINGLE.controller.addAccount("broken");
account1.addAttributeValue(ATTR_GIVEN_NAME, "Karl");
account1.addAttributeValue(ATTR_FAMILY_NAME, "Reddy");
Expand All @@ -252,19 +231,10 @@ void test300importUserWithBrokenMapping() throws Exception {
assertNotNull(result);
}

private void markShadow(String oid, String markOid, Task task, OperationResult result) throws CommonException {
var statement = new PolicyStatementType()
.markRef(markOid, MarkType.COMPLEX_TYPE)
.type(PolicyStatementTypeType.APPLY);
modifyObjectAddContainer(ShadowType.class, oid, ShadowType.F_POLICY_STATEMENT, task, result, statement);
};

// Add users / synchronize users
// Mark shadow "Correlate later" and verify it is not synced

// Mark Existing user shadow "Do not touch" and verify it is not synced / modified

// Mark existing user shadow "Invalid data and verify it is not synced / modified"


}
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ public void initSystem(Task initTask, OperationResult initResult) throws Excepti

if (areMarksSupported()) {
repoAdd(CommonInitialObjects.ARCHETYPE_OBJECT_MARK, initResult);
repoAdd(CommonInitialObjects.MARK_PROTECTED_SHADOW, initResult);
repoAdd(CommonInitialObjects.MARK_PROTECTED, initResult);
}
assumeAssignmentPolicy(AssignmentPolicyEnforcementType.NONE);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ public void initSystem(Task initTask, OperationResult initResult) throws Excepti

if (areMarksSupported()) {
repoAdd(CommonInitialObjects.ARCHETYPE_OBJECT_MARK, initResult);
repoAdd(CommonInitialObjects.MARK_PROTECTED_SHADOW, initResult);
repoAdd(CommonInitialObjects.MARK_PROTECTED, initResult);
}
// templates
repoAddObjectFromFile(USER_TEMPLATE_FILE, initResult);
Expand Down

0 comments on commit 0953dd4

Please sign in to comment.