diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ContainerWrapper.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ContainerWrapper.java index bb876f55fdd..8707e4cf7f7 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ContainerWrapper.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/ContainerWrapper.java @@ -171,7 +171,7 @@ private List createProperties(PageBase pageBase) { PrismObject resource = resourceRef.getValue().getObject(); definition = pageBase.getModelInteractionService() - .getEditObjectClassDefinition(object.getObject(), resource).toResourceAttributeContainerDefinition(); + .getEditObjectClassDefinition(object.getObject(), resource, AuthorizationPhaseType.REQUEST).toResourceAttributeContainerDefinition(); if (LOGGER.isTraceEnabled()) { LOGGER.trace("Refined account def:\n{}", definition.debugDump()); diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/util/ObjectWrapperUtil.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/util/ObjectWrapperUtil.java index cd531b0c1f8..85e7fcf1a44 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/util/ObjectWrapperUtil.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/util/ObjectWrapperUtil.java @@ -31,7 +31,7 @@ public static ObjectWrapper createObjectWrapper(String di if (isShadow(object)) { PrismReference resourceRef = object.findReference(ShadowType.F_RESOURCE_REF); PrismObject resource = resourceRef.getValue().getObject(); - objectClassDefinitionForEditing = pageBase.getModelInteractionService().getEditObjectClassDefinition((PrismObject) object, resource); + objectClassDefinitionForEditing = pageBase.getModelInteractionService().getEditObjectClassDefinition((PrismObject) object, resource, AuthorizationPhaseType.REQUEST); } ObjectWrapper wrapper = new ObjectWrapper(displayName, description, object, objectDefinitionForEditing, objectClassDefinitionForEditing, status, delayContainerCreation, pageBase); diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/configuration/PageDebugView.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/configuration/PageDebugView.java index 27cdce7069b..12f0984647f 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/configuration/PageDebugView.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/configuration/PageDebugView.java @@ -117,7 +117,9 @@ private ObjectViewDto loadObject() { try { MidPointApplication application = PageDebugView.this.getMidpointApplication(); - Collection> options = SelectorOptions.createCollection(GetOperationOptions.createRaw()); + GetOperationOptions rootOptions = GetOperationOptions.createRaw(); + rootOptions.setResolveNames(true); + Collection> options = SelectorOptions.createCollection(rootOptions); // FIXME: ObjectType.class will not work well here. We need more specific type. //todo on page debug list create page params, put there oid and class for object type and send that to this page....read it here Class type = ObjectType.class; diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/configuration/component/PageDebugDownloadBehaviour.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/configuration/component/PageDebugDownloadBehaviour.java index 8b056be36a0..9b233a67ea9 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/configuration/component/PageDebugDownloadBehaviour.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/configuration/component/PageDebugDownloadBehaviour.java @@ -176,8 +176,11 @@ public boolean handle(PrismObject object, OperationResult parentResult) { }; ModelService service = page.getModelService(); - service.searchObjectsIterative(type, query, handler, SelectorOptions.createCollection(new ItemPath(), - GetOperationOptions.createRaw()), page.createSimpleTask(OPERATION_SEARCH_OBJECT), result); + GetOperationOptions options = GetOperationOptions.createRaw(); + // TODO enable when necessary + //options.setResolveNames(true); + service.searchObjectsIterative(type, query, handler, SelectorOptions.createCollection(options), + page.createSimpleTask(OPERATION_SEARCH_OBJECT), result); } private PageBase getPage() { diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/PrismValue.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/PrismValue.java index e71ab662569..bc1392ab609 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/PrismValue.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/PrismValue.java @@ -29,7 +29,9 @@ import java.util.ArrayList; import java.util.Collection; import java.util.Comparator; +import java.util.HashMap; import java.util.HashSet; +import java.util.Map; import java.util.Set; /** @@ -42,7 +44,8 @@ public abstract class PrismValue implements Visitable, PathVisitable, Serializab private Objectable originObject; private Itemable parent; protected Element domElement = null; - + private transient Map userData = new HashMap<>();; + PrismValue() { super(); } @@ -75,8 +78,20 @@ public OriginType getOriginType() { public Objectable getOriginObject() { return originObject; } - - public Itemable getParent() { + + public Map getUserData() { + return userData; + } + + public Object getUserData(String key) { + return userData.get(key); + } + + public void setUserData(String key, Object value) { + userData.put(key, value); + } + + public Itemable getParent() { return parent; } diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/parser/DomSerializer.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/parser/DomSerializer.java index 09058d9cd3b..6b71af7db5b 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/parser/DomSerializer.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/parser/DomSerializer.java @@ -27,10 +27,13 @@ import com.evolveum.midpoint.prism.xnode.XNode; import com.evolveum.midpoint.util.DOMUtil; import com.evolveum.midpoint.util.exception.SchemaException; +import com.sun.org.apache.xml.internal.utils.XMLChar; import org.apache.commons.lang.StringUtils; +import org.w3c.dom.Comment; import org.w3c.dom.DOMException; import org.w3c.dom.Document; import org.w3c.dom.Element; +import org.w3c.dom.Node; import javax.xml.namespace.QName; import java.util.Map.Entry; @@ -139,10 +142,12 @@ private void serializeSubnode(XNode xsubnode, Element parentElement, QName eleme } if (xsubnode instanceof RootXNode) { Element element = createElement(elementName, parentElement); + appendCommentIfPresent(element, xsubnode); parentElement.appendChild(element); serializeSubnode(((RootXNode) xsubnode).getSubnode(), element, ((RootXNode) xsubnode).getRootElementName()); } else if (xsubnode instanceof MapXNode) { Element element = createElement(elementName, parentElement); + appendCommentIfPresent(element, xsubnode); if (xsubnode.isExplicitTypeDeclaration() && xsubnode.getTypeQName() != null){ DOMUtil.setXsiType(element, xsubnode.getTypeQName()); } @@ -199,6 +204,7 @@ private void serializePrimitiveElementOrAttribute(PrimitiveXNode xprim, Eleme Element element; try { element = createElement(elementOrAttributeName, parentElement); + appendCommentIfPresent(element, xprim); } catch (DOMException e) { throw new DOMException(e.code, e.getMessage() + "; creating element "+elementOrAttributeName+" in element "+DOMUtil.getQName(parentElement)); } @@ -240,6 +246,7 @@ private void serializePrimitiveElementOrAttribute(PrimitiveXNode xprim, Eleme } catch (DOMException e) { throw new DOMException(e.code, e.getMessage() + "; creating element "+elementOrAttributeName+" in element "+DOMUtil.getQName(parentElement)); } + appendCommentIfPresent(element, xprim); parentElement.appendChild(element); } @@ -271,6 +278,13 @@ private void serializePrimitiveElementOrAttribute(PrimitiveXNode xprim, Eleme } } + private void appendCommentIfPresent(Element element, XNode xnode) { + String text = xnode.getComment(); + if (StringUtils.isNotEmpty(text)) { + DOMUtil.createComment(element, text); + } + } + private void serializeSchema(SchemaXNode xschema, Element parentElement) { Element schemaElement = xschema.getSchemaElement(); if (schemaElement == null){ diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/parser/XNodeSerializer.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/parser/XNodeSerializer.java index ec94967b36d..993c1f97e95 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/parser/XNodeSerializer.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/parser/XNodeSerializer.java @@ -67,6 +67,9 @@ public class XNodeSerializer { private PrismBeanConverter beanConverter; private boolean serializeCompositeObjects = false; + + // TODO think out where to put this key + public static final String USER_DATA_KEY_COMMENT = XNodeSerializer.class.getName()+".comment"; public XNodeSerializer(PrismBeanConverter beanConverter) { super(); @@ -183,24 +186,7 @@ public XNode serializeItemValue(V itemValue, ItemDefiniti return serializePropertyRawValue((PrismPropertyValue) itemValue); } if (beanConverter.getPrismContext() == null) { - // hope we don't need this code any more throw new IllegalStateException("No prismContext in beanConverter!"); -// // HACK. Ugly hack. We need to make sure that the bean converter has a prism context. -// // If it does not then it cannot serialize any values and the subsequent calls may fail. -// // The bean converter usually has a context. The context may be missing if it was initialized -// // inside one of the JAXB getters/setters. -// // We need to get rid of JAXB entirelly to get rid of hacks like this -// PrismContext context = null; -// if (definition != null) { -// context = definition.getPrismContext(); -// } -// if (context == null && itemValue.getParent() != null) { -// context = itemValue.getParent().getPrismContext(); -// } -// if (context == null) { -// throw new SystemException("Cannot determine prism context when serializing "+itemValue); -// } -// beanConverter.setPrismContext(context); } if (itemValue instanceof PrismReferenceValue) { xnode = serializeReferenceValue((PrismReferenceValue)itemValue, (PrismReferenceDefinition) definition); @@ -214,6 +200,10 @@ public XNode serializeItemValue(V itemValue, ItemDefiniti if (definition.isDynamic()) { xnode.setExplicitTypeDeclaration(true); } + Object commentValue = itemValue.getUserData(USER_DATA_KEY_COMMENT); + if (commentValue != null) { + xnode.setComment(commentValue.toString()); + } // System.out.println("item value serialization: \n" + xnode.debugDump()); return xnode; } diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/xnode/XNode.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/xnode/XNode.java index 03818cac74e..d0cfa77bd25 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/xnode/XNode.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/xnode/XNode.java @@ -66,6 +66,9 @@ public abstract class XNode implements DebugDumpable, Visitable, Cloneable, Seri private QName typeQName; private Integer maxOccurs; + // a comment that could be stored into formats that support these (e.g. XML or YAML) + private String comment; + public XNode getParent() { return parent; } @@ -98,7 +101,15 @@ public void setLineNumber(int lineNumber) { this.lineNumber = lineNumber; } - public QName getTypeQName() { + public String getComment() { + return comment; + } + + public void setComment(String comment) { + this.comment = comment; + } + + public QName getTypeQName() { return typeQName; } diff --git a/infra/schema/src/main/java/com/evolveum/midpoint/schema/GetOperationOptions.java b/infra/schema/src/main/java/com/evolveum/midpoint/schema/GetOperationOptions.java index 8fdc9a13405..d105d03f878 100644 --- a/infra/schema/src/main/java/com/evolveum/midpoint/schema/GetOperationOptions.java +++ b/infra/schema/src/main/java/com/evolveum/midpoint/schema/GetOperationOptions.java @@ -28,7 +28,7 @@ * @author semancik * */ -public class GetOperationOptions implements Serializable { +public class GetOperationOptions implements Serializable, Cloneable { /** * Specifies whether to return specific items. It is used for optimizations. @@ -59,8 +59,17 @@ public class GetOperationOptions implements Serializable { * Resolve the object reference. This only makes sense with a (path-based) selector. */ Boolean resolve; - - /** + + /** + * Resolve the object reference names. (Currently applicable only as a top-level option.) + * + * Names of referenced objects are provided as PrismValue userData entries. + * + * EXPERIMENTAL. + */ + Boolean resolveNames; + + /** * No not fetch any information from external sources, e.g. do not fetch account data from resource, * do not fetch resource schema, etc. * Such operation returns only the data stored in midPoint repository. @@ -79,8 +88,7 @@ public class GetOperationOptions implements Serializable { * from the gui, for example */ Boolean doNotDiscovery; - - + public RetrieveOption getRetrieve() { return retrieve; } @@ -163,31 +171,56 @@ public static Collection> createRetrieveAtt return optionsCollection; } - public Boolean getRaw() { - return raw; + public Boolean getResolveNames() { + return resolveNames; } - public void setRaw(Boolean raw) { - this.raw = raw; + public void setResolveNames(Boolean resolveNames) { + this.resolveNames = resolveNames; } - public static boolean isRaw(GetOperationOptions options) { + public static boolean isResolveNames(GetOperationOptions options) { if (options == null) { return false; } - if (options.raw == null) { + if (options.resolveNames == null) { return false; } - return options.raw; + return options.resolveNames; } - public static GetOperationOptions createRaw() { + public static GetOperationOptions createResolveNames() { GetOperationOptions opts = new GetOperationOptions(); - opts.setRaw(true); + opts.setResolveNames(true); return opts; } - - public Boolean getDoNotDiscovery() { + + public Boolean getRaw() { + return raw; + } + + public void setRaw(Boolean raw) { + this.raw = raw; + } + + public static boolean isRaw(GetOperationOptions options) { + if (options == null) { + return false; + } + if (options.raw == null) { + return false; + } + return options.raw; + } + + public static GetOperationOptions createRaw() { + GetOperationOptions opts = new GetOperationOptions(); + opts.setRaw(true); + return opts; + } + + + public Boolean getDoNotDiscovery() { return doNotDiscovery; } @@ -258,6 +291,17 @@ public boolean equals(Object obj) { return true; } + public GetOperationOptions clone() { + GetOperationOptions clone = new GetOperationOptions(); + clone.noFetch = this.noFetch; + clone.doNotDiscovery = this.doNotDiscovery; + clone.raw = this.raw; + clone.resolve = this.resolve; + clone.resolveNames = this.resolveNames; + clone.retrieve = this.retrieve; + return clone; + } + @Override public String toString() { return "GetOperationOptions(resolve=" + resolve + ", noFetch=" + noFetch diff --git a/infra/util/src/main/java/com/evolveum/midpoint/util/DOMUtil.java b/infra/util/src/main/java/com/evolveum/midpoint/util/DOMUtil.java index 503339318d5..e215803e3a4 100644 --- a/infra/util/src/main/java/com/evolveum/midpoint/util/DOMUtil.java +++ b/infra/util/src/main/java/com/evolveum/midpoint/util/DOMUtil.java @@ -49,6 +49,7 @@ import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.Validate; import org.w3c.dom.Attr; +import org.w3c.dom.Comment; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.NamedNodeMap; @@ -1260,5 +1261,24 @@ private static String makeSafelyPrintable(String text, int maxSize) { return sb.toString(); } + public static void createComment(Element element, String text) { + if (text != null) { + Comment commentNode = element.getOwnerDocument().createComment(replaceInvalidXmlChars(text)); + element.appendChild(commentNode); + } + } + + private static String replaceInvalidXmlChars(String text) { + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < text.length(); i++) { + char c = text.charAt(i); + if (!XMLChar.isValid(c)) { + sb.append('.'); + } else { + sb.append(c); + } + } + return sb.toString(); + } } diff --git a/model/model-api/src/main/java/com/evolveum/midpoint/model/api/ModelInteractionService.java b/model/model-api/src/main/java/com/evolveum/midpoint/model/api/ModelInteractionService.java index 892cb146687..0219abf2edd 100644 --- a/model/model-api/src/main/java/com/evolveum/midpoint/model/api/ModelInteractionService.java +++ b/model/model-api/src/main/java/com/evolveum/midpoint/model/api/ModelInteractionService.java @@ -102,7 +102,7 @@ ModelContext previewChanges( */ PrismObjectDefinition getEditObjectDefinition(PrismObject object, AuthorizationPhaseType phase) throws SchemaException; - RefinedObjectClassDefinition getEditObjectClassDefinition(PrismObject shadow, PrismObject resource) throws SchemaException; + RefinedObjectClassDefinition getEditObjectClassDefinition(PrismObject shadow, PrismObject resource, AuthorizationPhaseType phase) throws SchemaException; /** *

diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/controller/ModelController.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/controller/ModelController.java index baede59f5e8..94914705d73 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/controller/ModelController.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/controller/ModelController.java @@ -33,13 +33,17 @@ import com.evolveum.midpoint.model.api.WorkflowService; import com.evolveum.midpoint.model.api.hooks.ReadHook; import com.evolveum.midpoint.model.impl.scripting.ScriptingExpressionEvaluator; +import com.evolveum.midpoint.prism.parser.XNodeSerializer; +import com.evolveum.midpoint.prism.polystring.PolyString; import com.evolveum.midpoint.wf.api.WorkflowManager; import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectSpecificationType; import com.evolveum.midpoint.xml.ns._public.model.model_context_3.LensContextType; import com.evolveum.midpoint.xml.ns._public.model.scripting_3.ScriptingExpressionType; import org.apache.commons.lang.NotImplementedException; +import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.Validate; +import org.apache.cxf.phase.Phase; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.security.core.Authentication; @@ -284,6 +288,7 @@ public PrismObject getObject(Class clazz, String oi object = objectResolver.getObject(clazz, oid, options, task, result).asPrismObject(); resolve(object, options, task, result); + resolveNames(object, options, task, result); } catch (SchemaException e) { ModelUtils.recordFatalError(result, e); throw e; @@ -327,8 +332,56 @@ protected void resolve(PrismObject object, Collection object, SelectorOptions option, Task task, OperationResult result) throws SchemaException, ObjectNotFoundException { + + protected void resolveNames(PrismObject object, Collection> options, + final Task task, final OperationResult result) throws SchemaException, ObjectNotFoundException { + if (object == null || options == null) { + return; + } + + // currently, only all-or-nothing names resolving is provided + GetOperationOptions rootOptions = SelectorOptions.findRootOptions(options); + if (!GetOperationOptions.isResolveNames(rootOptions)) { + return; + } + + final GetOperationOptions rootOptionsNoResolve = rootOptions.clone(); + rootOptionsNoResolve.setResolveNames(false); + rootOptionsNoResolve.setResolve(false); + rootOptionsNoResolve.setRaw(true); + + object.accept(new Visitor() { + @Override + public void visit(Visitable visitable) { + if (visitable instanceof PrismReferenceValue) { + PrismReferenceValue refVal = (PrismReferenceValue) visitable; + PrismObject refObject = refVal.getObject(); + if (refObject == null) { + try { + // TODO what about security here?! + // TODO use some minimalistic get options (e.g. retrieve name only) + refObject = objectResolver.resolve(refVal, "", rootOptionsNoResolve, task, result); + } catch (ObjectNotFoundException e) { + // can be safely ignored + result.recordHandledError(e.getMessage()); + } + } + String name; + if (refObject != null) { + name = PolyString.getOrig(refObject.asObjectable().getName()); + } else { + name = "(object not found)"; + } + if (StringUtils.isNotEmpty(name)) { + refVal.setUserData(XNodeSerializer.USER_DATA_KEY_COMMENT, " " + name + " "); + } + } + } + }); + } + + + private void resolve(PrismObject object, SelectorOptions option, Task task, OperationResult result) throws SchemaException, ObjectNotFoundException { if (!GetOperationOptions.isResolve(option.getOptions())) { return; } @@ -726,12 +779,13 @@ public PrismObjectDefinition getEditObjectDefinition(P PrismObjectDefinition finalDefinition = applySecurityContraints(origDefinition, new ItemPath(), securityConstraints, securityConstraints.getActionDecision(ModelAuthorizationAction.READ.getUrl(), phase), securityConstraints.getActionDecision(ModelAuthorizationAction.ADD.getUrl(), phase), - securityConstraints.getActionDecision(ModelAuthorizationAction.MODIFY.getUrl(), phase)); + securityConstraints.getActionDecision(ModelAuthorizationAction.MODIFY.getUrl(), phase), phase); return finalDefinition; } private D applySecurityContraints(D origItemDefinition, ItemPath itemPath, ObjectSecurityConstraints securityConstraints, - AuthorizationDecisionType defaultReadDecition, AuthorizationDecisionType defaultAddDecition, AuthorizationDecisionType defaultModifyDecition) { + AuthorizationDecisionType defaultReadDecition, AuthorizationDecisionType defaultAddDecition, AuthorizationDecisionType defaultModifyDecition, + AuthorizationPhaseType phase) { D itemDefinition = (D) origItemDefinition.clone(); // We need to make a super-deep clone here. Even make sure that the complex types inside are cloned. // Otherwise permissions from one part of the definition tree may be incorrectly propagated to another part @@ -740,9 +794,9 @@ private D applySecurityContraints(D origItemDefinitio ComplexTypeDefinition origCtd = containerDefinition.getComplexTypeDefinition(); containerDefinition.setComplexTypeDefinition(origCtd.clone()); } - AuthorizationDecisionType readDecision = computeItemDecision(securityConstraints, itemPath, ModelAuthorizationAction.READ.getUrl(), defaultReadDecition); - AuthorizationDecisionType addDecision = computeItemDecision(securityConstraints, itemPath, ModelAuthorizationAction.ADD.getUrl(), defaultAddDecition); - AuthorizationDecisionType modifyDecision = computeItemDecision(securityConstraints, itemPath, ModelAuthorizationAction.MODIFY.getUrl(), defaultModifyDecition); + AuthorizationDecisionType readDecision = computeItemDecision(securityConstraints, itemPath, ModelAuthorizationAction.READ.getUrl(), defaultReadDecition, phase); + AuthorizationDecisionType addDecision = computeItemDecision(securityConstraints, itemPath, ModelAuthorizationAction.ADD.getUrl(), defaultAddDecition, phase); + AuthorizationDecisionType modifyDecision = computeItemDecision(securityConstraints, itemPath, ModelAuthorizationAction.MODIFY.getUrl(), defaultModifyDecition, phase); // LOGGER.trace("Decision for {}: {}", itemPath, readDecision); if (readDecision != AuthorizationDecisionType.ALLOW) { itemDefinition.setCanRead(false); @@ -764,7 +818,7 @@ private D applySecurityContraints(D origItemDefinitio // it's too late to come up with a serious solution if (!(itemPath.lastNamed() != null && ObjectSpecificationType.F_OWNER.equals(itemPath.lastNamed().getName()) && ObjectSpecificationType.F_OWNER.equals(subDef.getName()))) { ItemDefinition newDef = applySecurityContraints(subDef, new ItemPath(itemPath, subDef.getName()), securityConstraints, - readDecision, addDecision, modifyDecision); + readDecision, addDecision, modifyDecision, phase); containerDefinition.getComplexTypeDefinition().add(newDef); } } @@ -773,8 +827,8 @@ private D applySecurityContraints(D origItemDefinitio } private AuthorizationDecisionType computeItemDecision(ObjectSecurityConstraints securityConstraints, ItemPath itemPath, String actionUrl, - AuthorizationDecisionType defaultDecision) { - AuthorizationDecisionType explicitDecision = securityConstraints.findItemDecision(itemPath, actionUrl, null); + AuthorizationDecisionType defaultDecision, AuthorizationPhaseType phase) { + AuthorizationDecisionType explicitDecision = securityConstraints.findItemDecision(itemPath, actionUrl, phase); // LOGGER.trace("Explicit decision for {}: {}", itemPath, explicitDecision); if (explicitDecision != null) { return explicitDecision; @@ -784,7 +838,7 @@ private AuthorizationDecisionType computeItemDecision(ObjectSecurityConstraints } @Override - public RefinedObjectClassDefinition getEditObjectClassDefinition(PrismObject shadow, PrismObject resource) + public RefinedObjectClassDefinition getEditObjectClassDefinition(PrismObject shadow, PrismObject resource, AuthorizationPhaseType phase) throws SchemaException { // TODO: maybe we need to expose owner resolver in the interface? ObjectSecurityConstraints securityConstraints = securityEnforcer.compileSecurityConstraints(shadow, null); @@ -815,11 +869,11 @@ public RefinedObjectClassDefinition getEditObjectClassDefinition(PrismObject List> searchObjects(Class type, hook.invoke(object, options, task, result); } } + // TODO enable when necessary + //resolveNames(object, options, task, result); } } finally { @@ -999,9 +1055,11 @@ public boolean handle(PrismObject object, OperationResult parentResult) { try { if (hookRegistry != null) { for (ReadHook hook : hookRegistry.getAllReadHooks()) { - hook.invoke(object, options, task, result); + hook.invoke(object, options, task, result); // TODO result or parentResult??? [med] } } + // TODO enable when necessary + //resolveNames(object, options, task, parentResult); postProcessObject(object, rootOptions, parentResult); } catch (SchemaException | ObjectNotFoundException | SecurityViolationException | CommunicationException | ConfigurationException ex) { diff --git a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestSecurity.java b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestSecurity.java index b32d12b0944..32a9d0554b0 100644 --- a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestSecurity.java +++ b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestSecurity.java @@ -920,7 +920,7 @@ public void test255AutzJackSelfAccountsReadWrite() throws Exception { assertGetAllow(ShadowType.class, accountOid); PrismObject shadow = getObject(ShadowType.class, accountOid); display("Jack's shadow", shadow); - RefinedObjectClassDefinition rOcDef = modelInteractionService.getEditObjectClassDefinition(shadow, resourceDummy); + RefinedObjectClassDefinition rOcDef = modelInteractionService.getEditObjectClassDefinition(shadow, resourceDummy, null); display("Refined objectclass def", rOcDef); assertAttributeFlags(rOcDef, SchemaConstants.ICFS_UID, true, false, false); assertAttributeFlags(rOcDef, SchemaConstants.ICFS_NAME, true, true, true); @@ -989,7 +989,7 @@ public void test256AutzJackSelfAccountsPartialControl() throws Exception { assertGetAllow(ShadowType.class, accountOid); PrismObject shadow = getObject(ShadowType.class, accountOid); display("Jack's shadow", shadow); - RefinedObjectClassDefinition rOcDef = modelInteractionService.getEditObjectClassDefinition(shadow, resourceDummy); + RefinedObjectClassDefinition rOcDef = modelInteractionService.getEditObjectClassDefinition(shadow, resourceDummy, null); display("Refined objectclass def", rOcDef); assertAttributeFlags(rOcDef, SchemaConstants.ICFS_UID, true, false, false); assertAttributeFlags(rOcDef, SchemaConstants.ICFS_NAME, true, false, false); 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 2cf96af019a..695802588f0 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 @@ -163,8 +163,14 @@ public PrismObject getObject(Class type, String oid if (ResourceType.class.isAssignableFrom(type)) { if (GetOperationOptions.isRaw(rootOptions)) { - resultingObject = (PrismObject) cacheRepositoryService.getObject(ResourceType.class, oid, + try { + resultingObject = (PrismObject) cacheRepositoryService.getObject(ResourceType.class, oid, null, result); + } catch (ObjectNotFoundException|SchemaException ex) { + // catching an exception is important because otherwise the result is UNKNOWN + result.recordFatalError(ex); + throw ex; + } try { applyDefinition(resultingObject, result); } catch (ObjectNotFoundException ex) {