diff --git a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ProvisioningServiceImpl.java b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ProvisioningServiceImpl.java index 7803428dd4a..c6c5fad37b1 100644 --- a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ProvisioningServiceImpl.java +++ b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ProvisioningServiceImpl.java @@ -23,13 +23,6 @@ import javax.annotation.PreDestroy; import javax.xml.namespace.QName; -import com.evolveum.midpoint.common.refinery.RefinedObjectClassDefinition; -import com.evolveum.midpoint.prism.*; -import com.evolveum.midpoint.provisioning.api.ConstraintViolationConfirmer; -import com.evolveum.midpoint.provisioning.api.ConstraintsCheckingResult; -import com.evolveum.midpoint.schema.LabeledString; -import com.evolveum.midpoint.schema.ProvisioningDiag; - import org.apache.commons.lang.Validate; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; @@ -38,6 +31,12 @@ import com.evolveum.midpoint.common.InternalsConfig; import com.evolveum.midpoint.common.crypto.CryptoUtil; +import com.evolveum.midpoint.common.refinery.RefinedObjectClassDefinition; +import com.evolveum.midpoint.prism.Objectable; +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.delta.ItemDelta; import com.evolveum.midpoint.prism.delta.ObjectDelta; import com.evolveum.midpoint.prism.delta.PropertyDelta; @@ -45,6 +44,8 @@ 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.provisioning.api.ConstraintViolationConfirmer; +import com.evolveum.midpoint.provisioning.api.ConstraintsCheckingResult; import com.evolveum.midpoint.provisioning.api.GenericConnectorException; import com.evolveum.midpoint.provisioning.api.ProvisioningOperationOptions; import com.evolveum.midpoint.provisioning.api.ProvisioningService; @@ -54,6 +55,8 @@ import com.evolveum.midpoint.repo.api.RepoAddOptions; import com.evolveum.midpoint.repo.api.RepositoryService; import com.evolveum.midpoint.schema.GetOperationOptions; +import com.evolveum.midpoint.schema.LabeledString; +import com.evolveum.midpoint.schema.ProvisioningDiag; import com.evolveum.midpoint.schema.ResourceShadowDiscriminator; import com.evolveum.midpoint.schema.ResultHandler; import com.evolveum.midpoint.schema.SearchResultList; @@ -638,6 +641,7 @@ private PrismObject completeObject(Class type, Pris } else { //TODO: applyDefinition??? applyDefinition(inObject, result); + setProtectedShadow((PrismObject) inObject, result); return inObject; } @@ -1025,6 +1029,46 @@ public void finishOperation(PrismObject object, Provis } result.cleanupResult(); } + + private boolean handleRepoObject(final Class type, PrismObject object, + final Collection> options, + final ResultHandler handler, final OperationResult objResult){ + PrismObject completeObject; + try { + completeObject = completeObject(type, object, options, objResult); + } catch (SchemaException e) { + LOGGER.error("Error while completing {}: {}. Using non-complete object.", new Object[] { + object, e.getMessage(), e }); + objResult.recordFatalError(e); + object.asObjectable().setFetchResult(objResult.createOperationResultType()); + completeObject = object; + } catch (ObjectNotFoundException e) { + LOGGER.error("Error while completing {}: {}. Using non-complete object.", new Object[] { + object, e.getMessage(), e }); + objResult.recordFatalError(e); + object.asObjectable().setFetchResult(objResult.createOperationResultType()); + completeObject = object; + } catch (CommunicationException e) { + LOGGER.error("Error while completing {}: {}. Using non-complete object.", new Object[] { + object, e.getMessage(), e }); + objResult.recordFatalError(e); + object.asObjectable().setFetchResult(objResult.createOperationResultType()); + completeObject = object; + } catch (ConfigurationException e) { + LOGGER.error("Error while completing {}: {}. Using non-complete object.", new Object[] { + object, e.getMessage(), e }); + objResult.recordFatalError(e); + object.asObjectable().setFetchResult(objResult.createOperationResultType()); + completeObject = object; + } + validateObject(completeObject); + + objResult.computeStatus(); + objResult.recordSuccessIfUnknown(); + + return handler.handle(completeObject, objResult); + + } @SuppressWarnings({ "rawtypes", "unchecked" }) @Override @@ -1069,45 +1113,18 @@ public SearchResultMetadata searchObjectsIterative(final return metadata; } - GetOperationOptions rootOptions = SelectorOptions.findRootOptions(options); + final GetOperationOptions rootOptions = SelectorOptions.findRootOptions(options); - if (!ShadowType.class.isAssignableFrom(type) || GetOperationOptions.isNoFetch(rootOptions)) { + if (!ShadowType.class.isAssignableFrom(type)){ + ResultHandler internalHandler = new ResultHandler() { @Override public boolean handle(PrismObject object, OperationResult objResult) { - PrismObject completeObject; - try { - completeObject = completeObject(type, object, options, objResult); - } catch (SchemaException e) { - LOGGER.error("Error while completing {}: {}. Using non-complete object.", new Object[] { - object, e.getMessage(), e }); - objResult.recordFatalError(e); - object.asObjectable().setFetchResult(objResult.createOperationResultType()); - completeObject = object; - } catch (ObjectNotFoundException e) { - LOGGER.error("Error while completing {}: {}. Using non-complete object.", new Object[] { - object, e.getMessage(), e }); - objResult.recordFatalError(e); - object.asObjectable().setFetchResult(objResult.createOperationResultType()); - completeObject = object; - } catch (CommunicationException e) { - LOGGER.error("Error while completing {}: {}. Using non-complete object.", new Object[] { - object, e.getMessage(), e }); - objResult.recordFatalError(e); - object.asObjectable().setFetchResult(objResult.createOperationResultType()); - completeObject = object; - } catch (ConfigurationException e) { - LOGGER.error("Error while completing {}: {}. Using non-complete object.", new Object[] { - object, e.getMessage(), e }); - objResult.recordFatalError(e); - object.asObjectable().setFetchResult(objResult.createOperationResultType()); - completeObject = object; - } - validateObject(completeObject); - return handler.handle(completeObject, objResult); + return handleRepoObject(type, object, options, handler, objResult); } }; + SearchResultMetadata metadata = null; try { @@ -1126,12 +1143,21 @@ public boolean handle(PrismObject object, OperationResult objResult) { } return metadata; - } + } + final ShadowHandler shadowHandler = new ShadowHandler() { @Override public boolean handle(ShadowType shadowType) { + + OperationResult handleResult = result.createSubresult(ProvisioningService.class.getName() + + ".searchObjectsIterative.handle"); + + if (GetOperationOptions.isNoFetch(rootOptions)){ + return handleRepoObject(type, shadowType.asPrismObject(), options, handler, handleResult); + } + if (shadowType == null) { throw new IllegalArgumentException("Null shadow in call to handler"); } @@ -1140,8 +1166,7 @@ public boolean handle(ShadowType shadowType) { SchemaDebugUtil.prettyPrint(shadowType)); } - OperationResult handleResult = result.createSubresult(ProvisioningService.class.getName() - + ".searchObjectsIterative.handle"); + boolean doContinue; try { @@ -1341,6 +1366,10 @@ public void applyDefinition(PrismObject object, Operat result.cleanupResult(); } } + + private void setProtectedShadow(PrismObject shdaow, OperationResult result) throws ObjectNotFoundException, SchemaException, CommunicationException, ConfigurationException { + getShadowCache(Mode.STANDARD).setProtectedShadow(shdaow, result); + } @Override public void applyDefinition(Class type, ObjectQuery query, OperationResult parentResult) 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 a4b08adfd62..cf76b085a21 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 @@ -294,7 +294,7 @@ public PrismObject addResourceObject(ProvisioningContext ctx, Collection> resourceAttributesAfterAdd = null; - if (isProtectedShadow(ctx.getObjectClassDefinition(), shadowClone)) { + if (ProvisioningUtil.isProtectedShadow(ctx.getObjectClassDefinition(), shadowClone, matchingRuleRegistry)) { LOGGER.error("Attempt to add protected shadow " + shadowType + "; ignoring the request"); throw new SecurityViolationException("Cannot get protected shadow " + shadowType); } @@ -371,7 +371,7 @@ public void deleteResourceObject(ProvisioningContext ctx, PrismObject> identifiers = ShadowUtil .getIdentifiers(shadow); - if (isProtectedShadow(ctx.getObjectClassDefinition(), shadow)) { + if (ProvisioningUtil.isProtectedShadow(ctx.getObjectClassDefinition(), shadow, matchingRuleRegistry)) { LOGGER.error("Attempt to delete protected resource object " + ctx.getObjectClassDefinition() + ": " + identifiers + "; ignoring the request"); throw new SecurityViolationException("Cannot delete protected resource object " @@ -443,7 +443,7 @@ public Collection> modifyResourceObject( Collection> identifiers = ShadowUtil.getIdentifiers(repoShadow); - if (isProtectedShadow(ctx.getObjectClassDefinition(), repoShadow)) { + if (ProvisioningUtil.isProtectedShadow(ctx.getObjectClassDefinition(), repoShadow, matchingRuleRegistry)) { if (hasChangesOnResource(itemDeltas)) { LOGGER.error("Attempt to modify protected resource object " + objectClassDefinition + ": " + identifiers); @@ -1613,7 +1613,7 @@ private PrismObject postProcessResourceObjectRead(ProvisioningContex ShadowType resourceObjectType = resourceObject.asObjectable(); setCachingMetadata(ctx, resourceObject); - setProtectedFlag(ctx, resourceObject); + ProvisioningUtil.setProtectedFlag(ctx, resourceObject, matchingRuleRegistry); // Simulated Activation // FIXME??? when there are not native capabilities for activation, the @@ -1639,12 +1639,6 @@ private PrismObject postProcessResourceObjectRead(ProvisioningContex return resourceObject; } - public void setProtectedFlag(ProvisioningContext ctx, PrismObject resourceObject) throws SchemaException, ConfigurationException, ObjectNotFoundException, CommunicationException { - if (isProtectedShadow(ctx.getObjectClassDefinition(), resourceObject)) { - resourceObject.asObjectable().setProtectedObject(true); - } - } - public void setCachingMetadata(ProvisioningContext ctx, PrismObject resourceObject) throws SchemaException, ConfigurationException, ObjectNotFoundException, CommunicationException { CachingMetadataType cachingMetadata = new CachingMetadataType(); cachingMetadata.setRetrievalTimestamp(clock.currentTimeXMLGregorianCalendar()); @@ -2175,20 +2169,5 @@ private void addExecuteScriptOperation(Collection operations, Provisi } } - private boolean isProtectedShadow(RefinedObjectClassDefinition objectClassDefinition, PrismObject shadow) throws SchemaException { - boolean isProtected = false; - if (objectClassDefinition == null) { - isProtected = false; - } else { - Collection protectedAccountPatterns = objectClassDefinition.getProtectedObjectPatterns(); - if (protectedAccountPatterns == null) { - isProtected = false; - } else { - isProtected = ResourceObjectPattern.matches(shadow, protectedAccountPatterns, matchingRuleRegistry); - } - } - LOGGER.trace("isProtectedShadow: {}: {} = {}", new Object[] { objectClassDefinition, - shadow, isProtected }); - return isProtected; - } + } 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 5d3f01f622b..9aac6c2a55d 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 @@ -53,6 +53,7 @@ import com.evolveum.midpoint.prism.delta.ItemDelta; import com.evolveum.midpoint.prism.delta.ObjectDelta; import com.evolveum.midpoint.prism.delta.PropertyDelta; +import com.evolveum.midpoint.prism.match.MatchingRuleRegistry; import com.evolveum.midpoint.prism.path.IdItemPathSegment; import com.evolveum.midpoint.prism.path.ItemPath; import com.evolveum.midpoint.prism.path.NameItemPathSegment; @@ -80,6 +81,7 @@ import com.evolveum.midpoint.provisioning.ucf.api.GenericFrameworkException; import com.evolveum.midpoint.provisioning.ucf.api.PropertyModificationOperation; import com.evolveum.midpoint.provisioning.ucf.api.ResultHandler; +import com.evolveum.midpoint.provisioning.util.ProvisioningUtil; import com.evolveum.midpoint.repo.api.RepositoryService; import com.evolveum.midpoint.schema.DeltaConvertor; import com.evolveum.midpoint.schema.GetOperationOptions; @@ -160,6 +162,9 @@ public abstract class ShadowCache { @Autowired(required = true) private ResourceObjectConverter resouceObjectConverter; + @Autowired(required=true) + private MatchingRuleRegistry matchingRuleRegistry; + @Autowired(required = true) protected ShadowManager shadowManager; @@ -578,7 +583,14 @@ public void applyDefinition(PrismObject shadow, OperationResult pare throws SchemaException, ObjectNotFoundException, CommunicationException, ConfigurationException { ProvisioningContext ctx = ctxFactory.create(shadow, null, parentResult); ctx.assertDefinition(); - applyAttributesDefinition(ctx, shadow); + ctx = applyAttributesDefinition(ctx, shadow); + + } + + public void setProtectedShadow(PrismObject shadow, OperationResult parentResult) throws ObjectNotFoundException, SchemaException, CommunicationException, ConfigurationException { + ProvisioningContext ctx = ctxFactory.create(shadow, null, parentResult); + ctx.assertDefinition(); + ProvisioningUtil.setProtectedFlag(ctx, shadow, matchingRuleRegistry); } public void applyDefinition(final ObjectQuery query, OperationResult result) throws SchemaException, ObjectNotFoundException, CommunicationException, ConfigurationException { @@ -857,7 +869,7 @@ public boolean handle(PrismObject object, OperationResult parentResult) { try { applyAttributesDefinition(ctx, object); - resouceObjectConverter.setProtectedFlag(ctx, object); // fixing MID-1640; hoping that the protected object filter uses only identifiers (that are stored in repo) + ProvisioningUtil.setProtectedFlag(ctx, object, matchingRuleRegistry); // fixing MID-1640; hoping that the protected object filter uses only identifiers (that are stored in repo) boolean cont = shadowHandler.handle(object.asObjectable()); parentResult.recordSuccess(); return cont; @@ -1343,7 +1355,7 @@ void processChange(ProvisioningContext ctx, Change change, PrismObje return; } - resouceObjectConverter.setProtectedFlag(ctx, oldShadow); + ProvisioningUtil.setProtectedFlag(ctx, oldShadow, matchingRuleRegistry); change.setOldShadow(oldShadow); if (change.getCurrentShadow() != null) { @@ -1577,7 +1589,7 @@ private PrismObject completeShadow(ProvisioningContext ctx, PrismObj resultAccountShadow.setCredentials(resourceAccountShadow.getCredentials()); //protected - resouceObjectConverter.setProtectedFlag(ctx, resultShadow); + ProvisioningUtil.setProtectedFlag(ctx, resultShadow, matchingRuleRegistry); // Activation ActivationType resultActivationType = resultShadowType.getActivation(); diff --git a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/util/ProvisioningUtil.java b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/util/ProvisioningUtil.java index 896bcd87158..d3846a3988b 100644 --- a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/util/ProvisioningUtil.java +++ b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/util/ProvisioningUtil.java @@ -16,6 +16,7 @@ package com.evolveum.midpoint.provisioning.util; +import com.evolveum.midpoint.common.ResourceObjectPattern; import com.evolveum.midpoint.common.StaticExpressionUtil; import com.evolveum.midpoint.common.refinery.RefinedAssociationDefinition; import com.evolveum.midpoint.common.refinery.RefinedAttributeDefinition; @@ -264,6 +265,29 @@ public static RefinedResourceSchema getRefinedSchema(ResourceType resourceType) return refinedSchema; } + public static boolean isProtectedShadow(RefinedObjectClassDefinition objectClassDefinition, PrismObject shadow, MatchingRuleRegistry matchingRuleRegistry) throws SchemaException { + boolean isProtected = false; + if (objectClassDefinition == null) { + isProtected = false; + } else { + Collection protectedAccountPatterns = objectClassDefinition.getProtectedObjectPatterns(); + if (protectedAccountPatterns == null) { + isProtected = false; + } else { + isProtected = ResourceObjectPattern.matches(shadow, protectedAccountPatterns, matchingRuleRegistry); + } + } + LOGGER.trace("isProtectedShadow: {}: {} = {}", new Object[] { objectClassDefinition, + shadow, isProtected }); + return isProtected; + } + + public static void setProtectedFlag(ProvisioningContext ctx, PrismObject resourceObject, MatchingRuleRegistry matchingRuleRegistry) throws SchemaException, ConfigurationException, ObjectNotFoundException, CommunicationException { + if (isProtectedShadow(ctx.getObjectClassDefinition(), resourceObject, matchingRuleRegistry)) { + resourceObject.asObjectable().setProtectedObject(true); + } + } + public static RefinedResourceSchema getRefinedSchema(PrismObject resource) throws SchemaException, ConfigurationException { RefinedResourceSchema refinedSchema = RefinedResourceSchema.getRefinedSchema(resource); if (refinedSchema == null) {