diff --git a/build-system/pom.xml b/build-system/pom.xml index aaf561f3b18..057e40f7977 100644 --- a/build-system/pom.xml +++ b/build-system/pom.xml @@ -83,7 +83,7 @@ 5.22.0 1.3 2.0.6 - 1.4.3.41 + 1.4.3.43 6.5.0 10.11.1.1 1.8.0 diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/api/component/DisplayNamePanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/api/component/DisplayNamePanel.java index 63d314f58df..05d55ad025a 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/api/component/DisplayNamePanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/api/component/DisplayNamePanel.java @@ -163,8 +163,7 @@ private boolean isIdentifierVisible() { // TODO: maybe move relation methods to subclass if we want this panel to be really reusable private boolean isRelationVisible() { - QName relation = getRelation(); - return relation != null && !QNameUtil.match(SchemaConstants.ORG_DEFAULT, relation); + return !WebComponentUtil.isDefaultRelation(getRelation()); } private boolean isKindIntentVisible(IModel kindIntentLabelModel) { diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/api/component/MemberPopupTabPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/api/component/MemberPopupTabPanel.java index 9fa35cdaa4b..8611200336c 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/api/component/MemberPopupTabPanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/api/component/MemberPopupTabPanel.java @@ -18,24 +18,17 @@ import com.evolveum.midpoint.gui.api.page.PageBase; import com.evolveum.midpoint.gui.api.util.WebComponentUtil; import com.evolveum.midpoint.prism.delta.ObjectDelta; -import com.evolveum.midpoint.schema.constants.ObjectTypes; -import com.evolveum.midpoint.schema.constants.RelationTypes; -import com.evolveum.midpoint.schema.constants.SchemaConstants; -import com.evolveum.midpoint.schema.result.OperationResult; import com.evolveum.midpoint.schema.util.ObjectTypeUtil; import com.evolveum.midpoint.util.exception.SchemaException; import com.evolveum.midpoint.util.logging.LoggingUtils; import com.evolveum.midpoint.util.logging.Trace; import com.evolveum.midpoint.util.logging.TraceManager; -import com.evolveum.midpoint.web.component.input.DropDownChoicePanel; import com.evolveum.midpoint.web.component.input.RelationDropDownChoicePanel; import com.evolveum.midpoint.web.component.util.VisibleEnableBehaviour; -import com.evolveum.midpoint.web.page.admin.configuration.component.EmptyOnChangeAjaxFormUpdatingBehavior; import com.evolveum.midpoint.xml.ns._public.common.common_3.*; import org.apache.commons.collections.CollectionUtils; import org.apache.wicket.markup.html.WebMarkupContainer; import org.apache.wicket.markup.html.panel.Fragment; -import org.apache.wicket.model.Model; import javax.xml.namespace.QName; import java.util.ArrayList; @@ -94,8 +87,7 @@ protected ObjectDelta prepareDelta(){ Class classType = WebComponentUtil.qnameToClass(pageBase.getPrismContext(), getObjectType().getTypeQName()); delta = ObjectDelta.createEmptyModifyDelta(classType, "fakeOid", pageBase.getPrismContext()); AssignmentType newAssignment = new AssignmentType(); - ObjectReferenceType ref = ObjectTypeUtil.createObjectRef(getAbstractRoleTypeObject()); - ref.setRelation(getRelationValue()); + ObjectReferenceType ref = ObjectTypeUtil.createObjectRef(getAbstractRoleTypeObject(), getRelationValue()); newAssignment.setTargetRef(ref); pageBase.getPrismContext().adopt(newAssignment); diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/api/component/MultiTypesMemberPopupTabPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/api/component/MultiTypesMemberPopupTabPanel.java index 17e47e8ebd1..e721fd817f3 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/api/component/MultiTypesMemberPopupTabPanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/api/component/MultiTypesMemberPopupTabPanel.java @@ -19,15 +19,9 @@ import com.evolveum.midpoint.gui.api.util.WebComponentUtil; import com.evolveum.midpoint.prism.delta.ObjectDelta; import com.evolveum.midpoint.schema.constants.ObjectTypes; -import com.evolveum.midpoint.schema.constants.RelationTypes; import com.evolveum.midpoint.schema.util.ObjectTypeUtil; -import com.evolveum.midpoint.task.api.Task; -import com.evolveum.midpoint.task.api.TaskCategory; -import com.evolveum.midpoint.util.exception.SchemaException; -import com.evolveum.midpoint.util.logging.LoggingUtils; import com.evolveum.midpoint.util.logging.Trace; import com.evolveum.midpoint.util.logging.TraceManager; -import com.evolveum.midpoint.web.page.admin.roles.AbstractRoleMemberPanel; import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectReferenceType; import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectType; import org.apache.wicket.ajax.AjaxRequestTarget; @@ -35,8 +29,6 @@ import org.apache.wicket.markup.html.WebMarkupContainer; import org.apache.wicket.markup.html.form.DropDownChoice; import org.apache.wicket.markup.html.form.EnumChoiceRenderer; -import org.apache.wicket.model.IModel; -import org.apache.wicket.model.Model; import javax.xml.namespace.QName; import java.util.ArrayList; @@ -93,8 +85,7 @@ protected void onUpdate(AjaxRequestTarget target) { @Override protected ObjectDelta prepareDelta(){ Class classType = WebComponentUtil.qnameToClass(getPageBase().getPrismContext(), getObjectType().getTypeQName()); - ObjectReferenceType ref = ObjectTypeUtil.createObjectRef(getAbstractRoleTypeObject()); - ref.setRelation(getRelationValue()); + ObjectReferenceType ref = ObjectTypeUtil.createObjectRef(getAbstractRoleTypeObject(), getRelationValue()); return ObjectDelta.createModificationAddReference(classType, "fakeOid", ObjectType.F_PARENT_ORG_REF, getPageBase().getPrismContext(), ref.asReferenceValue()); diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/api/component/ResourceTypeAssignmentPopupTabPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/api/component/ResourceTypeAssignmentPopupTabPanel.java index c4215ced7e2..103dcfb3f41 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/api/component/ResourceTypeAssignmentPopupTabPanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/api/component/ResourceTypeAssignmentPopupTabPanel.java @@ -161,7 +161,9 @@ protected Map getSelectedAssignmentsMap(){ ShadowKindType kind = getKindValue(); String intent = getIntentValue(); selectedObjects.forEach(selectedObject -> { - assignmentList.put(selectedObject.getOid(), ObjectTypeUtil.createAssignmentWithConstruction(selectedObject.asPrismObject(), kind, intent)); + assignmentList.put(selectedObject.getOid(), + ObjectTypeUtil.createAssignmentWithConstruction( + selectedObject.asPrismObject(), kind, intent, getPageBase().getPrismContext())); }); return assignmentList; } diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/api/component/TypedAssignablePanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/api/component/TypedAssignablePanel.java index 367d98f31dd..33fc2f84b1b 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/api/component/TypedAssignablePanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/api/component/TypedAssignablePanel.java @@ -364,7 +364,7 @@ private QName getSelectedRelation(){ DropDownChoicePanel relationPanel = (DropDownChoicePanel) get(ID_RELATION_CONTAINER).get(ID_RELATION); RelationTypes relation = relationPanel.getModel().getObject(); if (relation == null) { - return SchemaConstants.ORG_DEFAULT; + return WebComponentUtil.getDefaultRelationOrFail(); } return relation.getRelation(); } diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/api/page/PageBase.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/api/page/PageBase.java index 04a19e6d8ea..fcb08ae61a0 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/api/page/PageBase.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/api/page/PageBase.java @@ -47,6 +47,7 @@ import com.evolveum.midpoint.repo.common.expression.ExpressionFactory; import com.evolveum.midpoint.repo.common.expression.ExpressionVariables; import com.evolveum.midpoint.report.api.ReportManager; +import com.evolveum.midpoint.schema.RelationRegistry; import com.evolveum.midpoint.schema.constants.ExpressionConstants; import com.evolveum.midpoint.schema.constants.SchemaConstants; import com.evolveum.midpoint.schema.internals.InternalsConfig; @@ -164,9 +165,7 @@ import javax.management.MBeanServer; import javax.management.MBeanServerFactory; import javax.management.ObjectName; -import javax.xml.namespace.QName; -import java.io.Serializable; import java.util.*; /** @@ -357,7 +356,7 @@ protected Integer load() { Task task = createSimpleTask(OPERATION_LOAD_WORK_ITEM_COUNT); S_FilterEntryOrEmpty q = QueryBuilder.queryFor(WorkItemType.class, getPrismContext()); ObjectQuery query = QueryUtils.filterForAssignees(q, getPrincipal(), - OtherPrivilegesLimitationType.F_APPROVAL_WORK_ITEMS).build(); + OtherPrivilegesLimitationType.F_APPROVAL_WORK_ITEMS, getRelationRegistry()).build(); return getModelService().countContainers(WorkItemType.class, query, null, task, task.getResult()); } catch (SchemaException | SecurityViolationException | ExpressionEvaluationException | ObjectNotFoundException | CommunicationException | ConfigurationException e) { LoggingUtils.logExceptionAsWarning(LOGGER, "Couldn't load work item count", e); @@ -471,6 +470,10 @@ public PrismContext getPrismContext() { return getMidpointApplication().getPrismContext(); } + public RelationRegistry getRelationRegistry() { + return getMidpointApplication().getRelationRegistry(); + } + public ExpressionFactory getExpressionFactory() { return getMidpointApplication().getExpressionFactory(); } diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/api/util/WebComponentUtil.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/api/util/WebComponentUtil.java index 680715cb6cd..dfa74ed13ff 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/api/util/WebComponentUtil.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/api/util/WebComponentUtil.java @@ -16,7 +16,6 @@ package com.evolveum.midpoint.gui.api.util; import static com.evolveum.midpoint.gui.api.page.PageBase.createStringResourceStatic; -import static com.evolveum.midpoint.schema.util.ObjectTypeUtil.normalizeRelation; import java.io.PrintWriter; import java.io.StringWriter; @@ -41,8 +40,6 @@ import java.util.stream.Collectors; import java.util.stream.StreamSupport; -import javax.xml.datatype.DatatypeConfigurationException; -import javax.xml.datatype.DatatypeFactory; import javax.xml.datatype.XMLGregorianCalendar; import javax.xml.namespace.QName; @@ -52,13 +49,10 @@ import com.evolveum.midpoint.model.api.ModelExecuteOptions; import com.evolveum.midpoint.prism.query.*; import com.evolveum.midpoint.prism.query.builder.S_FilterEntryOrEmpty; -import com.evolveum.midpoint.schema.GetOperationOptions; -import com.evolveum.midpoint.schema.SelectorOptions; +import com.evolveum.midpoint.schema.*; import com.evolveum.midpoint.schema.util.LocalizationUtil; import com.evolveum.midpoint.task.api.Task; import com.evolveum.midpoint.util.*; -import com.evolveum.midpoint.util.exception.CommunicationException; -import com.evolveum.midpoint.util.exception.ObjectNotFoundException; import com.evolveum.midpoint.web.component.breadcrumbs.Breadcrumb; import com.evolveum.midpoint.web.component.breadcrumbs.BreadcrumbPageClass; import com.evolveum.midpoint.web.component.breadcrumbs.BreadcrumbPageInstance; @@ -66,8 +60,6 @@ import com.evolveum.midpoint.web.component.menu.cog.InlineMenuItem; import com.evolveum.midpoint.web.component.menu.cog.InlineMenuItemAction; import com.evolveum.midpoint.web.component.prism.*; -import com.evolveum.midpoint.web.page.admin.PageAdminObjectDetails; -import com.evolveum.midpoint.web.page.admin.reports.dto.ReportDeleteDialogDto; import com.evolveum.midpoint.web.util.ObjectTypeGuiDescriptor; import com.evolveum.midpoint.xml.ns._public.common.common_3.*; import org.apache.commons.collections4.CollectionUtils; @@ -138,8 +130,6 @@ import com.evolveum.midpoint.prism.polystring.PolyString; import com.evolveum.midpoint.prism.query.builder.QueryBuilder; import com.evolveum.midpoint.prism.xml.XmlTypeConverter; -import com.evolveum.midpoint.schema.DeltaConvertor; -import com.evolveum.midpoint.schema.SchemaConstantsGenerated; import com.evolveum.midpoint.schema.constants.ObjectTypes; import com.evolveum.midpoint.schema.constants.SchemaConstants; import com.evolveum.midpoint.schema.result.OperationResult; @@ -205,7 +195,11 @@ public final class WebComponentUtil { private static final String KEY_BOOLEAN_TRUE = "Boolean.TRUE"; private static final String KEY_BOOLEAN_FALSE = "Boolean.FALSE"; - private static DatatypeFactory df = null; + /** + * To be used only for tests when there's no MidpointApplication. + * (Quite a hack. Replace eventually by a more serious solution.) + */ + private static RelationRegistry staticallyProvidedRelationRegistry; private static Map, Class> objectDetailsPageMap; @@ -481,14 +475,6 @@ public String getChannel() { } } - static { - try { - df = DatatypeFactory.newInstance(); - } catch (DatatypeConfigurationException dce) { - throw new IllegalStateException("Exception while obtaining Datatype Factory instance", dce); - } - } - public static DateValidator getRangeValidator(Form form, ItemPath path) { DateValidator validator = null; List validators = form.getBehaviors(DateValidator.class); @@ -1113,8 +1099,8 @@ public static String getDisplayName(PrismContainerValu if (prismContainerValue.canRepresent(AssignmentType.class)) { AssignmentType assignmentType = (AssignmentType) prismContainerValue.asContainerable(); if (assignmentType.getTargetRef() != null){ - ObjectReferenceType assignemntTargetRef = assignmentType.getTargetRef(); - return getName(assignemntTargetRef) + " - " + normalizeRelation(assignemntTargetRef.getRelation()).getLocalPart(); + ObjectReferenceType assignmentTargetRef = assignmentType.getTargetRef(); + return getName(assignmentTargetRef) + " - " + normalizeRelation(assignmentTargetRef.getRelation()).getLocalPart(); } else { return "AssignmentTypeDetailsPanel.containerTitle"; } @@ -1192,6 +1178,10 @@ public static String getDisplayName(PrismContainerValu return "ContainerPanel.containerProperties"; } + public static QName normalizeRelation(QName relation) { + return getRelationRegistry().normalizeRelation(relation); + } + public static String getDisplayNameOrName(PrismObject object) { if (object == null) { return null; @@ -1667,6 +1657,79 @@ public static String getBoxThinCssClasses(QName objectTyp } } + // can this implementation be made more efficient? [pm] + @SuppressWarnings("WeakerAccess") + public static boolean isOfKind(QName relation, RelationKindType kind) { + return getRelationRegistry().isOfKind(relation, kind); + } + + protected static RelationRegistry getRelationRegistry() { + if (staticallyProvidedRelationRegistry != null) { + return staticallyProvidedRelationRegistry; + } else { + return MidPointApplication.get().getRelationRegistry(); + } + } + + public static boolean isManagerRelation(QName relation) { + return isOfKind(relation, RelationKindType.MANAGER); + } + + public static boolean isDefaultRelation(QName relation) { + return getRelationRegistry().isDefault(relation); + } + + @SuppressWarnings("WeakerAccess") + public static QName getDefaultRelation() { + return getRelationRegistry().getDefaultRelation(); + } + + @NotNull + public static QName getDefaultRelationOrFail() { + QName relation = getDefaultRelation(); + if (relation != null) { + return relation; + } else { + throw new IllegalStateException("No default relation is defined"); + } + } + + @SuppressWarnings("WeakerAccess") + @Nullable + public static QName getDefaultRelationFor(RelationKindType kind) { + return getRelationRegistry().getDefaultRelationFor(kind); + } + + @NotNull + public static QName getDefaultRelationOrFail(RelationKindType kind) { + QName relation = getDefaultRelationFor(kind); + if (relation != null) { + return relation; + } else { + throw new IllegalStateException("No default relation for kind " + kind); + } + } + + @NotNull + public static String getRelationHeaderLabelKey(QName relation) { + String label = getRelationHeaderLabelKeyIfKnown(relation); + if (label != null) { + return label; + } else { + return relation != null ? relation.getLocalPart() : "default"; + } + } + + @Nullable + public static String getRelationHeaderLabelKeyIfKnown(QName relation) { + RelationDefinitionType definition = getRelationRegistry().getRelationDefinition(relation); + if (definition != null && definition.getDisplay() != null && definition.getDisplay().getLabel() != null) { + return definition.getDisplay().getLabel(); + } else { + return null; + } + } + public static String createUserIcon(PrismObject object) { UserType user = object.asObjectable(); @@ -1688,7 +1751,7 @@ public static String createUserIcon(PrismObject object) { boolean isManager = false; for (ObjectReferenceType parentOrgRef : user.getParentOrgRef()) { - if (ObjectTypeUtil.isManagerRelation(parentOrgRef.getRelation())) { + if (isManagerRelation(parentOrgRef.getRelation())) { isManager = true; break; } @@ -2003,7 +2066,7 @@ public static boolean isObjectOrgManager(PrismObject objec List parentOrgRefs = objectType.getParentOrgRef(); for (ObjectReferenceType ref : parentOrgRefs) { - if (ObjectTypeUtil.isManagerRelation(ref.getRelation())) { + if (isManagerRelation(ref.getRelation())) { return true; } } @@ -2426,7 +2489,8 @@ public static boolean getElementVisibility(UserInterfaceElementVisibilityType vi return true; } - public static IModel createAbstractRoleConfirmationMessage(String actionName, ColumnMenuAction action, MainObjectListPanel abstractRoleTable, PageBase pageBase) { + public static IModel createAbstractRoleConfirmationMessage(String actionName, + ColumnMenuAction action, MainObjectListPanel abstractRoleTable, PageBase pageBase) { List selectedRoles = new ArrayList<>(); if (action.getRowModel() == null) { selectedRoles.addAll(abstractRoleTable.getSelectedObjects()); @@ -2436,7 +2500,11 @@ public static IModel createAbstractRoleCon OperationResult result = new OperationResult("Search Members"); boolean atLeastOneWithMembers = false; for (AR selectedRole : selectedRoles) { - ObjectQuery query = QueryBuilder.queryFor(FocusType.class, pageBase.getPrismContext()).item(FocusType.F_ROLE_MEMBERSHIP_REF).ref(ObjectTypeUtil.createObjectRef(selectedRole).asReferenceValue()).maxSize(1).build(); + ObjectQuery query = QueryBuilder.queryFor(FocusType.class, pageBase.getPrismContext()) + .item(FocusType.F_ROLE_MEMBERSHIP_REF)// TODO MID-3581 + .ref(ObjectTypeUtil.createObjectRef(selectedRole, pageBase.getPrismContext()).asReferenceValue()) + .maxSize(1) + .build(); List> members = WebModelServiceUtils.searchObjects(FocusType.class, query, result, pageBase); if (CollectionUtils.isNotEmpty(members)) { atLeastOneWithMembers = true; @@ -2518,32 +2586,28 @@ public static ItemVisibility checkShadowActivationAndPasswordVisibility(ItemWrap public static List getCategoryRelationChoices(AreaCategoryType category, ModelServiceLocator pageBase){ List relationsList = new ArrayList<>(); List defList = getRelationDefinitions(pageBase); - if (defList != null) { - defList.forEach(def -> { - if (def.getCategory() != null && def.getCategory().contains(category)) { - relationsList.add(def.getRef()); - } - }); - } + defList.forEach(def -> { + if (def.getCategory() != null && def.getCategory().contains(category)) { + relationsList.add(def.getRef()); + } + }); return relationsList; } public static List getAllRelations(ModelServiceLocator pageBase) { - List allRelationdefinitions = getRelationDefinitions(pageBase); - List allRelationsQName = new ArrayList<>(allRelationdefinitions.size()); - allRelationdefinitions.stream().forEach(relation -> allRelationsQName.add(relation.getRef())); + List allRelationDefinitions = getRelationDefinitions(pageBase); + List allRelationsQName = new ArrayList<>(allRelationDefinitions.size()); + allRelationDefinitions.forEach(relation -> allRelationsQName.add(relation.getRef())); return allRelationsQName; } - public static List getRelationDefinitions(ModelServiceLocator pageBase){ - OperationResult result = new OperationResult("get relation definitions"); - try { - return pageBase.getModelInteractionService().getRelationDefinitions(result); - } catch (ObjectNotFoundException | SchemaException ex){ - result.computeStatus(); - LOGGER.error("Unable to load relation definitions, " + ex.getLocalizedMessage()); - } - return null; + @NotNull + public static List getRelationDefinitions(ModelServiceLocator pageBase) { + return pageBase.getModelInteractionService().getRelationDefinitions(); + } + + public static RelationDefinitionType getRelationDefinition(QName relation) { + return getRelationRegistry().getRelationDefinition(relation); } public static DropDownChoice createTriStateCombo(String id, IModel model) { @@ -2728,7 +2792,16 @@ private Map prepareExtensionValues(Collection oids) throw }); return menuItems; } - + + @SuppressWarnings("unused") + public static RelationRegistry getStaticallyProvidedRelationRegistry() { + return staticallyProvidedRelationRegistry; + } + + public static void setStaticallyProvidedRelationRegistry(RelationRegistry staticallyProvidedRelationRegistry) { + WebComponentUtil.staticallyProvidedRelationRegistry = staticallyProvidedRelationRegistry; + } + public static String loadHelpText(IModel model, Panel panel) { if(model == null || model.getObject() == null) { return null; diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/api/util/WebModelServiceUtils.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/api/util/WebModelServiceUtils.java index 91834255daa..9e5a9af7b2b 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/api/util/WebModelServiceUtils.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/api/util/WebModelServiceUtils.java @@ -33,7 +33,6 @@ import com.evolveum.midpoint.web.component.prism.ItemWrapper; import com.evolveum.midpoint.web.component.prism.ObjectWrapper; import com.evolveum.midpoint.web.component.prism.ObjectWrapperFactory; -import com.evolveum.midpoint.web.component.prism.PropertyOrReferenceWrapper; import com.evolveum.midpoint.web.component.prism.ValueStatus; import com.evolveum.midpoint.web.page.error.PageError; import com.evolveum.midpoint.web.page.login.PageLogin; @@ -160,7 +159,7 @@ public static List createObjectRefer for(PrismObject object: objects){ referenceMap.put(object.getOid(), WebComponentUtil.getName(object)); - references.add(ObjectTypeUtil.createObjectRef(object)); + references.add(ObjectTypeUtil.createObjectRef(object, page.getPrismContext())); } return references; diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/boot/MidPointErrorPageRegistrar.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/boot/MidPointErrorPageRegistrar.java new file mode 100644 index 00000000000..c0866d9c0f5 --- /dev/null +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/boot/MidPointErrorPageRegistrar.java @@ -0,0 +1,23 @@ +package com.evolveum.midpoint.web.boot; + +import org.springframework.boot.web.server.ErrorPage; +import org.springframework.boot.web.server.ErrorPageRegistrar; +import org.springframework.boot.web.server.ErrorPageRegistry; +import org.springframework.http.HttpStatus; + +import com.evolveum.midpoint.web.security.MidPointApplication; + +public class MidPointErrorPageRegistrar implements ErrorPageRegistrar { + + @Override + public void registerErrorPages(ErrorPageRegistry registry) { + + registry.addErrorPages( + new ErrorPage(HttpStatus.UNAUTHORIZED, MidPointApplication.MOUNT_UNAUTHORIZED_ERROR), + new ErrorPage(HttpStatus.FORBIDDEN, MidPointApplication.MOUNT_FORBIDEN_ERROR), + new ErrorPage(HttpStatus.NOT_FOUND, MidPointApplication.MOUNT_NOT_FOUND_ERROR), + new ErrorPage(HttpStatus.GONE, MidPointApplication.MOUNT_GONE_ERROR), + new ErrorPage(HttpStatus.INTERNAL_SERVER_ERROR, MidPointApplication.MOUNT_INTERNAL_SERVER_ERROR)); + } + +} diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/boot/MidPointSpringApplication.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/boot/MidPointSpringApplication.java index 1487119ba27..ffd9a69d0ce 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/boot/MidPointSpringApplication.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/boot/MidPointSpringApplication.java @@ -16,13 +16,11 @@ package com.evolveum.midpoint.web.boot; -import com.evolveum.midpoint.gui.impl.util.ReportPeerQueryInterceptor; -import com.evolveum.midpoint.init.StartupConfiguration; -import com.evolveum.midpoint.model.api.authentication.NodeAuthenticationEvaluator; -import com.evolveum.midpoint.prism.schema.CatalogImpl; -import com.evolveum.midpoint.util.logging.Trace; -import com.evolveum.midpoint.util.logging.TraceManager; -import com.evolveum.midpoint.web.util.MidPointProfilingServletFilter; +import java.io.File; +import java.lang.management.ManagementFactory; +import java.time.Duration; + +import javax.servlet.DispatcherType; import org.apache.catalina.Valve; import org.apache.commons.lang.StringUtils; @@ -35,27 +33,23 @@ import org.springframework.boot.ExitCodeGenerator; import org.springframework.boot.SpringApplication; import org.springframework.boot.SpringBootConfiguration; -import org.springframework.boot.actuate.autoconfigure.endpoint.EndpointAutoConfiguration; import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointAutoConfiguration; import org.springframework.boot.actuate.autoconfigure.health.HealthEndpointAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.health.HealthIndicatorAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.web.mappings.MappingsEndpointAutoConfiguration; import org.springframework.boot.actuate.autoconfigure.web.servlet.ServletManagementContextAutoConfiguration; -import org.springframework.boot.actuate.endpoint.EndpointFilter; -import org.springframework.boot.actuate.endpoint.ExposableEndpoint; -import org.springframework.boot.actuate.endpoint.web.EndpointServlet; -import org.springframework.boot.actuate.endpoint.web.annotation.ServletEndpointDiscoverer; -import org.springframework.boot.actuate.health.HealthEndpoint; import org.springframework.boot.autoconfigure.ImportAutoConfiguration; import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration; import org.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConfiguration; import org.springframework.boot.autoconfigure.security.servlet.SecurityFilterAutoConfiguration; import org.springframework.boot.autoconfigure.web.ServerProperties; -import org.springframework.boot.autoconfigure.web.embedded.EmbeddedWebServerFactoryCustomizerAutoConfiguration; -import org.springframework.boot.autoconfigure.web.servlet.*; +import org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration; +import org.springframework.boot.autoconfigure.web.servlet.HttpEncodingAutoConfiguration; +import org.springframework.boot.autoconfigure.web.servlet.MultipartAutoConfiguration; +import org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryCustomizer; +import org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration; import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory; import org.springframework.boot.web.server.ErrorPage; +import org.springframework.boot.web.server.ErrorPageRegistrar; import org.springframework.boot.web.server.WebServerFactoryCustomizer; import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.boot.web.servlet.ServletListenerRegistrationBean; @@ -70,14 +64,16 @@ import org.springframework.stereotype.Component; import org.springframework.web.context.request.RequestContextListener; import org.springframework.web.filter.DelegatingFilterProxy; -import ro.isdc.wro.http.WroFilter; -import javax.servlet.DispatcherType; -import javax.servlet.Servlet; +import com.evolveum.midpoint.gui.impl.util.ReportPeerQueryInterceptor; +import com.evolveum.midpoint.init.StartupConfiguration; +import com.evolveum.midpoint.model.api.authentication.NodeAuthenticationEvaluator; +import com.evolveum.midpoint.prism.schema.CatalogImpl; +import com.evolveum.midpoint.util.logging.Trace; +import com.evolveum.midpoint.util.logging.TraceManager; +import com.evolveum.midpoint.web.util.MidPointProfilingServletFilter; -import java.io.File; -import java.lang.management.ManagementFactory; -import java.time.Duration; +import ro.isdc.wro.http.WroFilter; /** * Created by Viliam Repan (lazyman). @@ -188,23 +184,24 @@ private static SpringApplicationBuilder configureApplication(SpringApplicationBu } @Bean - public ServletListenerRegistrationBean requestContextListener() { - return new ServletListenerRegistrationBean(new RequestContextListener()); + public ServletListenerRegistrationBean requestContextListener() { + return new ServletListenerRegistrationBean<>(new RequestContextListener()); } @Bean - public FilterRegistrationBean midPointProfilingServletFilter() { - FilterRegistrationBean registration = new FilterRegistrationBean(); + public FilterRegistrationBean midPointProfilingServletFilter() { + FilterRegistrationBean registration = new FilterRegistrationBean<>(); registration.setFilter(new MidPointProfilingServletFilter()); +// registration.setDispatcherTypes(EnumSet.allOf(DispatcherType.class)); registration.addUrlPatterns("/*"); return registration; } @Bean - public FilterRegistrationBean wicket() { - FilterRegistrationBean registration = new FilterRegistrationBean(); + public FilterRegistrationBean wicket() { + FilterRegistrationBean registration = new FilterRegistrationBean<>(); registration.setFilter(new WicketFilter()); - registration.setDispatcherTypes(DispatcherType.REQUEST, DispatcherType.ERROR); + registration.setDispatcherTypes(DispatcherType.ERROR, DispatcherType.REQUEST, DispatcherType.FORWARD); registration.addUrlPatterns("/*"); registration.addInitParameter(WicketFilter.FILTER_MAPPING_PARAM, "/*"); registration.addInitParameter(Application.CONFIGURATION, "deployment"); // development @@ -215,16 +212,16 @@ public FilterRegistrationBean wicket() { } @Bean - public FilterRegistrationBean springSecurityFilterChain() { - FilterRegistrationBean registration = new FilterRegistrationBean(); + public FilterRegistrationBean springSecurityFilterChain() { + FilterRegistrationBean registration = new FilterRegistrationBean<>(); registration.setFilter(new DelegatingFilterProxy()); registration.addUrlPatterns("/*"); return registration; } @Bean - public FilterRegistrationBean webResourceOptimizer(WroFilter wroFilter) { - FilterRegistrationBean registration = new FilterRegistrationBean(); + public FilterRegistrationBean webResourceOptimizer(WroFilter wroFilter) { + FilterRegistrationBean registration = new FilterRegistrationBean<>(); registration.setFilter(wroFilter); registration.addUrlPatterns("/wro/*"); return registration; @@ -239,8 +236,8 @@ public FilterRegistrationBean webResourceOptimizer(WroFilter wroFilter) { // } @Bean - public ServletRegistrationBean cxfServlet() { - ServletRegistrationBean registration = new ServletRegistrationBean(); + public ServletRegistrationBean cxfServlet() { + ServletRegistrationBean registration = new ServletRegistrationBean<>(); registration.setServlet(new CXFServlet()); registration.addInitParameter("service-list-path", "midpointservices"); registration.setLoadOnStartup(1); @@ -250,8 +247,8 @@ public ServletRegistrationBean cxfServlet() { } @Bean - public ServletRegistrationBean reportPeerQueryInterceptor() { - ServletRegistrationBean registration = new ServletRegistrationBean(); + public ServletRegistrationBean reportPeerQueryInterceptor() { + ServletRegistrationBean registration = new ServletRegistrationBean<>(); registration.setServlet(new ReportPeerQueryInterceptor(nodeAuthenticator)); registration.addUrlMappings("/report"); @@ -259,8 +256,8 @@ public ServletRegistrationBean reportPeerQueryInterceptor() { } @Bean - public ServletRegistrationBean staticWebServlet() { - ServletRegistrationBean registration = new ServletRegistrationBean(); + public ServletRegistrationBean staticWebServlet() { + ServletRegistrationBean registration = new ServletRegistrationBean<>(); StaticWebServlet servlet = new StaticWebServlet( new File(startupConfiguration.getMidpointHome(), "static-web")); registration.setServlet(servlet); @@ -268,6 +265,12 @@ public ServletRegistrationBean staticWebServlet() { return registration; } + @Bean + public ErrorPageRegistrar errorPageRegistrar() { + return new MidPointErrorPageRegistrar(); + } + + @Component public class ServerCustomization implements WebServerFactoryCustomizer { diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/boot/WebSecurityConfig.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/boot/WebSecurityConfig.java index fba6fbbf773..a5a1217f7da 100755 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/boot/WebSecurityConfig.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/boot/WebSecurityConfig.java @@ -23,6 +23,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.autoconfigure.security.SecurityProperties; +import org.springframework.boot.web.server.ErrorPageRegistrar; import org.springframework.context.annotation.*; import org.springframework.core.annotation.Order; import org.springframework.core.env.Environment; @@ -163,7 +164,7 @@ protected void configure(HttpSecurity http) throws Exception { http.addFilterBefore(requestHeaderAuthenticationFilter(), LogoutFilter.class); } } - + @Bean @Override protected AuthenticationManager authenticationManager() throws Exception { diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/AbstractAssignmentListPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/AbstractAssignmentListPanel.java index d49a9b8ac91..9d4bb2b4b60 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/AbstractAssignmentListPanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/AbstractAssignmentListPanel.java @@ -16,8 +16,8 @@ package com.evolveum.midpoint.web.component.assignment; import com.evolveum.midpoint.gui.api.component.BasePanel; +import com.evolveum.midpoint.gui.api.util.WebComponentUtil; import com.evolveum.midpoint.prism.path.ItemPath; -import com.evolveum.midpoint.schema.constants.SchemaConstants; import com.evolveum.midpoint.util.exception.SchemaException; import com.evolveum.midpoint.util.logging.LoggingUtils; import com.evolveum.midpoint.util.logging.Trace; @@ -28,7 +28,6 @@ import com.evolveum.midpoint.web.page.admin.users.dto.UserDtoStatus; import com.evolveum.midpoint.xml.ns._public.common.common_3.*; import org.apache.wicket.ajax.AjaxRequestTarget; -import org.apache.wicket.extensions.ajax.markup.html.modal.ModalWindow; import org.apache.wicket.model.AbstractReadOnlyModel; import org.apache.wicket.model.IModel; @@ -138,7 +137,7 @@ protected AssignmentEditorDto createAssignmentFromSelectedObjects(ObjectType obj } if (object instanceof UserType) { AssignmentEditorDto dto = AssignmentEditorDto.createDtoAddFromSelectedObject(object, - SchemaConstants.ORG_DEPUTY, getPageBase()); + WebComponentUtil.getDefaultRelationOrFail(RelationKindType.DELEGATION), getPageBase()); dto.getTargetRef().setRelation(relation); return dto; } else { diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/AbstractRoleAssignmentPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/AbstractRoleAssignmentPanel.java index 40b93d7160e..1657d5a2029 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/AbstractRoleAssignmentPanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/AbstractRoleAssignmentPanel.java @@ -21,20 +21,38 @@ import java.util.List; import com.evolveum.midpoint.gui.api.component.AssignmentPopup; +import com.evolveum.midpoint.gui.api.page.PageBase; +import com.evolveum.midpoint.gui.api.util.WebComponentUtil; +import com.evolveum.midpoint.gui.api.util.WebModelServiceUtils; import com.evolveum.midpoint.prism.*; +import com.evolveum.midpoint.prism.path.ItemPath; +import com.evolveum.midpoint.prism.query.ObjectPaging; +import com.evolveum.midpoint.prism.query.ObjectQuery; +import com.evolveum.midpoint.prism.query.builder.QueryBuilder; import com.evolveum.midpoint.prism.query.NotFilter; import com.evolveum.midpoint.prism.query.ObjectFilter; import com.evolveum.midpoint.schema.constants.ObjectTypes; +import com.evolveum.midpoint.schema.constants.RelationTypes; import com.evolveum.midpoint.schema.constants.SchemaConstants; import com.evolveum.midpoint.schema.result.OperationResult; -import com.evolveum.midpoint.web.component.prism.*; +import com.evolveum.midpoint.util.exception.SchemaException; +import com.evolveum.midpoint.util.logging.Trace; +import com.evolveum.midpoint.util.logging.TraceManager; +import com.evolveum.midpoint.web.component.AjaxButton; +import com.evolveum.midpoint.web.component.input.DropDownChoicePanel; +import com.evolveum.midpoint.web.component.prism.ContainerValueWrapper; +import com.evolveum.midpoint.web.component.prism.ContainerWrapper; +import com.evolveum.midpoint.web.component.prism.PropertyOrReferenceWrapper; +import com.evolveum.midpoint.web.component.prism.ValueWrapper; import com.evolveum.midpoint.web.component.search.SearchFactory; import com.evolveum.midpoint.web.component.search.SearchItemDefinition; +import com.evolveum.midpoint.web.component.util.VisibleEnableBehaviour; import com.evolveum.midpoint.web.page.admin.PageAdminFocus; -import com.evolveum.midpoint.web.page.admin.users.component.AssignmentInfoDto; import com.evolveum.midpoint.web.page.admin.users.component.AllAssignmentsPreviewDialog; +import com.evolveum.midpoint.web.page.admin.users.component.AssignmentInfoDto; +import com.evolveum.midpoint.web.session.UserProfileStorage; +import com.evolveum.midpoint.web.session.UserProfileStorage.TableId; import com.evolveum.midpoint.xml.ns._public.common.common_3.*; - import org.apache.commons.lang.StringUtils; import org.apache.wicket.ajax.AjaxRequestTarget; import org.apache.wicket.extensions.markup.html.repeater.data.grid.ICellPopulator; @@ -46,6 +64,11 @@ import org.apache.wicket.model.IModel; import org.apache.wicket.model.Model; +import javax.xml.namespace.QName; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; import com.evolveum.midpoint.gui.api.page.PageBase; import com.evolveum.midpoint.gui.api.util.WebComponentUtil; import com.evolveum.midpoint.gui.api.util.WebModelServiceUtils; @@ -261,9 +284,11 @@ protected int getItemsPerPage() { } protected ObjectQuery createObjectQuery() { + Collection delegationRelations = getParentPage().getRelationRegistry() + .getAllRelationsFor(RelationKindType.DELEGATION); ObjectFilter deputyFilter = QueryBuilder.queryFor(AssignmentType.class, getParentPage().getPrismContext()) .item(new ItemPath(AssignmentType.F_TARGET_REF)) - .ref(SchemaConstants.ORG_DEPUTY) + .ref(delegationRelations.toArray(new QName[0])) .buildFilter(); ObjectQuery query = QueryBuilder.queryFor(AssignmentType.class, getParentPage().getPrismContext()) .not() diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/ApplicablePolicyGroupPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/ApplicablePolicyGroupPanel.java index 7f6a21487dd..c24b4d16806 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/ApplicablePolicyGroupPanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/ApplicablePolicyGroupPanel.java @@ -20,7 +20,6 @@ import com.evolveum.midpoint.gui.api.model.LoadableModel; import com.evolveum.midpoint.gui.api.util.WebComponentUtil; import com.evolveum.midpoint.gui.api.util.WebModelServiceUtils; -import com.evolveum.midpoint.prism.ItemDefinition; import com.evolveum.midpoint.prism.PrismContainerValue; import com.evolveum.midpoint.prism.PrismObject; import com.evolveum.midpoint.prism.query.ObjectQuery; @@ -30,7 +29,6 @@ import com.evolveum.midpoint.task.api.Task; import com.evolveum.midpoint.util.logging.Trace; import com.evolveum.midpoint.util.logging.TraceManager; -import com.evolveum.midpoint.web.component.data.column.IsolatedCheckBoxPanel; import com.evolveum.midpoint.web.component.prism.*; import com.evolveum.midpoint.xml.ns._public.common.common_3.*; import org.apache.wicket.ajax.AjaxRequestTarget; @@ -174,7 +172,7 @@ private void onPolicyAddedOrRemoved(PrismObject assignmentTarg if (added){ //TODO: not sure if this is correct way of creating new value.. this value is added directly to the origin object... what about deltas?? PrismContainerValue newAssignment = assignmentsModel.getObject().getItem().createNewValue(); - ObjectReferenceType ref = ObjectTypeUtil.createObjectRef(assignmentTargetObject); + ObjectReferenceType ref = ObjectTypeUtil.createObjectRef(assignmentTargetObject, getPageBase().getPrismContext()); AssignmentType assignmentType = newAssignment.asContainerable(); assignmentType.setTargetRef(ref); Task task = getPageBase().createSimpleTask("Creating new applicable policy"); diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/AssignmentDto.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/AssignmentDto.java deleted file mode 100644 index bd68c9e6854..00000000000 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/AssignmentDto.java +++ /dev/null @@ -1,110 +0,0 @@ -/* - * 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. - */ -package com.evolveum.midpoint.web.component.assignment; - -import java.io.Serializable; -import java.util.Collection; - -import javax.xml.namespace.QName; - -import org.apache.commons.lang.Validate; - -import com.evolveum.midpoint.prism.delta.ItemDelta; -import com.evolveum.midpoint.schema.constants.RelationTypes; -import com.evolveum.midpoint.schema.constants.SchemaConstants; -import com.evolveum.midpoint.web.component.util.Selectable; -import com.evolveum.midpoint.web.page.admin.users.dto.UserDtoStatus; -import com.evolveum.midpoint.xml.ns._public.common.common_3.AssignmentType; - -public class AssignmentDto extends Selectable implements Comparable, Serializable{ - - private static final long serialVersionUID = 1L; - - private AssignmentType assignment; - private UserDtoStatus status; - private AssignmentType oldAssignment; -// private RelationTypes relationType; - - public static final String F_VALUE = "assignment"; - public static final String F_RELATION_TYPE = "relationType"; - - public AssignmentDto(AssignmentType assignment, UserDtoStatus status) { - this.assignment = assignment; - this.oldAssignment = assignment.clone(); - this.status = status; - } - - public Collection computeAssignmentDelta() { - Collection deltas = oldAssignment.asPrismContainerValue().diff(assignment.asPrismContainerValue()); - return deltas; - } - - public void revertChanges() { - assignment = oldAssignment.clone(); - } - - public QName getRelation() { - - //TODO: what kind of rlation should be returned for the PERSONA CONSTRUCTION? - - if (assignment.getConstruction() != null) { - return SchemaConstants.ORG_DEFAULT; - } - - if (assignment.getTargetRef() == null) { - return null; - } - - return assignment.getTargetRef().getRelation(); - - } - - public RelationTypes getRelationType() { - return RelationTypes.getRelationType(getRelation()); - } - - public void setRelationType(RelationTypes relationType){ - if (assignment.getTargetRef() == null) { - return; - } - - assignment.getTargetRef().setRelation(relationType.getRelation()); - } - - - public AssignmentType getAssignment() { - return assignment; - } - - @Override - public int compareTo(AssignmentDto other) { - Validate.notNull(other, "Can't compare assignment editor dto with null."); - - String name1 = "";//getName() != null ? getName() : ""; - String name2 = "";//other.getName() != null ? other.getName() : ""; - - return String.CASE_INSENSITIVE_ORDER.compare(name1, name2); - } - - public UserDtoStatus getStatus() { - return status; - } - - public void setStatus(UserDtoStatus status) { - this.status = status; - } - -} diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/AssignmentEditorDto.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/AssignmentEditorDto.java index d30a6555b2b..56a9e62aa8c 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/AssignmentEditorDto.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/AssignmentEditorDto.java @@ -24,9 +24,8 @@ import com.evolveum.midpoint.common.refinery.RefinedResourceSchemaImpl; import com.evolveum.midpoint.prism.*; import com.evolveum.midpoint.prism.path.ItemPath; +import com.evolveum.midpoint.schema.RelationRegistry; import com.evolveum.midpoint.schema.constants.ObjectTypes; -import com.evolveum.midpoint.schema.constants.RelationTypes; -import com.evolveum.midpoint.schema.util.ObjectTypeUtil; import com.evolveum.midpoint.util.QNameUtil; import com.evolveum.midpoint.web.page.admin.users.component.AssignmentInfoDto; import com.evolveum.midpoint.xml.ns._public.common.common_3.*; @@ -41,7 +40,6 @@ import com.evolveum.midpoint.gui.api.util.WebComponentUtil; import com.evolveum.midpoint.gui.api.util.WebModelServiceUtils; import com.evolveum.midpoint.prism.util.ItemPathUtil; -import com.evolveum.midpoint.schema.constants.SchemaConstants; import com.evolveum.midpoint.schema.result.OperationResult; import com.evolveum.midpoint.task.api.Task; import com.evolveum.midpoint.util.exception.SchemaException; @@ -148,7 +146,7 @@ public AssignmentEditorDto(UserDtoStatus status, AssignmentType assignment, Page this.altName = getAlternativeName(assignment); this.attributes = prepareAssignmentAttributes(assignment, pageBase); - this.isOrgUnitManager = determineUserOrgRelation(assignment); + this.isOrgUnitManager = isOrgUnitManager(assignment); this.privilegeLimitationList = getAssignmentPrivilegesList(assignment); } @@ -164,7 +162,7 @@ public static AssignmentEditorDto createDtoAddFromSelectedObject(ObjectType obje PageBase pageBase, UserType delegationOwner) { AssignmentEditorDto dto = createDtoFromObject(object, UserDtoStatus.ADD, relation, pageBase); dto.setDelegationOwner(delegationOwner); - if (SchemaConstants.ORG_DEPUTY.equals(relation)){ + if (pageBase.getRelationRegistry().isDelegation(relation)) { OtherPrivilegesLimitationType limitations = new OtherPrivilegesLimitationType(); WorkItemSelectorType approvalWorkItemSelector = new WorkItemSelectorType(); @@ -245,18 +243,11 @@ private List getAssignmentPrivilegesList(AssignmentType assig } return list; } - private Boolean determineUserOrgRelation(AssignmentType assignment) { - - if (assignment == null || assignment.getTargetRef() == null - || ObjectTypeUtil.isDefaultRelation(assignment.getTargetRef().getRelation())) { - return Boolean.FALSE; - } - - if (ObjectTypeUtil.isManagerRelation(assignment.getTargetRef().getRelation())) { - return Boolean.TRUE; - } - - return Boolean.FALSE; + private boolean isOrgUnitManager(AssignmentType assignment) { + RelationRegistry relationRegistry = pageBase.getRelationRegistry(); + return assignment != null + && assignment.getTargetRef() != null + && relationRegistry.isManager(assignment.getTargetRef().getRelation()); } private List prepareAssignmentAttributes(AssignmentType assignment, PageBase pageBase) { @@ -439,7 +430,9 @@ private String getNameForTargetObject(AssignmentType assignment) { } if (assignment.getTargetRef() != null && assignment.getTargetRef().getRelation() != null) { - sb.append(" - " + RelationTypes.getRelationType(assignment.getTargetRef().getRelation()).getHeaderLabel()); + String relationName = pageBase + .getString(WebComponentUtil.getRelationHeaderLabelKey(assignment.getTargetRef().getRelation())); + sb.append(" - ").append(relationName); } return sb.toString(); diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/AssignmentEditorPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/AssignmentEditorPanel.java index 9f4ac7f8ab2..dbfdc000776 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/AssignmentEditorPanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/AssignmentEditorPanel.java @@ -422,10 +422,13 @@ public String getObject() { } AssignmentEditorDto object = getModel().getObject(); - String propertyKey = RelationTypes.class.getSimpleName() + "." + - (object.getTargetRef() == null || object.getTargetRef().getRelation() == null ? - RelationTypes.MEMBER : RelationTypes.getRelationType(object.getTargetRef().getRelation())); - return createStringResource(propertyKey).getString(); + if (object.getTargetRef() != null) { + QName relation = object.getTargetRef() != null ? object.getTargetRef().getRelation() : null; + String propertyKey = WebComponentUtil.getRelationHeaderLabelKey(relation); + return createStringResource(propertyKey).getString(); + } else { + return ""; + } } }); relationLabel.setOutputMarkupId(true); @@ -986,7 +989,7 @@ private void addRelationDropDown(WebMarkupContainer relationContainer){ QName assignmentRelation = getModelObject().getTargetRef() != null ? getModelObject().getTargetRef().getRelation() : null; RelationDropDownChoicePanel relationDropDown = new RelationDropDownChoicePanel(ID_RELATION, - assignmentRelation != null ? assignmentRelation : SchemaConstants.ORG_DEFAULT, getSupportedRelations(), false); relationDropDown.setEnabled(getModel().getObject().isEditable()); + assignmentRelation != null ? assignmentRelation : WebComponentUtil.getDefaultRelationOrFail(), getSupportedRelations(), false); relationDropDown.setEnabled(getModel().getObject().isEditable()); relationDropDown.add(new VisibleEnableBehaviour() { private static final long serialVersionUID = 1L; @@ -1011,33 +1014,32 @@ private List getSupportedRelations() { } } - - protected IModel getRelationModel(){ - return new IModel() { - private static final long serialVersionUID = 1L; - - @Override - public RelationTypes getObject() { - if (getModelObject().getTargetRef() == null) { - return RelationTypes.MEMBER; - } - return RelationTypes.getRelationType(getModelObject().getTargetRef().getRelation()); - } - - @Override - public void setObject(RelationTypes newValue) { - ObjectReferenceType ref = getModelObject().getTargetRef(); - if (ref != null){ - ref.setRelation(newValue.getRelation()); - } - } - - @Override - public void detach() { - - } - }; - } +// protected IModel getRelationModel() { +// return new IModel() { +// private static final long serialVersionUID = 1L; +// +// @Override +// public RelationTypes getObject() { +// if (getModelObject().getTargetRef() == null) { +// return RelationTypes.MEMBER; +// } +// return RelationTypes.getRelationType(getModelObject().getTargetRef().getRelation()); +// } +// +// @Override +// public void setObject(RelationTypes newValue) { +// ObjectReferenceType ref = getModelObject().getTargetRef(); +// if (ref != null){ +// ref.setRelation(newValue.getRelation()); +// } +// } +// +// @Override +// public void detach() { +// +// } +// }; +// } private PrismObject getTargetObject(AssignmentEditorDto dto) throws ObjectNotFoundException, SchemaException, SecurityViolationException, diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/AssignmentTablePanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/AssignmentTablePanel.java index 53edf29eb85..7fa426be713 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/AssignmentTablePanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/AssignmentTablePanel.java @@ -242,7 +242,7 @@ public void onClick(AjaxRequestTarget target) { protected void assignSelectedOrgPerformed(List selectedOrgs, AjaxRequestTarget target) { // TODO Auto-generated method stub - addSelectedAssignablePerformed(target, (List) selectedOrgs, SchemaConstants.ORG_DEFAULT, + addSelectedAssignablePerformed(target, (List) selectedOrgs, WebComponentUtil.getDefaultRelationOrFail(), getPageBase().getMainPopup().getId()); reloadMainFormButtons(target); } diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/AssignmentsUtil.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/AssignmentsUtil.java index 5ba2551b239..cb82ac9309f 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/AssignmentsUtil.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/AssignmentsUtil.java @@ -297,12 +297,9 @@ private static void appendRelation(AssignmentType assignment, StringBuilder sb, return; } - RelationDefinitionType relationDef = ObjectTypeUtil.findRelationDefinition( - WebComponentUtil.getRelationDefinitions(pageBase), - assignment.getTargetRef().getRelation()); - if (relationDef != null && relationDef.getDisplay() != null && - !relationDef.getDisplay().getLabel().isEmpty()) { - sb.append(" - " + pageBase.createStringResource(relationDef.getDisplay().getLabel()).getString()); + String labelKey = WebComponentUtil.getRelationHeaderLabelKeyIfKnown(assignment.getTargetRef().getRelation()); + if (StringUtils.isNotEmpty(labelKey)) { + sb.append(" - ").append(pageBase.createStringResource(labelKey).getString()); } } diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/RoleCatalogItemButton.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/RoleCatalogItemButton.java index fd3351807ca..c7e3450309f 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/RoleCatalogItemButton.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/RoleCatalogItemButton.java @@ -318,7 +318,7 @@ private void addAssignmentPerformed(AssignmentEditorDto assignment, AjaxRequestT protected void assignmentAddedToShoppingCartPerformed(AjaxRequestTarget target){ } - protected QName getNewAssignmentRelation(){ - return SchemaConstants.ORG_DEFAULT; + protected QName getNewAssignmentRelation() { + return WebComponentUtil.getDefaultRelationOrFail(); } } diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/SimpleRoleSelector.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/SimpleRoleSelector.java index f25f32a4b5a..992d7f3b43e 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/SimpleRoleSelector.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/SimpleRoleSelector.java @@ -160,7 +160,7 @@ private void toggleRole(PrismObject role) { } } - AssignmentType newAssignment = ObjectTypeUtil.createAssignmentTo(role); +// AssignmentType newAssignment = ObjectTypeUtil.createAssignmentTo(role, prismContext); //TODO //create ContainerValueWrapper for new assignment // getAssignmentModel().getObject().add(newAssignment); diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/data/BaseSortableDataProvider.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/data/BaseSortableDataProvider.java index 8962aefa2e2..08a772e7372 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/data/BaseSortableDataProvider.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/data/BaseSortableDataProvider.java @@ -27,6 +27,7 @@ import com.evolveum.midpoint.prism.query.OrderDirection; import com.evolveum.midpoint.repo.api.RepositoryService; import com.evolveum.midpoint.schema.GetOperationOptions; +import com.evolveum.midpoint.schema.RelationRegistry; import com.evolveum.midpoint.schema.SchemaConstantsGenerated; import com.evolveum.midpoint.schema.SelectorOptions; import com.evolveum.midpoint.schema.result.OperationResult; @@ -116,6 +117,11 @@ protected PrismContext getPrismContext() { return application.getPrismContext(); } + protected RelationRegistry getRelationRegistry() { + MidPointApplication application = MidPointApplication.get(); + return application.getRelationRegistry(); + } + protected TaskService getTaskService() { MidPointApplication application = MidPointApplication.get(); return application.getTaskService(); diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/form/ValueChoosePanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/form/ValueChoosePanel.java index ee2f2c0924e..d9c0dc150c6 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/form/ValueChoosePanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/form/ValueChoosePanel.java @@ -125,7 +125,7 @@ protected boolean isEditButtonEnabled() { } protected void replaceIfEmpty(ObjectType object) { - ObjectReferenceType ort = ObjectTypeUtil.createObjectRef(object); + ObjectReferenceType ort = ObjectTypeUtil.createObjectRef(object, getPageBase().getPrismContext()); getModel().setObject((T) ort.asReferenceValue()); } diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/input/RelationDropDownChoicePanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/input/RelationDropDownChoicePanel.java index fab210b8052..f3370e51ac5 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/input/RelationDropDownChoicePanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/input/RelationDropDownChoicePanel.java @@ -108,8 +108,7 @@ public QName getObject(String id, IModel choices) { @Override public Object getDisplayValue(QName object) { - RelationDefinitionType def = - ObjectTypeUtil.findRelationDefinition(WebComponentUtil.getRelationDefinitions(RelationDropDownChoicePanel.this.getPageBase()), object); + RelationDefinitionType def = WebComponentUtil.getRelationDefinition(object); if (def != null){ DisplayType display = def.getDisplay(); if (display != null){ diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/objectdetails/ObjectHistoryTabPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/objectdetails/ObjectHistoryTabPanel.java index 87e7d6b6ed9..a2bd645e3d5 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/objectdetails/ObjectHistoryTabPanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/objectdetails/ObjectHistoryTabPanel.java @@ -48,14 +48,12 @@ import com.evolveum.midpoint.web.page.admin.PageAdminObjectDetails; import com.evolveum.midpoint.web.page.admin.reports.component.AuditLogViewerPanel; import com.evolveum.midpoint.web.page.admin.reports.dto.AuditSearchDto; -import com.evolveum.midpoint.web.page.admin.users.PageUserHistory; import com.evolveum.midpoint.web.page.admin.users.PageXmlDataReview; import com.evolveum.midpoint.web.session.AuditLogStorage; import com.evolveum.midpoint.xml.ns._public.common.audit_3.AuditEventRecordType; import com.evolveum.midpoint.xml.ns._public.common.audit_3.AuditEventStageType; import com.evolveum.midpoint.xml.ns._public.common.common_3.FocusType; import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectReferenceType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.UserType; /** * Created by honchar. @@ -166,7 +164,7 @@ protected long getCurrentPage() { private AuditSearchDto createAuditSearchDto(F focus) { AuditSearchDto searchDto = new AuditSearchDto(); - ObjectReferenceType ort = ObjectTypeUtil.createObjectRef(focus); + ObjectReferenceType ort = ObjectTypeUtil.createObjectRef(focus, getPrismContext()); searchDto.setTargetNames(asList(ort)); searchDto.setEventStage(AuditEventStageType.EXECUTION); return searchDto; diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/objectdetails/UserDelegationsTabPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/objectdetails/UserDelegationsTabPanel.java index 6df7c812b22..8241d1157f7 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/objectdetails/UserDelegationsTabPanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/objectdetails/UserDelegationsTabPanel.java @@ -23,7 +23,6 @@ import com.evolveum.midpoint.prism.query.InOidFilter; import com.evolveum.midpoint.prism.query.NotFilter; import com.evolveum.midpoint.prism.query.ObjectFilter; -import com.evolveum.midpoint.schema.constants.SchemaConstants; import com.evolveum.midpoint.security.api.AuthorizationConstants; import com.evolveum.midpoint.util.logging.LoggingUtils; import com.evolveum.midpoint.util.logging.Trace; @@ -39,6 +38,7 @@ import com.evolveum.midpoint.web.page.admin.users.dto.UserDtoStatus; import com.evolveum.midpoint.xml.ns._public.common.common_3.FocusType; import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.RelationKindType; import com.evolveum.midpoint.xml.ns._public.common.common_3.UserType; import org.apache.wicket.ajax.AjaxRequestTarget; import org.apache.wicket.extensions.ajax.markup.html.modal.ModalWindow; @@ -192,7 +192,7 @@ protected void addSelectedAssignablePerformed(AjaxRequestTarget target, List)getObjectWrapper().getObject()).asObjectable(), - SchemaConstants.ORG_DEPUTY, getPageBase(), (UserType) object); + WebComponentUtil.getDefaultRelationOrFail(RelationKindType.DELEGATION), getPageBase(), (UserType) object); dto.setPrivilegeLimitationList(privilegesListModel.getObject()); delegationsModel.getObject().add(dto); } catch (Exception e) { diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/show/ScenePanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/show/ScenePanel.java index 51cda0140bd..c05d5b462a4 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/show/ScenePanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/show/ScenePanel.java @@ -42,8 +42,6 @@ import org.apache.wicket.model.*; import org.jetbrains.annotations.NotNull; -import java.util.List; - /** * @author mederly */ @@ -147,7 +145,7 @@ public void onClick(AjaxRequestTarget target) { PrismContainerValue value = getModelObject().getScene().getSourceValue(); if (value != null && value.getParent() instanceof PrismObject) { PrismObject object = (PrismObject) value.getParent(); - WebComponentUtil.dispatchToObjectDetailsPage(ObjectTypeUtil.createObjectRef(object), getPageBase(), false); + WebComponentUtil.dispatchToObjectDetailsPage(ObjectTypeUtil.createObjectRef(object, getPageBase().getPrismContext()), getPageBase(), false); } } }; diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/search/SearchFactory.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/search/SearchFactory.java index 98444188f31..1bb0c3732ce 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/search/SearchFactory.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/search/SearchFactory.java @@ -17,11 +17,7 @@ package com.evolveum.midpoint.web.component.search; import java.lang.reflect.Modifier; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.util.*; import com.evolveum.midpoint.gui.api.page.PageBase; import com.evolveum.midpoint.gui.api.util.ModelServiceLocator; @@ -36,7 +32,6 @@ import com.evolveum.midpoint.prism.path.ItemPath; import com.evolveum.midpoint.prism.schema.SchemaRegistry; import com.evolveum.midpoint.schema.ResourceShadowDiscriminator; -import com.evolveum.midpoint.schema.constants.SchemaConstants; import com.evolveum.midpoint.schema.result.OperationResult; import com.evolveum.midpoint.schema.util.FullTextSearchConfigurationUtil; import com.evolveum.midpoint.task.api.Task; @@ -60,8 +55,6 @@ import com.evolveum.midpoint.xml.ns._public.common.common_3.GenericObjectType; import com.evolveum.midpoint.xml.ns._public.common.common_3.GuiObjectListViewType; import com.evolveum.midpoint.xml.ns._public.common.common_3.GuiObjectListViewsType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.LifecycleStateModelType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.LifecycleStateType; import com.evolveum.midpoint.xml.ns._public.common.common_3.NodeType; import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectPolicyConfigurationType; import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectType; @@ -360,10 +353,9 @@ public static void addSearchRefDef(PrismContainerDefin return; } if (pageBase == null) { - defs.add(new SearchItemDefinition(path, refDef, Arrays.asList(SchemaConstants.ORG_DEFAULT))); + defs.add(new SearchItemDefinition(path, refDef, Collections.singletonList(WebComponentUtil.getDefaultRelationOrFail()))); return; } - OperationResult result = new OperationResult("resolve applicable relations"); defs.add(new SearchItemDefinition(path, refDef, WebComponentUtil.getCategoryRelationChoices(category, pageBase))); } diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/wizard/resource/NameStep.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/wizard/resource/NameStep.java index 0315869c7ca..4c961e1b2e7 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/wizard/resource/NameStep.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/wizard/resource/NameStep.java @@ -449,7 +449,7 @@ public void applyState() { ResourceType resourceType = resource.asObjectable(); resourceType.setName(PolyStringType.fromOrig(resourceNameModel.getObject())); resourceType.setDescription(resourceDescriptionModel.getObject()); - resourceType.setConnectorRef(ObjectTypeUtil.createObjectRef(connector)); + resourceType.setConnectorRef(ObjectTypeUtil.createObjectRef(connector, prismContext)); delta = ObjectDelta.createAddDelta(resource); } else { PrismObject oldResourceObject = @@ -470,7 +470,7 @@ public void applyState() { String oldConnectorOid = oldResource.getConnectorRef() != null ? oldResource.getConnectorRef().getOid() : null; String newConnectorOid = connector.getOid(); if (!StringUtils.equals(oldConnectorOid, newConnectorOid)) { - i = i.item(ResourceType.F_CONNECTOR_REF).replace(ObjectTypeUtil.createObjectRef(connector).asReferenceValue()); + i = i.item(ResourceType.F_CONNECTOR_REF).replace(ObjectTypeUtil.createObjectRef(connector, prismContext).asReferenceValue()); } if (!isConfigurationSchemaCompatible(connector)) { i = i.item(ResourceType.F_CONNECTOR_CONFIGURATION).replace(); diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/PageAdminFocus.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/PageAdminFocus.java index 1593280f1fe..6e9c0628184 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/PageAdminFocus.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/PageAdminFocus.java @@ -822,7 +822,7 @@ public List showAllAssignmentsPerformed(AjaxRequestTarget aja DeltaSetTriple targetsTriple = evaluatedAssignment.getRoles(); Collection targets = targetsTriple.getNonNegativeValues(); for (EvaluatedAssignmentTarget target : targets) { - if (target.appliesToFocusWithAnyRelation()) { + if (target.appliesToFocusWithAnyRelation(getRelationRegistry())) { assignmentInfoDtoSet.add(createAssignmentsPreviewDto(target, task, result)); } } diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/cases/PageCaseWorkItems.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/cases/PageCaseWorkItems.java index 29f33676916..4648b729b2a 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/cases/PageCaseWorkItems.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/cases/PageCaseWorkItems.java @@ -142,7 +142,7 @@ private ObjectQuery createQuery() throws SchemaException, ObjectNotFoundExceptio } else { // not authorized to see all => sees only allocated to him (not quite what is expected, but sufficient for the time being) query = QueryUtils.filterForAssignees(q, SecurityUtils.getPrincipalUser(), - OtherPrivilegesLimitationType.F_APPROVAL_WORK_ITEMS) + OtherPrivilegesLimitationType.F_APPROVAL_WORK_ITEMS, getRelationRegistry()) .and().item(CaseWorkItemType.F_CLOSE_TIMESTAMP).isNull().build(); } IsolatedCheckBoxPanel includeClosedCases = (IsolatedCheckBoxPanel) getCaseWorkItemsSearchField(ID_SEARCH_FILTER_INCLUDE_CLOSED_CASES); @@ -161,8 +161,10 @@ private ObjectQuery createQuery() throws SchemaException, ObjectNotFoundExceptio ObjectType resource = resources.get(0); if (resource != null) { query.addFilter( + // TODO MID-3581 QueryBuilder.queryFor(CaseWorkItemType.class, getPrismContext()) - .item(PrismConstants.T_PARENT, CaseType.F_OBJECT_REF).ref(ObjectTypeUtil.createObjectRef(resource).asReferenceValue()).buildFilter() + .item(PrismConstants.T_PARENT, CaseType.F_OBJECT_REF).ref(ObjectTypeUtil.createObjectRef(resource, + getPrismContext()).asReferenceValue()).buildFilter() ); } } @@ -175,9 +177,10 @@ private ObjectQuery createQuery() throws SchemaException, ObjectNotFoundExceptio if (assignees != null && assignees.size() > 0) { ObjectType assignee = assignees.get(0); if (assignee != null) { + // TODO MID-3581 query.addFilter( QueryBuilder.queryFor(CaseWorkItemType.class, getPrismContext()) - .item(CaseWorkItemType.F_ASSIGNEE_REF).ref(ObjectTypeUtil.createObjectRef(assignee).asReferenceValue()).buildFilter() + .item(CaseWorkItemType.F_ASSIGNEE_REF).ref(ObjectTypeUtil.createObjectRef(assignee, getPrismContext()).asReferenceValue()).buildFilter() ); } } @@ -432,7 +435,7 @@ private void searchFilterPerformed(AjaxRequestTarget target) { private Function objectReferenceTransformer = (Function & Serializable) (ObjectType o) -> - ObjectTypeUtil.createObjectRef(o); + ObjectTypeUtil.createObjectRef(o, getPrismContext()); private static class ButtonBar extends Fragment { diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/certification/dto/CertCaseOrWorkItemDto.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/certification/dto/CertCaseOrWorkItemDto.java index 0e08d6b8bb0..d3eb32690cf 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/certification/dto/CertCaseOrWorkItemDto.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/certification/dto/CertCaseOrWorkItemDto.java @@ -57,12 +57,14 @@ public class CertCaseOrWorkItemDto extends Selectable { private String objectName; private String targetName; private String deadlineAsString; + private QName defaultRelation; CertCaseOrWorkItemDto(@NotNull AccessCertificationCaseType _case, PageBase page) { this.certCase = _case; this.objectName = getName(_case.getObjectRef()); this.targetName = getName(_case.getTargetRef()); this.deadlineAsString = computeDeadlineAsString(page); + this.defaultRelation = page.getPrismContext().getDefaultRelation(); } // ugly hack (for now) - we extract the name from serialization metadata @@ -107,7 +109,7 @@ public QName getTargetType() { } public ObjectReferenceType getCampaignRef() { - return ObjectTypeUtil.createObjectRef(getCampaign()); + return ObjectTypeUtil.createObjectRef(getCampaign(), defaultRelation); } public Long getCaseId() { 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 6d06dfbde20..154f0630d80 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 @@ -16,6 +16,7 @@ package com.evolveum.midpoint.web.page.admin.configuration; +import java.io.Serializable; import java.util.Collection; import javax.xml.namespace.QName; @@ -359,9 +360,11 @@ private void validateObject(OperationResult result, Holder objectHol } - class DebugViewOptions { + class DebugViewOptions implements Serializable { - private final static String ID_ENCRYPT = "encrypt"; + private static final long serialVersionUID = 1L; + + private final static String ID_ENCRYPT = "encrypt"; private final static String ID_SAVE_AS_RAW = "saveAsRaw"; private final static String ID_REEVALUATE_SEARCH_FILTERS = "reevaluateSearchFilters"; private final static String ID_VALIDATE_SCHEMA = "validateSchema"; diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/reports/component/AuditLogViewerPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/reports/component/AuditLogViewerPanel.java index 6149d8f023b..d4bb14ce59a 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/reports/component/AuditLogViewerPanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/reports/component/AuditLogViewerPanel.java @@ -51,7 +51,6 @@ import com.evolveum.midpoint.audit.api.AuditEventRecord; import com.evolveum.midpoint.gui.api.component.BasePanel; import com.evolveum.midpoint.gui.api.component.button.CsvDownloadButtonPanel; -import com.evolveum.midpoint.gui.api.component.path.ItemPathDto; import com.evolveum.midpoint.gui.api.component.path.ItemPathPanel; import com.evolveum.midpoint.gui.api.util.WebComponentUtil; import com.evolveum.midpoint.gui.api.util.WebModelServiceUtils; @@ -363,7 +362,7 @@ public boolean isVisible() { // Serializable as it becomes part of panel which is serialized private Function objectReferenceTransformer = (Function & Serializable) (ObjectType o) -> - ObjectTypeUtil.createObjectRef(o); + ObjectTypeUtil.createObjectRef(o, getPageBase().getPrismContext()); // Serializable as it becomes part of panel which is serialized private Function stringTransformer = diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/resources/ResourceContentPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/resources/ResourceContentPanel.java index bd4f7d5a55e..7b274d97afc 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/resources/ResourceContentPanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/resources/ResourceContentPanel.java @@ -22,10 +22,8 @@ import javax.xml.namespace.QName; -import com.evolveum.midpoint.gui.api.GuiConstants; import com.evolveum.midpoint.gui.api.component.PendingOperationPanel; import com.evolveum.midpoint.web.component.menu.cog.ButtonInlineMenuItem; -import com.evolveum.midpoint.web.component.prism.ObjectWrapper; import com.evolveum.midpoint.xml.ns._public.common.common_3.*; import org.apache.commons.lang.StringUtils; import org.apache.wicket.ajax.AjaxRequestTarget; @@ -99,7 +97,6 @@ import com.evolveum.midpoint.web.component.data.column.ColumnMenuAction; import com.evolveum.midpoint.web.component.data.column.ColumnTypeDto; import com.evolveum.midpoint.web.component.data.column.ColumnUtils; -import com.evolveum.midpoint.web.component.data.column.InlineMenuHeaderColumn; import com.evolveum.midpoint.web.component.data.column.LinkColumn; import com.evolveum.midpoint.web.component.data.column.ObjectLinkColumn; import com.evolveum.midpoint.web.component.dialog.ConfirmationPanel; @@ -108,7 +105,6 @@ import com.evolveum.midpoint.web.component.search.Search; import com.evolveum.midpoint.web.component.util.SelectableBean; import com.evolveum.midpoint.web.component.util.VisibleEnableBehaviour; -import com.evolveum.midpoint.web.page.admin.configuration.component.HeaderMenuAction; import com.evolveum.midpoint.web.page.admin.resources.ResourceContentTabPanel.Operation; import com.evolveum.midpoint.web.page.admin.resources.content.PageAccount; import com.evolveum.midpoint.web.page.admin.server.PageTaskAdd; @@ -446,7 +442,7 @@ private void newTaskPerformed(String category, AjaxRequestTarget target) { } PrismObject resource = getResourceModel().getObject(); - taskType.setObjectRef(ObjectTypeUtil.createObjectRef(resource)); + taskType.setObjectRef(ObjectTypeUtil.createObjectRef(resource, getPageBase().getPrismContext())); taskType.setCategory(category); setResponsePage(new PageTaskAdd(taskType)); @@ -1147,7 +1143,7 @@ private void changeOwner(ShadowType selected, AjaxRequestTarget target, FocusTyp if (owner != null) { delta = ReferenceDelta.createModificationDelete(FocusType.F_LINK_REF, getFocusDefinition(), - ObjectTypeUtil.createObjectRef(shadow).asReferenceValue()); + ObjectTypeUtil.createObjectRef(shadow, getPageBase().getPrismContext()).asReferenceValue()); ((Collection) modifications).add(delta); changeOwnerInternal(owner.getOid(), modifications, target); @@ -1163,7 +1159,7 @@ private void changeOwner(ShadowType selected, AjaxRequestTarget target, FocusTyp FocusType owner = loadShadowOwner(shadow.getOid()); if (owner != null) { delta = ReferenceDelta.createModificationDelete(FocusType.F_LINK_REF, - getFocusDefinition(), ObjectTypeUtil.createObjectRef(shadow).asReferenceValue()); + getFocusDefinition(), ObjectTypeUtil.createObjectRef(shadow, getPageBase().getPrismContext()).asReferenceValue()); ((Collection) modifications).add(delta); changeOwnerInternal(owner.getOid(), modifications, target); @@ -1171,7 +1167,7 @@ private void changeOwner(ShadowType selected, AjaxRequestTarget target, FocusTyp modifications = new ArrayList<>(); delta = ReferenceDelta.createModificationAdd(FocusType.F_LINK_REF, getFocusDefinition(), - ObjectTypeUtil.createObjectRef(shadow).asReferenceValue()); + ObjectTypeUtil.createObjectRef(shadow, getPageBase().getPrismContext()).asReferenceValue()); ((Collection) modifications).add(delta); changeOwnerInternal(ownerToChange.getOid(), modifications, target); diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/roles/AbstractRoleMemberPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/roles/AbstractRoleMemberPanel.java index 731bb04c5a2..77bfa582b05 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/roles/AbstractRoleMemberPanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/roles/AbstractRoleMemberPanel.java @@ -38,7 +38,6 @@ import org.apache.wicket.extensions.markup.html.repeater.data.table.export.AbstractExportableColumn; import org.apache.wicket.markup.html.WebMarkupContainer; import org.apache.wicket.markup.html.basic.Label; -import org.apache.wicket.markup.html.form.DropDownChoice; import org.apache.wicket.markup.html.form.Form; import org.apache.wicket.markup.html.form.IChoiceRenderer; import org.apache.wicket.markup.repeater.Item; @@ -52,13 +51,11 @@ import com.evolveum.midpoint.gui.api.util.WebComponentUtil; import com.evolveum.midpoint.prism.PrismConstants; import com.evolveum.midpoint.prism.PrismContext; -import com.evolveum.midpoint.prism.PrismReferenceValue; import com.evolveum.midpoint.prism.query.AndFilter; import com.evolveum.midpoint.prism.query.NotFilter; import com.evolveum.midpoint.prism.query.ObjectFilter; import com.evolveum.midpoint.prism.query.ObjectQuery; import com.evolveum.midpoint.prism.query.builder.QueryBuilder; -import com.evolveum.midpoint.prism.query.builder.S_FilterEntryOrEmpty; import com.evolveum.midpoint.schema.GetOperationOptions; import com.evolveum.midpoint.schema.SelectorOptions; import com.evolveum.midpoint.schema.constants.ObjectTypes; @@ -666,7 +663,7 @@ protected ObjectQuery createAllMemberQuery(Collection relations) { protected ObjectReferenceType createReference() { - ObjectReferenceType ref = ObjectTypeUtil.createObjectRef(getModelObject()); + ObjectReferenceType ref = ObjectTypeUtil.createObjectRef(getModelObject(), getPageBase().getPrismContext()); return ref; } diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/roles/MemberOperationsHelper.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/roles/MemberOperationsHelper.java index d4c0841bc92..6e3c09fb37a 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/roles/MemberOperationsHelper.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/roles/MemberOperationsHelper.java @@ -158,15 +158,18 @@ public static void initObject public static ObjectQuery createDirectMemberQuery(R targetObject, QName objectType, Collection relations, ObjectViewDto tenant, ObjectViewDto project, PrismContext prismContext) { ObjectQuery query; + // We assume tenantRef.relation and orgRef.relation are always default ones (see also MID-3581) S_AtomicFilterExit q = QueryBuilder.queryFor(FocusType.class, prismContext) .item(FocusType.F_ASSIGNMENT, AssignmentType.F_TARGET_REF) .ref(createReferenceValuesList(targetObject, relations)); if (tenant != null && tenant.getObjectType() != null) { - q = q.and().item(FocusType.F_ASSIGNMENT, AssignmentType.F_TENANT_REF).ref(ObjectTypeUtil.createObjectRef(tenant.getObjectType()).asReferenceValue()); + q = q.and().item(FocusType.F_ASSIGNMENT, AssignmentType.F_TENANT_REF).ref(ObjectTypeUtil.createObjectRef(tenant.getObjectType(), + prismContext).asReferenceValue()); } - if (project != null && project.getObjectType() !=null) { - q = q.and().item(FocusType.F_ASSIGNMENT, AssignmentType.F_ORG_REF).ref(ObjectTypeUtil.createObjectRef(project.getObjectType()).asReferenceValue()); + if (project != null && project.getObjectType() != null) { + q = q.and().item(FocusType.F_ASSIGNMENT, AssignmentType.F_ORG_REF).ref(ObjectTypeUtil.createObjectRef(project.getObjectType(), + prismContext).asReferenceValue()); } query = q.build(); @@ -183,9 +186,8 @@ public static ObjectQuery createDirectMemberQuery(R public static List createReferenceValuesList(R targetObject, Collection relations) { List referenceValuesList = new ArrayList<>(); - relations.stream().forEach(relation -> referenceValuesList.add(createReference(targetObject, relation).asReferenceValue())); + relations.forEach(relation -> referenceValuesList.add(createReference(targetObject, relation).asReferenceValue())); return referenceValuesList; - } public static ObjectQuery createSelectedObjectsQuery(List selectedObjects) { @@ -311,7 +313,8 @@ protected static ObjectDelta getDeleteAssignmentDel protected static ObjectDelta getAddParentOrgDelta(R targetObject, Collection relations, PrismContext prismContext) throws SchemaException { ObjectDelta delta = ObjectDelta.createEmptyModifyDelta(ObjectType.class, "fakeOid", prismContext); if (relations == null || relations.isEmpty()) { - delta.addModificationAddReference(ObjectType.F_PARENT_ORG_REF, ObjectTypeUtil.createObjectRef(targetObject).asReferenceValue()); + delta.addModificationAddReference(ObjectType.F_PARENT_ORG_REF, ObjectTypeUtil.createObjectRef(targetObject, + prismContext).asReferenceValue()); return delta; } @@ -324,7 +327,7 @@ protected static ObjectDelta getAddParentOrgDelta(R protected static ObjectDelta getDeleteParentOrgDelta(R targetObject, Collection relations, PrismContext prismContext) throws SchemaException { if (relations == null || relations.isEmpty()) { return ObjectDelta.createModificationDeleteReference(ObjectType.class, "fakeOid", - ObjectType.F_PARENT_ORG_REF, prismContext, ObjectTypeUtil.createObjectRef(targetObject).asReferenceValue()); + ObjectType.F_PARENT_ORG_REF, prismContext, ObjectTypeUtil.createObjectRef(targetObject, prismContext).asReferenceValue()); } ObjectDelta delta = ObjectDelta.createEmptyModifyDelta(ObjectType.class, "fakeOid", prismContext); diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/PageTaskController.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/PageTaskController.java index 573128e6f5a..a3460a73f73 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/PageTaskController.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/PageTaskController.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010-2017 Evolveum + * Copyright (c) 2010-2018 Evolveum * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -78,7 +78,7 @@ public void deleteSyncTokenPerformed(AjaxRequestTarget target) { if (property == null) { result.recordWarning("Token is not present in this task."); // should be treated by isVisible } else { - final ObjectDelta delta = (ObjectDelta) + final ObjectDelta delta = DeltaBuilder.deltaFor(TaskType.class, parentPage.getPrismContext()) .item(new ItemPath(TaskType.F_EXTENSION, SchemaConstants.SYNC_TOKEN), property.getDefinition()).replace() .asObjectDelta(parentPage.getTaskDto().getOid()); diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/TaskBasicTabPanel.html b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/TaskBasicTabPanel.html index 197c13f92fd..c089569fdd4 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/TaskBasicTabPanel.html +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/TaskBasicTabPanel.html @@ -23,44 +23,46 @@
- - - - - - - - - - -
+
+ + + + + + + + + + +
+
diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/handlers/ResourceRelatedHandlerPanel.html b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/handlers/ResourceRelatedHandlerPanel.html index 4d2c916c9a6..c73e721f6e1 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/handlers/ResourceRelatedHandlerPanel.html +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/handlers/ResourceRelatedHandlerPanel.html @@ -21,34 +21,36 @@
- - - - - - - - - - - - - - - - - - - - - - -
- -
+
+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/handlers/ScannerHandlerPanel.html b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/handlers/ScannerHandlerPanel.html index 7cfc4ebf242..0c820175ceb 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/handlers/ScannerHandlerPanel.html +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/handlers/ScannerHandlerPanel.html @@ -21,12 +21,14 @@
- - - - - -
+
+ + + + + +
+
diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/handlers/ScriptExecutionHandlerPanel.html b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/handlers/ScriptExecutionHandlerPanel.html index c2c6a7b0f35..bd93bcd2ef7 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/handlers/ScriptExecutionHandlerPanel.html +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/server/handlers/ScriptExecutionHandlerPanel.html @@ -21,12 +21,14 @@
- - - - - -
+
+ + + + + +
+
diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/users/PageUser.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/users/PageUser.java index a90ee7c82b7..381100f8888 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/users/PageUser.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/users/PageUser.java @@ -52,7 +52,6 @@ import com.evolveum.midpoint.web.component.objectdetails.FocusMainPanel; import com.evolveum.midpoint.web.component.objectdetails.FocusPersonasTabPanel; import com.evolveum.midpoint.web.component.objectdetails.UserDelegationsTabPanel; -import com.evolveum.midpoint.web.component.prism.ContainerStatus; import com.evolveum.midpoint.web.page.admin.PageAdminFocus; import com.evolveum.midpoint.web.page.admin.PageAdminObjectDetails; import com.evolveum.midpoint.web.page.admin.users.component.AssignmentInfoDto; @@ -61,6 +60,7 @@ import com.evolveum.midpoint.web.util.OnePageParameterEncoder; import com.evolveum.midpoint.xml.ns._public.common.common_3.AssignmentType; import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.RelationKindType; import com.evolveum.midpoint.xml.ns._public.common.common_3.UserType; import org.apache.commons.lang3.StringUtils; import org.apache.wicket.ajax.AjaxRequestTarget; @@ -329,7 +329,7 @@ private List loadDelegatedByMeAssignments() { PrismReferenceValue referenceValue = new PrismReferenceValue(getObjectWrapper().getOid(), UserType.COMPLEX_TYPE); - referenceValue.setRelation(SchemaConstants.ORG_DEPUTY); + referenceValue.setRelation(WebComponentUtil.getDefaultRelationOrFail(RelationKindType.DELEGATION)); ObjectFilter refFilter = QueryBuilder.queryFor(UserType.class, getPrismContext()) .item(UserType.F_ASSIGNMENT, AssignmentType.F_TARGET_REF).ref(referenceValue) diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/users/component/AssignmentInfoDto.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/users/component/AssignmentInfoDto.java index 2c5ba533a04..762b9b87b8d 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/users/component/AssignmentInfoDto.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/users/component/AssignmentInfoDto.java @@ -17,7 +17,7 @@ package com.evolveum.midpoint.web.page.admin.users.component; import com.evolveum.midpoint.gui.api.page.PageBase; -import com.evolveum.midpoint.schema.util.ObjectTypeUtil; +import com.evolveum.midpoint.gui.api.util.WebComponentUtil; import com.evolveum.midpoint.web.component.util.Selectable; import com.evolveum.midpoint.xml.ns._public.common.common_3.*; import org.apache.wicket.Component; @@ -258,7 +258,12 @@ private int getClassOrder(Class targetClass) { } public IModel getRelationDisplayNameModel(Component component) { - String localizationKey = ObjectTypeUtil.getRelationNameLocalizationKey(relation, true); + String localizationKey; + if (WebComponentUtil.isDefaultRelation(relation)) { + localizationKey = null; + } else { + localizationKey = WebComponentUtil.getRelationHeaderLabelKey(relation); + } return localizationKey != null ? PageBase.createStringResourceStatic(component, localizationKey) : Model.of(""); } } diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/users/component/TreeTablePanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/users/component/TreeTablePanel.java index 7562dcea0ad..a7cbdf4cda3 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/users/component/TreeTablePanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/users/component/TreeTablePanel.java @@ -25,7 +25,6 @@ import com.evolveum.midpoint.prism.PrismContext; import com.evolveum.midpoint.prism.PrismObject; import com.evolveum.midpoint.prism.PrismObjectDefinition; -import com.evolveum.midpoint.prism.PrismReferenceValue; import com.evolveum.midpoint.prism.delta.ContainerDelta; import com.evolveum.midpoint.prism.delta.ObjectDelta; import com.evolveum.midpoint.prism.query.ObjectQuery; @@ -33,7 +32,6 @@ import com.evolveum.midpoint.schema.GetOperationOptions; import com.evolveum.midpoint.schema.RetrieveOption; import com.evolveum.midpoint.schema.SelectorOptions; -import com.evolveum.midpoint.schema.constants.SchemaConstants; import com.evolveum.midpoint.schema.result.OperationResult; import com.evolveum.midpoint.schema.util.ObjectTypeUtil; import com.evolveum.midpoint.task.api.Task; @@ -41,7 +39,6 @@ import com.evolveum.midpoint.util.logging.LoggingUtils; import com.evolveum.midpoint.util.logging.Trace; import com.evolveum.midpoint.util.logging.TraceManager; -import com.evolveum.midpoint.web.component.AjaxButton; import com.evolveum.midpoint.web.component.FocusSummaryPanel; import com.evolveum.midpoint.web.component.data.column.ColumnMenuAction; import com.evolveum.midpoint.web.component.dialog.ConfirmationPanel; @@ -51,8 +48,6 @@ import com.evolveum.midpoint.web.component.util.ObjectWrapperUtil; import com.evolveum.midpoint.web.component.menu.cog.InlineMenuItemAction; import com.evolveum.midpoint.web.component.util.SelectableBean; -import com.evolveum.midpoint.web.component.util.VisibleEnableBehaviour; -import com.evolveum.midpoint.web.page.admin.configuration.component.HeaderMenuAction; import com.evolveum.midpoint.web.page.admin.orgs.OrgTreeAssignablePanel; import com.evolveum.midpoint.web.page.admin.orgs.OrgTreePanel; import com.evolveum.midpoint.web.page.admin.users.PageOrgTree; @@ -63,8 +58,6 @@ import com.evolveum.midpoint.xml.ns._public.common.common_3.*; import org.apache.wicket.RestartResponseException; import org.apache.wicket.ajax.AjaxRequestTarget; -import org.apache.wicket.markup.html.form.Form; -import org.apache.wicket.ajax.markup.html.AjaxLink; import org.apache.wicket.markup.html.WebMarkupContainer; import org.apache.wicket.markup.repeater.RepeatingView; import org.apache.wicket.model.AbstractReadOnlyModel; @@ -201,9 +194,8 @@ private WebMarkupContainer createManagerPanel(OrgType org) { } private ObjectQuery createManagerQuery(OrgType org) { - ObjectQuery query = QueryBuilder.queryFor(FocusType.class, getPageBase().getPrismContext()) - .item(FocusType.F_PARENT_ORG_REF).ref(ObjectTypeUtil.createObjectRef(org, SchemaConstants.ORG_MANAGER).asReferenceValue()) - .build(); + ObjectQuery query = ObjectTypeUtil.createManagerQuery(FocusType.class, org.getOid(), + parentPage.getRelationRegistry(), parentPage.getPrismContext()); if (LOGGER.isTraceEnabled()) { LOGGER.trace("Searching members of org {} with query:\n{}", org.getOid(), query.debugDump()); } @@ -366,7 +358,7 @@ public InlineMenuItemAction initAction() { public void onClick(AjaxRequestTarget target) { try { initObjectForAdd( - ObjectTypeUtil.createObjectRef(getRowModel().getObject().getValue()), + ObjectTypeUtil.createObjectRef(getRowModel().getObject().getValue(), getPageBase().getPrismContext()), OrgType.COMPLEX_TYPE, null, target); } catch (SchemaException e) { throw new SystemException(e.getMessage(), e); @@ -404,7 +396,7 @@ private void initObjectForAdd(ObjectReferenceType parentOrgRef, QName type, QNam // TODO: fix MID-3234 if (parentOrgRef == null) { ObjectType org = getTreePanel().getSelected().getValue(); - parentOrgRef = ObjectTypeUtil.createObjectRef(org); + parentOrgRef = ObjectTypeUtil.createObjectRef(org, prismContext); parentOrgRef.setRelation(relation); objType.getParentOrgRef().add(parentOrgRef); } else { @@ -462,7 +454,7 @@ private void moveConfirmPerformed(SelectableBean orgToMove, SelectableB try { for (OrgType parentOrg : toMove.getParentOrg()) { AssignmentType oldRoot = new AssignmentType(); - oldRoot.setTargetRef(ObjectTypeUtil.createObjectRef(parentOrg)); + oldRoot.setTargetRef(ObjectTypeUtil.createObjectRef(parentOrg, getPageBase().getPrismContext())); moveOrgDelta.addModification(ContainerDelta.createModificationDelete(OrgType.F_ASSIGNMENT, OrgType.class, getPageBase().getPrismContext(), oldRoot.asPrismContainerValue())); @@ -472,7 +464,7 @@ private void moveConfirmPerformed(SelectableBean orgToMove, SelectableB } AssignmentType newRoot = new AssignmentType(); - newRoot.setTargetRef(ObjectTypeUtil.createObjectRef(selected.getValue())); + newRoot.setTargetRef(ObjectTypeUtil.createObjectRef(selected.getValue(), getPageBase().getPrismContext())); moveOrgDelta.addModification(ContainerDelta.createModificationAdd(OrgType.F_ASSIGNMENT, OrgType.class, getPageBase().getPrismContext(), newRoot.asPrismContainerValue())); // moveOrgDelta.addModification(ReferenceDelta.createModificationAdd(OrgType.F_PARENT_ORG_REF, diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/users/component/UserSummaryPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/users/component/UserSummaryPanel.java index 4b39338827b..d36b0c29ec2 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/users/component/UserSummaryPanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/users/component/UserSummaryPanel.java @@ -19,14 +19,12 @@ import javax.xml.namespace.QName; -import com.evolveum.midpoint.schema.util.ObjectTypeUtil; -import com.evolveum.midpoint.util.QNameUtil; +import com.evolveum.midpoint.gui.api.util.WebComponentUtil; import org.apache.wicket.model.IModel; import com.evolveum.midpoint.gui.api.GuiStyleConstants; import com.evolveum.midpoint.gui.api.util.ModelServiceLocator; -import com.evolveum.midpoint.schema.constants.SchemaConstants; import com.evolveum.midpoint.web.component.FocusSummaryPanel; import com.evolveum.midpoint.web.component.prism.ObjectWrapper; import com.evolveum.midpoint.web.component.util.SummaryTag; @@ -67,7 +65,7 @@ protected void initialize(ObjectWrapper wrapper) { continue; } QName relation = assignment.getTargetRef().getRelation(); - if (relation != null && !QNameUtil.match(SchemaConstants.ORG_DEFAULT, relation)) { + if (!WebComponentUtil.isDefaultRelation(relation)) { continue; } if (SystemObjectsType.ROLE_SUPERUSER.value().equals(assignment.getTargetRef().getOid())) { @@ -106,7 +104,7 @@ protected void initialize(ObjectWrapper wrapper) { boolean isManager = false; boolean isMember = false; for (ObjectReferenceType parentOrgRef: wrapper.getObject().asObjectable().getParentOrgRef()) { - if (ObjectTypeUtil.isManagerRelation(parentOrgRef.getRelation())) { + if (WebComponentUtil.isManagerRelation(parentOrgRef.getRelation())) { isManager = true; } else { isMember = true; diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/workflow/PageWorkItem.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/workflow/PageWorkItem.java index 63817b0173b..286693a4e78 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/workflow/PageWorkItem.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/workflow/PageWorkItem.java @@ -348,7 +348,7 @@ private void delegateConfirmedPerformed(AjaxRequestTarget target, UserType deleg OperationResult result = new OperationResult(OPERATION_DELEGATE_WORK_ITEM); try { WorkItemDto dto = workItemDtoModel.getObject(); - List delegates = Collections.singletonList(ObjectTypeUtil.createObjectRef(delegate)); + List delegates = Collections.singletonList(ObjectTypeUtil.createObjectRef(delegate, getPrismContext())); try { assumePowerOfAttorneyIfRequested(result); getWorkflowService().delegateWorkItem(dto.getWorkItemId(), delegates, WorkItemDelegationMethodType.ADD_ASSIGNEES, result); diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/workflow/dto/WorkItemDtoProvider.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/workflow/dto/WorkItemDtoProvider.java index 9f69418e05e..ae798ca4427 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/workflow/dto/WorkItemDtoProvider.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/workflow/dto/WorkItemDtoProvider.java @@ -181,11 +181,11 @@ private ObjectQuery createQuery(OperationResult result) throws SchemaException { if (WorkItemsPageType.ALL.equals(workItemsPageType) && authorizedToSeeAll) { return q.build(); } else if (WorkItemsPageType.CLAIMABLE.equals(workItemsPageType)) { - return QueryUtils.filterForGroups(q, currentUserOid(), getRepositoryService(), result).build(); + return QueryUtils.filterForGroups(q, currentUserOid(), getRepositoryService(), getRelationRegistry(), result).build(); } else { // not authorized to see all => sees only allocated to him (not quite what is expected, but sufficient for the time being) return QueryUtils.filterForAssignees(q, SecurityUtils.getPrincipalUser(), - OtherPrivilegesLimitationType.F_APPROVAL_WORK_ITEMS).build(); + OtherPrivilegesLimitationType.F_APPROVAL_WORK_ITEMS, getRelationRegistry()).build(); } } diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/self/AbstractShoppingCartTabPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/self/AbstractShoppingCartTabPanel.java index 4bb19d39718..365e2e984e2 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/self/AbstractShoppingCartTabPanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/self/AbstractShoppingCartTabPanel.java @@ -337,8 +337,8 @@ private UserType getTargetUser(){ protected void assignmentAddedToShoppingCartPerformed(AjaxRequestTarget target){ } - protected QName getNewAssignmentRelation(){ - return SchemaConstants.ORG_DEFAULT; + protected QName getNewAssignmentRelation() { + return WebComponentUtil.getDefaultRelationOrFail(); } protected RoleCatalogStorage getRoleCatalogStorage(){ diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/self/PageSelfDashboard.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/self/PageSelfDashboard.java index 569c48ea2d8..e4e3451a81f 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/self/PageSelfDashboard.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/self/PageSelfDashboard.java @@ -288,7 +288,7 @@ private CallableResult> loadWorkItems() { // (Note that the current code is consistent with the other places where work items are displayed.) S_FilterEntryOrEmpty q = QueryBuilder.queryFor(WorkItemType.class, getPrismContext()); ObjectQuery query = QueryUtils.filterForAssignees(q, SecurityUtils.getPrincipalUser(), - OtherPrivilegesLimitationType.F_APPROVAL_WORK_ITEMS) + OtherPrivilegesLimitationType.F_APPROVAL_WORK_ITEMS, getRelationRegistry()) .desc(F_CREATE_TIMESTAMP) .build(); Collection> options = diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/self/UserViewTabPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/self/UserViewTabPanel.java index 97f7f9177d9..600fe36e733 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/self/UserViewTabPanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/self/UserViewTabPanel.java @@ -160,8 +160,7 @@ public IModel getBody() { if (relation == null){ return createStringResource("RelationTypes.ANY"); } - List defList = WebComponentUtil.getRelationDefinitions(UserViewTabPanel.this.getPageBase()); - RelationDefinitionType def = ObjectTypeUtil.findRelationDefinition(defList, model.getObject()); + RelationDefinitionType def = WebComponentUtil.getRelationDefinition(model.getObject()); if (def != null) { DisplayType display = def.getDisplay(); if (display != null) { diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/security/MidPointApplication.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/security/MidPointApplication.java index e3c41603025..63e1a3f1ed0 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/security/MidPointApplication.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/security/MidPointApplication.java @@ -30,6 +30,7 @@ import com.evolveum.midpoint.prism.match.MatchingRuleRegistry; import com.evolveum.midpoint.repo.api.RepositoryService; import com.evolveum.midpoint.repo.common.expression.ExpressionFactory; +import com.evolveum.midpoint.schema.RelationRegistry; import com.evolveum.midpoint.schema.result.OperationResult; import com.evolveum.midpoint.schema.util.SchemaDebugUtil; import com.evolveum.midpoint.security.api.AuthorizationConstants; @@ -158,6 +159,8 @@ public class MidPointApplication extends AuthenticatedWebApplication { @Autowired transient ModelInteractionService modelInteractionService; @Autowired + transient RelationRegistry relationRegistry; + @Autowired transient TaskService taskService; @Autowired transient PrismContext prismContext; @@ -193,6 +196,12 @@ public class MidPointApplication extends AuthenticatedWebApplication { transient ApplicationContext applicationContext; private WebApplicationConfiguration webApplicationConfiguration; + + public static final String MOUNT_INTERNAL_SERVER_ERROR = "/error"; + public static final String MOUNT_UNAUTHORIZED_ERROR = "/error/401"; + public static final String MOUNT_FORBIDEN_ERROR = "/error/403"; + public static final String MOUNT_NOT_FOUND_ERROR = "/error/404"; + public static final String MOUNT_GONE_ERROR = "/error/410"; @Override public Class getHomePage() { @@ -249,11 +258,11 @@ public void init() { appSettings.setInternalErrorPage(PageError.class); appSettings.setPageExpiredErrorPage(PageError.class); - mount(new MountedMapper("/error", PageError.class, new PageParametersEncoder())); - mount(new MountedMapper("/error/401", PageError401.class, new PageParametersEncoder())); - mount(new MountedMapper("/error/403", PageError403.class, new PageParametersEncoder())); - mount(new MountedMapper("/error/404", PageError404.class, new PageParametersEncoder())); - mount(new MountedMapper("/error/410", PageError410.class, new PageParametersEncoder())); + mount(new MountedMapper(MOUNT_INTERNAL_SERVER_ERROR, PageError.class, new PageParametersEncoder())); + mount(new MountedMapper(MOUNT_UNAUTHORIZED_ERROR, PageError401.class, new PageParametersEncoder())); + mount(new MountedMapper(MOUNT_FORBIDEN_ERROR, PageError403.class, new PageParametersEncoder())); + mount(new MountedMapper(MOUNT_NOT_FOUND_ERROR, PageError404.class, new PageParametersEncoder())); + mount(new MountedMapper(MOUNT_GONE_ERROR, PageError410.class, new PageParametersEncoder())); getRequestCycleListeners().add(new LoggingRequestCycleListener(this)); @@ -491,6 +500,10 @@ public ModelInteractionService getModelInteractionService() { return modelInteractionService; } + public RelationRegistry getRelationRegistry() { + return relationRegistry; + } + public static boolean containsLocale(Locale locale) { if (locale == null) { return false; diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/util/MidPointProfilingServletFilter.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/util/MidPointProfilingServletFilter.java index c81e994e350..66e4653a720 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/util/MidPointProfilingServletFilter.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/util/MidPointProfilingServletFilter.java @@ -20,6 +20,7 @@ import com.evolveum.midpoint.util.aspect.ProfilingDataManager; import com.evolveum.midpoint.util.logging.Trace; import com.evolveum.midpoint.util.logging.TraceManager; +import org.apache.catalina.connector.ClientAbortException; import javax.servlet.*; import javax.servlet.http.HttpServletRequest; @@ -68,7 +69,7 @@ public void doFilter(ServletRequest request, ServletResponse response, FilterCha try { chain.doFilter(request, response); } catch (IOException | ServletException | RuntimeException | Error e) { - LOGGER.debug("Encountered exception: {}: {}", e.getClass().getName(), e.getMessage(), e); + logException(e); throw e; } @@ -85,7 +86,7 @@ public void doFilter(ServletRequest request, ServletResponse response, FilterCha try { chain.doFilter(request, response); } catch (IOException | ServletException | RuntimeException | Error e) { - LOGGER.debug("Encountered exception: {}: {}", e.getClass().getName(), e.getMessage(), e); + logException(e); throw e; } } @@ -99,5 +100,15 @@ private void prepareRequestProfilingEvent(ServletRequest request, long elapsed, ProfilingDataManager.getInstance().prepareRequestProfilingEvent(event); } + private void logException(Throwable t) throws IOException, ServletException { + if (t instanceof ClientAbortException) { + if (LOGGER.isDebugEnabled()) { + // client abort exceptions are quite OK as they are not an application/server problem + LOGGER.debug("Encountered exception: {}: {}", t.getClass().getName(), t.getMessage(), t); + } + return; + } + LOGGER.error("Encountered exception: {}: {}", t.getClass().getName(), t.getMessage(), t); + } } diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/util/ObjectTypeGuiDescriptor.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/util/ObjectTypeGuiDescriptor.java index ea62e9c3649..bd23765693a 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/util/ObjectTypeGuiDescriptor.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/util/ObjectTypeGuiDescriptor.java @@ -18,9 +18,6 @@ import com.evolveum.midpoint.gui.api.GuiStyleConstants; import com.evolveum.midpoint.schema.constants.ObjectTypes; -import com.evolveum.midpoint.schema.constants.SchemaConstants; - -import javax.xml.namespace.QName; /** * @author lazyman @@ -67,8 +64,6 @@ public enum ObjectTypeGuiDescriptor { SECURITY_POLICY(ObjectTypes.SECURITY_POLICY, "ObjectTypeGuiDescriptor.securityPolicy", "", ""), - USER_ORG_MANAGER(SchemaConstants.ORG_MANAGER, "ObjectTypeGuiDescriptor.orgManager", "silk-user_red", "silk-user_red"), - LOOKUP_TABLE(ObjectTypes.LOOKUP_TABLE, "ObjectTypeGuiDescriptor.lookupTable", "", ""), ACCESS_CERTIFICATION_DEFINITION(ObjectTypes.ACCESS_CERTIFICATION_DEFINITION, "ObjectTypeGuiDescriptor.accessCertificationDefinition", "", ""), @@ -89,7 +84,6 @@ public enum ObjectTypeGuiDescriptor { public static final String ERROR_LOCALIZATION_KEY = "ObjectTypeGuiDescriptor.unknown"; private ObjectTypes type; - private QName relation; private String localizationKey; private String coloredIcon; private String blackIcon; @@ -101,13 +95,6 @@ public enum ObjectTypeGuiDescriptor { this.type = type; } - ObjectTypeGuiDescriptor(QName relation, String localizationKey, String coloredIcon, String blackIcon) { - this.coloredIcon = coloredIcon; - this.blackIcon = blackIcon; - this.localizationKey = localizationKey; - this.relation = relation; - } - @SuppressWarnings("unused") public String getColoredIcon() { return coloredIcon; @@ -125,10 +112,6 @@ public ObjectTypes getType() { return type; } - public QName getRelation() { - return relation; - } - public static ObjectTypeGuiDescriptor getDescriptor(Class type) { for (ObjectTypeGuiDescriptor descr : ObjectTypeGuiDescriptor.values()) { if (descr.getType() != null && descr.getType().getClassDefinition().equals(type)) { @@ -151,14 +134,4 @@ public static ObjectTypeGuiDescriptor getDescriptor(ObjectTypes type) { return null; } - - public static ObjectTypeGuiDescriptor getDescriptor(QName relation) { - for (ObjectTypeGuiDescriptor descr : ObjectTypeGuiDescriptor.values()) { - if (descr.getRelation() != null && descr.getRelation().equals(relation)) { - return descr; - } - } - - return null; - } } diff --git a/gui/admin-gui/src/test/java/com/evolveum/midpoint/web/AbstractGuiIntegrationTest.java b/gui/admin-gui/src/test/java/com/evolveum/midpoint/web/AbstractGuiIntegrationTest.java index 4aa78b926a6..aa655f8d302 100644 --- a/gui/admin-gui/src/test/java/com/evolveum/midpoint/web/AbstractGuiIntegrationTest.java +++ b/gui/admin-gui/src/test/java/com/evolveum/midpoint/web/AbstractGuiIntegrationTest.java @@ -22,7 +22,7 @@ import com.evolveum.midpoint.common.LocalizationService; import com.evolveum.midpoint.gui.api.util.ModelServiceLocator; -import com.evolveum.midpoint.gui.api.util.WebModelServiceUtils; +import com.evolveum.midpoint.gui.api.util.WebComponentUtil; import com.evolveum.midpoint.model.api.ModelInteractionService; import com.evolveum.midpoint.model.api.ModelService; import com.evolveum.midpoint.model.test.AbstractModelIntegrationTest; @@ -31,9 +31,9 @@ import com.evolveum.midpoint.prism.path.ItemPath; import com.evolveum.midpoint.prism.util.PrismAsserts; import com.evolveum.midpoint.repo.common.expression.ExpressionFactory; +import com.evolveum.midpoint.schema.RelationRegistry; import com.evolveum.midpoint.schema.constants.SchemaConstants; import com.evolveum.midpoint.schema.result.OperationResult; -import com.evolveum.midpoint.security.api.MidPointPrincipal; import com.evolveum.midpoint.security.api.SecurityContextManager; import com.evolveum.midpoint.security.enforcer.api.SecurityEnforcer; import com.evolveum.midpoint.task.api.Task; @@ -44,7 +44,6 @@ import com.evolveum.midpoint.util.logging.TraceManager; import com.evolveum.midpoint.web.application.DescriptorLoader; import com.evolveum.midpoint.web.security.MidPointApplication; -import com.evolveum.midpoint.web.security.SecurityUtils; import com.evolveum.midpoint.xml.ns._public.common.common_3.AdminGuiConfigurationType; import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectType; import com.evolveum.midpoint.xml.ns._public.common.common_3.UserType; @@ -113,10 +112,12 @@ public abstract class AbstractGuiIntegrationTest extends AbstractModelIntegratio @Autowired private ApplicationContext appContext; @Autowired protected PrismContext prismContext; @Autowired protected ExpressionFactory expressionFactory; + @Autowired protected RelationRegistry relationRegistry; @Override public void initSystem(Task initTask, OperationResult initResult) throws Exception { super.initSystem(initTask, initResult); + WebComponentUtil.setStaticallyProvidedRelationRegistry(relationRegistry); } @PostConstruct diff --git a/icf-connectors/dummy-connector/src/main/java/com/evolveum/icf/dummy/connector/AbstractDummyConnector.java b/icf-connectors/dummy-connector/src/main/java/com/evolveum/icf/dummy/connector/AbstractDummyConnector.java index a5cc62910e4..47fee87865a 100644 --- a/icf-connectors/dummy-connector/src/main/java/com/evolveum/icf/dummy/connector/AbstractDummyConnector.java +++ b/icf-connectors/dummy-connector/src/main/java/com/evolveum/icf/dummy/connector/AbstractDummyConnector.java @@ -23,6 +23,7 @@ import org.identityconnectors.framework.common.exceptions.ConnectorException; import org.identityconnectors.framework.common.exceptions.ConnectorIOException; import org.identityconnectors.framework.common.exceptions.InvalidAttributeValueException; +import org.identityconnectors.framework.common.exceptions.InvalidPasswordException; import org.identityconnectors.framework.common.exceptions.UnknownUidException; import org.identityconnectors.framework.common.objects.*; @@ -390,7 +391,8 @@ public Schema schema() { throw new UnsupportedOperationException(); } - SchemaBuilder builder = new SchemaBuilder(AbstractDummyConnector.class); + SchemaBuilder builder = new SchemaBuilder(this.getClass()); + log.ok("Building schema for {0}", this.getClass()); try { @@ -418,11 +420,17 @@ public Schema schema() { builder.defineOperationOption(OperationOptionInfoBuilder.buildPageSize(), SearchOp.class); builder.defineOperationOption(OperationOptionInfoBuilder.buildSortKeys(), SearchOp.class); } + + extendSchema(builder); log.info("schema::end"); return builder.build(); } + protected void extendSchema(SchemaBuilder builder) { + // for subclasses + } + private String getAccountObjectClassName() { if (configuration.getUseLegacySchema()) { return ObjectClass.ACCOUNT_NAME; @@ -1598,6 +1606,32 @@ private boolean attributesToGetHasAttribute(Collection attributesToGet, } return attributesToGet.contains(attrName); } + + protected void applyModifyMetadata(DummyObject object, OperationOptions options) throws ConnectException, FileNotFoundException, SchemaViolationException, ConflictException { + String runAsUser = options.getRunAsUser(); + if (runAsUser != null) { + if (!configuration.getSupportRunAs()) { + throw new UnsupportedOperationException("runAsUser option is not supported"); + } + DummyAccount runAsAccount = resource.getAccountByUsername(runAsUser); + if (runAsAccount == null) { + new ConfigurationException("No runAsUser "+runAsUser); + } + GuardedString runWithPassword = options.getRunWithPassword(); + if (runWithPassword != null) { + runWithPassword.access((clearChars) -> { + if (!runAsAccount.getPassword().equals(new String(clearChars))) { + throw new InvalidPasswordException("Wrong runWithPassword"); + } + }); + } else { + throw new InvalidPasswordException("No runWithPassword"); + } + object.setLastModifier(runAsAccount.getName()); + } else { + object.setLastModifier(null); + } + } public void validate(ObjectClass oc) { if (oc == null) { diff --git a/icf-connectors/dummy-connector/src/main/java/com/evolveum/icf/dummy/connector/DummyConfiguration.java b/icf-connectors/dummy-connector/src/main/java/com/evolveum/icf/dummy/connector/DummyConfiguration.java index 0e6a3788027..c816942e080 100644 --- a/icf-connectors/dummy-connector/src/main/java/com/evolveum/icf/dummy/connector/DummyConfiguration.java +++ b/icf-connectors/dummy-connector/src/main/java/com/evolveum/icf/dummy/connector/DummyConfiguration.java @@ -45,6 +45,7 @@ public class DummyConfiguration extends AbstractConfiguration { private boolean supportSchema = true; private boolean supportActivation = true; private boolean supportValidity = false; + private boolean supportRunAs = true; private String uidMode = UID_MODE_NAME; private boolean enforceUniqueName = true; private String passwordReadabilityMode = PASSWORD_READABILITY_MODE_UNREADABLE; @@ -126,6 +127,16 @@ public boolean getSupportValidity() { public void setSupportValidity(boolean supportValidity) { this.supportValidity = supportValidity; } + + @ConfigurationProperty(displayMessageKey = "UI_SUPPORT_RUN_AS", + helpMessageKey = "UI_SUPPORT_RUN_AS_HELP") + public boolean getSupportRunAs() { + return supportRunAs; + } + + public void setSupportRunAs(boolean supportRunAs) { + this.supportRunAs = supportRunAs; + } @ConfigurationProperty(displayMessageKey = "UI_UID_MODE", helpMessageKey = "UI_UID_MODE_HELP") diff --git a/icf-connectors/dummy-connector/src/main/java/com/evolveum/icf/dummy/connector/DummyConnector.java b/icf-connectors/dummy-connector/src/main/java/com/evolveum/icf/dummy/connector/DummyConnector.java index 51c1fd8eaff..df5e37a839d 100644 --- a/icf-connectors/dummy-connector/src/main/java/com/evolveum/icf/dummy/connector/DummyConnector.java +++ b/icf-connectors/dummy-connector/src/main/java/com/evolveum/icf/dummy/connector/DummyConnector.java @@ -23,6 +23,7 @@ import org.identityconnectors.framework.common.exceptions.ConnectorException; import org.identityconnectors.framework.common.exceptions.ConnectorIOException; import org.identityconnectors.framework.common.exceptions.InvalidAttributeValueException; +import org.identityconnectors.framework.common.exceptions.InvalidPasswordException; import org.identityconnectors.framework.common.exceptions.UnknownUidException; import org.identityconnectors.framework.common.objects.*; @@ -125,6 +126,7 @@ public Set updateDelta(final ObjectClass objectClass, final Uid if (account == null) { throw new UnknownUidException("Account with UID "+uid+" does not exist on resource"); } + applyModifyMetadata(account, options); // we do this before setting attribute values, in case when description itself would be changed resource.changeDescriptionIfNeeded(account); @@ -174,6 +176,7 @@ public Set updateDelta(final ObjectClass objectClass, final Uid } } + } else if (ObjectClass.GROUP.is(objectClass.getObjectClassValue())) { @@ -188,6 +191,7 @@ public Set updateDelta(final ObjectClass objectClass, final Uid if (group == null) { throw new UnknownUidException("Group with UID "+uid+" does not exist on resource"); } + applyModifyMetadata(group, options); for (AttributeDelta delta : modifications) { if (delta.is(Name.NAME)) { @@ -219,6 +223,7 @@ public Set updateDelta(final ObjectClass objectClass, final Uid applyOrdinaryAttributeDelta(group, delta, valuesTransformer); } } + } else if (objectClass.is(OBJECTCLASS_PRIVILEGE_NAME)) { @@ -233,6 +238,7 @@ public Set updateDelta(final ObjectClass objectClass, final Uid if (priv == null) { throw new UnknownUidException("Privilege with UID "+uid+" does not exist on resource"); } + applyModifyMetadata(priv, options); for (AttributeDelta delta : modifications) { if (delta.is(Name.NAME)) { @@ -257,6 +263,7 @@ public Set updateDelta(final ObjectClass objectClass, final Uid applyOrdinaryAttributeDelta(priv, delta, null); } } + } else if (objectClass.is(OBJECTCLASS_ORG_NAME)) { @@ -271,6 +278,7 @@ public Set updateDelta(final ObjectClass objectClass, final Uid if (org == null) { throw new UnknownUidException("Org with UID "+uid+" does not exist on resource"); } + applyModifyMetadata(org, options); for (AttributeDelta delta : modifications) { if (delta.is(Name.NAME)) { @@ -295,7 +303,7 @@ public Set updateDelta(final ObjectClass objectClass, final Uid applyOrdinaryAttributeDelta(org, delta, null); } } - + } else { throw new ConnectorException("Unknown object class "+objectClass); @@ -321,7 +329,7 @@ public Set updateDelta(final ObjectClass objectClass, final Uid log.info("update::end {0}", instanceName); return sideEffectChanges; } - + private void applyAuxiliaryObjectClassDelta(DummyObject dummyObject, AttributeDelta delta) { List replaceValues = getReplaceValues(delta, String.class); if (replaceValues != null) { @@ -490,4 +498,15 @@ protected void addAdditionalCommonAttributes(ConnectorObjectBuilder builder, Dum } } + @Override + protected void extendSchema(SchemaBuilder builder) { + super.extendSchema(builder); + + if (configuration.getSupportRunAs()) { + log.ok("Adding runAs options to schema"); + builder.defineOperationOption(OperationOptionInfoBuilder.buildRunWithUser(), UpdateDeltaOp.class); + builder.defineOperationOption(OperationOptionInfoBuilder.buildRunWithPassword(), UpdateDeltaOp.class); + } + } + } diff --git a/icf-connectors/dummy-connector/src/main/java/com/evolveum/icf/dummy/connector/DummyConnectorLegacyUpdate.java b/icf-connectors/dummy-connector/src/main/java/com/evolveum/icf/dummy/connector/DummyConnectorLegacyUpdate.java index 046ccc3505c..f3d1c2eef8a 100644 --- a/icf-connectors/dummy-connector/src/main/java/com/evolveum/icf/dummy/connector/DummyConnectorLegacyUpdate.java +++ b/icf-connectors/dummy-connector/src/main/java/com/evolveum/icf/dummy/connector/DummyConnectorLegacyUpdate.java @@ -116,6 +116,7 @@ public Uid update(ObjectClass objectClass, Uid uid, Set replaceAttrib if (account == null) { throw new UnknownUidException("Account with UID "+uid+" does not exist on resource"); } + applyModifyMetadata(account, options); // we do this before setting attribute values, in case when description itself would be changed resource.changeDescriptionIfNeeded(account); @@ -179,6 +180,7 @@ public Uid update(ObjectClass objectClass, Uid uid, Set replaceAttrib if (group == null) { throw new UnknownUidException("Group with UID "+uid+" does not exist on resource"); } + applyModifyMetadata(group, options); for (Attribute attr : replaceAttributes) { if (attr.is(Name.NAME)) { @@ -229,6 +231,7 @@ public Uid update(ObjectClass objectClass, Uid uid, Set replaceAttrib if (priv == null) { throw new UnknownUidException("Privilege with UID "+uid+" does not exist on resource"); } + applyModifyMetadata(priv, options); for (Attribute attr : replaceAttributes) { if (attr.is(Name.NAME)) { @@ -271,6 +274,7 @@ public Uid update(ObjectClass objectClass, Uid uid, Set replaceAttrib if (org == null) { throw new UnknownUidException("Org with UID "+uid+" does not exist on resource"); } + applyModifyMetadata(org, options); for (Attribute attr : replaceAttributes) { if (attr.is(Name.NAME)) { @@ -346,6 +350,7 @@ public Uid addAttributeValues(ObjectClass objectClass, Uid uid, Set v if (account == null) { throw new UnknownUidException("Account with UID "+uid+" does not exist on resource"); } + applyModifyMetadata(account, options); // we could change the description here, but don't do that not to collide with ADD operation // TODO add the functionality if needed @@ -391,6 +396,7 @@ public Uid addAttributeValues(ObjectClass objectClass, Uid uid, Set v if (group == null) { throw new UnknownUidException("Group with UID "+uid+" does not exist on resource"); } + applyModifyMetadata(group, options); for (Attribute attr : valuesToAdd) { @@ -435,6 +441,7 @@ public Uid addAttributeValues(ObjectClass objectClass, Uid uid, Set v if (priv == null) { throw new UnknownUidException("Privilege with UID "+uid+" does not exist on resource"); } + applyModifyMetadata(priv, options); for (Attribute attr : valuesToAdd) { @@ -471,6 +478,7 @@ public Uid addAttributeValues(ObjectClass objectClass, Uid uid, Set v if (org == null) { throw new UnknownUidException("Org with UID "+uid+" does not exist on resource"); } + applyModifyMetadata(org, options); for (Attribute attr : valuesToAdd) { @@ -538,6 +546,7 @@ public Uid removeAttributeValues(ObjectClass objectClass, Uid uid, Set auxiliaryObjectClassNames = new HashSet<>(); @@ -117,6 +118,14 @@ public void setValidTo(Date validTo) throws ConnectException, FileNotFoundExcept recordModify(); } + public String getLastModifier() { + return lastModifier; + } + + public void setLastModifier(String lastModifier) { + this.lastModifier = lastModifier; + } + public BreakMode getModifyBreakMode() { return modifyBreakMode; } @@ -460,11 +469,6 @@ protected String toStringContent() { return "name=" + name + ", attributes=" + attributes + ", enabled=" + enabled; } - @Override - public String debugDump() { - return debugDump(0); - } - @Override public String debugDump(int indent) { StringBuilder sb = new StringBuilder(); @@ -483,6 +487,8 @@ public String debugDump(int indent) { sb.append(" ").append(PrettyPrinter.prettyPrint(validFrom)).append(" - ").append(PrettyPrinter.prettyPrint(validTo)); } sb.append("\n"); + DebugUtil.debugDumpWithLabel(sb, "lastModifier", lastModifier, indent + 1); + sb.append("\n"); DebugUtil.debugDumpWithLabel(sb, "Attributes", attributes, indent + 1); extendDebugDump(sb, indent); return sb.toString(); diff --git a/infra/common/src/main/java/com/evolveum/midpoint/common/ResourceObjectPattern.java b/infra/common/src/main/java/com/evolveum/midpoint/common/ResourceObjectPattern.java index 15e099c2841..0e783df9b27 100644 --- a/infra/common/src/main/java/com/evolveum/midpoint/common/ResourceObjectPattern.java +++ b/infra/common/src/main/java/com/evolveum/midpoint/common/ResourceObjectPattern.java @@ -28,6 +28,7 @@ import com.evolveum.midpoint.prism.match.MatchingRuleRegistry; import com.evolveum.midpoint.prism.query.ObjectFilter; import com.evolveum.midpoint.prism.query.ObjectQuery; +import com.evolveum.midpoint.schema.RelationRegistry; import com.evolveum.midpoint.schema.processor.ResourceAttribute; import com.evolveum.midpoint.schema.processor.ResourceAttributeContainer; import com.evolveum.midpoint.schema.util.ObjectTypeUtil; @@ -61,18 +62,19 @@ public void addIdentifier(ResourceAttribute identifier) { } public static boolean matches(PrismObject shadowToMatch, - Collection protectedAccountPatterns, MatchingRuleRegistry matchingRuleRegistry) throws SchemaException { + Collection protectedAccountPatterns, MatchingRuleRegistry matchingRuleRegistry, + RelationRegistry relationRegistry) throws SchemaException { for (ResourceObjectPattern pattern: protectedAccountPatterns) { - if (pattern.matches(shadowToMatch, matchingRuleRegistry)) { + if (pattern.matches(shadowToMatch, matchingRuleRegistry, relationRegistry)) { return true; } } return false; } - public boolean matches(PrismObject shadowToMatch, MatchingRuleRegistry matchingRuleRegistry) throws SchemaException { + public boolean matches(PrismObject shadowToMatch, MatchingRuleRegistry matchingRuleRegistry, RelationRegistry relationRegistry) throws SchemaException { if (objectFilter != null) { - ObjectTypeUtil.normalizeFilter(objectFilter); // we suppose references in shadowToMatch are normalized (on return from repo) + ObjectTypeUtil.normalizeFilter(objectFilter, relationRegistry); // we suppose references in shadowToMatch are normalized (on return from repo) return ObjectQuery.match(shadowToMatch, objectFilter, matchingRuleRegistry); } else { // Deprecated method diff --git a/infra/common/src/test/java/com/evolveum/midpoint/common/refinery/RelationRegistryDummyImpl.java b/infra/common/src/test/java/com/evolveum/midpoint/common/refinery/RelationRegistryDummyImpl.java new file mode 100644 index 00000000000..375fd18c739 --- /dev/null +++ b/infra/common/src/test/java/com/evolveum/midpoint/common/refinery/RelationRegistryDummyImpl.java @@ -0,0 +1,132 @@ +/* + * Copyright (c) 2010-2018 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. + */ + +package com.evolveum.midpoint.common.refinery; + +import com.evolveum.midpoint.schema.RelationRegistry; +import com.evolveum.midpoint.util.QNameUtil; +import com.evolveum.midpoint.xml.ns._public.common.common_3.RelationDefinitionType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.RelationKindType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.SystemConfigurationType; +import org.jetbrains.annotations.NotNull; + +import javax.xml.namespace.QName; +import java.util.Collection; +import java.util.List; + +import static com.evolveum.midpoint.schema.constants.SchemaConstants.ORG_DEFAULT; +import static java.util.Collections.emptyList; +import static java.util.Collections.singleton; +import static java.util.Collections.singletonList; + +/** + * Temporary workaround: in TestRefinedSchema we don't have spring context. + * @author mederly + */ +class RelationRegistryDummyImpl implements RelationRegistry { + + @Override + public List getRelationDefinitions() { + return emptyList(); + } + + @Override + public RelationDefinitionType getRelationDefinition(QName relation) { + return null; + } + + @Override + public boolean isOfKind(QName relation, RelationKindType kind) { + return kind == RelationKindType.MEMBERSHIP && (relation == null || QNameUtil.match(relation, ORG_DEFAULT)); + } + + @Override + public boolean isManager(QName relation) { + return false; + } + + @Override + public boolean isDelegation(QName relation) { + return false; + } + + @Override + public boolean isMembership(QName relation) { + return isOfKind(relation, RelationKindType.MEMBERSHIP); + } + + @Override + public boolean isOwner(QName relation) { + return false; + } + + @Override + public boolean isApprover(QName relation) { + return false; + } + + @Override + public boolean processRelationOnLogin(QName relation) { + return false; + } + + @Override + public boolean processRelationOnRecompute(QName relation) { + return false; + } + + @Override + public boolean includeIntoParentOrgRef(QName relation) { + return false; + } + + @Override + public QName getDefaultRelation() { + return ORG_DEFAULT; + } + + @NotNull + @Override + public Collection getAllRelationsFor(RelationKindType kind) { + return kind == RelationKindType.MEMBERSHIP ? singletonList(ORG_DEFAULT) : emptyList(); + } + + @Override + public QName getDefaultRelationFor(RelationKindType kind) { + return kind == RelationKindType.MEMBERSHIP ? ORG_DEFAULT : null; + } + + @NotNull + @Override + public QName normalizeRelation(QName relation) { + return relation == null ? ORG_DEFAULT : relation; + } + + @Override + public void applyRelationConfiguration(SystemConfigurationType relationsDefinition) { + } + + @Override + public boolean isDefault(QName relation) { + return relation == null || QNameUtil.match(relation, ORG_DEFAULT); + } + + @NotNull + @Override + public Collection getAliases(QName relation) { + return singleton(relation); + } +} diff --git a/infra/common/src/test/java/com/evolveum/midpoint/common/refinery/TestRefinedSchema.java b/infra/common/src/test/java/com/evolveum/midpoint/common/refinery/TestRefinedSchema.java index 428eb663361..193d5cad641 100644 --- a/infra/common/src/test/java/com/evolveum/midpoint/common/refinery/TestRefinedSchema.java +++ b/infra/common/src/test/java/com/evolveum/midpoint/common/refinery/TestRefinedSchema.java @@ -33,6 +33,7 @@ import com.evolveum.midpoint.prism.ConsistencyCheckScope; import com.evolveum.midpoint.prism.util.PrismTestUtil; +import com.evolveum.midpoint.schema.RelationRegistry; import com.evolveum.midpoint.schema.processor.*; import org.testng.Assert; import org.testng.AssertJUnit; @@ -85,6 +86,8 @@ public class TestRefinedSchema { private static final QName OBJECT_CLASS_INETORGPERSON_QNAME = new QName(MidPointConstants.NS_RI, "inetOrgPerson"); + private final RelationRegistry relationRegistry = new RelationRegistryDummyImpl(); + @BeforeSuite public void setup() throws SchemaException, SAXException, IOException { PrettyPrinter.setDefaultNamespacePrefix(MidPointConstants.NS_MIDPOINT_PUBLIC_PREFIX); @@ -544,9 +547,9 @@ private void assertDeprecatedProtectedAccount(String message, ResourceObjectPatt ResourceAttribute confusingAttr2 = createStringAttribute(new QName("http://whatever.com","confuseMeAgain"), "WoodchuckWouldChuckNoWoodAsWoodchuckCannotChuckWood"); attributesContainer.add(confusingAttr2); - assertTrue("Test attr not matched in "+message, protectedPattern.matches(shadow, null)); + assertTrue("Test attr not matched in "+message, protectedPattern.matches(shadow, null, relationRegistry)); nameAttr.setRealValue("huhulumululul"); - assertFalse("Test attr nonsense was matched in "+message, protectedPattern.matches(shadow, null)); + assertFalse("Test attr nonsense was matched in "+message, protectedPattern.matches(shadow, null, relationRegistry)); } private ResourceAttribute createStringAttribute(QName attrName, String value) { diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/PrismContext.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/PrismContext.java index b6c55b92306..b51e64b072d 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/PrismContext.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/PrismContext.java @@ -36,6 +36,7 @@ import java.io.File; import java.io.IOException; import java.io.InputStream; +import java.util.List; /** * @@ -267,8 +268,20 @@ void adopt(PrismContainerValue relationQuery, QName relation); + } diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/PrismContextImpl.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/PrismContextImpl.java index 9276c2051d3..1bb56f77a2a 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/PrismContextImpl.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/PrismContextImpl.java @@ -31,6 +31,7 @@ import com.evolveum.midpoint.prism.util.PrismMonitor; import com.evolveum.midpoint.prism.util.PrismPrettyPrinter; import com.evolveum.midpoint.prism.xnode.RootXNode; +import com.evolveum.midpoint.util.QNameUtil; import com.evolveum.midpoint.util.exception.SchemaException; import com.evolveum.midpoint.util.exception.SystemException; import com.evolveum.midpoint.util.logging.Trace; @@ -46,6 +47,7 @@ import java.io.File; import java.io.IOException; import java.io.InputStream; +import java.util.List; /** * @author semancik @@ -475,4 +477,28 @@ public O createKnownObjectable(@NotNull Class clazz) { public LexicalProcessorRegistry getLexicalProcessorRegistry() { return lexicalProcessorRegistry; } + + @Override + public boolean isDefaultRelation(QName relation) { + return relation == null || defaultRelation != null && QNameUtil.match(relation, defaultRelation); + } + + @Override + public boolean relationsEquivalent(QName relation1, QName relation2) { + if (isDefaultRelation(relation1)) { + return isDefaultRelation(relation2); + } else { + return QNameUtil.match(relation1, relation2); + } + } + + @Override + public boolean relationMatches(QName relationQuery, QName relation) { + return QNameUtil.match(relationQuery, PrismConstants.Q_ANY) || relationsEquivalent(relationQuery, relation); + } + + @Override + public boolean relationMatches(@NotNull List relationQuery, QName relation) { + return relationQuery.stream().anyMatch(rq -> relationMatches(rq, relation)); + } } diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/delta/ItemDelta.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/delta/ItemDelta.java index 97d55403604..d8e653629a2 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/delta/ItemDelta.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/delta/ItemDelta.java @@ -1178,10 +1178,29 @@ public void merge(ItemDelta deltaToMerge) { mergeValuesToDelete(PrismValue.cloneValues(deltaToMerge.valuesToDelete)); } } + + if (CollectionUtils.isNotEmpty(deltaToMerge.estimatedOldValues)) { + mergeOldValues(PrismValue.cloneValues(deltaToMerge.estimatedOldValues)); + } + // We do not want to clean up the sets during merging (e.g. in removeValue methods) because the set // may become empty and the a values may be added later. So just clean it up when all is done. removeEmptySets(); } + + private void mergeOldValues(Collection oldValues) { + if (estimatedOldValues == null) { + estimatedOldValues = newValueCollection(); + } + + for (V oldValue : oldValues) { + if (containsEquivalentValue(estimatedOldValues, oldValue)) { + continue; + } + + estimatedOldValues.add(oldValue); + } + } private void removeEmptySets() { // Do not remove replace set, even if it is empty. diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/delta/builder/DeltaBuilder.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/delta/builder/DeltaBuilder.java index 6eadc1e9af3..1af1aab7ded 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/delta/builder/DeltaBuilder.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/delta/builder/DeltaBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010-2015 Evolveum + * Copyright (c) 2010-2018 Evolveum * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -199,6 +199,14 @@ public S_ValuesEntry oldRealValues(Collection realValues) { } return this; } + + @Override + public S_ValuesEntry oldRealValue(T realValue) { + if (realValue != null) { + currentDelta.addEstimatedOldValue(toPrismValue(currentDelta, realValue)); + } + return this; + } @Override public S_ValuesEntry old(PrismValue... values) { diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/delta/builder/S_ItemEntry.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/delta/builder/S_ItemEntry.java index ee323185ee1..34e869b4504 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/delta/builder/S_ItemEntry.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/delta/builder/S_ItemEntry.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010-2015 Evolveum + * Copyright (c) 2010-2018 Evolveum * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -36,7 +36,7 @@ public interface S_ItemEntry { S_ValuesEntry item(ItemPath path, ItemDefinition itemDefinition); List> asObjectDeltas(String oid); - ObjectDelta asObjectDelta(String oid); + ObjectDelta asObjectDelta(String oid); // TEMPORARY HACK @SuppressWarnings("unchecked") diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/delta/builder/S_ValuesEntry.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/delta/builder/S_ValuesEntry.java index 25237c86a6d..7973340c7aa 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/delta/builder/S_ValuesEntry.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/delta/builder/S_ValuesEntry.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010-2015 Evolveum + * Copyright (c) 2010-2018 Evolveum * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -44,6 +44,7 @@ public interface S_ValuesEntry { S_ItemEntry replace(Collection values); S_ValuesEntry old(Object... realValues); S_ValuesEntry oldRealValues(Collection realValues); + S_ValuesEntry oldRealValue(T realValue); S_ValuesEntry old(PrismValue... values); S_ValuesEntry old(Collection values); } diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/builder/R_AtomicFilter.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/builder/R_AtomicFilter.java index 6da5e097aa1..170f475b0ae 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/builder/R_AtomicFilter.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/builder/R_AtomicFilter.java @@ -222,11 +222,13 @@ public S_MatchingRuleEntry containsPoly(String orig) { } @Override - public S_AtomicFilterExit ref(QName relation) { - PrismReferenceValue ref = new PrismReferenceValue(); - ref.setRelation(relation); - List values = new ArrayList<>(); - values.add(ref); + public S_AtomicFilterExit ref(QName... relations) { + List values = new ArrayList<>(); + for (QName relation : relations) { + PrismReferenceValue ref = new PrismReferenceValue(); + ref.setRelation(relation); + values.add(ref); + } RefFilter filter = RefFilter.createReferenceEqual(itemPath, referenceDefinition, values); filter.setOidNullAsAny(true); filter.setTargetTypeNullAsAny(true); diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/builder/S_ConditionEntry.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/builder/S_ConditionEntry.java index 319409fbbd6..e6236cda526 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/builder/S_ConditionEntry.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/query/builder/S_ConditionEntry.java @@ -48,7 +48,7 @@ public interface S_ConditionEntry { S_MatchingRuleEntry contains(Object value); S_MatchingRuleEntry containsPoly(String orig, String norm); S_MatchingRuleEntry containsPoly(String orig); - S_AtomicFilterExit ref(QName relation); // TODO is this supported by repo query interpreter? + S_AtomicFilterExit ref(QName... relations); // TODO is this supported by repo query interpreter? S_AtomicFilterExit ref(PrismReferenceValue... value); S_AtomicFilterExit ref(Collection values); S_AtomicFilterExit ref(Collection values, boolean nullTypeAsAny); // beware, 'nullTypeAsAny' is supported only by built-in match(..) method diff --git a/infra/schema/pom.xml b/infra/schema/pom.xml index 31b099603ab..9b01e988a34 100644 --- a/infra/schema/pom.xml +++ b/infra/schema/pom.xml @@ -42,6 +42,18 @@ util 3.9-SNAPSHOT + + org.springframework + spring-core + + + org.springframework + spring-beans + + + org.springframework + spring-context + commons-collections commons-collections diff --git a/infra/schema/src/main/java/com/evolveum/midpoint/schema/RelationRegistry.java b/infra/schema/src/main/java/com/evolveum/midpoint/schema/RelationRegistry.java new file mode 100644 index 00000000000..8179135b910 --- /dev/null +++ b/infra/schema/src/main/java/com/evolveum/midpoint/schema/RelationRegistry.java @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2010-2018 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. + */ + +package com.evolveum.midpoint.schema; + +import com.evolveum.midpoint.xml.ns._public.common.common_3.RelationDefinitionType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.RelationKindType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.SystemConfigurationType; +import org.jetbrains.annotations.NotNull; + +import javax.xml.namespace.QName; +import java.util.Collection; +import java.util.List; + +/** + * TODO think about precise place of this interface + * + * @author mederly + */ +public interface RelationRegistry { + + List getRelationDefinitions(); + + RelationDefinitionType getRelationDefinition(QName relation); + + // SchemaException is thrown as SystemException as it really should not occur + + boolean isOfKind(QName relation, RelationKindType kind); + + boolean isManager(QName relation); + + boolean isDelegation(QName relation); + + boolean isMembership(QName relation); + + boolean isOwner(QName relation); + + boolean isApprover(QName relation); + + boolean processRelationOnLogin(QName relation); + + boolean processRelationOnRecompute(QName relation); + + boolean includeIntoParentOrgRef(QName relation); + + QName getDefaultRelation(); + + @NotNull + Collection getAllRelationsFor(RelationKindType kind); + + QName getDefaultRelationFor(RelationKindType kind); + + @NotNull + QName normalizeRelation(QName relation); + + void applyRelationConfiguration(SystemConfigurationType relationsDefinition); + + boolean isDefault(QName relation); + + /** + * Returns aliases of a relation. Currently these are: + * - unnormalized version of the relation QNme + * - null if the relation is the default one + * + * In the future we might return some other values (e.g. explicitly configured aliases) as well. + * But we would need to adapt prismContext.relationsEquivalent method and other comparison methods as well. + * It is perhaps not worth the effort. + */ + @NotNull + Collection getAliases(QName relation); +} diff --git a/infra/schema/src/main/java/com/evolveum/midpoint/schema/constants/RelationTypes.java b/infra/schema/src/main/java/com/evolveum/midpoint/schema/constants/RelationTypes.java index fddfab68477..a70c494dfd6 100755 --- a/infra/schema/src/main/java/com/evolveum/midpoint/schema/constants/RelationTypes.java +++ b/infra/schema/src/main/java/com/evolveum/midpoint/schema/constants/RelationTypes.java @@ -16,11 +16,16 @@ package com.evolveum.midpoint.schema.constants; -import com.evolveum.midpoint.schema.util.ObjectTypeUtil; -import com.evolveum.midpoint.util.QNameUtil; import com.evolveum.midpoint.xml.ns._public.common.common_3.AreaCategoryType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.RelationKindType; +import org.jetbrains.annotations.NotNull; import javax.xml.namespace.QName; +import java.util.ArrayList; +import java.util.Collection; + +import static com.evolveum.midpoint.xml.ns._public.common.common_3.AreaCategoryType.*; +import static java.util.Collections.singletonList; /** * Built-in (hardcoded) relations. @@ -29,22 +34,31 @@ */ public enum RelationTypes { - MEMBER(SchemaConstants.ORG_DEFAULT, "", AreaCategoryType.ADMINISTRATION, AreaCategoryType.ORGANIZATION, AreaCategoryType.SELF_SERVICE), - MANAGER(SchemaConstants.ORG_MANAGER, "Manager", AreaCategoryType.ADMINISTRATION, AreaCategoryType.GOVERNANCE, AreaCategoryType.ORGANIZATION, AreaCategoryType.SELF_SERVICE), - META(SchemaConstants.ORG_META, "Meta", AreaCategoryType.POLICY), - DEPUTY(SchemaConstants.ORG_DEPUTY, "Deputy" /* no values */), - APPROVER(SchemaConstants.ORG_APPROVER, "Approver", AreaCategoryType.ADMINISTRATION, AreaCategoryType.GOVERNANCE, AreaCategoryType.ORGANIZATION, AreaCategoryType.SELF_SERVICE), - OWNER(SchemaConstants.ORG_OWNER, "Owner", AreaCategoryType.ADMINISTRATION, AreaCategoryType.GOVERNANCE, AreaCategoryType.ORGANIZATION, AreaCategoryType.SELF_SERVICE), - CONSENT(SchemaConstants.ORG_CONSENT, "Consent", AreaCategoryType.DATA_PROTECTION),; - + MEMBER(SchemaConstants.ORG_DEFAULT, "", RelationKindType.MEMBERSHIP, null, ADMINISTRATION, ORGANIZATION, SELF_SERVICE), + MANAGER(SchemaConstants.ORG_MANAGER, "Manager", RelationKindType.MANAGER, singletonList(RelationKindType.MEMBERSHIP), ADMINISTRATION, GOVERNANCE, ORGANIZATION, SELF_SERVICE), + META(SchemaConstants.ORG_META, "Meta", RelationKindType.META, singletonList(RelationKindType.MEMBERSHIP), POLICY), + DEPUTY(SchemaConstants.ORG_DEPUTY, "Deputy", RelationKindType.DELEGATION, null /* no values */), + APPROVER(SchemaConstants.ORG_APPROVER, "Approver", RelationKindType.APPROVER, null, ADMINISTRATION, GOVERNANCE, ORGANIZATION, SELF_SERVICE), + OWNER(SchemaConstants.ORG_OWNER, "Owner", RelationKindType.OWNER, null, ADMINISTRATION, GOVERNANCE, ORGANIZATION, SELF_SERVICE), + CONSENT(SchemaConstants.ORG_CONSENT, "Consent", RelationKindType.CONSENT, null, DATA_PROTECTION); private final QName relation; private final String headerLabel; + private final RelationKindType defaultFor; + @NotNull private final Collection kinds; private final AreaCategoryType[] categories; - RelationTypes(QName relation, String headerLabel, AreaCategoryType... categories) { + RelationTypes(QName relation, String headerLabel, RelationKindType defaultFor, Collection additionalKinds, AreaCategoryType... categories) { this.relation = relation; this.headerLabel = headerLabel; + this.kinds = new ArrayList<>(); + if (defaultFor != null) { + kinds.add(defaultFor); + } + if (additionalKinds != null) { + kinds.addAll(additionalKinds); + } + this.defaultFor = defaultFor; this.categories = categories; } @@ -59,20 +73,17 @@ public String getHeaderLabel() { public String getLabelKey() { return RelationTypes.class.getSimpleName() + "." + relation.getLocalPart(); } - + + public RelationKindType getDefaultFor() { + return defaultFor; + } + + @NotNull + public Collection getKinds() { + return kinds; + } + public AreaCategoryType[] getCategories() { return categories; } - - public static RelationTypes getRelationType(QName relation) { - if (ObjectTypeUtil.isDefaultRelation(relation)) { - return RelationTypes.MEMBER; - } - for (RelationTypes relationTypes : RelationTypes.values()) { - if (QNameUtil.match(relation, relationTypes.getRelation())) { - return relationTypes; - } - } - return RelationTypes.MEMBER; - } } diff --git a/infra/schema/src/main/java/com/evolveum/midpoint/schema/constants/SchemaConstants.java b/infra/schema/src/main/java/com/evolveum/midpoint/schema/constants/SchemaConstants.java index 58e5f65b884..5abdc08bf1e 100644 --- a/infra/schema/src/main/java/com/evolveum/midpoint/schema/constants/SchemaConstants.java +++ b/infra/schema/src/main/java/com/evolveum/midpoint/schema/constants/SchemaConstants.java @@ -139,64 +139,54 @@ public abstract class SchemaConstants { // public static final QName T_PROTECTED_BYTE_ARRAY_TYPE = new QName(NS_C, // "ProtectedByteArrayType"); + /* + * Constants for default relations. + * + * Please DO NOT use these in production code. Use RelationKind values instead. + * =========================================== + * + * You can, however, freely use these in tests. + */ + /** - * Default relation, usually meaning "has" or "is member of". Used as a relation value in object references. - * Specifies that the subject is a member of organization, or that the subject - * has been assigned a role in a way that he gets authorizations and other content - * provided by that role. + * Default membership relation. Used as a relation value in object references. + * See RelationKind.MEMBERSHIP for more details. */ public static final QName ORG_DEFAULT = new QName(NS_ORG, "default"); /** - * Relation "is manager of". Used as a relation value in object references. - * Specifies that the subject is a manager of organizational unit. + * Default 'manager' relation. Used as a relation value in object references. + * See RelationKind.MANAGER for more details. */ public static final QName ORG_MANAGER = new QName(NS_ORG, "manager"); /** - * Relation used for metarole assignments. Sometimes it is important to - * distinguish metarole and member assignments. This relation is used - * for that purpose. + * Default 'metarole assignment' relation. Used as a relation value in object references. + * See RelationKind.META for more details. */ public static final QName ORG_META = new QName(NS_ORG, "meta"); /** - * Relation "is deputy of". Used as a relation value in object references. - * Specifies that the subject is a deputy of another user. + * Default delegation relation. Used as a relation value in object references. + * See RelationKind.DELEGATION for more details. */ public static final QName ORG_DEPUTY = new QName(NS_ORG, "deputy"); /** - * Relation "is approver of". Used as a relation value in object references. - * Specifies that the subject is a (general) approver of specified (abstract) role. - * The approver will be asked for decision if the role is assigned, if there is - * a rule conflict during assignment (e.g. SoD conflict) or if there is any similar - * situation. - * - * This is a generic approver used for all the situation. The system may be customized - * with more specific approver roles, e.g. technicalApprover, securityApprover, etc. - * - * This approver is responsible for the use of the role, which mostly means - * that he decides about role assignment. It is NOT meant to approve role changes. - * Role owner is meant for that purpose. + * Default 'approver' relation. Used as a relation value in object references. + * See RelationKind.APPROVER for more details. */ public static final QName ORG_APPROVER = new QName(NS_ORG, "approver"); /** - * Relation "is owner of". Used as a relation value in object references. - * Specifies that the subject is a (business) owner of specified (abstract) role. - * The owner will be asked for decision if the role is modified, when the associated - * policy changes and so on. - * - * This owner is responsible for maintaining role definition and policies. It is - * NPT necessarily concerned with role use (e.g. assignment). The approver relation - * is meant for that purpose. + * Default 'owner' relation. Used as a relation value in object references. + * See RelationKind.OWNER for more details. */ public static final QName ORG_OWNER = new QName(NS_ORG, "owner"); /** - * Relation "is consent for". Used as a relation value in object references. - * Specifies that the subject gave a consent for using personnel information related to this role. + * Default 'consent' relation. Used as a relation value in object references. + * See RelationKind.CONSENT for more details. */ public static final QName ORG_CONSENT = new QName(NS_ORG, "consent"); @@ -399,12 +389,24 @@ public abstract class SchemaConstants { public static final String NS_GUI = NS_MIDPOINT_PUBLIC + "/gui"; public static final String NS_GUI_CHANNEL = NS_GUI + "/channels-3"; + + // Init channel, used when system is initializing itself public static final QName CHANNEL_GUI_INIT_QNAME = new QName(NS_GUI_CHANNEL, "init"); public static final String CHANNEL_GUI_INIT_URI = QNameUtil.qNameToUri(CHANNEL_GUI_INIT_QNAME); + public static final QName CHANNEL_GUI_SELF_REGISTRATION_QNAME = new QName(NS_GUI_CHANNEL, "selfRegistration"); public static final String CHANNEL_GUI_SELF_REGISTRATION_URI = QNameUtil.qNameToUri(CHANNEL_GUI_SELF_REGISTRATION_QNAME); + + // Channel for self-service part of the user interface. These are the pages when user is changing his own data. + // E.g. update of his own profile and password change are considered to be self-service. + public static final QName CHANNEL_GUI_SELF_SERVICE_QNAME = new QName(NS_GUI_CHANNEL, "selfService"); + public static final String CHANNEL_GUI_SELF_SERVICE_URI = QNameUtil.qNameToUri(CHANNEL_GUI_SELF_SERVICE_QNAME); + + // Password reset channel. This is *reset*, which means that the user does not know the old password and cannot log in. public static final QName CHANNEL_GUI_RESET_PASSWORD_QNAME = new QName(NS_GUI_CHANNEL, "resetPassword"); public static final String CHANNEL_GUI_RESET_PASSWORD_URI = QNameUtil.qNameToUri(CHANNEL_GUI_RESET_PASSWORD_QNAME); + + // Catch-all channel for all user operations in user interface. public static final QName CHANNEL_GUI_USER_QNAME = new QName(NS_GUI_CHANNEL, "user"); public static final String CHANNEL_GUI_USER_URI = QNameUtil.qNameToUri(CHANNEL_GUI_USER_QNAME); diff --git a/infra/schema/src/main/java/com/evolveum/midpoint/schema/processor/ResourceObjectIdentification.java b/infra/schema/src/main/java/com/evolveum/midpoint/schema/processor/ResourceObjectIdentification.java index 2c1d699c67b..c2a4ccf8003 100644 --- a/infra/schema/src/main/java/com/evolveum/midpoint/schema/processor/ResourceObjectIdentification.java +++ b/infra/schema/src/main/java/com/evolveum/midpoint/schema/processor/ResourceObjectIdentification.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-2016 Evolveum + * Copyright (c) 2015-2018 Evolveum * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,6 +18,7 @@ import java.io.Serializable; import java.util.ArrayList; import java.util.Collection; +import java.util.List; import com.evolveum.midpoint.schema.util.ShadowUtil; import com.evolveum.midpoint.util.PrettyPrinter; @@ -72,6 +73,19 @@ public ResourceAttribute getSecondaryIdentifier() throws SchemaException return (ResourceAttribute) secondaryIdentifiers.iterator().next(); } + @SuppressWarnings({ "unchecked", "rawtypes" }) + public Collection> getAllIdentifiers() { + if (primaryIdentifiers == null) { + return secondaryIdentifiers; + } + if (secondaryIdentifiers == null) { + return primaryIdentifiers; + } + List allIdentifiers = new ArrayList<>(primaryIdentifiers.size() + secondaryIdentifiers.size()); + allIdentifiers.addAll(primaryIdentifiers); + allIdentifiers.addAll(secondaryIdentifiers); + return allIdentifiers; + } public ObjectClassComplexTypeDefinition getObjectClassDefinition() { return objectClassDefinition; diff --git a/infra/schema/src/main/java/com/evolveum/midpoint/schema/relation/IndexedRelationDefinitions.java b/infra/schema/src/main/java/com/evolveum/midpoint/schema/relation/IndexedRelationDefinitions.java new file mode 100644 index 00000000000..fc4e1b52504 --- /dev/null +++ b/infra/schema/src/main/java/com/evolveum/midpoint/schema/relation/IndexedRelationDefinitions.java @@ -0,0 +1,347 @@ +/* + * Copyright (c) 2010-2018 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. + */ + +package com.evolveum.midpoint.schema.relation; + +import com.evolveum.midpoint.schema.constants.RelationTypes; +import com.evolveum.midpoint.schema.constants.SchemaConstants; +import com.evolveum.midpoint.util.QNameUtil; +import com.evolveum.midpoint.util.logging.Trace; +import com.evolveum.midpoint.util.logging.TraceManager; +import com.evolveum.midpoint.xml.ns._public.common.common_3.RelationDefinitionType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.RelationKindType; +import org.apache.commons.collections4.ListValuedMap; +import org.apache.commons.collections4.SetValuedMap; +import org.apache.commons.collections4.multimap.ArrayListValuedHashMap; +import org.apache.commons.collections4.multimap.HashSetValuedHashMap; +import org.jetbrains.annotations.NotNull; +import org.springframework.util.CollectionUtils; + +import javax.xml.namespace.QName; +import java.util.*; + +import static java.util.Collections.singleton; +import static org.apache.commons.collections4.CollectionUtils.emptyIfNull; + +/** + * Relation definitions indexed for fast querying by the relation registry. + * It is intentionally package-private. Should be used only for RelationRegistryImpl. + * + * @author mederly + */ +class IndexedRelationDefinitions { + + private static final Trace LOGGER = TraceManager.getTrace(IndexedRelationDefinitions.class); + + /** + * All valid definitions are here; duplicates and invalid ones are filtered out. + */ + @NotNull private final List definitions; + /** + * Looking up relation definition by its name. + * + * All variants of relation name are present in keySet, e.g. both 'org:approver' and 'approver' (in default configuration) + * There's also an entry with key=null, denoting the default relation. + */ + @NotNull private final Map relationDefinitionsByRelationName; + /** + * Looking up relation kinds by its name. It is returned as HashSet to allow for quick determination of presence of specified kinds. + * + * Both qualified and unqualified forms of relation name are listed here, e.g. both 'org:approver' and 'approver'. + * Also an entry with key=null is present. + */ + @NotNull private final SetValuedMap kindsByRelationName; + /** + * Looking up relations by its kind. + * + * Each relation is listed only once in values; e.g. there's 'org:approver' but not 'approver' (in default configuration) + */ + @NotNull private final SetValuedMap relationsByKind; + /** + * Default relation for each kind. + * There should be exactly one for each kind. + */ + @NotNull private final Map defaultRelationByKind; + /** + * Relations to be processed on login. Each relation is listed here under all its names. + */ + @NotNull private final Set relationsToProcessOnLogin; + /** + * Relations to be processed on recompute. Each relation is listed here under all its names. + */ + @NotNull private final Set relationsToProcessOnRecompute; + /** + * Aliases for each normalized relation QName. + */ + @NotNull private final SetValuedMap aliases; + + //region Initialization + + IndexedRelationDefinitions(@NotNull List definitions) { + List validatedDefinitions = validateDefinitions(definitions); + this.definitions = validatedDefinitions; + relationDefinitionsByRelationName = initializeRelationDefinitionsByRelationName(validatedDefinitions); + kindsByRelationName = computeKindsByRelationName(); + relationsByKind = computeRelationsByKind(); + defaultRelationByKind = computeDefaultRelationByKind(); + + addDefaultRelationToMaps(); + + relationsToProcessOnLogin = computeRelationsToProcessOnLogin(); + relationsToProcessOnRecompute = computeRelationsToProcessOnRecompute(); + + aliases = computeAliases(); + logState(); + } + + private void addDefaultRelationToMaps() { + QName defaultRelation = defaultRelationByKind.get(RelationKindType.MEMBERSHIP); + if (defaultRelation != null) { + relationDefinitionsByRelationName.put(null, relationDefinitionsByRelationName.get(defaultRelation)); + kindsByRelationName.putAll(null, kindsByRelationName.get(defaultRelation)); + } + } + + private void logState() { + if (LOGGER.isTraceEnabled()) { + LOGGER.trace("relation definitions = {}", definitions); + LOGGER.trace("relationDefinitionsByRelationName = {}", relationDefinitionsByRelationName); + LOGGER.trace("relationsByKind = {}", relationsByKind); + LOGGER.trace("defaultRelationByKind = {}", defaultRelationByKind); + LOGGER.trace("relationsToProcessOnLogin = {}", relationsToProcessOnLogin); + LOGGER.trace("relationsToProcessOnRecompute = {}", relationsToProcessOnRecompute); + LOGGER.trace("aliases = {}", aliases); + } + } + + private List validateDefinitions(@NotNull List definitions) { + List validatedDefinitions = new ArrayList<>(definitions.size()); + boolean membershipRelationExists = false; + for (RelationDefinitionType definition : definitions) { + if (definition.getRef() == null) { + LOGGER.error("Relation definition with null ref; ignoring: {}", definition); + } else { + if (QNameUtil.isUnqualified(definition.getRef())) { + LOGGER.warn("Unqualified relation name '{}'; please fix it as soon as possible; in {}", definition.getRef(), definition); + } + validatedDefinitions.add(definition); + if (!membershipRelationExists && definition.getKind().contains(RelationKindType.MEMBERSHIP)) { + membershipRelationExists = true; + } + } + } + if (!membershipRelationExists) { + LOGGER.error("No 'member' relation was defined. This would be a fatal condition, so we define one."); + validatedDefinitions.add(RelationRegistryImpl.createRelationDefinitionFromStaticDefinition(RelationTypes.MEMBER)); + } + return validatedDefinitions; + } + + /** + * Removes duplicate definitions as well. + */ + @NotNull + private Map initializeRelationDefinitionsByRelationName(List definitions) { + Map map = new HashMap<>(); + ListValuedMap expansions = new ArrayListValuedHashMap<>(); + for (Iterator iterator = definitions.iterator(); iterator.hasNext(); ) { + RelationDefinitionType definition = iterator.next(); + if (map.containsKey(definition.getRef())) { + LOGGER.error("Duplicate relation definition for '{}'; ignoring: {}", definition.getRef(), definition); + iterator.remove(); + } else { + map.put(definition.getRef(), definition); + expansions.put(definition.getRef().getLocalPart(), definition.getRef()); + } + } + // add entries for unqualified versions of the relation names + for (String unqualified : expansions.keySet()) { + List names = expansions.get(unqualified); + if (names.contains(new QName(unqualified))) { + continue; // cannot expand unqualified if the expanded value is also unqualified + } + assert !names.isEmpty(); + assert names.stream().allMatch(QNameUtil::isQualified); + @NotNull QName chosenExpansion; + if (names.size() == 1) { + chosenExpansion = names.get(0); + } else { + QName nameInOrgNamespace = names.stream() + .filter(n -> SchemaConstants.NS_ORG.equals(n.getNamespaceURI())) + .findFirst().orElse(null); + if (nameInOrgNamespace != null) { + // org:xxx expansion will be the default one + chosenExpansion = nameInOrgNamespace; + } else { + chosenExpansion = names.get(0); + LOGGER.warn("Multiple resolutions of unqualified relation name '{}' ({}); " + + "using the first one as default: '{}'. Please reconsider this as it could lead to " + + "unpredictable behavior.", unqualified, names, chosenExpansion); + } + } + assert QNameUtil.isQualified(chosenExpansion); + map.put(new QName(unqualified), map.get(chosenExpansion)); + } + return map; + } + + private SetValuedMap computeKindsByRelationName() { + SetValuedMap rv = new HashSetValuedHashMap<>(); + for (Map.Entry entry : relationDefinitionsByRelationName.entrySet()) { + for (RelationKindType kind : entry.getValue().getKind()) { + rv.put(entry.getKey(), kind); + } + } + return rv; + } + + private SetValuedMap computeRelationsByKind() { + SetValuedMap rv = new HashSetValuedHashMap<>(); + for (RelationDefinitionType definition : definitions) { + for (RelationKindType kind : definition.getKind()) { + rv.put(kind, definition.getRef()); + } + } + return rv; + } + + // not optimized for speed + @NotNull + private Collection getAllRelationNamesFor(RelationKindType kind) { + Set rv = new HashSet<>(); + for (Map.Entry entry : relationDefinitionsByRelationName.entrySet()) { + if (entry.getValue().getKind().contains(kind)) { + rv.add(entry.getKey()); + } + } + return rv; + } + + private Map computeDefaultRelationByKind() { + Map rv = new HashMap<>(); + for (RelationKindType kind : RelationKindType.values()) { + Set relationNames = relationsByKind.get(kind); + if (relationNames.isEmpty()) { + LOGGER.warn("No relations defined for kind {}, please define at least one", kind); + continue; + } + Set defaultRelationNames = new HashSet<>(); + for (QName relationName : relationNames) { + RelationDefinitionType definition = relationDefinitionsByRelationName.get(relationName); + assert definition != null; + if (definition.getDefaultFor() == kind) { + defaultRelationNames.add(relationName); + } + } + QName chosen; + if (defaultRelationNames.size() > 1) { + chosen = defaultRelationNames.iterator().next(); + LOGGER.error("More than one default relation set up for kind '{}': {}. Please choose one! Temporarily selecting '{}'", + kind, defaultRelationNames, chosen); + } else if (defaultRelationNames.size() == 1) { + chosen = defaultRelationNames.iterator().next(); + } else { + chosen = relationNames.iterator().next(); // maybe we could select org:xxx here but let's not bother now + LOGGER.warn("No default relation set up for kind '{}'. Please choose one! Temporarily selecting '{}'", kind, chosen); + } + rv.put(kind, chosen); + } + return rv; + } + + // We want to make this configurable in the future MID-3581 + private Set computeRelationsToProcessOnLogin() { + HashSet rv = new HashSet<>(); + rv.addAll(getAllRelationNamesFor(RelationKindType.MEMBERSHIP)); + rv.addAll(getAllRelationNamesFor(RelationKindType.DELEGATION)); + return rv; + } + + // We want to make this configurable in the future MID-3581 + private Set computeRelationsToProcessOnRecompute() { + HashSet rv = new HashSet<>(); + rv.addAll(getAllRelationsFor(RelationKindType.MEMBERSHIP)); + rv.addAll(getAllRelationsFor(RelationKindType.MANAGER)); + rv.addAll(getAllRelationsFor(RelationKindType.DELEGATION)); + return rv; + } + + private SetValuedMap computeAliases() { + SetValuedMap rv = new HashSetValuedHashMap<>(); + for (Map.Entry entry : relationDefinitionsByRelationName.entrySet()) { + rv.put(entry.getValue().getRef(), entry.getKey()); + } + return rv; + } + + //endregion + + //region Querying + @NotNull + List getDefinitions() { + return definitions; + } + + RelationDefinitionType getRelationDefinition(QName relation) { + return relationDefinitionsByRelationName.get(relation); + } + + boolean isOfKind(QName relation, RelationKindType kind) { + Set relationKinds = kindsByRelationName.get(relation); + return relationKinds != null && relationKinds.contains(kind); + } + + boolean processRelationOnLogin(QName relation) { + return relationsToProcessOnLogin.contains(relation); + } + + boolean processRelationOnRecompute(QName relation) { + return relationsToProcessOnRecompute.contains(relation); + } + + // We want to make this configurable in the future MID-3581 + public boolean includeIntoParentOrgRef(QName relation) { + return isOfKind(relation, RelationKindType.MEMBERSHIP) && !isOfKind(relation, RelationKindType.META); + } + + QName getDefaultRelationFor(RelationKindType kind) { + return defaultRelationByKind.get(kind); + } + + @NotNull + Collection getAllRelationsFor(RelationKindType kind) { + return emptyIfNull(relationsByKind.get(kind)); + } + + @NotNull + QName normalizeRelation(QName relation) { + RelationDefinitionType definition = getRelationDefinition(relation); + assert !(relation == null && definition == null); // there is always a default definition + return definition != null ? definition.getRef() : relation; + } + + @NotNull + Collection getAliases(QName relation) { + Set aliases = this.aliases.get(normalizeRelation(relation)); + if (!CollectionUtils.isEmpty(aliases)) { + return aliases; + } else { + // for unknown relations we would like to return at least the provided name + return singleton(relation); + } + } + //endregion +} diff --git a/infra/schema/src/main/java/com/evolveum/midpoint/schema/relation/RelationRegistryImpl.java b/infra/schema/src/main/java/com/evolveum/midpoint/schema/relation/RelationRegistryImpl.java new file mode 100644 index 00000000000..f1455e777dc --- /dev/null +++ b/infra/schema/src/main/java/com/evolveum/midpoint/schema/relation/RelationRegistryImpl.java @@ -0,0 +1,201 @@ +/* + * Copyright (c) 2010-2018 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. + */ + +package com.evolveum.midpoint.schema.relation; + +import com.evolveum.midpoint.prism.PrismContext; +import com.evolveum.midpoint.schema.RelationRegistry; +import com.evolveum.midpoint.schema.constants.RelationTypes; +import com.evolveum.midpoint.schema.util.ObjectTypeUtil; +import com.evolveum.midpoint.util.logging.Trace; +import com.evolveum.midpoint.util.logging.TraceManager; +import com.evolveum.midpoint.xml.ns._public.common.common_3.*; +import org.apache.commons.lang.BooleanUtils; +import org.jetbrains.annotations.NotNull; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import javax.xml.namespace.QName; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.List; + +import static java.util.Collections.emptyList; + +/** + * @author mederly + * @author semancik + */ +@Component +public class RelationRegistryImpl implements RelationRegistry { + + private static final Trace LOGGER = TraceManager.getTrace(RelationRegistryImpl.class); + + @Autowired private PrismContext prismContext; + + @NotNull + private IndexedRelationDefinitions indexedRelationDefinitions = createAndIndexRelationDefinitions(null); + + @Override + public void applyRelationConfiguration(SystemConfigurationType systemConfiguration) { + RoleManagementConfigurationType roleManagement = systemConfiguration != null ? systemConfiguration.getRoleManagement() : null; + RelationsDefinitionType relationsDef = roleManagement != null ? roleManagement.getRelations() : null; + LOGGER.info("Applying relation configuration ({} entries)", relationsDef != null ? relationsDef.getRelation().size() : 0); + indexedRelationDefinitions = createAndIndexRelationDefinitions(relationsDef); + prismContext.setDefaultRelation(indexedRelationDefinitions.getDefaultRelationFor(RelationKindType.MEMBERSHIP)); + } + + public List getRelationDefinitions() { + return indexedRelationDefinitions.getDefinitions(); + } + + @NotNull + private IndexedRelationDefinitions createAndIndexRelationDefinitions(RelationsDefinitionType relationsDef) { + List configuredRelations = emptyList(); + boolean includeDefaultRelations = true; + if (relationsDef != null) { + configuredRelations = relationsDef.getRelation(); + if (BooleanUtils.isFalse(relationsDef.isIncludeDefaultRelations())) { + includeDefaultRelations = false; + } + } + List relations = new ArrayList<>(); + for (RelationDefinitionType configuredRelation: configuredRelations) { + relations.add(cloneAndNormalize(configuredRelation)); + } + if (includeDefaultRelations) { + addDefaultRelations(relations); + } + return new IndexedRelationDefinitions(relations); + } + + private RelationDefinitionType cloneAndNormalize(RelationDefinitionType definition) { + RelationDefinitionType clone = definition.clone(); + if (clone.getDefaultFor() != null && !clone.getKind().contains(clone.getDefaultFor())) { + clone.getKind().add(clone.getDefaultFor()); + } + return clone; + } + + private void addDefaultRelations(List relations) { + for (RelationTypes defaultRelationDefinition : RelationTypes.values()) { + if (ObjectTypeUtil.findRelationDefinition(relations, defaultRelationDefinition.getRelation()) == null) { + relations.add(createRelationDefinitionFromStaticDefinition(defaultRelationDefinition)); + } + } + } + + @NotNull + static RelationDefinitionType createRelationDefinitionFromStaticDefinition(RelationTypes defaultRelationDefinition) { + RelationDefinitionType relationDef = new RelationDefinitionType(); + relationDef.setRef(defaultRelationDefinition.getRelation()); + DisplayType display = new DisplayType(); + display.setLabel(defaultRelationDefinition.getLabelKey()); + relationDef.setDisplay(display); + relationDef.setDefaultFor(defaultRelationDefinition.getDefaultFor()); + relationDef.getKind().addAll(defaultRelationDefinition.getKinds()); + relationDef.getCategory().addAll(Arrays.asList(defaultRelationDefinition.getCategories())); + return relationDef; + } + + //region =============================================================================================== query methods + + @Override + public RelationDefinitionType getRelationDefinition(QName relation) { + return indexedRelationDefinitions.getRelationDefinition(relation); + } + + @Override + public boolean isOfKind(QName relation, RelationKindType kind) { + return indexedRelationDefinitions.isOfKind(relation, kind); + } + + @Override + public boolean isMembership(QName relation) { + return isOfKind(relation, RelationKindType.MEMBERSHIP); + } + + @Override + public boolean isManager(QName relation) { + return isOfKind(relation, RelationKindType.MANAGER); + } + + @Override + public boolean isDelegation(QName relation) { + return isOfKind(relation, RelationKindType.DELEGATION); + } + + @Override + public boolean isOwner(QName relation) { + return isOfKind(relation, RelationKindType.OWNER); + } + + @Override + public boolean isApprover(QName relation) { + return isOfKind(relation, RelationKindType.APPROVER); + } + + @Override + public boolean processRelationOnLogin(QName relation) { + return indexedRelationDefinitions.processRelationOnLogin(relation); + } + + @Override + public boolean processRelationOnRecompute(QName relation) { + return indexedRelationDefinitions.processRelationOnRecompute(relation); + } + + @Override + public boolean includeIntoParentOrgRef(QName relation) { + return indexedRelationDefinitions.includeIntoParentOrgRef(relation); + } + + @Override + public QName getDefaultRelationFor(RelationKindType kind) { + return indexedRelationDefinitions.getDefaultRelationFor(kind); + } + + @NotNull + @Override + public Collection getAllRelationsFor(RelationKindType kind) { + return indexedRelationDefinitions.getAllRelationsFor(kind); + } + + @Override + public QName getDefaultRelation() { + return getDefaultRelationFor(RelationKindType.MEMBERSHIP); + } + + @NotNull + @Override + public QName normalizeRelation(QName relation) { + return indexedRelationDefinitions.normalizeRelation(relation); + } + + @Override + public boolean isDefault(QName relation) { + return prismContext.isDefaultRelation(relation); + } + + @Override + @NotNull + public Collection getAliases(QName relation) { + return indexedRelationDefinitions.getAliases(relation); + } + + //endregion +} diff --git a/infra/schema/src/main/java/com/evolveum/midpoint/schema/util/FocusTypeUtil.java b/infra/schema/src/main/java/com/evolveum/midpoint/schema/util/FocusTypeUtil.java index ff53b82bdb3..502057f68cb 100644 --- a/infra/schema/src/main/java/com/evolveum/midpoint/schema/util/FocusTypeUtil.java +++ b/infra/schema/src/main/java/com/evolveum/midpoint/schema/util/FocusTypeUtil.java @@ -20,6 +20,7 @@ import javax.xml.namespace.QName; +import com.evolveum.midpoint.prism.PrismContext; import com.evolveum.midpoint.prism.PrismObject; import com.evolveum.midpoint.schema.constants.SchemaConstants; import com.evolveum.midpoint.xml.ns._public.common.common_3.AssignmentSelectorType; @@ -106,12 +107,13 @@ public static String dumpInducementConstraints(AssignmentType assignmentType) { return sb.toString(); } - public static boolean selectorMatches(AssignmentSelectorType assignmentSelector, AssignmentType assignmentType) { + public static boolean selectorMatches(AssignmentSelectorType assignmentSelector, AssignmentType assignmentType, + PrismContext prismContext) { if (assignmentType.getTargetRef() == null) { return false; } for (ObjectReferenceType selectorTargetRef: assignmentSelector.getTargetRef()) { - if (MiscSchemaUtil.referenceMatches(selectorTargetRef, assignmentType.getTargetRef())) { + if (MiscSchemaUtil.referenceMatches(selectorTargetRef, assignmentType.getTargetRef(), prismContext)) { return true; } } diff --git a/infra/schema/src/main/java/com/evolveum/midpoint/schema/util/MiscSchemaUtil.java b/infra/schema/src/main/java/com/evolveum/midpoint/schema/util/MiscSchemaUtil.java index 18a6835c4b8..c2ff7c0fa3e 100644 --- a/infra/schema/src/main/java/com/evolveum/midpoint/schema/util/MiscSchemaUtil.java +++ b/infra/schema/src/main/java/com/evolveum/midpoint/schema/util/MiscSchemaUtil.java @@ -305,10 +305,6 @@ public static AssignmentPolicyEnforcementType getAssignmentPolicyEnforcementType return assignmentPolicyEnforcement; } - public static boolean compareRelation(QName query, QName refRelation) { - return ObjectTypeUtil.relationMatches(query, refRelation); - } - public static PrismReferenceValue objectReferenceTypeToReferenceValue(ObjectReferenceType refType) { if (refType == null) { return null; @@ -397,14 +393,15 @@ public static void serializeFaultMessage(Detail detail, FaultMessage faultMessag } } - public static boolean referenceMatches(ObjectReferenceType refPattern, ObjectReferenceType ref) { + public static boolean referenceMatches(ObjectReferenceType refPattern, ObjectReferenceType ref, + PrismContext prismContext) { if (refPattern.getOid() != null && !refPattern.getOid().equals(ref.getOid())) { return false; } if (refPattern.getType() != null && !QNameUtil.match(refPattern.getType(), ref.getType())) { return false; } - if (!ObjectTypeUtil.relationMatches(refPattern.getRelation(), ref.getRelation())) { + if (!prismContext.relationMatches(refPattern.getRelation(), ref.getRelation())) { return false; } return true; diff --git a/infra/schema/src/main/java/com/evolveum/midpoint/schema/util/ObjectQueryUtil.java b/infra/schema/src/main/java/com/evolveum/midpoint/schema/util/ObjectQueryUtil.java index 34c405bb98d..c04b69ee70b 100644 --- a/infra/schema/src/main/java/com/evolveum/midpoint/schema/util/ObjectQueryUtil.java +++ b/infra/schema/src/main/java/com/evolveum/midpoint/schema/util/ObjectQueryUtil.java @@ -27,6 +27,8 @@ import com.evolveum.midpoint.prism.query.Visitor; import com.evolveum.midpoint.prism.query.builder.QueryBuilder; import com.evolveum.midpoint.prism.query.builder.S_AtomicFilterExit; +import com.evolveum.midpoint.schema.RelationRegistry; +import com.evolveum.midpoint.xml.ns._public.common.common_3.*; import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.lang.Validate; import org.apache.commons.lang.mutable.MutableBoolean; @@ -38,13 +40,11 @@ import com.evolveum.midpoint.schema.ResourceShadowDiscriminator; import com.evolveum.midpoint.util.DOMUtil; import com.evolveum.midpoint.util.exception.SchemaException; -import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowKindType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowType; import com.evolveum.prism.xml.ns._public.query_3.QueryType; import com.evolveum.prism.xml.ns._public.types_3.PolyStringType; import org.jetbrains.annotations.NotNull; +import static java.util.Collections.singleton; import static java.util.Collections.singletonList; import static org.apache.commons.collections4.CollectionUtils.isEmpty; @@ -544,6 +544,23 @@ public static FilterComponents factorOutOrFilter(ObjectFilter filter, ItemPath.. return components; } + // Creates references for querying + public static List createReferences(String oid, RelationKindType kind, + RelationRegistry relationRegistry) { + return createReferences(singleton(oid), kind, relationRegistry); + } + + public static List createReferences(Collection oids, RelationKindType kind, + RelationRegistry relationRegistry) { + List rv = new ArrayList<>(); + for (QName relation : relationRegistry.getAllRelationsFor(kind)) { + for (String oid : oids) { + rv.add(new ObjectReferenceType().oid(oid).relation(relation).asReferenceValue()); + } + } + return rv; + } + /** * Describes how to treat a filter when factoring out a query/filter. */ diff --git a/infra/schema/src/main/java/com/evolveum/midpoint/schema/util/ObjectTypeUtil.java b/infra/schema/src/main/java/com/evolveum/midpoint/schema/util/ObjectTypeUtil.java index ada0fb9438a..273a295610c 100644 --- a/infra/schema/src/main/java/com/evolveum/midpoint/schema/util/ObjectTypeUtil.java +++ b/infra/schema/src/main/java/com/evolveum/midpoint/schema/util/ObjectTypeUtil.java @@ -23,14 +23,19 @@ import com.evolveum.midpoint.prism.path.ItemPath; import com.evolveum.midpoint.prism.polystring.PolyString; import com.evolveum.midpoint.prism.query.ObjectFilter; +import com.evolveum.midpoint.prism.query.ObjectQuery; import com.evolveum.midpoint.prism.query.RefFilter; +import com.evolveum.midpoint.prism.query.builder.QueryBuilder; import com.evolveum.midpoint.prism.util.ItemPathUtil; +import com.evolveum.midpoint.schema.RelationRegistry; import com.evolveum.midpoint.schema.constants.ObjectTypes; import com.evolveum.midpoint.schema.constants.SchemaConstants; import com.evolveum.midpoint.util.LocalizableMessage; import com.evolveum.midpoint.util.LocalizableMessageBuilder; import com.evolveum.midpoint.util.QNameUtil; import com.evolveum.midpoint.util.exception.SchemaException; +import com.evolveum.midpoint.util.logging.Trace; +import com.evolveum.midpoint.util.logging.TraceManager; import com.evolveum.midpoint.xml.ns._public.common.common_3.*; import com.evolveum.prism.xml.ns._public.types_3.ItemDeltaType; import com.evolveum.prism.xml.ns._public.types_3.ItemPathType; @@ -60,6 +65,8 @@ */ public class ObjectTypeUtil { + private static final Trace LOGGER = TraceManager.getTrace(ObjectTypeUtil.class); + /** * Never returns null. Returns empty collection instead. */ @@ -237,8 +244,9 @@ public static AssignmentType createAssignmentTo(@NotNull } @NotNull - public static AssignmentType createAssignmentTo(@NotNull PrismObject object) { - return createAssignmentTo(object, SchemaConstants.ORG_DEFAULT); + public static AssignmentType createAssignmentTo(@NotNull PrismObject object, + PrismContext prismContext) { + return createAssignmentTo(object, prismContext.getDefaultRelation()); } @NotNull @@ -255,10 +263,11 @@ public static AssignmentType createAssignmentTo(@NotNull } @NotNull - public static AssignmentType createAssignmentWithConstruction(@NotNull PrismObject object, ShadowKindType kind, String intent) { - AssignmentType assignment = new AssignmentType(object.getPrismContext()); - ConstructionType construction = new ConstructionType(object.getPrismContext()); - construction.setResourceRef(createObjectRef(object)); + public static AssignmentType createAssignmentWithConstruction(@NotNull PrismObject object, ShadowKindType kind, + String intent, PrismContext prismContext) { + AssignmentType assignment = new AssignmentType(prismContext); + ConstructionType construction = new ConstructionType(prismContext); + construction.setResourceRef(createObjectRef(object, prismContext)); construction.setKind(kind); construction.setIntent(intent); assignment.setConstruction(construction); @@ -276,15 +285,18 @@ public static ObjectReferenceType createObjectRef(PrismReferenceValue prv) { return ort; } - public static ObjectReferenceType createObjectRefWithFullObject(ObjectType objectType) { + public static ObjectReferenceType createObjectRefWithFullObject(ObjectType objectType, PrismContext prismContext) { if (objectType == null) { return null; } - return createObjectRefWithFullObject(objectType.asPrismObject()); + return createObjectRefWithFullObject(objectType.asPrismObject(), prismContext); } - public static ObjectReferenceType createObjectRef(ObjectType objectType) { - return createObjectRef(objectType, SchemaConstants.ORG_DEFAULT); + public static ObjectReferenceType createObjectRef(ObjectType object, PrismContext prismContext) { + if (object == null) { + return null; + } + return createObjectRef(object, prismContext.getDefaultRelation()); } public static ObjectReferenceType createObjectRef(ObjectType objectType, QName relation) { @@ -294,8 +306,11 @@ public static ObjectReferenceType createObjectRef(ObjectType objectType, QName r return createObjectRef(objectType.asPrismObject(), relation); } - public static ObjectReferenceType createObjectRef(PrismObject object) { - return createObjectRef(object, SchemaConstants.ORG_DEFAULT); + public static ObjectReferenceType createObjectRef(PrismObject object, PrismContext prismContext) { + if (object == null) { + return null; + } + return createObjectRef(object, prismContext.getDefaultRelation()); } public static ObjectReferenceType createObjectRef(PrismObject object, QName relation) { @@ -313,11 +328,12 @@ public static ObjectReferenceType createObjectRef(PrismOb return ref; } - public static ObjectReferenceType createObjectRefWithFullObject(PrismObject object) { + public static ObjectReferenceType createObjectRefWithFullObject(PrismObject object, + PrismContext prismContext) { if (object == null) { return null; } - ObjectReferenceType ref = createObjectRef(object); + ObjectReferenceType ref = createObjectRef(object, prismContext); ref.asReferenceValue().setObject(object); return ref; } @@ -629,83 +645,48 @@ public static T getExtensionItemRealValue(@Nullable ExtensionType extension, return item != null ? (T) item.getRealValue() : null; } - @NotNull - public static QName normalizeRelation(QName name) { - if (name == null) { - return SchemaConstants.ORG_DEFAULT; - } else { - return QNameUtil.setNamespaceIfMissing(name, SchemaConstants.NS_ORG, SchemaConstants.PREFIX_NS_ORG); - } - } - - public static void normalizeRelation(ObjectReferenceType reference) { + public static void normalizeRelation(ObjectReferenceType reference, RelationRegistry relationRegistry) { if (reference != null) { - reference.setRelation(normalizeRelation(reference.getRelation())); + reference.setRelation(relationRegistry.normalizeRelation(reference.getRelation())); } } - public static void normalizeRelation(PrismReferenceValue reference) { + public static void normalizeRelation(PrismReferenceValue reference, RelationRegistry relationRegistry) { if (reference != null) { - reference.setRelation(normalizeRelation(reference.getRelation())); + reference.setRelation(relationRegistry.normalizeRelation(reference.getRelation())); } } - public static void normalizeAllRelations(PrismValue value) { + public static void normalizeAllRelations(PrismValue value, RelationRegistry relationRegistry) { if (value != null) { - value.accept(createNormalizingVisitor()); + value.accept(createNormalizingVisitor(relationRegistry)); } } - public static void normalizeAllRelations(Item item) { + public static void normalizeAllRelations(Item item, RelationRegistry relationRegistry) { if (item != null) { - item.accept(createNormalizingVisitor()); + item.accept(createNormalizingVisitor(relationRegistry)); } } - private static Visitor createNormalizingVisitor() { + private static Visitor createNormalizingVisitor(RelationRegistry relationRegistry) { return v -> { if (v instanceof PrismReferenceValue) { - normalizeRelation((PrismReferenceValue) v); + normalizeRelation((PrismReferenceValue) v, relationRegistry); } }; } - public static void normalizeFilter(ObjectFilter filter) { + public static void normalizeFilter(ObjectFilter filter, RelationRegistry relationRegistry) { if (filter != null) { filter.accept(f -> { if (f instanceof RefFilter) { - emptyIfNull(((RefFilter) f).getValues()).forEach(v -> normalizeRelation(v)); + emptyIfNull(((RefFilter) f).getValues()).forEach(v -> normalizeRelation(v, relationRegistry)); } }); } } - // This is not the right place for this. But let's leave it here for now. - // See MID-3581 - public static boolean isDelegationRelation(QName relation) { - return QNameUtil.match(relation, SchemaConstants.ORG_DEPUTY); - } - - // This is not the right place for this. But let's leave it here for now. - // See MID-3581 - public static boolean isMembershipRelation(QName relation) { - return isDefaultRelation(relation) - || isManagerRelation(relation) - || QNameUtil.match(relation, SchemaConstants.ORG_META); - } - - // This is not the right place for this. But let's leave it here for now. - // See MID-3581 - public static boolean isManagerRelation(QName relation) { - return QNameUtil.match(relation, SchemaConstants.ORG_MANAGER); - } - - // This is not the right place for this. But let's leave it here for now. - // See MID-3581 - public static boolean isDefaultRelation(QName relation) { - return relation == null || QNameUtil.match(relation, SchemaConstants.ORG_DEFAULT); - } - public static RelationDefinitionType findRelationDefinition(List relationDefinitions, QName qname) { for (RelationDefinitionType relation: relationDefinitions) { if (QNameUtil.match(qname, relation.getRef())) { @@ -715,33 +696,8 @@ public static RelationDefinitionType findRelationDefinition(List relationQuery, QName relation) { - return relationQuery.stream().anyMatch(rq -> relationMatches(rq, relation)); - } - - public static boolean relationsEquivalent(QName relation1, QName relation2) { - if (ObjectTypeUtil.isDefaultRelation(relation1)) { - return ObjectTypeUtil.isDefaultRelation(relation2); - } else { - return QNameUtil.match(relation1, relation2); - } - } - - public static boolean referenceMatches(ObjectReferenceType ref, String targetOid, QName targetType, QName relation) { + public static boolean referenceMatches(ObjectReferenceType ref, String targetOid, QName targetType, QName relation, + PrismContext prismContext) { if (ref == null) { return false; } @@ -756,7 +712,7 @@ public static boolean referenceMatches(ObjectReferenceType ref, String targetOid } } if (relation != null) { - if (!relationMatches(relation, ref.getRelation())) { + if (!prismContext.relationMatches(relation, ref.getRelation())) { return false; } } @@ -838,15 +794,6 @@ public static LocalizableMessage createTypeDisplayInformation(String objectClass .build(); } - @Nullable - public static String getRelationNameLocalizationKey(@Nullable QName relation, boolean defaultAsNull) { - if (relation == null || defaultAsNull && QNameUtil.match(relation, SchemaConstants.ORG_DEFAULT)) { - return null; - } else { - return SchemaConstants.RELATION_NAME_KEY_PREFIX + relation.getLocalPart(); - } - } - @NotNull @Deprecated public static Collection getSubtypeValues(@NotNull PrismObject object) { @@ -903,4 +850,24 @@ private static void addRealValue(Item extensionItem, extensionItem.add(PrismValue.fromRealValue(value).clone()); } } + + @NotNull + public static ObjectQuery createManagerQuery(Class objectTypeClass, String orgOid, + RelationRegistry relationRegistry, PrismContext prismContext) { + Collection managerRelations = relationRegistry.getAllRelationsFor(RelationKindType.MANAGER); + if (managerRelations.isEmpty()) { + LOGGER.warn("No manager relation is defined"); + return QueryBuilder.queryFor(objectTypeClass, prismContext).none().build(); + } + + List referencesToFind = new ArrayList<>(); + for (QName managerRelation : managerRelations) { + PrismReferenceValue parentOrgRefVal = new PrismReferenceValue(orgOid, OrgType.COMPLEX_TYPE); + parentOrgRefVal.setRelation(managerRelation); + referencesToFind.add(parentOrgRefVal); + } + return QueryBuilder.queryFor(objectTypeClass, prismContext) + .item(ObjectType.F_PARENT_ORG_REF).ref(referencesToFind) + .build(); + } } diff --git a/infra/schema/src/main/resources/xml/ns/public/common/common-core-3.xsd b/infra/schema/src/main/resources/xml/ns/public/common/common-core-3.xsd index a854df26278..49f58266f8f 100755 --- a/infra/schema/src/main/resources/xml/ns/public/common/common-core-3.xsd +++ b/infra/schema/src/main/resources/xml/ns/public/common/common-core-3.xsd @@ -16264,19 +16264,172 @@ + + + + If this relation is a default for a relation kind, specify the kind here. + + + 3.9 + RelationDefinitionType.defaultFor + + + + + + + Kind(s) of which this relation is. A value of "defaultFor", if present, is automatically considered + to be a kind for this relation, so it is not necessary to list it here. + + + 3.9 + RelationDefinitionType.kind + + + - + + + + + Denotes a set of relations serving a single purpose. + + Until midPoint 3.9, there were fixed relations denoting e.g. manager of an organization (org:manager) or an approver + of a role (org:approver). Starting with 3.9, relations are configurable, and each relation is characterized by its kind + or sometimes a set of kinds. + + So we can have e.g. three approver relations (e:securityApprover, e:technicalApprover, e:businessApprover), + a set of membership relations (org:default, e:assistant, e:external), etc. Note that here 'e' is a prefix for a custom + namespace used to define these custom (extension) relations. + + Each relation has 0, 1 or more kinds. For example, the default org:manager relation is of MANAGER and MEMBERSHIP kinds. + + For each kind, there should be a single relation marked as the default one. + + + 3.9 + + + + + + + Membership relation, usually meaning "has" or "is member of". + Used as a relation value in object references. + Specifies that the subject is a member of organization, or that the subject + has been assigned a role in a way that he gets authorizations and other content + provided by that role. + + Default relation of MEMBERSHIP kind is also considered to be the overall default relation (i.e. used when + ref.relation is null). + + + + + + + + + + Relations of "is manager of" kind. Specifies that the subject is a manager of organizational unit. + Relations of this kind are usually also of MEMBERSHIP kind. + + + + + + + + + + Relations used for metarole assignments. Sometimes it is important to + distinguish metarole and member assignments. This kind of relation is used + for that purpose. + + Relations of this kind should be also of MEMBERSHIP kind. + (Otherwise they would not provide metarole assignment functionality!) + + + + + + + + + + Relation of "is deputy of" kind. Specifies that the subject is a deputy of another user. + + + + + + + + + + Relation "is approver of" kind. + + Specifies that the subject is a (general) approver of specified (abstract) role. + The approver will be asked for decision if the role is assigned, if there is + a rule conflict during assignment (e.g. SoD conflict) or if there is any similar + situation. + + This is a generic approver used for all the situation. The system may be customized + with more specific approver roles, e.g. technicalApprover, securityApprover, etc. + + This approver is responsible for the use of the role, which mostly means + that he decides about role assignment. It is NOT meant to approve role changes. + Role owner is meant for that purpose. + + + + + + + + + + Relation of "is owner of" kind. + + Specifies that the subject is a (business) owner of specified (abstract) role. + The owner will be asked for decision if the role is modified, when the associated + policy changes and so on. + + This owner is responsible for maintaining role definition and policies. It is + NOT necessarily concerned with role use (e.g. assignment). The approver relation kind + is meant for that purpose. + + + + + + + + + + Relation "is consent for" kind. + + Specifies that the subject gave a consent for using personnel information related to this role. + + + + + + + + + Specifies category or "area" of a particular concept. Such category can be used to display the concepts in appropriate parts of user interface. For example the category may be used to display only governance-related relations in the governance - UI spanels. + UI panels. 3.9 diff --git a/infra/schema/src/main/resources/xml/ns/public/resource/capabilities-3.xsd b/infra/schema/src/main/resources/xml/ns/public/resource/capabilities-3.xsd index 1a59a093334..ea7ab029782 100644 --- a/infra/schema/src/main/resources/xml/ns/public/resource/capabilities-3.xsd +++ b/infra/schema/src/main/resources/xml/ns/public/resource/capabilities-3.xsd @@ -1,6 +1,6 @@ + + + + + + + diff --git a/infra/schema/src/test/java/com/evolveum/midpoint/schema/TestParseDiffPatch.java b/infra/schema/src/test/java/com/evolveum/midpoint/schema/TestParseDiffPatch.java index f3b6d074786..32d3a8e905e 100644 --- a/infra/schema/src/test/java/com/evolveum/midpoint/schema/TestParseDiffPatch.java +++ b/infra/schema/src/test/java/com/evolveum/midpoint/schema/TestParseDiffPatch.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010-2017 Evolveum + * Copyright (c) 2010-2018 Evolveum * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -903,7 +903,7 @@ public void testCampaign() throws SchemaException, SAXException, IOException, JA triggerToDelete.setHandlerUri("http://midpoint.evolveum.com/xml/ns/public/certification/trigger/close-stage/handler-3"); @SuppressWarnings({"unchecked", "raw"}) - ObjectDelta delta = (ObjectDelta) + ObjectDelta delta = DeltaBuilder.deltaFor(AccessCertificationCampaignType.class, getPrismContext()) .item(AccessCertificationCampaignType.F_TRIGGER).delete(triggerToDelete) .asObjectDelta(campaign.getOid()); diff --git a/infra/test-util/pom.xml b/infra/test-util/pom.xml index 349b1dbfd74..d56e6bc2a84 100644 --- a/infra/test-util/pom.xml +++ b/infra/test-util/pom.xml @@ -71,6 +71,14 @@ org.springframework spring-core + + org.springframework + spring-beans + + + org.springframework + spring-context + org.apache.felix org.osgi.core diff --git a/infra/test-util/src/main/java/com/evolveum/midpoint/test/util/MidPointAsserts.java b/infra/test-util/src/main/java/com/evolveum/midpoint/test/util/MidPointAsserts.java index 0a4c2f901fc..5d5f88be90f 100644 --- a/infra/test-util/src/main/java/com/evolveum/midpoint/test/util/MidPointAsserts.java +++ b/infra/test-util/src/main/java/com/evolveum/midpoint/test/util/MidPointAsserts.java @@ -25,6 +25,7 @@ import javax.xml.namespace.QName; +import com.evolveum.midpoint.prism.PrismContext; import com.evolveum.midpoint.schema.util.ObjectTypeUtil; import com.evolveum.midpoint.util.QNameUtil; @@ -73,7 +74,7 @@ public static void assertAssigned(PrismObject focus, String if (targetRef != null) { if (refType.equals(targetRef.getType())) { if (targetOid.equals(targetRef.getOid()) && - MiscSchemaUtil.compareRelation(targetRef.getRelation(), relation)) { + getPrismContext().relationMatches(targetRef.getRelation(), relation)) { return; } } @@ -233,7 +234,7 @@ public static void assertNotAssignedOrg(PrismObject use ObjectReferenceType targetRef = assignmentType.getTargetRef(); if (targetRef != null) { if (OrgType.COMPLEX_TYPE.equals(targetRef.getType())) { - if (orgOid.equals(targetRef.getOid()) && ObjectTypeUtil.relationMatches(relation, targetRef.getRelation())) { + if (orgOid.equals(targetRef.getOid()) && getPrismContext().relationMatches(relation, targetRef.getRelation())) { AssertJUnit.fail(user + " does have assigned OrgType "+orgOid+" with relation "+relation+" while not expecting it"); } } @@ -265,7 +266,7 @@ public static void assertHasOrg(PrismObject object, St public static boolean hasOrg(PrismObject user, String orgOid, QName relation) { for (ObjectReferenceType orgRef: user.asObjectable().getParentOrgRef()) { if (orgOid.equals(orgRef.getOid()) && - MiscSchemaUtil.compareRelation(relation, orgRef.getRelation())) { + getPrismContext().relationMatches(relation, orgRef.getRelation())) { return true; } } @@ -347,4 +348,8 @@ public static void assertInstanceOf(String message, Object object, Class expe assertTrue(message+" is not instance of "+expectedClass+", it is "+object.getClass(), expectedClass.isAssignableFrom(object.getClass())); } + + private static PrismContext getPrismContext() { + return TestSpringContextHolder.getPrismContext(); + } } diff --git a/infra/test-util/src/main/java/com/evolveum/midpoint/test/util/TestSpringContextHolder.java b/infra/test-util/src/main/java/com/evolveum/midpoint/test/util/TestSpringContextHolder.java new file mode 100644 index 00000000000..03d0086642a --- /dev/null +++ b/infra/test-util/src/main/java/com/evolveum/midpoint/test/util/TestSpringContextHolder.java @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2010-2018 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. + */ + +package com.evolveum.midpoint.test.util; + +import com.evolveum.midpoint.prism.PrismContext; +import org.springframework.beans.BeansException; +import org.springframework.context.ApplicationContext; +import org.springframework.context.ApplicationContextAware; +import org.springframework.stereotype.Component; + +/** + * To be used in tests only. Mainly for access PrismContext from static assertion methods. + */ + +@Component +public class TestSpringContextHolder implements ApplicationContextAware { + + private static ApplicationContext context; + + public void setApplicationContext(ApplicationContext ctx) throws BeansException { + context = ctx; + } + + @SuppressWarnings("WeakerAccess") + public static ApplicationContext getApplicationContext() { + if (context == null) { + throw new IllegalStateException("Spring application context could not be determined."); + } + return context; + } + + @SuppressWarnings("SameParameterValue") + private static T getBean(Class aClass) { + String className = aClass.getSimpleName(); + String beanName = Character.toLowerCase(className.charAt(0)) + className.substring(1); + return getBean(beanName, aClass); + } + + private static T getBean(String name, Class aClass) { + T bean = getApplicationContext().getBean(name, aClass); + if (bean == null) { + throw new IllegalStateException("Could not find " + name + " bean"); + } + return bean; + } + + public static PrismContext getPrismContext() { + return getBean(PrismContext.class); + } +} diff --git a/infra/util/src/main/java/com/evolveum/midpoint/util/QNameUtil.java b/infra/util/src/main/java/com/evolveum/midpoint/util/QNameUtil.java index 167e9407e96..06a72fcba05 100644 --- a/infra/util/src/main/java/com/evolveum/midpoint/util/QNameUtil.java +++ b/infra/util/src/main/java/com/evolveum/midpoint/util/QNameUtil.java @@ -293,8 +293,12 @@ public static QName nullNamespace(QName qname) { return new QName(null, qname.getLocalPart(), qname.getPrefix()); } - public static boolean isUnqualified(QName targetTypeQName) { - return StringUtils.isBlank(targetTypeQName.getNamespaceURI()); + public static boolean isUnqualified(QName name) { + return StringUtils.isBlank(name.getNamespaceURI()); + } + + public static boolean isQualified(QName name) { + return !isUnqualified(name); } public static boolean isTolerateUndeclaredPrefixes() { diff --git a/model/certification-impl/src/main/java/com/evolveum/midpoint/certification/impl/AccCertCaseOperationsHelper.java b/model/certification-impl/src/main/java/com/evolveum/midpoint/certification/impl/AccCertCaseOperationsHelper.java index ec4a06ea1f6..8741be8500c 100644 --- a/model/certification-impl/src/main/java/com/evolveum/midpoint/certification/impl/AccCertCaseOperationsHelper.java +++ b/model/certification-impl/src/main/java/com/evolveum/midpoint/certification/impl/AccCertCaseOperationsHelper.java @@ -43,7 +43,6 @@ import com.evolveum.midpoint.util.logging.Trace; import com.evolveum.midpoint.util.logging.TraceManager; import com.evolveum.midpoint.xml.ns._public.common.common_3.*; -import org.apache.commons.lang.ObjectUtils; import org.jetbrains.annotations.NotNull; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @@ -99,7 +98,7 @@ void recordDecision(String campaignOid, long caseId, long workItemId, AccessCert throw new ObjectNotFoundException("Work item " + workItemId + " was not found in campaign " + toShortString(campaign) + ", case " + caseId); } - ObjectReferenceType responderRef = ObjectTypeUtil.createObjectRef(securityContextManager.getPrincipal().getUser()); + ObjectReferenceType responderRef = ObjectTypeUtil.createObjectRef(securityContextManager.getPrincipal().getUser(), prismContext); XMLGregorianCalendar now = clock.currentTimeXMLGregorianCalendar(); ItemPath workItemPath = new ItemPath(F_CASE, caseId, F_WORK_ITEM, workItemId); Collection> deltaList = DeltaBuilder.deltaFor(AccessCertificationCampaignType.class, prismContext) @@ -146,8 +145,8 @@ void delegateWorkItems(String campaignOid, List MidPointPrincipal principal = securityContextManager.getPrincipal(); result.addContext("user", toShortString(principal.getUser())); - ObjectReferenceType initiator = ObjectTypeUtil.createObjectRef(principal.getUser()); - ObjectReferenceType attorney = ObjectTypeUtil.createObjectRef(principal.getAttorney()); + ObjectReferenceType initiator = ObjectTypeUtil.createObjectRef(principal.getUser(), prismContext); + ObjectReferenceType attorney = ObjectTypeUtil.createObjectRef(principal.getAttorney(), prismContext); XMLGregorianCalendar now = clock.currentTimeXMLGregorianCalendar(); List> deltas = new ArrayList<>(); @@ -212,8 +211,8 @@ public void escalateCampaign(String campaignOid, EscalateWorkItemActionType esca throws SchemaException, ObjectNotFoundException, ObjectAlreadyExistsException, SecurityViolationException { MidPointPrincipal principal = securityContextManager.getPrincipal(); result.addContext("user", toShortString(principal.getUser())); - ObjectReferenceType initiator = ObjectTypeUtil.createObjectRef(principal.getUser()); - ObjectReferenceType attorney = ObjectTypeUtil.createObjectRef(principal.getAttorney()); + ObjectReferenceType initiator = ObjectTypeUtil.createObjectRef(principal.getUser(), prismContext); + ObjectReferenceType attorney = ObjectTypeUtil.createObjectRef(principal.getAttorney(), prismContext); List workItems = queryHelper.searchOpenWorkItems( CertCampaignTypeUtil.createWorkItemsForCampaignQuery(campaignOid, prismContext), diff --git a/model/certification-impl/src/main/java/com/evolveum/midpoint/certification/impl/AccCertOpenerHelper.java b/model/certification-impl/src/main/java/com/evolveum/midpoint/certification/impl/AccCertOpenerHelper.java index c108d60f292..5748eba613c 100644 --- a/model/certification-impl/src/main/java/com/evolveum/midpoint/certification/impl/AccCertOpenerHelper.java +++ b/model/certification-impl/src/main/java/com/evolveum/midpoint/certification/impl/AccCertOpenerHelper.java @@ -124,7 +124,7 @@ private AccessCertificationCampaignType createCampaignObject(AccessCertification newCampaign.setDescription(definition.getDescription()); newCampaign.setOwnerRef(securityContextManager.getPrincipal().toObjectReference()); newCampaign.setTenantRef(definition.getTenantRef()); - newCampaign.setDefinitionRef(ObjectTypeUtil.createObjectRef(definition)); + newCampaign.setDefinitionRef(ObjectTypeUtil.createObjectRef(definition, prismContext)); if (definition.getHandlerUri() != null) { newCampaign.setHandlerUri(definition.getHandlerUri()); diff --git a/model/certification-impl/src/main/java/com/evolveum/midpoint/certification/impl/AccCertQueryHelper.java b/model/certification-impl/src/main/java/com/evolveum/midpoint/certification/impl/AccCertQueryHelper.java index d4dadbe6a9c..084b7c5deea 100644 --- a/model/certification-impl/src/main/java/com/evolveum/midpoint/certification/impl/AccCertQueryHelper.java +++ b/model/certification-impl/src/main/java/com/evolveum/midpoint/certification/impl/AccCertQueryHelper.java @@ -24,6 +24,7 @@ import com.evolveum.midpoint.prism.query.builder.QueryBuilder; import com.evolveum.midpoint.repo.api.RepositoryService; import com.evolveum.midpoint.schema.GetOperationOptions; +import com.evolveum.midpoint.schema.RelationRegistry; import com.evolveum.midpoint.schema.SelectorOptions; import com.evolveum.midpoint.schema.constants.SchemaConstants; import com.evolveum.midpoint.schema.result.OperationResult; @@ -54,6 +55,7 @@ public class AccCertQueryHelper { private static final transient Trace LOGGER = TraceManager.getTrace(AccCertQueryHelper.class); @Autowired private PrismContext prismContext; + @Autowired private RelationRegistry relationRegistry; @Autowired protected AccCertGeneralHelper helper; @Autowired @Qualifier("cacheRepositoryService") private RepositoryService repositoryService; @@ -138,7 +140,8 @@ private ObjectFilter getReviewerAndEnabledFilterForWI(MidPointPrincipal principa return QueryUtils.filterForAssignees( QueryBuilder.queryFor(AccessCertificationWorkItemType.class, prismContext), principal, - OtherPrivilegesLimitationType.F_CERTIFICATION_WORK_ITEMS) + OtherPrivilegesLimitationType.F_CERTIFICATION_WORK_ITEMS, + relationRegistry) .and().item(F_CLOSE_TIMESTAMP).isNull() .buildFilter(); } else { diff --git a/model/certification-impl/src/main/java/com/evolveum/midpoint/certification/impl/AccCertReviewersHelper.java b/model/certification-impl/src/main/java/com/evolveum/midpoint/certification/impl/AccCertReviewersHelper.java index 0965c35a758..009bd8e332e 100644 --- a/model/certification-impl/src/main/java/com/evolveum/midpoint/certification/impl/AccCertReviewersHelper.java +++ b/model/certification-impl/src/main/java/com/evolveum/midpoint/certification/impl/AccCertReviewersHelper.java @@ -26,10 +26,11 @@ import com.evolveum.midpoint.prism.query.ObjectQuery; import com.evolveum.midpoint.prism.query.builder.QueryBuilder; import com.evolveum.midpoint.repo.api.RepositoryService; +import com.evolveum.midpoint.schema.RelationRegistry; import com.evolveum.midpoint.schema.constants.ExpressionConstants; -import com.evolveum.midpoint.schema.constants.SchemaConstants; import com.evolveum.midpoint.schema.result.OperationResult; import com.evolveum.midpoint.schema.util.CertCampaignTypeUtil; +import com.evolveum.midpoint.schema.util.ObjectQueryUtil; import com.evolveum.midpoint.schema.util.ObjectTypeUtil; import com.evolveum.midpoint.schema.util.ResourceTypeUtil; import com.evolveum.midpoint.task.api.Task; @@ -62,6 +63,7 @@ public class AccCertReviewersHelper { @Autowired private OrgStructFunctions orgStructFunctions; @Autowired private PrismContext prismContext; @Autowired private AccCertExpressionHelper expressionHelper; + @Autowired private RelationRegistry relationRegistry; AccessCertificationReviewerSpecificationType findReviewersSpecification(AccessCertificationCampaignType campaign, int stage) { AccessCertificationStageDefinitionType stageDef = CertCampaignTypeUtil.findStageDefinition(campaign, stage); @@ -130,11 +132,15 @@ private void resolveRoleReviewers(List reviewers, Operation private List getMembers(ObjectReferenceType abstractRoleRef, OperationResult result) throws SchemaException { - ObjectQuery query = QueryBuilder.queryFor(UserType.class, prismContext) - .item(UserType.F_ROLE_MEMBERSHIP_REF).ref(abstractRoleRef.getOid()) - .build(); + Collection references = ObjectQueryUtil + .createReferences(abstractRoleRef.getOid(), RelationKindType.MEMBERSHIP, relationRegistry); + ObjectQuery query = references.isEmpty() + ? QueryBuilder.queryFor(UserType.class, prismContext).none().build() + : QueryBuilder.queryFor(UserType.class, prismContext) + .item(UserType.F_ROLE_MEMBERSHIP_REF).ref(references) + .build(); return repositoryService.searchObjects(UserType.class, query, null, result).stream() - .map(obj -> ObjectTypeUtil.createObjectRef(obj)) + .map(obj -> ObjectTypeUtil.createObjectRef(obj, prismContext)) .collect(Collectors.toList()); } @@ -183,7 +189,7 @@ private Collection getObjectManagers(AccessCertificationCas } List retval = new ArrayList<>(managers.size()); for (UserType manager : managers) { - retval.add(ObjectTypeUtil.createObjectRef(manager)); + retval.add(ObjectTypeUtil.createObjectRef(manager, prismContext)); } return retval; } catch (SecurityViolationException e) { @@ -201,7 +207,7 @@ private List getTargetObjectOwners(AccessCertificationCaseT } ObjectType target = resolveReference(_case.getTargetRef(), ObjectType.class, result); if (target instanceof AbstractRoleType) { - return getAssignees((AbstractRoleType) target, SchemaConstants.ORG_OWNER, result); + return getAssignees((AbstractRoleType) target, RelationKindType.OWNER, result); } else if (target instanceof ResourceType) { return ResourceTypeUtil.getOwnerRef((ResourceType) target); } else { @@ -209,25 +215,29 @@ private List getTargetObjectOwners(AccessCertificationCaseT } } - private List getAssignees(AbstractRoleType role, QName relation, OperationResult result) + private List getAssignees(AbstractRoleType role, RelationKindType relationKind, OperationResult result) throws SchemaException { List rv = new ArrayList<>(); - if (SchemaConstants.ORG_OWNER.equals(relation)) { + if (relationKind == RelationKindType.OWNER) { CollectionUtils.addIgnoreNull(rv, role.getOwnerRef()); - } else if (SchemaConstants.ORG_APPROVER.equals(relation)) { + } else if (relationKind == RelationKindType.APPROVER) { rv.addAll(role.getApproverRef()); } else { - throw new AssertionError(relation); + throw new AssertionError(relationKind); } // TODO in theory, we could look for approvers/owners of UserType, right? - PrismReferenceValue ref = new PrismReferenceValue(role.getOid()); - ref.setRelation(relation); + Collection values = new ArrayList<>(); + for (QName relation : relationRegistry.getAllRelationsFor(relationKind)) { + PrismReferenceValue ref = new PrismReferenceValue(role.getOid()); + ref.setRelation(relation); + values.add(ref); + } ObjectQuery query = QueryBuilder.queryFor(FocusType.class, prismContext) - .item(FocusType.F_ROLE_MEMBERSHIP_REF).ref(ref) + .item(FocusType.F_ROLE_MEMBERSHIP_REF).ref(values) .build(); List> assignees = repositoryService.searchObjects(FocusType.class, query, null, result); - LOGGER.trace("Looking for '{}' of {} using {}: found: {}", relation.getLocalPart(), role, query, assignees); - assignees.forEach(o -> rv.add(ObjectTypeUtil.createObjectRef(o))); + LOGGER.trace("Looking for '{}' of {} using {}: found: {}", relationKind, role, query, assignees); + assignees.forEach(o -> rv.add(ObjectTypeUtil.createObjectRef(o, prismContext))); return rv; } @@ -238,7 +248,7 @@ private List getObjectOwners(AccessCertificationCaseType _c } ObjectType object = resolveReference(_case.getObjectRef(), ObjectType.class, result); if (object instanceof AbstractRoleType) { - return getAssignees((AbstractRoleType) object, SchemaConstants.ORG_OWNER, result); + return getAssignees((AbstractRoleType) object, RelationKindType.OWNER, result); } else { return null; } @@ -251,7 +261,7 @@ private Collection getTargetObjectApprovers(AccessCertifica } ObjectType target = resolveReference(_case.getTargetRef(), ObjectType.class, result); if (target instanceof AbstractRoleType) { - return getAssignees((AbstractRoleType) target, SchemaConstants.ORG_APPROVER, result); + return getAssignees((AbstractRoleType) target, RelationKindType.APPROVER, result); } else if (target instanceof ResourceType) { return ResourceTypeUtil.getApproverRef((ResourceType) target); } else { @@ -266,7 +276,7 @@ private Collection getObjectApprovers(AccessCertificationCa } ObjectType object = resolveReference(_case.getObjectRef(), ObjectType.class, result); if (object instanceof AbstractRoleType) { - return getAssignees((AbstractRoleType) object, SchemaConstants.ORG_APPROVER, result); + return getAssignees((AbstractRoleType) object, RelationKindType.APPROVER, result); } else { return null; } diff --git a/model/certification-impl/src/main/java/com/evolveum/midpoint/certification/impl/AccessCertificationClosingTaskHandler.java b/model/certification-impl/src/main/java/com/evolveum/midpoint/certification/impl/AccessCertificationClosingTaskHandler.java index 02b83d79ccb..f6dc9857849 100644 --- a/model/certification-impl/src/main/java/com/evolveum/midpoint/certification/impl/AccessCertificationClosingTaskHandler.java +++ b/model/certification-impl/src/main/java/com/evolveum/midpoint/certification/impl/AccessCertificationClosingTaskHandler.java @@ -265,7 +265,7 @@ public void launch(AccessCertificationCampaignType campaign, OperationResult par Task task = taskManager.createTaskInstance(); task.setHandlerUri(HANDLER_URI); task.setName(new PolyStringType("Closing " + campaign.getName())); - task.setObjectRef(ObjectTypeUtil.createObjectRef(campaign)); + task.setObjectRef(ObjectTypeUtil.createObjectRef(campaign, prismContext)); task.setOwner(repositoryService.getObject(UserType.class, SystemObjectsType.USER_ADMINISTRATOR.value(), null, result)); taskManager.switchToBackground(task, result); result.setBackgroundTaskOid(task.getOid()); diff --git a/model/certification-impl/src/main/java/com/evolveum/midpoint/certification/impl/AccessCertificationRemediationTaskHandler.java b/model/certification-impl/src/main/java/com/evolveum/midpoint/certification/impl/AccessCertificationRemediationTaskHandler.java index 44a91caf2bf..e8d5e21969b 100644 --- a/model/certification-impl/src/main/java/com/evolveum/midpoint/certification/impl/AccessCertificationRemediationTaskHandler.java +++ b/model/certification-impl/src/main/java/com/evolveum/midpoint/certification/impl/AccessCertificationRemediationTaskHandler.java @@ -17,6 +17,7 @@ import com.evolveum.midpoint.certification.api.OutcomeUtils; import com.evolveum.midpoint.certification.impl.handlers.CertificationHandler; +import com.evolveum.midpoint.prism.PrismContext; import com.evolveum.midpoint.repo.api.RepositoryService; import com.evolveum.midpoint.schema.constants.SchemaConstants; import com.evolveum.midpoint.schema.result.OperationResult; @@ -63,6 +64,7 @@ public class AccessCertificationRemediationTaskHandler implements TaskHandler { @Autowired private AccCertGeneralHelper helper; @Autowired private AccCertCaseOperationsHelper caseHelper; @Autowired private AccCertQueryHelper queryHelper; + @Autowired private PrismContext prismContext; @Autowired @Qualifier("cacheRepositoryService") private RepositoryService repositoryService; private static final transient Trace LOGGER = TraceManager.getTrace(AccessCertificationRemediationTaskHandler.class); @@ -188,7 +190,7 @@ public void launch(AccessCertificationCampaignType campaign, OperationResult par task.setName(polyString); // Set reference to the resource - task.setObjectRef(ObjectTypeUtil.createObjectRef(campaign)); + task.setObjectRef(ObjectTypeUtil.createObjectRef(campaign, prismContext)); task.setOwner(repositoryService.getObject(UserType.class, SystemObjectsType.USER_ADMINISTRATOR.value(), null, result)); diff --git a/model/certification-impl/src/main/java/com/evolveum/midpoint/certification/impl/handlers/DirectAssignmentCertificationHandler.java b/model/certification-impl/src/main/java/com/evolveum/midpoint/certification/impl/handlers/DirectAssignmentCertificationHandler.java index 22f3d549a64..2cf11b01747 100644 --- a/model/certification-impl/src/main/java/com/evolveum/midpoint/certification/impl/handlers/DirectAssignmentCertificationHandler.java +++ b/model/certification-impl/src/main/java/com/evolveum/midpoint/certification/impl/handlers/DirectAssignmentCertificationHandler.java @@ -20,7 +20,6 @@ import com.evolveum.midpoint.repo.common.expression.ExpressionVariables; import com.evolveum.midpoint.prism.PrismObject; import com.evolveum.midpoint.schema.constants.ExpressionConstants; -import com.evolveum.midpoint.schema.constants.SchemaConstants; import com.evolveum.midpoint.schema.result.OperationResult; import com.evolveum.midpoint.schema.util.ActivationUtil; import com.evolveum.midpoint.schema.util.ObjectTypeUtil; @@ -33,8 +32,6 @@ 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.*; import org.springframework.stereotype.Component; @@ -96,7 +93,7 @@ private void processAssignment(AssignmentType assignment, boolean isInducement, AccessCertificationAssignmentCaseType assignmentCase = new AccessCertificationAssignmentCaseType(prismContext); assignmentCase.setAssignment(assignment.clone()); assignmentCase.setIsInducement(isInducement); - assignmentCase.setObjectRef(ObjectTypeUtil.createObjectRef(object)); + assignmentCase.setObjectRef(ObjectTypeUtil.createObjectRef(object, prismContext)); assignmentCase.setTenantRef(assignment.getTenantRef()); assignmentCase.setOrgRef(assignment.getOrgRef()); assignmentCase.setActivation(assignment.getActivation()); @@ -129,8 +126,8 @@ private void processAssignment(AssignmentType assignment, boolean isInducement, } private boolean relationMatches(QName assignmentRelation, List scopeRelations) { - return (!scopeRelations.isEmpty() ? scopeRelations : Collections.singletonList(SchemaConstants.ORG_DEFAULT)) - .stream().anyMatch(r -> ObjectTypeUtil.relationMatches(r, assignmentRelation)); + return (!scopeRelations.isEmpty() ? scopeRelations : Collections.singletonList(prismContext.getDefaultRelation())) + .stream().anyMatch(r -> prismContext.relationMatches(r, assignmentRelation)); } @SuppressWarnings("unused") diff --git a/model/certification-impl/src/main/java/com/evolveum/midpoint/certification/impl/handlers/ExclusionCertificationHandler.java b/model/certification-impl/src/main/java/com/evolveum/midpoint/certification/impl/handlers/ExclusionCertificationHandler.java index c7e9bd9912c..ed08749b8c0 100644 --- a/model/certification-impl/src/main/java/com/evolveum/midpoint/certification/impl/handlers/ExclusionCertificationHandler.java +++ b/model/certification-impl/src/main/java/com/evolveum/midpoint/certification/impl/handlers/ExclusionCertificationHandler.java @@ -23,8 +23,6 @@ import com.evolveum.midpoint.schema.util.ObjectTypeUtil; import com.evolveum.midpoint.task.api.Task; import com.evolveum.midpoint.util.exception.*; -import com.evolveum.midpoint.util.logging.Trace; -import com.evolveum.midpoint.util.logging.TraceManager; import com.evolveum.midpoint.xml.ns._public.common.common_3.*; import org.springframework.stereotype.Component; @@ -71,7 +69,7 @@ public Collection c private void processAssignment(AssignmentType assignment, ObjectType object, List caseList) { AccessCertificationAssignmentCaseType assignmentCase = new AccessCertificationAssignmentCaseType(prismContext); assignmentCase.setAssignment(assignment.clone()); - assignmentCase.setObjectRef(ObjectTypeUtil.createObjectRef(object)); + assignmentCase.setObjectRef(ObjectTypeUtil.createObjectRef(object, prismContext)); assignmentCase.setTenantRef(assignment.getTenantRef()); assignmentCase.setOrgRef(assignment.getOrgRef()); assignmentCase.setActivation(assignment.getActivation()); diff --git a/model/certification-impl/src/test/java/com/evolveum/midpoint/certification/test/AbstractCertificationTest.java b/model/certification-impl/src/test/java/com/evolveum/midpoint/certification/test/AbstractCertificationTest.java index d3ab42e95e3..beec289fd23 100644 --- a/model/certification-impl/src/test/java/com/evolveum/midpoint/certification/test/AbstractCertificationTest.java +++ b/model/certification-impl/src/test/java/com/evolveum/midpoint/certification/test/AbstractCertificationTest.java @@ -423,7 +423,7 @@ protected void assertDefinitionAndOwner(AccessCertificationCampaignType campaign AccessCertificationDefinitionType certificationDefinition, String expectedOwnerOid) { assertRefEquals("Unexpected ownerRef", ObjectTypeUtil.createObjectRef(expectedOwnerOid, ObjectTypes.USER), campaign.getOwnerRef()); assertRefEquals("Unexpected definitionRef", - ObjectTypeUtil.createObjectRef(certificationDefinition), + ObjectTypeUtil.createObjectRef(certificationDefinition, prismContext), campaign.getDefinitionRef()); } diff --git a/model/certification-impl/src/test/java/com/evolveum/midpoint/certification/test/TestAdHocCertification.java b/model/certification-impl/src/test/java/com/evolveum/midpoint/certification/test/TestAdHocCertification.java index e1c018cd1d8..a9ace748634 100644 --- a/model/certification-impl/src/test/java/com/evolveum/midpoint/certification/test/TestAdHocCertification.java +++ b/model/certification-impl/src/test/java/com/evolveum/midpoint/certification/test/TestAdHocCertification.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010-2017 Evolveum + * Copyright (c) 2010-2018 Evolveum * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -115,7 +115,7 @@ public void test020ModifyIndigo() throws Exception { // WHEN TestUtil.displayWhen(TEST_NAME); @SuppressWarnings({ "unchecked", "raw" }) - ObjectDelta delta = (ObjectDelta) DeltaBuilder.deltaFor(UserType.class, prismContext) + ObjectDelta delta = DeltaBuilder.deltaFor(UserType.class, prismContext) .item(UserType.F_DESCRIPTION).replace("new description") .item(UserType.F_ACTIVATION, ActivationType.F_ADMINISTRATIVE_STATUS).replace(ActivationStatusType.DISABLED) .asObjectDelta(USER_INDIGO_OID); 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 24526675307..68dac4125de 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 @@ -353,7 +353,7 @@ ExecuteCredentialResetResponseType executeCredentialsReset(PrismObject void refreshPrincipal(String oid) throws ObjectNotFoundException, SchemaException, CommunicationException, ConfigurationException, SecurityViolationException, ExpressionEvaluationException; - List getRelationDefinitions(OperationResult parentResult) throws ObjectNotFoundException, SchemaException; + List getRelationDefinitions(); @NotNull TaskType submitTaskFromTemplate(String templateTaskOid, List> extensionItems, Task opTask, OperationResult result) diff --git a/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluatedAssignment.java b/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluatedAssignment.java index 48df4df62b0..552d9b70b22 100644 --- a/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluatedAssignment.java +++ b/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluatedAssignment.java @@ -22,6 +22,7 @@ import com.evolveum.midpoint.common.LocalizationService; import com.evolveum.midpoint.prism.PrismObject; import com.evolveum.midpoint.prism.delta.DeltaSetTriple; +import com.evolveum.midpoint.schema.RelationRegistry; import com.evolveum.midpoint.schema.result.OperationResult; import com.evolveum.midpoint.security.api.Authorization; import com.evolveum.midpoint.task.api.Task; @@ -52,8 +53,11 @@ public interface EvaluatedAssignment extends DebugDumpable AssignmentType getAssignmentType(boolean old); + // return value of null is ambiguous: either targetRef is null or targetRef.relation is null QName getRelation(); + QName getNormalizedRelation(RelationRegistry relationRegistry); + boolean isValid(); boolean isPresentInCurrentObject(); diff --git a/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluatedAssignmentTarget.java b/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluatedAssignmentTarget.java index d09d7d03c05..4048c02a61a 100644 --- a/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluatedAssignmentTarget.java +++ b/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluatedAssignmentTarget.java @@ -16,6 +16,7 @@ package com.evolveum.midpoint.model.api.context; import com.evolveum.midpoint.prism.PrismObject; +import com.evolveum.midpoint.schema.RelationRegistry; import com.evolveum.midpoint.util.DebugDumpable; import com.evolveum.midpoint.xml.ns._public.common.common_3.AssignmentType; import com.evolveum.midpoint.xml.ns._public.common.common_3.FocusType; @@ -38,7 +39,7 @@ public interface EvaluatedAssignmentTarget extends DebugDumpable { // if this target applies to focus (by direct assignment or by some inducement) // accepts all relations // TODO clarify this - boolean appliesToFocusWithAnyRelation(); + boolean appliesToFocusWithAnyRelation(RelationRegistry relationRegistry); /** * True for roles whose constructions are evaluated - i.e. those roles that are considered to be applied diff --git a/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluatedCompositeTrigger.java b/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluatedCompositeTrigger.java index 6c3551d5d31..05c8fb2d44a 100644 --- a/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluatedCompositeTrigger.java +++ b/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluatedCompositeTrigger.java @@ -16,6 +16,7 @@ package com.evolveum.midpoint.model.api.context; +import com.evolveum.midpoint.prism.PrismContext; import com.evolveum.midpoint.util.DebugUtil; import com.evolveum.midpoint.util.LocalizableMessage; import com.evolveum.midpoint.xml.ns._public.common.common_3.EvaluatedLogicalTriggerType; @@ -77,11 +78,12 @@ protected void debugDumpSpecific(StringBuilder sb, int indent) { } @Override - public EvaluatedLogicalTriggerType toEvaluatedPolicyRuleTriggerType(PolicyRuleExternalizationOptions options) { + public EvaluatedLogicalTriggerType toEvaluatedPolicyRuleTriggerType(PolicyRuleExternalizationOptions options, + PrismContext prismContext) { EvaluatedLogicalTriggerType rv = new EvaluatedLogicalTriggerType(); fillCommonContent(rv); if (!options.isRespectFinalFlag() || !isFinal()) { - innerTriggers.forEach(t -> rv.getEmbedded().add(t.toEvaluatedPolicyRuleTriggerType(options))); + innerTriggers.forEach(t -> rv.getEmbedded().add(t.toEvaluatedPolicyRuleTriggerType(options, prismContext))); } return rv; } diff --git a/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluatedExclusionTrigger.java b/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluatedExclusionTrigger.java index 8fee04be27c..da4c1a7e875 100644 --- a/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluatedExclusionTrigger.java +++ b/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluatedExclusionTrigger.java @@ -16,6 +16,7 @@ package com.evolveum.midpoint.model.api.context; +import com.evolveum.midpoint.prism.PrismContext; import com.evolveum.midpoint.schema.util.ObjectTypeUtil; import com.evolveum.midpoint.util.DebugUtil; import com.evolveum.midpoint.util.LocalizableMessage; @@ -90,11 +91,12 @@ protected void debugDumpSpecific(StringBuilder sb, int indent) { } @Override - public EvaluatedExclusionTriggerType toEvaluatedPolicyRuleTriggerType(PolicyRuleExternalizationOptions options) { + public EvaluatedExclusionTriggerType toEvaluatedPolicyRuleTriggerType(PolicyRuleExternalizationOptions options, + PrismContext prismContext) { EvaluatedExclusionTriggerType rv = new EvaluatedExclusionTriggerType(); fillCommonContent(rv); if (options.getTriggeredRulesStorageStrategy() == FULL) { - rv.setConflictingObjectRef(ObjectTypeUtil.createObjectRef(conflictingTarget)); + rv.setConflictingObjectRef(ObjectTypeUtil.createObjectRef(conflictingTarget, prismContext)); rv.setConflictingObjectDisplayName(ObjectTypeUtil.getDisplayName(conflictingTarget)); if (conflictingPath != null) { rv.setConflictingObjectPath(conflictingPath.toAssignmentPathType(options.isIncludeAssignmentsContent())); diff --git a/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluatedHasAssignmentTrigger.java b/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluatedHasAssignmentTrigger.java index 1e77a004f63..e8acf4ff967 100644 --- a/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluatedHasAssignmentTrigger.java +++ b/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluatedHasAssignmentTrigger.java @@ -16,6 +16,7 @@ package com.evolveum.midpoint.model.api.context; +import com.evolveum.midpoint.prism.PrismContext; import com.evolveum.midpoint.util.LocalizableMessage; import com.evolveum.midpoint.xml.ns._public.common.common_3.*; import org.jetbrains.annotations.NotNull; @@ -31,7 +32,8 @@ public EvaluatedHasAssignmentTrigger(@NotNull PolicyConstraintKindType kind, @No } @Override - public EvaluatedHasAssignmentTriggerType toEvaluatedPolicyRuleTriggerType(PolicyRuleExternalizationOptions options) { + public EvaluatedHasAssignmentTriggerType toEvaluatedPolicyRuleTriggerType(PolicyRuleExternalizationOptions options, + PrismContext prismContext) { EvaluatedHasAssignmentTriggerType rv = new EvaluatedHasAssignmentTriggerType(); fillCommonContent(rv); return rv; diff --git a/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluatedModificationTrigger.java b/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluatedModificationTrigger.java index bc83fbe68f4..89023229309 100644 --- a/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluatedModificationTrigger.java +++ b/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluatedModificationTrigger.java @@ -16,6 +16,7 @@ package com.evolveum.midpoint.model.api.context; +import com.evolveum.midpoint.prism.PrismContext; import com.evolveum.midpoint.util.LocalizableMessage; import com.evolveum.midpoint.xml.ns._public.common.common_3.*; import org.jetbrains.annotations.NotNull; @@ -31,7 +32,8 @@ public EvaluatedModificationTrigger(@NotNull PolicyConstraintKindType kind, @Not } @Override - public EvaluatedModificationTriggerType toEvaluatedPolicyRuleTriggerType(PolicyRuleExternalizationOptions options) { + public EvaluatedModificationTriggerType toEvaluatedPolicyRuleTriggerType(PolicyRuleExternalizationOptions options, + PrismContext prismContext) { EvaluatedModificationTriggerType rv = new EvaluatedModificationTriggerType(); fillCommonContent(rv); return rv; diff --git a/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluatedMultiplicityTrigger.java b/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluatedMultiplicityTrigger.java index 1c4b60c8782..db883fcd932 100644 --- a/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluatedMultiplicityTrigger.java +++ b/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluatedMultiplicityTrigger.java @@ -16,6 +16,7 @@ package com.evolveum.midpoint.model.api.context; +import com.evolveum.midpoint.prism.PrismContext; import com.evolveum.midpoint.util.LocalizableMessage; import com.evolveum.midpoint.xml.ns._public.common.common_3.*; import org.jetbrains.annotations.NotNull; @@ -31,7 +32,8 @@ public EvaluatedMultiplicityTrigger(@NotNull PolicyConstraintKindType kind, @Not } @Override - public EvaluatedMultiplicityTriggerType toEvaluatedPolicyRuleTriggerType(PolicyRuleExternalizationOptions options) { + public EvaluatedMultiplicityTriggerType toEvaluatedPolicyRuleTriggerType(PolicyRuleExternalizationOptions options, + PrismContext prismContext) { EvaluatedMultiplicityTriggerType rv = new EvaluatedMultiplicityTriggerType(); fillCommonContent(rv); return rv; diff --git a/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluatedPolicyRule.java b/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluatedPolicyRule.java index 2d84efe33be..cbfaf8fa6fb 100644 --- a/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluatedPolicyRule.java +++ b/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluatedPolicyRule.java @@ -20,6 +20,7 @@ import java.util.List; import java.util.function.Predicate; +import com.evolveum.midpoint.prism.PrismContext; import com.evolveum.midpoint.util.DebugDumpable; import com.evolveum.midpoint.util.LocalizableMessage; import com.evolveum.midpoint.util.TreeNode; @@ -69,7 +70,7 @@ default boolean isTriggered() { Collection getPolicyExceptions(); void addToEvaluatedPolicyRuleTypes(Collection rules, PolicyRuleExternalizationOptions options, - Predicate> triggerSelector); + Predicate> triggerSelector, PrismContext prismContext); boolean isGlobal(); diff --git a/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluatedPolicyRuleTrigger.java b/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluatedPolicyRuleTrigger.java index 45065f803f0..d35f067c887 100644 --- a/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluatedPolicyRuleTrigger.java +++ b/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluatedPolicyRuleTrigger.java @@ -15,6 +15,7 @@ */ package com.evolveum.midpoint.model.api.context; +import com.evolveum.midpoint.prism.PrismContext; import com.evolveum.midpoint.schema.util.LocalizationUtil; import com.evolveum.midpoint.schema.util.PolicyRuleTypeUtil; import com.evolveum.midpoint.util.DebugDumpable; @@ -144,7 +145,8 @@ public String toDiagShortcut() { return PolicyRuleTypeUtil.toDiagShortcut(constraintKind); } - public EvaluatedPolicyRuleTriggerType toEvaluatedPolicyRuleTriggerType(PolicyRuleExternalizationOptions options) { + public EvaluatedPolicyRuleTriggerType toEvaluatedPolicyRuleTriggerType(PolicyRuleExternalizationOptions options, + PrismContext prismContext) { EvaluatedPolicyRuleTriggerType rv = new EvaluatedPolicyRuleTriggerType(); fillCommonContent(rv); return rv; diff --git a/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluatedSituationTrigger.java b/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluatedSituationTrigger.java index 9dde1b58a33..0c17edd81a1 100644 --- a/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluatedSituationTrigger.java +++ b/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluatedSituationTrigger.java @@ -16,6 +16,7 @@ package com.evolveum.midpoint.model.api.context; +import com.evolveum.midpoint.prism.PrismContext; import com.evolveum.midpoint.schema.util.PolicyRuleTypeUtil; import com.evolveum.midpoint.util.DebugUtil; import com.evolveum.midpoint.util.LocalizableMessage; @@ -103,11 +104,12 @@ protected void debugDumpSpecific(StringBuilder sb, int indent) { } @Override - public EvaluatedSituationTriggerType toEvaluatedPolicyRuleTriggerType(PolicyRuleExternalizationOptions options) { + public EvaluatedSituationTriggerType toEvaluatedPolicyRuleTriggerType(PolicyRuleExternalizationOptions options, + PrismContext prismContext) { EvaluatedSituationTriggerType rv = new EvaluatedSituationTriggerType(); fillCommonContent(rv); if (!options.isRespectFinalFlag() || !isFinal()) { - sourceRules.forEach(r -> r.addToEvaluatedPolicyRuleTypes(rv.getSourceRule(), options, null)); + sourceRules.forEach(r -> r.addToEvaluatedPolicyRuleTypes(rv.getSourceRule(), options, null, prismContext)); } return rv; } diff --git a/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluatedStateTrigger.java b/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluatedStateTrigger.java index 017dcbe9964..6fb3d4a2719 100644 --- a/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluatedStateTrigger.java +++ b/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluatedStateTrigger.java @@ -16,6 +16,7 @@ package com.evolveum.midpoint.model.api.context; +import com.evolveum.midpoint.prism.PrismContext; import com.evolveum.midpoint.util.LocalizableMessage; import com.evolveum.midpoint.xml.ns._public.common.common_3.EvaluatedStateTriggerType; import com.evolveum.midpoint.xml.ns._public.common.common_3.PolicyConstraintKindType; @@ -33,7 +34,8 @@ public EvaluatedStateTrigger(@NotNull PolicyConstraintKindType kind, @NotNull St } @Override - public EvaluatedStateTriggerType toEvaluatedPolicyRuleTriggerType(PolicyRuleExternalizationOptions options) { + public EvaluatedStateTriggerType toEvaluatedPolicyRuleTriggerType(PolicyRuleExternalizationOptions options, + PrismContext prismContext) { EvaluatedStateTriggerType rv = new EvaluatedStateTriggerType(); fillCommonContent(rv); return rv; diff --git a/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluatedTimeValidityTrigger.java b/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluatedTimeValidityTrigger.java index 800d47dcb8e..5e16bb9f7ed 100644 --- a/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluatedTimeValidityTrigger.java +++ b/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluatedTimeValidityTrigger.java @@ -16,6 +16,7 @@ package com.evolveum.midpoint.model.api.context; +import com.evolveum.midpoint.prism.PrismContext; import com.evolveum.midpoint.util.LocalizableMessage; import com.evolveum.midpoint.xml.ns._public.common.common_3.*; import org.jetbrains.annotations.NotNull; @@ -31,7 +32,8 @@ public EvaluatedTimeValidityTrigger(@NotNull PolicyConstraintKindType kind, @Not } @Override - public EvaluatedTimeValidityTriggerType toEvaluatedPolicyRuleTriggerType(PolicyRuleExternalizationOptions options) { + public EvaluatedTimeValidityTriggerType toEvaluatedPolicyRuleTriggerType(PolicyRuleExternalizationOptions options, + PrismContext prismContext) { EvaluatedTimeValidityTriggerType rv = new EvaluatedTimeValidityTriggerType(); fillCommonContent(rv); return rv; diff --git a/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluatedTransitionTrigger.java b/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluatedTransitionTrigger.java index ac403fd4948..983c01c2b17 100644 --- a/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluatedTransitionTrigger.java +++ b/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluatedTransitionTrigger.java @@ -16,6 +16,7 @@ package com.evolveum.midpoint.model.api.context; +import com.evolveum.midpoint.prism.PrismContext; import com.evolveum.midpoint.util.DebugUtil; import com.evolveum.midpoint.util.LocalizableMessage; import com.evolveum.midpoint.xml.ns._public.common.common_3.*; @@ -75,11 +76,12 @@ protected void debugDumpSpecific(StringBuilder sb, int indent) { } @Override - public EvaluatedTransitionTriggerType toEvaluatedPolicyRuleTriggerType(PolicyRuleExternalizationOptions options) { + public EvaluatedTransitionTriggerType toEvaluatedPolicyRuleTriggerType(PolicyRuleExternalizationOptions options, + PrismContext prismContext) { EvaluatedTransitionTriggerType rv = new EvaluatedTransitionTriggerType(); fillCommonContent(rv); if (!options.isRespectFinalFlag() || !isFinal()) { - innerTriggers.forEach(t -> rv.getEmbedded().add(t.toEvaluatedPolicyRuleTriggerType(options))); + innerTriggers.forEach(t -> rv.getEmbedded().add(t.toEvaluatedPolicyRuleTriggerType(options, prismContext))); } return rv; } diff --git a/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluationOrder.java b/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluationOrder.java index 8ef1ea4156a..5b9197d2e6e 100644 --- a/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluationOrder.java +++ b/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluationOrder.java @@ -50,7 +50,7 @@ public interface EvaluationOrder extends DebugDumpable, ShortDumpable, Cloneable // both current and new states must be defined Map diff(EvaluationOrder newState); - EvaluationOrder applyDifference(Map difference); + EvaluationOrder applyDifference(Map difference); boolean isDefined(); diff --git a/model/model-api/src/main/java/com/evolveum/midpoint/model/api/util/DeputyUtils.java b/model/model-api/src/main/java/com/evolveum/midpoint/model/api/util/DeputyUtils.java index b78ffef675a..825b03137cc 100644 --- a/model/model-api/src/main/java/com/evolveum/midpoint/model/api/util/DeputyUtils.java +++ b/model/model-api/src/main/java/com/evolveum/midpoint/model/api/util/DeputyUtils.java @@ -20,7 +20,7 @@ import com.evolveum.midpoint.model.api.context.AssignmentPathSegment; import com.evolveum.midpoint.prism.PrismContainer; import com.evolveum.midpoint.prism.PrismReferenceValue; -import com.evolveum.midpoint.schema.util.ObjectTypeUtil; +import com.evolveum.midpoint.schema.RelationRegistry; import com.evolveum.midpoint.xml.ns._public.common.common_3.*; import org.apache.commons.collections4.CollectionUtils; import org.jetbrains.annotations.NotNull; @@ -39,33 +39,35 @@ public class DeputyUtils { @NotNull - public static Collection getDelegatorReferences(@NotNull UserType user) { + public static Collection getDelegatorReferences(@NotNull UserType user, + @NotNull RelationRegistry relationRegistry) { return user.getDelegatedRef().stream() - .filter(ref -> ObjectTypeUtil.isDelegationRelation(ref.getRelation())) + .filter(ref -> relationRegistry.isDelegation(ref.getRelation())) .map(ref -> ref.asReferenceValue().clone()) .collect(Collectors.toList()); } @NotNull - public static Collection getDelegatorOids(@NotNull UserType user) { - return getDelegatorReferences(user).stream() + public static Collection getDelegatorOids(@NotNull UserType user, @NotNull RelationRegistry relationRegistry) { + return getDelegatorReferences(user, relationRegistry).stream() .map(PrismReferenceValue::getOid) .collect(Collectors.toList()); } - public static boolean isDelegationPresent(@NotNull UserType deputy, @NotNull String delegatorOid) { - return getDelegatorOids(deputy).contains(delegatorOid); + public static boolean isDelegationPresent(@NotNull UserType deputy, @NotNull String delegatorOid, + @NotNull RelationRegistry relationRegistry) { + return getDelegatorOids(deputy, relationRegistry).contains(delegatorOid); } - public static boolean isDelegationAssignment(AssignmentType assignment) { + public static boolean isDelegationAssignment(AssignmentType assignment, @NotNull RelationRegistry relationRegistry) { return assignment != null && assignment.getTargetRef() != null - && ObjectTypeUtil.isDelegationRelation(assignment.getTargetRef().getRelation()); + && relationRegistry.isDelegation(assignment.getTargetRef().getRelation()); } - public static boolean isDelegationPath(AssignmentPath assignmentPath) { + public static boolean isDelegationPath(@NotNull AssignmentPath assignmentPath, @NotNull RelationRegistry relationRegistry) { for (AssignmentPathSegment segment : assignmentPath.getSegments()) { - if (!isDelegationAssignment(segment.getAssignment())) { + if (!isDelegationAssignment(segment.getAssignment(), relationRegistry)) { return false; } } diff --git a/model/model-common/src/main/java/com/evolveum/midpoint/model/common/SystemObjectCache.java b/model/model-common/src/main/java/com/evolveum/midpoint/model/common/SystemObjectCache.java index 12804599e79..8c9ccb197e4 100644 --- a/model/model-common/src/main/java/com/evolveum/midpoint/model/common/SystemObjectCache.java +++ b/model/model-common/src/main/java/com/evolveum/midpoint/model/common/SystemObjectCache.java @@ -1,4 +1,4 @@ -/** +/* * Copyright (c) 2016-2018 Evolveum * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -15,32 +15,22 @@ */ package com.evolveum.midpoint.model.common; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.List; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.stereotype.Component; - import com.evolveum.midpoint.prism.PrismObject; import com.evolveum.midpoint.repo.api.RepositoryService; import com.evolveum.midpoint.schema.GetOperationOptions; import com.evolveum.midpoint.schema.SelectorOptions; -import com.evolveum.midpoint.schema.constants.RelationTypes; import com.evolveum.midpoint.schema.result.OperationResult; -import com.evolveum.midpoint.schema.util.ObjectTypeUtil; import com.evolveum.midpoint.util.exception.ObjectNotFoundException; import com.evolveum.midpoint.util.exception.SchemaException; import com.evolveum.midpoint.util.logging.Trace; import com.evolveum.midpoint.util.logging.TraceManager; -import com.evolveum.midpoint.xml.ns._public.common.common_3.DisplayType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.RelationDefinitionType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.RelationsDefinitionType; -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.SystemObjectsType; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.stereotype.Component; + +import java.util.Collection; /** * Cache for system object such as SystemConfigurationType. This is a global cache, @@ -65,8 +55,6 @@ public class SystemObjectCache { private static final Trace LOGGER = TraceManager.getTrace(SystemObjectCache.class); - private static final String USER_DATA_KEY_RELATIONS = SystemObjectCache.class.getName() + ".relations"; - @Autowired @Qualifier("cacheRepositoryService") private transient RepositoryService cacheRepositoryService; @@ -131,59 +119,4 @@ private void loadSystemConfiguration(OperationResult result) throws ObjectNotFou public synchronized void invalidateCaches() { systemConfiguration = null; } - - public List getRelationDefinitions(OperationResult parentResult) throws ObjectNotFoundException, SchemaException { - PrismObject systemConfiguration = getSystemConfiguration(parentResult); - if (systemConfiguration == null) { - return createRelationDefinitions(null); - } - List cachedRelations = systemConfiguration.getUserData(USER_DATA_KEY_RELATIONS); - if (cachedRelations != null) { - return cachedRelations; - } - RoleManagementConfigurationType roleManagement = systemConfiguration.asObjectable().getRoleManagement(); - RelationsDefinitionType relationsDef = null; - if (roleManagement != null) { - relationsDef = roleManagement.getRelations(); - } - cachedRelations = createRelationDefinitions(relationsDef); - systemConfiguration.setUserData(USER_DATA_KEY_RELATIONS, cachedRelations); - return cachedRelations; - } - - private List createRelationDefinitions(RelationsDefinitionType relationsDef) { - List configuredRelations = null; - boolean includeDefaultRelations = true; - if (relationsDef != null) { - configuredRelations = relationsDef.getRelation(); - if (relationsDef.isIncludeDefaultRelations() != null && !relationsDef.isIncludeDefaultRelations()) { - includeDefaultRelations = false; - } - } - List relations = new ArrayList<>(); - if (configuredRelations != null) { - for (RelationDefinitionType configuredRelation: configuredRelations) { - relations.add(configuredRelation.clone()); - } - } - if (includeDefaultRelations) { - addDefaultRelations(relations); - } - return relations; - } - - private void addDefaultRelations(List relations) { - for (RelationTypes relationTypeEnum : RelationTypes.values()) { - if (ObjectTypeUtil.findRelationDefinition(relations, relationTypeEnum.getRelation()) != null) { - continue; - } - RelationDefinitionType relationDef = new RelationDefinitionType(); - relationDef.setRef(relationTypeEnum.getRelation()); - DisplayType display = new DisplayType(); - display.setLabel(relationTypeEnum.getLabelKey()); - relationDef.setDisplay(display); - relationDef.getCategory().addAll(Arrays.asList(relationTypeEnum.getCategories())); - relations.add(relationDef); - } - } } diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/controller/ModelInteractionServiceImpl.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/controller/ModelInteractionServiceImpl.java index 29aa21d7371..9bfb9d9ac6d 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/controller/ModelInteractionServiceImpl.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/controller/ModelInteractionServiceImpl.java @@ -29,6 +29,7 @@ import com.evolveum.midpoint.prism.*; import com.evolveum.midpoint.repo.common.expression.*; +import com.evolveum.midpoint.schema.*; import com.evolveum.midpoint.xml.ns._public.common.common_3.*; import org.apache.commons.lang.BooleanUtils; import org.apache.commons.lang.Validate; @@ -105,12 +106,6 @@ import com.evolveum.midpoint.repo.api.RepositoryService; import com.evolveum.midpoint.repo.cache.RepositoryCache; import com.evolveum.midpoint.repo.common.CacheRegistry; -import com.evolveum.midpoint.schema.GetOperationOptions; -import com.evolveum.midpoint.schema.ObjectDeltaOperation; -import com.evolveum.midpoint.schema.ResourceShadowDiscriminator; -import com.evolveum.midpoint.schema.RetrieveOption; -import com.evolveum.midpoint.schema.SearchResultList; -import com.evolveum.midpoint.schema.SelectorOptions; import com.evolveum.midpoint.schema.constants.SchemaConstants; import com.evolveum.midpoint.schema.result.OperationResult; import com.evolveum.midpoint.schema.result.OperationResultStatus; @@ -182,6 +177,7 @@ public class ModelInteractionServiceImpl implements ModelInteractionService { @Qualifier("cacheRepositoryService") private transient RepositoryService cacheRepositoryService; @Autowired private SystemObjectCache systemObjectCache; + @Autowired private RelationRegistry relationRegistry; @Autowired private ValuePolicyProcessor policyProcessor; @Autowired private Protector protector; @Autowired private PrismContext prismContext; @@ -1449,7 +1445,7 @@ private void getDeputyAssignees(List deputies, AbstractWork continue; } if (determineDeputyValidity(potentialDeputy, workItem.getAssigneeRef(), workItem, OtherPrivilegesLimitationType.F_APPROVAL_WORK_ITEMS, task, result)) { - deputies.add(ObjectTypeUtil.createObjectRefWithFullObject(potentialDeputy)); + deputies.add(ObjectTypeUtil.createObjectRefWithFullObject(potentialDeputy, prismContext)); oidsToSkip.add(potentialDeputy.getOid()); } } @@ -1469,7 +1465,7 @@ private void getDeputyAssigneesNoWorkItem(List deputies, Ob continue; } if (determineDeputyValidity(potentialDeputy, Collections.singletonList(assigneeRef), null, limitationItemName, task, result)) { - deputies.add(ObjectTypeUtil.createObjectRefWithFullObject(potentialDeputy)); + deputies.add(ObjectTypeUtil.createObjectRefWithFullObject(potentialDeputy, prismContext)); oidsToSkip.add(potentialDeputy.getOid()); } } @@ -1484,6 +1480,7 @@ private boolean determineDeputyValidity(PrismObject potentialDeputy, L .channel(null) .objectResolver(objectResolver) .systemObjectCache(systemObjectCache) + .relationRegistry(relationRegistry) .prismContext(prismContext) .mappingFactory(mappingFactory) .mappingEvaluator(mappingEvaluator) @@ -1496,7 +1493,7 @@ private boolean determineDeputyValidity(PrismObject potentialDeputy, L AssignmentEvaluator assignmentEvaluator = builder.build(); for (AssignmentType assignmentType: potentialDeputy.asObjectable().getAssignment()) { - if (!DeputyUtils.isDelegationAssignment(assignmentType)) { + if (!DeputyUtils.isDelegationAssignment(assignmentType, relationRegistry)) { continue; } try { @@ -1512,7 +1509,7 @@ private boolean determineDeputyValidity(PrismObject potentialDeputy, L } for (EvaluatedAssignmentTarget target : assignment.getRoles().getNonNegativeValues()) { if (target.getTarget() != null && target.getTarget().getOid() != null - && DeputyUtils.isDelegationPath(target.getAssignmentPath()) + && DeputyUtils.isDelegationPath(target.getAssignmentPath(), relationRegistry) && ObjectTypeUtil.containsOid(assignees, target.getTarget().getOid())) { List limitations = DeputyUtils.extractLimitations(target.getAssignmentPath()); if (workItem != null && DeputyUtils.limitationsAllow(limitations, privilegeLimitationItemName, workItem) @@ -1679,8 +1676,8 @@ public void refreshPrincipal(String oid) throws ObjectNotFoundException, SchemaE } @Override - public List getRelationDefinitions(OperationResult parentResult) throws ObjectNotFoundException, SchemaException { - return systemObjectCache.getRelationDefinitions(parentResult); + public List getRelationDefinitions() { + return relationRegistry.getRelationDefinitions(); } @NotNull @@ -1699,7 +1696,7 @@ public TaskType submitTaskFromTemplate(String templateTaskOid, List> newTask.setName(PolyStringType.fromOrig(newTask.getName().getOrig() + " " + (int) (Math.random() * 10000))); newTask.setOid(null); newTask.setTaskIdentifier(null); - newTask.setOwnerRef(createObjectRef(principal.getUser())); + newTask.setOwnerRef(createObjectRef(principal.getUser(), prismContext)); newTask.setExecutionStatus(RUNNABLE); for (Item extensionItem : extensionItems) { newTask.asPrismObject().getExtension().add(extensionItem.clone()); diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/controller/SystemConfigurationHandler.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/controller/SystemConfigurationHandler.java index d784c999aa2..f3edda12999 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/controller/SystemConfigurationHandler.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/controller/SystemConfigurationHandler.java @@ -26,6 +26,7 @@ import com.evolveum.midpoint.prism.PrismContext; import com.evolveum.midpoint.prism.PrismObject; import com.evolveum.midpoint.repo.api.RepositoryService; +import com.evolveum.midpoint.schema.RelationRegistry; import com.evolveum.midpoint.schema.result.OperationResult; import com.evolveum.midpoint.schema.util.SystemConfigurationTypeUtil; import com.evolveum.midpoint.security.api.SecurityUtil; @@ -66,6 +67,7 @@ public class SystemConfigurationHandler implements ChangeHook { @Autowired private HookRegistry hookRegistry; @Autowired private PrismContext prismContext; + @Autowired private RelationRegistry relationRegistry; @Autowired @Qualifier("cacheRepositoryService") @@ -141,6 +143,7 @@ public HookOperationMode invoke(@NotNull ModelContext applyPrismConfiguration(configType); cacheRepositoryService.applyFullTextSearchConfiguration(config.asObjectable().getFullTextSearch()); + relationRegistry.applyRelationConfiguration(config.asObjectable()); SystemConfigurationTypeUtil.applyOperationResultHandling(config.asObjectable()); result.recordSuccessIfUnknown(); diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/expr/MidpointFunctionsImpl.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/expr/MidpointFunctionsImpl.java index 12e00d7ef1b..ae572184a3d 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/expr/MidpointFunctionsImpl.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/expr/MidpointFunctionsImpl.java @@ -16,7 +16,6 @@ package com.evolveum.midpoint.model.impl.expr; import com.evolveum.midpoint.common.LocalizationService; -import com.evolveum.midpoint.common.SynchronizationUtils; import com.evolveum.midpoint.common.refinery.RefinedAttributeDefinition; import com.evolveum.midpoint.common.refinery.RefinedObjectClassDefinition; import com.evolveum.midpoint.common.refinery.RefinedResourceSchema; @@ -54,7 +53,6 @@ import com.evolveum.midpoint.provisioning.api.ProvisioningService; import com.evolveum.midpoint.repo.api.RepositoryService; import com.evolveum.midpoint.repo.common.expression.ExpressionFactory; -import com.evolveum.midpoint.repo.common.expression.ExpressionUtil; import com.evolveum.midpoint.schema.*; import com.evolveum.midpoint.schema.constants.SchemaConstants; import com.evolveum.midpoint.schema.result.OperationResult; @@ -1389,7 +1387,7 @@ public Map parseXmlToMap(String xml) { public List getMembersAsReferences(String orgOid) throws SchemaException, SecurityViolationException, CommunicationException, ConfigurationException, ObjectNotFoundException, ExpressionEvaluationException { return getMembers(orgOid).stream() - .map(obj -> createObjectRef(obj)) + .map(obj -> createObjectRef(obj, prismContext)) .collect(Collectors.toList()); } @@ -1607,7 +1605,7 @@ public TaskType executeChangesAsynchronously(Collection> deltas, newTask.setName(PolyStringType.fromOrig(newTask.getName().getOrig() + " " + (int) (Math.random()*10000))); newTask.setOid(null); newTask.setTaskIdentifier(null); - newTask.setOwnerRef(createObjectRef(principal.getUser())); + newTask.setOwnerRef(createObjectRef(principal.getUser(), prismContext)); newTask.setExecutionStatus(RUNNABLE); newTask.setHandlerUri(ModelPublicConstants.EXECUTE_DELTAS_TASK_HANDLER_URI); if (deltas.isEmpty()) { diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/expr/OrgStructFunctionsImpl.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/expr/OrgStructFunctionsImpl.java index 258643bd013..3f321ed90b8 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/expr/OrgStructFunctionsImpl.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/expr/OrgStructFunctionsImpl.java @@ -20,12 +20,10 @@ import com.evolveum.midpoint.prism.PrismConstants; import com.evolveum.midpoint.prism.PrismContext; import com.evolveum.midpoint.prism.PrismObject; -import com.evolveum.midpoint.prism.PrismReferenceValue; import com.evolveum.midpoint.prism.polystring.PolyString; import com.evolveum.midpoint.prism.query.ObjectQuery; -import com.evolveum.midpoint.prism.query.builder.QueryBuilder; import com.evolveum.midpoint.repo.api.RepositoryService; -import com.evolveum.midpoint.schema.constants.SchemaConstants; +import com.evolveum.midpoint.schema.RelationRegistry; import com.evolveum.midpoint.schema.result.OperationResult; import com.evolveum.midpoint.schema.util.ObjectQueryUtil; import com.evolveum.midpoint.schema.util.ObjectTypeUtil; @@ -65,6 +63,9 @@ public class OrgStructFunctionsImpl implements OrgStructFunctions { @Autowired private PrismContext prismContext; + @Autowired + private RelationRegistry relationRegistry; + /** * Returns a list of user's managers. Formally, for each Org O which this user has (any) relation to, * all managers of O are added to the result. @@ -73,13 +74,11 @@ public class OrgStructFunctionsImpl implements OrgStructFunctions { * or defining who is a manager of a user who is itself a manager in its org.unit. (A parent org unit manager, * perhaps.) * - * @param user * @return list of oids of the respective managers - * @throws SchemaException - * @throws ObjectNotFoundException */ @Override - public Collection getManagersOids(UserType user, boolean preAuthorized) throws SchemaException, ObjectNotFoundException, SecurityViolationException { + public Collection getManagersOids(UserType user, boolean preAuthorized) throws SchemaException, + SecurityViolationException { Set retval = new HashSet<>(); for (UserType u : getManagers(user, preAuthorized)) { retval.add(u.getOid()); @@ -88,7 +87,8 @@ public Collection getManagersOids(UserType user, boolean preAuthorized) } @Override - public Collection getManagersOidsExceptUser(UserType user, boolean preAuthorized) throws SchemaException, ObjectNotFoundException, SecurityViolationException { + public Collection getManagersOidsExceptUser(UserType user, boolean preAuthorized) throws SchemaException, + SecurityViolationException { Set retval = new HashSet<>(); for (UserType u : getManagers(user, preAuthorized)) { if (!u.getOid().equals(user.getOid())) { @@ -110,17 +110,20 @@ public Collection getManagersOidsExceptUser(@NotNull Collection getManagers(UserType user, boolean preAuthorized) throws SchemaException, ObjectNotFoundException, SecurityViolationException { + public Collection getManagers(UserType user, boolean preAuthorized) throws SchemaException, + SecurityViolationException { return getManagers(user, null, false, preAuthorized); } @Override - public Collection getManagersByOrgType(UserType user, String orgType, boolean preAuthorized) throws SchemaException, ObjectNotFoundException, SecurityViolationException { + public Collection getManagersByOrgType(UserType user, String orgType, boolean preAuthorized) throws SchemaException, + SecurityViolationException { return getManagers(user, orgType, false, preAuthorized); } @Override - public Collection getManagers(UserType user, String orgType, boolean allowSelf, boolean preAuthorized) throws SchemaException, ObjectNotFoundException, SecurityViolationException { + public Collection getManagers(UserType user, String orgType, boolean allowSelf, boolean preAuthorized) throws SchemaException, + SecurityViolationException { Set retval = new HashSet<>(); if (user == null) { return retval; @@ -195,7 +198,7 @@ public Collection getOrgUnits(UserType user, QName relation, boolean pre return retval; } for (ObjectReferenceType orgRef : user.getParentOrgRef()) { - if (ObjectTypeUtil.relationMatches(relation, orgRef.getRelation())) { + if (prismContext.relationMatches(relation, orgRef.getRelation())) { retval.add(orgRef.getOid()); } } @@ -264,7 +267,7 @@ public Collection getParentOrgs(ObjectType object, QName relation, Stri List parentOrgRefs = object.getParentOrgRef(); List parentOrgs = new ArrayList<>(parentOrgRefs.size()); for (ObjectReferenceType parentOrgRef: parentOrgRefs) { - if (!ObjectTypeUtil.relationMatches(relation, parentOrgRef.getRelation())) { + if (!prismContext.relationMatches(relation, parentOrgRef.getRelation())) { continue; } OrgType parentOrg; @@ -290,12 +293,7 @@ public Collection getManagersOfOrg(String orgOid, boolean preAuthorize Set retval = new HashSet<>(); OperationResult result = new OperationResult("getManagerOfOrg"); - PrismReferenceValue parentOrgRefVal = new PrismReferenceValue(orgOid, OrgType.COMPLEX_TYPE); - parentOrgRefVal.setRelation(SchemaConstants.ORG_MANAGER); - ObjectQuery objectQuery = QueryBuilder.queryFor(ObjectType.class, prismContext) - .item(ObjectType.F_PARENT_ORG_REF).ref(parentOrgRefVal) - .build(); - + ObjectQuery objectQuery = ObjectTypeUtil.createManagerQuery(ObjectType.class, orgOid, relationRegistry, prismContext); List> members = searchObjects(ObjectType.class, objectQuery, result, preAuthorized); for (PrismObject member : members) { if (member.asObjectable() instanceof UserType) { @@ -309,7 +307,8 @@ public Collection getManagersOfOrg(String orgOid, boolean preAuthorize @Override public boolean isManagerOf(UserType user, String orgOid, boolean preAuthorized) { for (ObjectReferenceType objectReferenceType : user.getParentOrgRef()) { - if (orgOid.equals(objectReferenceType.getOid()) && ObjectTypeUtil.isManagerRelation(objectReferenceType.getRelation())) { + if (orgOid.equals(objectReferenceType.getOid()) && + relationRegistry.isManager(objectReferenceType.getRelation())) { return true; } } @@ -319,7 +318,7 @@ public boolean isManagerOf(UserType user, String orgOid, boolean preAuthorized) @Override public boolean isManager(UserType user) { for (ObjectReferenceType objectReferenceType : user.getParentOrgRef()) { - if (ObjectTypeUtil.isManagerRelation(objectReferenceType.getRelation())) { + if (relationRegistry.isManager(objectReferenceType.getRelation())) { return true; } } @@ -329,7 +328,7 @@ public boolean isManager(UserType user) { @Override public boolean isManagerOfOrgType(UserType user, String orgType, boolean preAuthorized) throws SchemaException { for (ObjectReferenceType objectReferenceType : user.getParentOrgRef()) { - if (ObjectTypeUtil.isManagerRelation(objectReferenceType.getRelation())) { + if (relationRegistry.isManager(objectReferenceType.getRelation())) { OrgType org = getOrgByOid(objectReferenceType.getOid(), preAuthorized); if (determineSubTypes(org).contains(orgType)) { return true; diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/importer/ImportAccountsFromResourceTaskHandler.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/importer/ImportAccountsFromResourceTaskHandler.java index 9d3dcec3e88..19e2fc7b91e 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/importer/ImportAccountsFromResourceTaskHandler.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/importer/ImportAccountsFromResourceTaskHandler.java @@ -140,7 +140,7 @@ public void launch(ResourceType resource, QName objectclass, Task task, Operatio // Set reference to the resource - task.setObjectRef(ObjectTypeUtil.createObjectRef(resource)); + task.setObjectRef(ObjectTypeUtil.createObjectRef(resource, prismContext)); try { PrismProperty objectclassProp = objectclassPropertyDefinition.instantiate(); diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/importer/ObjectImporter.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/importer/ObjectImporter.java index aeea21e416e..e6116735acf 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/importer/ObjectImporter.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/importer/ObjectImporter.java @@ -245,7 +245,7 @@ private EventResult importParsedObject(PrismObject pri metaData.setCreateChannel(channel); metaData.setCreateTimestamp(clock.currentTimeXMLGregorianCalendar()); if (task.getOwner() != null) { - metaData.setCreatorRef(ObjectTypeUtil.createObjectRef(task.getOwner())); + metaData.setCreatorRef(ObjectTypeUtil.createObjectRef(task.getOwner(), prismContext)); } object.asObjectable().setMetadata(metaData); } diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/AssignmentEvaluator.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/AssignmentEvaluator.java index 53f2323c595..e28cb97fdf6 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/AssignmentEvaluator.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/AssignmentEvaluator.java @@ -52,6 +52,7 @@ import com.evolveum.midpoint.prism.query.ObjectQuery; import com.evolveum.midpoint.prism.query.builder.QueryBuilder; import com.evolveum.midpoint.repo.api.RepositoryService; +import com.evolveum.midpoint.schema.RelationRegistry; import com.evolveum.midpoint.schema.ResultHandler; import com.evolveum.midpoint.schema.VirtualAssignmenetSpecification; import com.evolveum.midpoint.schema.constants.ExpressionConstants; @@ -101,6 +102,7 @@ public class AssignmentEvaluator { private final String channel; private final ObjectResolver objectResolver; private final SystemObjectCache systemObjectCache; + private final RelationRegistry relationRegistry; private final PrismContext prismContext; private final MappingFactory mappingFactory; private final ActivationComputer activationComputer; @@ -118,6 +120,7 @@ private AssignmentEvaluator(Builder builder) { channel = builder.channel; objectResolver = builder.objectResolver; systemObjectCache = builder.systemObjectCache; + relationRegistry = builder.relationRegistry; prismContext = builder.prismContext; mappingFactory = builder.mappingFactory; activationComputer = builder.activationComputer; @@ -233,9 +236,9 @@ public EvaluatedAssignmentImpl evaluate( new AssignmentPathImpl(prismContext), primaryAssignmentMode, evaluateOld, task, result); - AssignmentPathSegmentImpl segment = new AssignmentPathSegmentImpl(source, sourceDescription, assignmentIdi, true, evaluateOld); + AssignmentPathSegmentImpl segment = new AssignmentPathSegmentImpl(source, sourceDescription, assignmentIdi, true, evaluateOld, relationRegistry, prismContext); segment.setEvaluationOrder(getInitialEvaluationOrder(assignmentIdi, ctx)); - segment.setEvaluationOrderForTarget(EvaluationOrderImpl.ZERO); + segment.setEvaluationOrderForTarget(EvaluationOrderImpl.zero(relationRegistry)); segment.setValidityOverride(true); segment.setPathToSourceValid(true); segment.setProcessMembership(true); @@ -251,7 +254,7 @@ private EvaluationOrder getInitialEvaluationOrder( ItemDeltaItem, PrismContainerDefinition> assignmentIdi, EvaluationContext ctx) { AssignmentType assignmentType = LensUtil.getAssignmentType(assignmentIdi, ctx.evaluateOld); - return EvaluationOrderImpl.ZERO.advance(getRelation(assignmentType)); + return EvaluationOrderImpl.zero(relationRegistry).advance(getRelation(assignmentType)); } /** @@ -432,12 +435,12 @@ private boolean evaluateSegmentContent(AssignmentPathSegm } if (assignmentType.getTarget() != null || assignmentType.getTargetRef() != null) { QName relation = getRelation(assignmentType); - if (loginMode && !ObjectTypeUtil.processRelationOnLogin(relation)) { + if (loginMode && !relationRegistry.processRelationOnLogin(relation)) { LOGGER.trace("Skipping processing of assignment target {} because relation {} is configured for login skip", assignmentType.getTargetRef().getOid(), relation); // Skip - to optimize logging-in, we skip all assignments with non-membership/non-delegation relations (e.g. approver, owner, etc) // We want to make this configurable in the future MID-3581 } else if (!loginMode && !isChanged(ctx.primaryAssignmentMode) && - !ObjectTypeUtil.processRelationOnRecompute(relation) && !shouldEvaluateAllAssignmentRelationsOnRecompute()) { + !relationRegistry.processRelationOnRecompute(relation) && !shouldEvaluateAllAssignmentRelationsOnRecompute()) { LOGGER.debug("Skipping processing of assignment target {} because relation {} is configured for recompute skip (mode={})", assignmentType.getTargetRef().getOid(), relation, relativeMode); // Skip - to optimize recompute, we skip all assignments with non-membership/non-delegation relations (e.g. approver, owner, etc) // never skip this if assignment has changed. We want to process this, e.g. to enforce min/max assignee rules @@ -864,7 +867,7 @@ private void evaluateAssignment(AssignmentPathSegmentImpl segment, PlusMinusZero ObjectType orderOneObject = getOrderOneObject(segment); - if (ObjectTypeUtil.isDelegationRelation(relation)) { + if (relationRegistry.isDelegation(relation)) { // We have to handle assignments as though they were inducements here. if (!isAllowedByLimitations(segment, roleAssignment, ctx)) { if (LOGGER.isTraceEnabled()) { @@ -882,7 +885,7 @@ private void evaluateAssignment(AssignmentPathSegmentImpl segment, PlusMinusZero segment.getEvaluationOrder().shortDump(), targetType, FocusTypeUtil.dumpAssignment(roleAssignment), nextEvaluationOrder); } String nextSourceDescription = targetType+" in "+segment.sourceDescription; - AssignmentPathSegmentImpl nextSegment = new AssignmentPathSegmentImpl(targetType, nextSourceDescription, roleAssignment, true); + AssignmentPathSegmentImpl nextSegment = new AssignmentPathSegmentImpl(targetType, nextSourceDescription, roleAssignment, true, relationRegistry, prismContext); nextSegment.setRelation(nextRelation); nextSegment.setEvaluationOrder(nextEvaluationOrder); nextSegment.setEvaluationOrderForTarget(nextEvaluationOrderForTarget); @@ -919,7 +922,7 @@ private void evaluateInducement(AssignmentPathSegmentImpl segment, PlusMinusZero return; } String subSourceDescription = targetType+" in "+segment.sourceDescription; - AssignmentPathSegmentImpl nextSegment = new AssignmentPathSegmentImpl(targetType, subSourceDescription, inducement, false); + AssignmentPathSegmentImpl nextSegment = new AssignmentPathSegmentImpl(targetType, subSourceDescription, inducement, false, relationRegistry, prismContext); // note that 'old' and 'new' values for assignment in nextSegment are the same boolean nextIsMatchingOrder = AssignmentPathSegmentImpl.computeMatchingOrder( segment.getEvaluationOrder(), nextSegment.getAssignmentNew()); @@ -1003,7 +1006,7 @@ private void adjustOrder(Holder evaluationOrderHolder, Holder evaluationOrderHolder, Holder targetClass, QName relation, Object targetDesc, EvaluationContext ctx) { - if (ctx.assignmentPath.getSegments().stream().anyMatch(aps -> DeputyUtils.isDelegationAssignment(aps.getAssignment(ctx.evaluateOld)))) { + if (ctx.assignmentPath.getSegments().stream().anyMatch(aps -> DeputyUtils.isDelegationAssignment(aps.getAssignment(ctx.evaluateOld), + relationRegistry))) { addIfNotThere(ctx.evalAssignment.getDelegationRefVals(), ctx.evalAssignment::addDelegationRefVal, membershipRefVal, "delegationRef", targetDesc); } else { @@ -1112,7 +1117,7 @@ private void collectMembershipRefVal(PrismReferenceValue membershipRefVal, Class "membershipRef", targetDesc); } } - if (OrgType.class.isAssignableFrom(targetClass) && (ObjectTypeUtil.isDefaultRelation(relation) || ObjectTypeUtil.isManagerRelation(relation))) { + if (OrgType.class.isAssignableFrom(targetClass) && relationRegistry.includeIntoParentOrgRef(relation)) { addIfNotThere(ctx.evalAssignment.getOrgRefVals(), ctx.evalAssignment::addOrgRefVal, membershipRefVal, "orgRef", targetDesc); } @@ -1145,7 +1150,7 @@ private void checkRelationWithTarget(AssignmentPathSegmentImpl segment, FocusTyp if (targetType instanceof AbstractRoleType) { // OK, just go on } else if (targetType instanceof UserType) { - if (!ObjectTypeUtil.isDelegationRelation(relation)) { + if (!relationRegistry.isDelegation(relation)) { throw new SchemaException("Unsupported relation " + relation + " for assignment of target type " + targetType + " in " + segment.sourceDescription); } } else { @@ -1182,16 +1187,13 @@ private boolean isAllowedByLimitations(AssignmentPathSegment segment, Assignment // As for the case of targetRef==null: we want to pass target-less assignments (focus mappings, policy rules etc) // from the delegator to delegatee. To block them we should use order constraints (but also for assignments?). return targetLimitation == null || nextAssignment.getTargetRef() == null || - FocusTypeUtil.selectorMatches(targetLimitation, nextAssignment); + FocusTypeUtil.selectorMatches(targetLimitation, nextAssignment, prismContext); } } private boolean isDeputyDelegation(AssignmentType assignmentType) { ObjectReferenceType targetRef = assignmentType.getTargetRef(); - if (targetRef == null) { - return false; - } - return ObjectTypeUtil.isDelegationRelation(targetRef.getRelation()); + return targetRef != null && relationRegistry.isDelegation(targetRef.getRelation()); } private Authorization createAuthorization(AuthorizationType authorizationType, String sourceDesc) { @@ -1285,7 +1287,7 @@ public PrismValueDeltaSetTriple> evaluateCondition(M @Nullable private QName getRelation(AssignmentType assignmentType) { return assignmentType.getTargetRef() != null ? - ObjectTypeUtil.normalizeRelation(assignmentType.getTargetRef().getRelation()) : null; + relationRegistry.normalizeRelation(assignmentType.getTargetRef().getRelation()) : null; } public static final class Builder { @@ -1295,6 +1297,7 @@ public static final class Builder { private String channel; private ObjectResolver objectResolver; private SystemObjectCache systemObjectCache; + private RelationRegistry relationRegistry; private PrismContext prismContext; private MappingFactory mappingFactory; private ActivationComputer activationComputer; @@ -1336,6 +1339,11 @@ public Builder systemObjectCache(SystemObjectCache val) { return this; } + public Builder relationRegistry(RelationRegistry val) { + relationRegistry = val; + return this; + } + public Builder prismContext(PrismContext val) { prismContext = val; return this; diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/AssignmentPathSegmentImpl.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/AssignmentPathSegmentImpl.java index ace129e2023..fb2d4897120 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/AssignmentPathSegmentImpl.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/AssignmentPathSegmentImpl.java @@ -17,6 +17,7 @@ import javax.xml.namespace.QName; +import com.evolveum.midpoint.prism.PrismContext; import com.evolveum.midpoint.repo.common.expression.ItemDeltaItem; import com.evolveum.midpoint.model.api.context.AssignmentPathSegment; import com.evolveum.midpoint.model.api.context.EvaluationOrder; @@ -24,6 +25,7 @@ import com.evolveum.midpoint.prism.PrismContainerDefinition; import com.evolveum.midpoint.prism.PrismContainerValue; import com.evolveum.midpoint.prism.xml.XsdTypeMapper; +import com.evolveum.midpoint.schema.RelationRegistry; import com.evolveum.midpoint.schema.util.ObjectTypeUtil; import com.evolveum.midpoint.util.DebugUtil; import com.evolveum.midpoint.util.QNameUtil; @@ -52,6 +54,9 @@ public class AssignmentPathSegmentImpl implements AssignmentPathSegment { private static final Trace LOGGER = TraceManager.getTrace(AssignmentPathSegmentImpl.class); + @NotNull private final RelationRegistry relationRegistry; + @NotNull private final PrismContext prismContext; + // "assignment path segment" information final ObjectType source; // we avoid "getter" notation for some final fields to simplify client code @@ -265,16 +270,20 @@ public class AssignmentPathSegmentImpl implements AssignmentPathSegment { AssignmentPathSegmentImpl(ObjectType source, String sourceDescription, ItemDeltaItem, PrismContainerDefinition> assignmentIdi, - boolean isAssignment, boolean evaluatedForOld) { + boolean isAssignment, boolean evaluatedForOld, @NotNull RelationRegistry relationRegistry, + @NotNull PrismContext prismContext) { this.source = source; this.sourceDescription = sourceDescription; this.assignmentIdi = assignmentIdi; this.isAssignment = isAssignment; this.evaluatedForOld = evaluatedForOld; + this.relationRegistry = relationRegistry; + this.prismContext = prismContext; } - AssignmentPathSegmentImpl(ObjectType source, String sourceDescription, AssignmentType assignment, boolean isAssignment) { - this(source, sourceDescription, createAssignmentIdi(assignment), isAssignment, false); + AssignmentPathSegmentImpl(ObjectType source, String sourceDescription, AssignmentType assignment, boolean isAssignment, + RelationRegistry relationRegistry, PrismContext prismContext) { + this(source, sourceDescription, createAssignmentIdi(assignment), isAssignment, false, relationRegistry, prismContext); } private static ItemDeltaItem, PrismContainerDefinition> createAssignmentIdi( @@ -479,7 +488,7 @@ private static boolean isMatchingConstraint(OrderConstraintsType orderConstraint @Override public boolean isDelegation() { - return ObjectTypeUtil.isDelegationRelation(relation); + return relationRegistry.isDelegation(relation); } @Override @@ -613,11 +622,11 @@ public AssignmentPathSegmentType toAssignmentPathSegmentType(boolean includeAssi rv.setAssignmentId(assignment.getId()); } if (source != null) { - rv.setSourceRef(ObjectTypeUtil.createObjectRef(source)); + rv.setSourceRef(ObjectTypeUtil.createObjectRef(source, prismContext)); rv.setSourceDisplayName(ObjectTypeUtil.getDisplayName(source)); } if (target != null) { - rv.setTargetRef(ObjectTypeUtil.createObjectRef(target)); + rv.setTargetRef(ObjectTypeUtil.createObjectRef(target, prismContext)); rv.setTargetDisplayName(ObjectTypeUtil.getDisplayName(target)); } rv.setMatchingOrder(isMatchingOrder()); @@ -642,7 +651,7 @@ public boolean matches(@NotNull List orderConstraints) { // that are to be checked for equivalency @Override public boolean equivalent(AssignmentPathSegment otherSegment) { - if (!ObjectTypeUtil.relationsEquivalent(relation, otherSegment.getRelation())) { + if (!prismContext.relationsEquivalent(relation, otherSegment.getRelation())) { return false; } if (target == null && otherSegment.getTarget() == null) { diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/ChangeExecutor.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/ChangeExecutor.java index b3de8c25cbd..28553178c8f 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/ChangeExecutor.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/ChangeExecutor.java @@ -63,7 +63,9 @@ import com.evolveum.midpoint.schema.result.OperationResult; import com.evolveum.midpoint.schema.result.OperationResultStatus; import com.evolveum.midpoint.schema.util.ShadowUtil; +import com.evolveum.midpoint.security.api.MidPointPrincipal; import com.evolveum.midpoint.security.api.OwnerResolver; +import com.evolveum.midpoint.security.api.SecurityContextManager; import com.evolveum.midpoint.security.enforcer.api.AuthorizationParameters; import com.evolveum.midpoint.security.enforcer.api.SecurityEnforcer; import com.evolveum.midpoint.task.api.Task; @@ -77,6 +79,7 @@ import com.evolveum.midpoint.util.logging.Trace; import com.evolveum.midpoint.util.logging.TraceManager; import com.evolveum.midpoint.xml.ns._public.common.common_3.*; +import com.evolveum.prism.xml.ns._public.types_3.ProtectedStringType; import com.evolveum.prism.xml.ns._public.types_3.RawType; import org.apache.commons.lang.BooleanUtils; @@ -116,6 +119,7 @@ public class ChangeExecutor { @Autowired private PrismContext prismContext; @Autowired private ExpressionFactory expressionFactory; @Autowired private SecurityEnforcer securityEnforcer; + @Autowired private SecurityContextManager securityContextManager; @Autowired private Clock clock; @Autowired private ModelObjectResolver objectResolver; @Autowired private OperationalDataManager metadataManager; @@ -1165,11 +1169,16 @@ private ProvisioningOperationOptions copyFromModelOptions(ModelExecuteOptions op } private ProvisioningOperationOptions getProvisioningOptions(LensContext context, - ModelExecuteOptions modelOptions) { + ModelExecuteOptions modelOptions, PrismObject existingShadow, ObjectDelta delta) throws SecurityViolationException { if (modelOptions == null && context != null) { modelOptions = context.getOptions(); } ProvisioningOperationOptions provisioningOptions = copyFromModelOptions(modelOptions); + + if (executeAsSelf(context, modelOptions, existingShadow, delta)) { + LOGGER.trace("Setting 'execute as self' provisioning option for {}", existingShadow); + provisioningOptions.setRunAsAccountOid(existingShadow.getOid()); + } if (context != null && context.getChannel() != null) { @@ -1188,6 +1197,62 @@ private ProvisioningOperationOptions getProvisioningOptio return provisioningOptions; } + + // This is a bit of black magic. We only want to execute as self if there a user is changing its own password + // and we also have old password value. + // Later, this should be improved. Maybe we need special model operation option for this? Or maybe it should be somehow + // automatically detected based on resource capabilities? We do not know yet. Therefore let's do the simplest possible + // thing. Otherwise we might do something that we will later regret. + private boolean executeAsSelf(LensContext context, + ModelExecuteOptions modelOptions, PrismObject existingShadow, ObjectDelta delta) throws SecurityViolationException { + if (existingShadow == null) { + return false; + } + + if (!SchemaConstants.CHANNEL_GUI_SELF_SERVICE_URI.equals(context.getChannel())) { + return false; + } + + if (delta == null) { + return false; + } + if (!delta.isModify()) { + return false; + } + PropertyDelta passwordDelta = delta.findPropertyDelta(SchemaConstants.PATH_PASSWORD_VALUE); + if (passwordDelta == null) { + return false; + } + if (passwordDelta.getEstimatedOldValues() == null || passwordDelta.getEstimatedOldValues().isEmpty()) { + return false; + } + ProtectedStringType oldPassword = passwordDelta.getEstimatedOldValues().iterator().next().getValue(); + if (!oldPassword.canGetCleartext()) { + return false; + } + + LensFocusContext focusContext = context.getFocusContext(); + if (focusContext == null) { + return false; + } + if (!focusContext.canRepresent(UserType.class)) { + return false; + } + + MidPointPrincipal principal = securityContextManager.getPrincipal(); + if (principal == null) { + return false; + } + UserType loggedInUser = principal.getUser(); + if (loggedInUser == null) { + return false; + } + + if (!loggedInUser.getOid().equals(focusContext.getOid())) { + return false; + } + return true; + } private void logDeltaExecution(ObjectDelta objectDelta, LensContext context, ResourceType resource, OperationResult result, Task task) { @@ -1268,7 +1333,8 @@ private PrismObject executeAddit throw new UnsupportedOperationException("NodeType cannot be added using model interface"); } else if (ObjectTypes.isManagedByProvisioning(objectTypeToAdd)) { - ProvisioningOperationOptions provisioningOptions = getProvisioningOptions(context, options); + ProvisioningOperationOptions provisioningOptions = getProvisioningOptions(context, options, + (PrismObject)objectContext.getObjectCurrent(), (ObjectDelta)change); oid = addProvisioningObject(objectToAdd, context, objectContext, provisioningOptions, resource, task, result); @@ -1319,7 +1385,8 @@ private PrismObject executeDelet } else if (NodeType.class.isAssignableFrom(objectTypeClass)) { taskManager.deleteNode(oid, result); } else if (ObjectTypes.isClassManagedByProvisioning(objectTypeClass)) { - ProvisioningOperationOptions provisioningOptions = getProvisioningOptions(context, options); + ProvisioningOperationOptions provisioningOptions = getProvisioningOptions(context, options, + (PrismObject)objectContext.getObjectCurrent(), (ObjectDelta)change); try { objectAfterModification = deleteProvisioningObject(objectTypeClass, oid, context, objectContext, provisioningOptions, resource, task, result); @@ -1387,7 +1454,8 @@ private void executeModification(Ob } else if (NodeType.class.isAssignableFrom(objectTypeClass)) { throw new UnsupportedOperationException("NodeType is not modifiable using model interface"); } else if (ObjectTypes.isClassManagedByProvisioning(objectTypeClass)) { - ProvisioningOperationOptions provisioningOptions = getProvisioningOptions(context, options); + ProvisioningOperationOptions provisioningOptions = getProvisioningOptions(context, options, + (PrismObject)objectContext.getObjectCurrent(), (ObjectDelta)delta); String oid = modifyProvisioningObject(objectTypeClass, delta.getOid(), delta.getModifications(), context, objectContext, provisioningOptions, resource, task, result); diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/Clockwork.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/Clockwork.java index bcf021fef48..85151ee289e 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/Clockwork.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/Clockwork.java @@ -58,6 +58,7 @@ import com.evolveum.midpoint.provisioning.api.ResourceOperationListener; import com.evolveum.midpoint.repo.api.RepositoryService; import com.evolveum.midpoint.schema.ObjectDeltaOperation; +import com.evolveum.midpoint.schema.RelationRegistry; import com.evolveum.midpoint.schema.constants.ExpressionConstants; import com.evolveum.midpoint.schema.constants.ObjectTypes; import com.evolveum.midpoint.schema.constants.SchemaConstants; @@ -106,7 +107,6 @@ import javax.xml.namespace.QName; import java.util.*; -import java.util.Map.Entry; import static com.evolveum.midpoint.model.api.ProgressInformation.ActivityType.CLOCKWORK; import static com.evolveum.midpoint.model.api.ProgressInformation.ActivityType.WAITING; @@ -138,6 +138,7 @@ public class Clockwork { @Autowired private Clock clock; @Autowired private ModelObjectResolver objectResolver; @Autowired private SystemObjectCache systemObjectCache; + @Autowired private RelationRegistry relationRegistry; @Autowired private transient ProvisioningService provisioningService; @Autowired private transient ChangeNotificationDispatcher changeNotificationDispatcher; @Autowired private ExpressionFactory expressionFactory; @@ -926,10 +927,10 @@ private void setOperationContext(OperationExecutionType operation, task = task.getParentForLightweightAsynchronousTask(); } if (task.isPersistent()) { - operation.setTaskRef(ObjectTypeUtil.createObjectRef(task.getTaskPrismObject())); + operation.setTaskRef(ObjectTypeUtil.createObjectRef(task.getTaskPrismObject(), prismContext)); } operation.setStatus(overallStatus); - operation.setInitiatorRef(ObjectTypeUtil.createObjectRef(task.getOwner())); // TODO what if the real initiator is different? (e.g. when executing approved changes) + operation.setInitiatorRef(ObjectTypeUtil.createObjectRef(task.getOwner(), prismContext)); // TODO what if the real initiator is different? (e.g. when executing approved changes) operation.setChannel(channel); operation.setTimestamp(now); } @@ -1102,7 +1103,7 @@ private void auditEvent(LensContext context, AuditEven AuditEventRecord auditRecord = new AuditEventRecord(eventType, stage); if (primaryObject != null) { - auditRecord.setTarget(primaryObject.clone()); + auditRecord.setTarget(primaryObject.clone(), prismContext); // } else { // throw new IllegalStateException("No primary object in:\n"+context.dump()); } @@ -1540,7 +1541,7 @@ private void authorizeAssignmentRequ assignmentDelta.addValuesToAdd(changedAssignment.asPrismContainerValue().clone()); QName relation = targetRef.getRelation(); if (relation == null) { - relation = SchemaConstants.ORG_DEFAULT; + relation = prismContext.getDefaultRelation(); } AuthorizationParameters autzParams = new AuthorizationParameters.Builder() .object(object) @@ -1570,7 +1571,7 @@ private void authorizeAssignmentRequ LOGGER.debug("{} of target {} to {} allowed with {} authorization", operationDesc, target, object, assignActionUrl); continue; } - if (ObjectTypeUtil.isDelegationRelation(relation)) { + if (relationRegistry.isDelegation(relation)) { if (securityEnforcer.isAuthorized(ModelAuthorizationAction.DELEGATE.getUrl(), getRequestAuthorizationPhase(context), autzParams, ownerResolver, task, result)) { if (LOGGER.isDebugEnabled()) { LOGGER.debug("{} of target {} to {} allowed with {} authorization", operationDesc, target, object, ModelAuthorizationAction.DELEGATE.getUrl()); diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/EvaluatedAssignmentImpl.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/EvaluatedAssignmentImpl.java index 7244db80455..4f5ac0ff591 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/EvaluatedAssignmentImpl.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/EvaluatedAssignmentImpl.java @@ -30,8 +30,8 @@ import com.evolveum.midpoint.model.common.mapping.PrismValueDeltaSetTripleProducer; import com.evolveum.midpoint.prism.delta.DeltaSetTriple; import com.evolveum.midpoint.prism.delta.PlusMinusZero; +import com.evolveum.midpoint.schema.RelationRegistry; import com.evolveum.midpoint.schema.result.OperationResult; -import com.evolveum.midpoint.schema.util.ObjectTypeUtil; import com.evolveum.midpoint.security.api.Authorization; import com.evolveum.midpoint.task.api.Task; import com.evolveum.midpoint.util.DebugUtil; @@ -122,17 +122,24 @@ public AssignmentType getAssignmentType(boolean old) { return asContainerable(assignmentIdi.getSingleValue(old)); } - @Override - public QName getRelation() { + private ObjectReferenceType getTargetRef() { AssignmentType assignmentType = getAssignmentType(); if (assignmentType == null) { return null; } - ObjectReferenceType targetRef = assignmentType.getTargetRef(); - if (targetRef == null) { - return null; - } - return ObjectTypeUtil.normalizeRelation(targetRef.getRelation()); + return assignmentType.getTargetRef(); + } + + @Override + public QName getRelation() { + ObjectReferenceType targetRef = getTargetRef(); + return targetRef != null ? targetRef.getRelation() : null; + } + + @Override + public QName getNormalizedRelation(RelationRegistry relationRegistry) { + ObjectReferenceType targetRef = getTargetRef(); + return targetRef != null ? relationRegistry.normalizeRelation(targetRef.getRelation()) : null; } @NotNull diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/EvaluatedAssignmentTargetCache.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/EvaluatedAssignmentTargetCache.java index 9a330e939a9..45d8dfc807d 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/EvaluatedAssignmentTargetCache.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/EvaluatedAssignmentTargetCache.java @@ -80,7 +80,7 @@ private boolean isCacheable(AbstractRoleType targetType) { public boolean canSkip(AssignmentPathSegmentImpl segment, PlusMinusZero mode) { ObjectType target = segment.getTarget(); - if (target == null || !(target instanceof AbstractRoleType)) { + if (!(target instanceof AbstractRoleType)) { // LOGGER.trace("Non-skippable target: {}", target); return false; } diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/EvaluatedAssignmentTargetImpl.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/EvaluatedAssignmentTargetImpl.java index d57dd9f143a..ced3c10fd30 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/EvaluatedAssignmentTargetImpl.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/EvaluatedAssignmentTargetImpl.java @@ -18,11 +18,12 @@ import com.evolveum.midpoint.model.api.context.EvaluatedAssignmentTarget; import com.evolveum.midpoint.model.api.context.EvaluationOrder; import com.evolveum.midpoint.prism.PrismObject; -import com.evolveum.midpoint.schema.constants.SchemaConstants; +import com.evolveum.midpoint.schema.RelationRegistry; import com.evolveum.midpoint.util.DebugUtil; import com.evolveum.midpoint.xml.ns._public.common.common_3.*; import org.jetbrains.annotations.NotNull; +import javax.xml.namespace.QName; import java.util.ArrayList; import java.util.Collection; @@ -66,7 +67,7 @@ public boolean appliesToFocus() { } @Override - public boolean appliesToFocusWithAnyRelation() { + public boolean appliesToFocusWithAnyRelation(RelationRegistry relationRegistry) { // TODO clean up this method if (appliesToFocus()) { // This covers any indirectly assigned targets, like user -> org -> parent-org -> root-org -(I)-> role @@ -77,7 +78,17 @@ public boolean appliesToFocusWithAnyRelation() { // Actually I think these should be also covered by appliesToFocus() i.e. their isMatchingOrder should be true. // But for some reason it is currently not so. EvaluationOrder order = assignmentPath.last().getEvaluationOrder(); - return order.getSummaryOrder() == 1 || order.getSummaryOrder() == 0 && order.getMatchingRelationOrder(SchemaConstants.ORG_DEPUTY) > 0; + if (order.getSummaryOrder() == 1) { + return true; + } + if (order.getSummaryOrder() != 0) { + return false; + } + int delegationCount = 0; + for (QName delegationRelation : relationRegistry.getAllRelationsFor(RelationKindType.DELEGATION)) { + delegationCount += order.getMatchingRelationOrder(delegationRelation); + } + return delegationCount > 0; } @Override diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/EvaluatedPolicyRuleImpl.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/EvaluatedPolicyRuleImpl.java index e01e245d8c3..4c4cea39b52 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/EvaluatedPolicyRuleImpl.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/EvaluatedPolicyRuleImpl.java @@ -337,7 +337,7 @@ public List> extractShortMessages() { @Override public void addToEvaluatedPolicyRuleTypes(Collection rules, PolicyRuleExternalizationOptions options, - Predicate> triggerSelector) { + Predicate> triggerSelector, PrismContext prismContext) { EvaluatedPolicyRuleType rv = new EvaluatedPolicyRuleType(); rv.setRuleName(getName()); boolean isFull = options.getTriggeredRulesStorageStrategy() == FULL; @@ -345,7 +345,7 @@ public void addToEvaluatedPolicyRuleTypes(Collection ru rv.setAssignmentPath(assignmentPath.toAssignmentPathType(options.isIncludeAssignmentsContent())); } if (isFull && directOwner != null) { - rv.setDirectOwnerRef(ObjectTypeUtil.createObjectRef(directOwner)); + rv.setDirectOwnerRef(ObjectTypeUtil.createObjectRef(directOwner, prismContext)); rv.setDirectOwnerDisplayName(ObjectTypeUtil.getDisplayName(directOwner)); } for (EvaluatedPolicyRuleTrigger trigger : triggers) { @@ -354,10 +354,10 @@ public void addToEvaluatedPolicyRuleTypes(Collection ru } if (trigger instanceof EvaluatedSituationTrigger && trigger.isHidden()) { for (EvaluatedPolicyRule sourceRule : ((EvaluatedSituationTrigger) trigger).getSourceRules()) { - sourceRule.addToEvaluatedPolicyRuleTypes(rules, options, null); + sourceRule.addToEvaluatedPolicyRuleTypes(rules, options, null, prismContext); } } else { - rv.getTrigger().add(trigger.toEvaluatedPolicyRuleTriggerType(options)); + rv.getTrigger().add(trigger.toEvaluatedPolicyRuleTriggerType(options, prismContext)); } } if (rv.getTrigger().isEmpty()) { diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/EvaluationOrderImpl.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/EvaluationOrderImpl.java index 98bea9869ca..1ab5497bb66 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/EvaluationOrderImpl.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/EvaluationOrderImpl.java @@ -22,10 +22,9 @@ import javax.xml.namespace.QName; import com.evolveum.midpoint.model.api.context.EvaluationOrder; -import com.evolveum.midpoint.schema.constants.SchemaConstants; -import com.evolveum.midpoint.schema.util.ObjectTypeUtil; +import com.evolveum.midpoint.schema.RelationRegistry; +import com.evolveum.midpoint.schema.result.OperationResult; import com.evolveum.midpoint.util.DebugUtil; -import com.evolveum.midpoint.util.QNameUtil; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.collections4.MultiSet; import org.jetbrains.annotations.NotNull; @@ -37,16 +36,24 @@ public class EvaluationOrderImpl implements EvaluationOrder { public static EvaluationOrder UNDEFINED = new UndefinedEvaluationOrderImpl(); - public static EvaluationOrder ZERO = createZero(); - public static EvaluationOrder ONE = ZERO.advance(SchemaConstants.ORG_DEFAULT); @NotNull private final HashMap orderMap; // see checkConsistence + @NotNull private final RelationRegistry relationRegistry; + + public static EvaluationOrder zero(RelationRegistry relationRegistry) { + EvaluationOrderImpl eo = new EvaluationOrderImpl(relationRegistry); + eo.orderMap.put(relationRegistry.getDefaultRelation(), 0); + return eo; + } private void checkConsistence() { if (CHECK_CONSISTENCE) { orderMap.forEach((r, v) -> { - if (r == null || QNameUtil.noNamespace(r)) { - throw new IllegalStateException("Null or unqualified relation " + r + " in " + this); + if (r == null) { + throw new IllegalStateException("Null relation in " + this); + } + if (isNotNormalized(r)) { + throw new IllegalStateException("Unnormalized relation " + r + " in " + this); } if (v == null) { throw new IllegalStateException("Null value in for relation " + r + " in " + this); @@ -55,27 +62,27 @@ private void checkConsistence() { } } + private boolean isNotNormalized(QName relation) { + return relation == null || !relation.equals(relationRegistry.normalizeRelation(relation)); + } + private static final boolean CHECK_CONSISTENCE = true; - private EvaluationOrderImpl() { + private EvaluationOrderImpl(@NotNull RelationRegistry relationRegistry) { + this.relationRegistry = relationRegistry; orderMap = new HashMap<>(); } private EvaluationOrderImpl(EvaluationOrderImpl that) { + this.relationRegistry = that.relationRegistry; this.orderMap = new HashMap<>(that.orderMap); } - private static EvaluationOrderImpl createZero() { - EvaluationOrderImpl eo = new EvaluationOrderImpl(); - eo.orderMap.put(SchemaConstants.ORG_DEFAULT, 0); - return eo; - } - @Override public int getSummaryOrder() { int rv = 0; for (Entry entry : orderMap.entrySet()) { - if (!ObjectTypeUtil.isDelegationRelation(entry.getKey())) { + if (!relationRegistry.isDelegation(entry.getKey())) { rv += entry.getValue(); } } @@ -107,7 +114,7 @@ public EvaluationOrder decrease(MultiSet relations) { // must always be private: public interface will not allow to modify object state! private void advanceThis(QName relation, int amount) { - @NotNull QName normalizedRelation = ObjectTypeUtil.normalizeRelation(relation); + @NotNull QName normalizedRelation = relationRegistry.normalizeRelation(relation); orderMap.put(normalizedRelation, getMatchingRelationOrder(normalizedRelation) + amount); } @@ -117,13 +124,13 @@ public int getMatchingRelationOrder(QName relation) { if (relation == null) { return getSummaryOrder(); } - return orderMap.getOrDefault(ObjectTypeUtil.normalizeRelation(relation), 0); + return orderMap.getOrDefault(relationRegistry.normalizeRelation(relation), 0); } @Override public EvaluationOrder resetOrder(QName relation, int newOrder) { EvaluationOrderImpl clone = clone(); - clone.orderMap.put(ObjectTypeUtil.normalizeRelation(relation), newOrder); + clone.orderMap.put(relationRegistry.normalizeRelation(relation), newOrder); clone.checkConsistence(); return clone; } @@ -142,7 +149,7 @@ public Map diff(EvaluationOrder newState) { } @Override - public EvaluationOrder applyDifference(Map difference) { + public EvaluationOrder applyDifference(Map difference) { EvaluationOrderImpl clone = clone(); difference.forEach((relation, count) -> clone.advanceThis(relation, count)); clone.checkConsistence(); @@ -214,7 +221,8 @@ public void shortDump(StringBuilder sb) { @Override public Collection getExtraRelations() { return orderMap.entrySet().stream() - .filter(e -> !ObjectTypeUtil.isMembershipRelation(e.getKey()) && !ObjectTypeUtil.isDelegationRelation(e.getKey()) && e.getValue() > 0) + .filter(e -> !relationRegistry.isMembership(e.getKey()) && + !relationRegistry.isDelegation(e.getKey()) && e.getValue() > 0) .map(e -> e.getKey()) .collect(Collectors.toSet()); } diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/LensElementContext.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/LensElementContext.java index 3f2ce5e0022..93b2b61ad32 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/LensElementContext.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/LensElementContext.java @@ -654,14 +654,14 @@ private PrismObject cloneObject(PrismObject thisObject) { void storeIntoLensElementContextType(LensElementContextType lensElementContextType, boolean reduced) throws SchemaException { if (objectOld != null) { if (reduced) { - lensElementContextType.setObjectOldRef(ObjectTypeUtil.createObjectRef(objectOld)); + lensElementContextType.setObjectOldRef(ObjectTypeUtil.createObjectRef(objectOld, getPrismContext())); } else { lensElementContextType.setObjectOld(objectOld.asObjectable()); } } if (objectNew != null) { if (reduced) { - lensElementContextType.setObjectNewRef(ObjectTypeUtil.createObjectRef(objectNew)); + lensElementContextType.setObjectNewRef(ObjectTypeUtil.createObjectRef(objectNew, getPrismContext())); } else { lensElementContextType.setObjectNew(objectNew.asObjectable()); } diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/LensUtil.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/LensUtil.java index 74c84b3c17f..f2a26f20cea 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/LensUtil.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/LensUtil.java @@ -576,7 +576,7 @@ public static Collection getForcedA if (virtualAssignmenetSpecification != null) { ResultHandler handler = (object, parentResult) -> { - AssignmentType assignment = ObjectTypeUtil.createAssignmentTo(object); + AssignmentType assignment = ObjectTypeUtil.createAssignmentTo(object, prismContext); return forcedAssignments.add(assignment); }; @@ -906,11 +906,6 @@ public static LensObjectDeltaOperation createObjectDel return objectDeltaOp; } - @Deprecated - public static boolean isDelegationRelation(QName relation) { - return ObjectTypeUtil.isDelegationRelation(relation); - } - public static void triggerRule(@NotNull EvaluatedPolicyRule rule, Collection> triggers, Collection policySituations) { diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/OperationalDataManager.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/OperationalDataManager.java index 6474458b9af..936752516d8 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/OperationalDataManager.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/OperationalDataManager.java @@ -81,7 +81,7 @@ private MetadataType collectRequestMetadata(LensContext void applyCreateMetadata(LensContext context, metaData.setCreateChannel(channel); metaData.setCreateTimestamp(now); if (task.getOwner() != null) { - metaData.setCreatorRef(createObjectRef(task.getOwner())); + metaData.setCreatorRef(createObjectRef(task.getOwner(), prismContext)); } - metaData.setCreateTaskRef(task.getOid() != null ? createObjectRef(task.getTaskPrismObject()) : null); + metaData.setCreateTaskRef(task.getOid() != null ? createObjectRef(task.getTaskPrismObject(), prismContext) : null); } public Collection> createModifyMetadataDeltas(LensContext context, @@ -264,9 +264,9 @@ public Collection> c return DeltaBuilder.deltaFor(objectType, prismContext) .item(metadataPath.subPath(MetadataType.F_MODIFY_CHANNEL)).replace(LensUtil.getChannel(context, task)) .item(metadataPath.subPath(MetadataType.F_MODIFY_TIMESTAMP)).replace(now) - .item(metadataPath.subPath(MetadataType.F_MODIFIER_REF)).replace(createObjectRef(task.getOwner())) + .item(metadataPath.subPath(MetadataType.F_MODIFIER_REF)).replace(createObjectRef(task.getOwner(), prismContext)) .item(metadataPath.subPath(MetadataType.F_MODIFY_TASK_REF)).replaceRealValues( - task.getOid() != null ? singleton(createObjectRef(task.getTaskPrismObject())) : emptySet()) + task.getOid() != null ? singleton(createObjectRef(task.getTaskPrismObject(), prismContext)) : emptySet()) .asItemDeltas(); } diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/ActivationProcessor.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/ActivationProcessor.java index c4ec97bc14f..dbf0015b548 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/ActivationProcessor.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/ActivationProcessor.java @@ -765,6 +765,7 @@ private void reconcileOutboundValue(LensContext cont } } + LensUtil.setDeltaOldValue(projCtx, targetItemDelta); if (!targetItemDelta.isEmpty()) { LOGGER.trace("Reconciliation delta:\n{}", targetItemDelta.debugDumpLazily(1)); projCtx.swallowToSecondaryDelta(targetItemDelta); diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/MappingEvaluator.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/MappingEvaluator.java index 7b1bb9b77eb..c565aa18be7 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/MappingEvaluator.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/MappingEvaluator.java @@ -473,10 +473,13 @@ public boolean isMeaningful(PrismValueDeltaSetTriple mappingOutputTriple) { + private void applyEstematedOldValueInReplaceCase(ItemDelta targetItemDelta, + PrismValueDeltaSetTriple outputTriple) { + Collection nonPositiveValues = outputTriple.getNonPositiveValues(); + if (nonPositiveValues == null || nonPositiveValues.isEmpty()) { + return; + } + targetItemDelta.setEstimatedOldValues(PrismValue.cloneCollection(nonPositiveValues)); + } + + private boolean isMeaningful(PrismValueDeltaSetTriple mappingOutputTriple) { if (mappingOutputTriple == null) { // this means: mapping not applicable return false; diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/credentials/ProjectionCredentialsProcessor.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/credentials/ProjectionCredentialsProcessor.java index c4ffd52b4f2..78f1515d4ce 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/credentials/ProjectionCredentialsProcessor.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/credentials/ProjectionCredentialsProcessor.java @@ -190,7 +190,7 @@ private void processProjectionPasswordMapping(LensContext< boolean evaluateWeak = getEvaluateWeak(projCtx); - final ItemDeltaItem, PrismPropertyDefinition> userPasswordIdi = focusContext + final ItemDeltaItem, PrismPropertyDefinition> userPasswordIdi = focusContext .getObjectDeltaObject().findIdi(SchemaConstants.PATH_PASSWORD_VALUE); ValuePolicyResolver stringPolicyResolver = new ValuePolicyResolver() { @@ -249,6 +249,30 @@ public ValuePolicyType resolve() { } } } + + Collection> minusSet = outputTriple.getMinusSet(); + if (minusSet != null && !minusSet.isEmpty()) { + if (!canGetCleartext(minusSet)) { + // We have hashed values in minus set. That is not great, we won't be able to get + // cleartext from that if we need it (e.g. for runAs in provisioning). + // Therefore try to get old value from user password delta. If that matches with + // hashed value then we have the cleartext. + ProtectedStringType oldProjectionPassword = minusSet.iterator().next().getRealValue(); + PropertyDelta userPasswordDelta = (PropertyDelta) userPasswordIdi.getDelta(); + Collection> userPasswordDeltaOldValues = userPasswordDelta.getEstimatedOldValues(); + if (userPasswordDeltaOldValues != null && !userPasswordDeltaOldValues.isEmpty()) { + ProtectedStringType oldUserPassword = userPasswordDeltaOldValues.iterator().next().getRealValue(); + try { + if (oldUserPassword.canGetCleartext() && protector.compare(oldUserPassword, oldProjectionPassword)) { + outputTriple.clearMinusSet(); + outputTriple.addToMinusSet(new PrismPropertyValue<>(oldUserPassword)); + } + } catch (EncryptionException e) { + throw new SystemException(e.getMessage(), e); + } + } + } + } return true; }; diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/focus/AssignmentProcessor.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/focus/AssignmentProcessor.java index 119282701ae..af2bf3553f2 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/focus/AssignmentProcessor.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/focus/AssignmentProcessor.java @@ -28,6 +28,7 @@ import com.evolveum.midpoint.model.impl.lens.projector.MappingEvaluator; import com.evolveum.midpoint.model.impl.lens.projector.policy.PolicyRuleProcessor; import com.evolveum.midpoint.model.impl.util.ModelImplUtils; +import com.evolveum.midpoint.schema.RelationRegistry; import com.evolveum.midpoint.xml.ns._public.common.common_3.*; import org.jetbrains.annotations.NotNull; import org.springframework.beans.factory.annotation.Autowired; @@ -122,6 +123,9 @@ public class AssignmentProcessor { @Autowired private SystemObjectCache systemObjectCache; + @Autowired + private RelationRegistry relationRegistry; + @Autowired private PrismContext prismContext; @@ -725,7 +729,7 @@ private void createAssignmentDelta(LensContext context, ContainerDelta assignmentDelta = ContainerDelta.createDelta(FocusType.F_ASSIGNMENT, focusClass, prismContext); AssignmentType assignment = new AssignmentType(); ConstructionType constructionType = new ConstructionType(); - constructionType.setResourceRef(ObjectTypeUtil.createObjectRef(accountContext.getResource())); + constructionType.setResourceRef(ObjectTypeUtil.createObjectRef(accountContext.getResource(), prismContext)); assignment.setConstruction(constructionType); assignmentDelta.addValueToAdd(assignment.asPrismContainerValue()); PrismContainerDefinition containerDefinition = prismContext.getSchemaRegistry().findObjectDefinitionByCompileTimeClass(focusClass).findContainerDefinition(FocusType.F_ASSIGNMENT); @@ -970,15 +974,15 @@ private void addReferences(Collection extractedReferences, boolean found = false; for (PrismReferenceValue exVal: extractedReferences) { if (MiscUtil.equals(exVal.getOid(), reference.getOid()) - && ObjectTypeUtil.relationsEquivalent(exVal.getRelation(), reference.getRelation())) { + && prismContext.relationsEquivalent(exVal.getRelation(), reference.getRelation())) { found = true; break; } } if (!found) { PrismReferenceValue ref = reference.cloneComplex(CloneStrategy.REUSE); // clone without full object instead of calling canonicalize() - if (ref.getRelation() != null && QNameUtil.isUnqualified(ref.getRelation())) { - ref.setRelation(new QName(SchemaConstants.NS_ORG, ref.getRelation().getLocalPart(), SchemaConstants.PREFIX_NS_ORG)); + if (ref.getRelation() == null || QNameUtil.isUnqualified(ref.getRelation())) { + ref.setRelation(relationRegistry.normalizeRelation(ref.getRelation())); } extractedReferences.add(ref); } @@ -994,6 +998,7 @@ private AssignmentEvaluator createAssignmentEvaluator(L .channel(context.getChannel()) .objectResolver(objectResolver) .systemObjectCache(systemObjectCache) + .relationRegistry(relationRegistry) .prismContext(prismContext) .mappingFactory(mappingFactory) .mappingEvaluator(mappingEvaluator) diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/PolicyRuleEnforcer.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/PolicyRuleEnforcer.java index e23445dcdaa..8175ee4f864 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/PolicyRuleEnforcer.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/PolicyRuleEnforcer.java @@ -141,7 +141,7 @@ private void enforceTriggeredRules(EvaluationContext evalCtx, Collection enforceAll || t.isEnforcementOverride()); + t -> enforceAll || t.isEnforcementOverride(), prismContext); List> messageTrees = EvaluatedPolicyRuleUtil.extractMessages(triggersFiltered, EvaluatedPolicyRuleUtil.MessageKind.NORMAL); for (TreeNode messageTree : messageTrees) { diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/PolicyStateRecorder.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/PolicyStateRecorder.java index b0ed2ee6060..528ef035c63 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/PolicyStateRecorder.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/PolicyStateRecorder.java @@ -119,7 +119,7 @@ private ComputationResult compute(@NotNull List rulesToReco if (recordAction.getPolicyRules() != TriggeredPolicyRulesStorageStrategyType.NONE) { PolicyRuleExternalizationOptions externalizationOptions = new PolicyRuleExternalizationOptions( recordAction.getPolicyRules(), false, true); - rule.addToEvaluatedPolicyRuleTypes(cr.newTriggeredRules, externalizationOptions, null); + rule.addToEvaluatedPolicyRuleTypes(cr.newTriggeredRules, externalizationOptions, null, prismContext); } } cr.oldPolicySituations.addAll(existingPolicySituation); diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/evaluators/AssignmentModificationConstraintEvaluator.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/evaluators/AssignmentModificationConstraintEvaluator.java index fb3b46ee03e..b98891e2fee 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/evaluators/AssignmentModificationConstraintEvaluator.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/evaluators/AssignmentModificationConstraintEvaluator.java @@ -24,7 +24,6 @@ import com.evolveum.midpoint.prism.path.ItemPath; import com.evolveum.midpoint.schema.constants.SchemaConstants; import com.evolveum.midpoint.schema.result.OperationResult; -import com.evolveum.midpoint.schema.util.MiscSchemaUtil; import com.evolveum.midpoint.schema.util.ObjectTypeUtil; import com.evolveum.midpoint.util.LocalizableMessage; import com.evolveum.midpoint.util.LocalizableMessageBuilder; @@ -87,10 +86,11 @@ private LocalizableMessage createMessage(JAXBElement ctx, OperationResult result) throws ExpressionEvaluationException, ObjectNotFoundException, SchemaException, CommunicationException, ConfigurationException, SecurityViolationException { String keyPostfix = createStateKey(ctx) + createOperationKey(ctx); + QName relation = ctx.evaluatedAssignment.getNormalizedRelation(relationRegistry); LocalizableMessage builtInMessage = new LocalizableMessageBuilder() .key(SchemaConstants.DEFAULT_POLICY_CONSTRAINT_KEY_PREFIX + CONSTRAINT_KEY_PREFIX + keyPostfix) .arg(ObjectTypeUtil.createDisplayInformation(ctx.evaluatedAssignment.getTarget(), false)) - .arg(ctx.evaluatedAssignment.getRelation() != null ? ctx.evaluatedAssignment.getRelation().getLocalPart() : null) + .arg(relation != null ? relation.getLocalPart() : null) .build(); return evaluatorHelper.createLocalizableMessage(constraint, ctx, builtInMessage, result); } @@ -123,7 +123,7 @@ private boolean relationMatches(AssignmentModificationPoli List relationsToCheck = constraint.getRelation().isEmpty() ? singletonList(null) : constraint.getRelation(); for (QName constraintRelation : relationsToCheck) { - if (MiscSchemaUtil.compareRelation(constraintRelation, ctx.evaluatedAssignment.getRelation())) { + if (prismContext.relationMatches(constraintRelation, ctx.evaluatedAssignment.getNormalizedRelation(relationRegistry))) { return true; } } diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/evaluators/ExclusionConstraintEvaluator.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/evaluators/ExclusionConstraintEvaluator.java index 81ab61a2abb..1dbb2bbe425 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/evaluators/ExclusionConstraintEvaluator.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/evaluators/ExclusionConstraintEvaluator.java @@ -30,6 +30,7 @@ import com.evolveum.midpoint.prism.match.MatchingRuleRegistry; import com.evolveum.midpoint.prism.polystring.PolyString; import com.evolveum.midpoint.prism.query.ObjectFilter; +import com.evolveum.midpoint.schema.RelationRegistry; import com.evolveum.midpoint.schema.constants.SchemaConstants; import com.evolveum.midpoint.schema.result.OperationResult; import com.evolveum.midpoint.schema.util.ObjectTypeUtil; @@ -70,6 +71,7 @@ public class ExclusionConstraintEvaluator implements PolicyConstraintEvaluator EvaluatedPolicyRuleTrigger evaluate(JAXBElement second ? Collections.singletonList(primaryRelationToMatch) : new ArrayList<>(secondaryRelationsToMatch); if (relationsToMatch.isEmpty()) { - relationsToMatch.add(SchemaConstants.ORG_DEFAULT); + relationsToMatch.add(prismContext.getDefaultRelation()); } - return ObjectTypeUtil.relationMatches(relationsToMatch, assignment.getTargetRef().getRelation()); + return prismContext.relationMatches(relationsToMatch, assignment.getTargetRef().getRelation()); } } diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/evaluators/ModificationConstraintEvaluator.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/evaluators/ModificationConstraintEvaluator.java index f3f9e6d1b84..3782ad1c953 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/evaluators/ModificationConstraintEvaluator.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/evaluators/ModificationConstraintEvaluator.java @@ -18,6 +18,8 @@ import com.evolveum.midpoint.model.api.context.ModelState; import com.evolveum.midpoint.model.impl.lens.projector.policy.PolicyRuleEvaluationContext; +import com.evolveum.midpoint.prism.PrismContext; +import com.evolveum.midpoint.schema.RelationRegistry; import com.evolveum.midpoint.schema.result.OperationResult; import com.evolveum.midpoint.util.exception.*; import com.evolveum.midpoint.util.logging.Trace; @@ -40,6 +42,8 @@ public abstract class ModificationConstraintEvaluator String createStateKey(PolicyRuleEvaluationContext rctx) { diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/evaluators/MultiplicityConstraintEvaluator.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/evaluators/MultiplicityConstraintEvaluator.java index dda2d3119fb..2ba84b647bb 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/evaluators/MultiplicityConstraintEvaluator.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/policy/evaluators/MultiplicityConstraintEvaluator.java @@ -32,6 +32,7 @@ import com.evolveum.midpoint.prism.query.builder.S_AtomicFilterExit; import com.evolveum.midpoint.prism.xml.XsdTypeMapper; import com.evolveum.midpoint.repo.api.RepositoryService; +import com.evolveum.midpoint.schema.RelationRegistry; import com.evolveum.midpoint.schema.constants.SchemaConstants; import com.evolveum.midpoint.schema.result.OperationResult; import com.evolveum.midpoint.schema.util.ObjectTypeUtil; @@ -71,6 +72,7 @@ public class MultiplicityConstraintEvaluator implements PolicyConstraintEvaluato @Autowired private ConstraintEvaluatorHelper evaluatorHelper; @Autowired private PrismContext prismContext; + @Autowired private RelationRegistry relationRegistry; @Autowired @Qualifier("cacheRepositoryService") private RepositoryService repositoryService; @Override @@ -95,7 +97,7 @@ private EvaluatedPolicyRuleTrigger evaluateForObject( return null; } List relationsToCheck = constraint.getValue().getRelation().isEmpty() - ? Collections.singletonList(SchemaConstants.ORG_DEFAULT) : constraint.getValue().getRelation(); + ? Collections.singletonList(prismContext.getDefaultRelation()) : constraint.getValue().getRelation(); AbstractRoleType targetRole = (AbstractRoleType) target.asObjectable(); boolean isMin = QNameUtil.match(constraint.getName(), PolicyConstraintsType.F_MIN_ASSIGNEES) @@ -175,8 +177,8 @@ private EvaluatedPolicyRuleTrigger EvaluatedPolicyRuleTrigger ObjectTypeUtil.relationMatches(constraintRelation, relation)); + .anyMatch(constraintRelation -> prismContext.relationMatches(constraintRelation, relation)); } private List getConstraintRelations(MultiplicityPolicyConstraintType constraint) { return !constraint.getRelation().isEmpty() ? constraint.getRelation() : - Collections.singletonList(SchemaConstants.ORG_DEFAULT); + Collections.singletonList(prismContext.getDefaultRelation()); } /** diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/scripting/PipelineData.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/scripting/PipelineData.java index 1989c332131..e498bceb3c2 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/scripting/PipelineData.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/scripting/PipelineData.java @@ -178,7 +178,7 @@ private Collection resolveQuery(Class ObjectQuery query = QueryJaxbConvertor.createObjectQuery(type, queryBean, context.getPrismContext()); SearchResultList> objects = context.getModelService() .searchObjects(type, query, null, context.getTask(), result); - return objects.stream().map(o -> ObjectTypeUtil.createObjectRef(o)).collect(Collectors.toList()); + return objects.stream().map(o -> ObjectTypeUtil.createObjectRef(o, context.getPrismContext())).collect(Collectors.toList()); } static PipelineData parseFrom(ValueListType input, Map frozenInitialVariables, PrismContext prismContext) { diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/security/UserProfileServiceImpl.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/security/UserProfileServiceImpl.java index ce2d1795bdf..4b309495ecf 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/security/UserProfileServiceImpl.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/security/UserProfileServiceImpl.java @@ -41,19 +41,16 @@ import com.evolveum.midpoint.prism.delta.ObjectDelta; import com.evolveum.midpoint.prism.delta.PlusMinusZero; import com.evolveum.midpoint.prism.polystring.PolyString; -import com.evolveum.midpoint.prism.query.ObjectFilter; import com.evolveum.midpoint.prism.query.ObjectQuery; import com.evolveum.midpoint.prism.query.builder.QueryBuilder; import com.evolveum.midpoint.repo.api.RepositoryService; -import com.evolveum.midpoint.schema.ResultHandler; +import com.evolveum.midpoint.schema.RelationRegistry; import com.evolveum.midpoint.schema.SearchResultList; import com.evolveum.midpoint.schema.constants.ObjectTypes; import com.evolveum.midpoint.schema.result.OperationResult; import com.evolveum.midpoint.schema.util.AdminGuiConfigTypeUtil; import com.evolveum.midpoint.schema.util.FocusTypeUtil; -import com.evolveum.midpoint.schema.util.LifecycleUtil; import com.evolveum.midpoint.schema.util.ObjectQueryUtil; -import com.evolveum.midpoint.schema.util.ObjectTypeUtil; import com.evolveum.midpoint.security.api.Authorization; import com.evolveum.midpoint.security.api.AuthorizationTransformer; import com.evolveum.midpoint.security.api.DelegatorWithOtherPrivilegesLimitations; @@ -108,6 +105,7 @@ public class UserProfileServiceImpl implements UserProfileService, UserDetailsSe @Autowired @Qualifier("modelObjectResolver") private ObjectResolver objectResolver; @Autowired private SystemObjectCache systemObjectCache; + @Autowired private RelationRegistry relationRegistry; @Autowired private MappingFactory mappingFactory; @Autowired private MappingEvaluator mappingEvaluator; @Autowired private SecurityHelper securityHelper; @@ -238,6 +236,7 @@ private void initializePrincipalFromAssignments(MidPointPrincipal principal, Pri .channel(null) .objectResolver(objectResolver) .systemObjectCache(systemObjectCache) + .relationRegistry(relationRegistry) .prismContext(prismContext) .mappingFactory(mappingFactory) .mappingEvaluator(mappingEvaluator) @@ -282,7 +281,7 @@ private void initializePrincipalFromAssignments(MidPointPrincipal principal, Pri } for (EvaluatedAssignmentTarget target : assignment.getRoles().getNonNegativeValues()) { if (target.isValid() && target.getTarget() != null && target.getTarget().asObjectable() instanceof UserType - && DeputyUtils.isDelegationPath(target.getAssignmentPath())) { + && DeputyUtils.isDelegationPath(target.getAssignmentPath(), relationRegistry)) { List limitations = DeputyUtils.extractLimitations(target.getAssignmentPath()); principal.addDelegatorWithOtherPrivilegesLimitations(new DelegatorWithOtherPrivilegesLimitations( (UserType) target.getTarget().asObjectable(), limitations)); diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/sync/CorrelationConfirmationEvaluator.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/sync/CorrelationConfirmationEvaluator.java index e3f8bd192bb..130b1d44a0e 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/sync/CorrelationConfirmationEvaluator.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/sync/CorrelationConfirmationEvaluator.java @@ -28,6 +28,7 @@ import com.evolveum.midpoint.model.impl.expr.ModelExpressionThreadLocalHolder; import com.evolveum.midpoint.model.impl.util.ModelImplUtils; import com.evolveum.midpoint.prism.*; +import com.evolveum.midpoint.schema.RelationRegistry; import com.evolveum.midpoint.schema.util.ObjectTypeUtil; import org.apache.commons.lang.Validate; import org.springframework.beans.factory.annotation.Autowired; @@ -78,6 +79,9 @@ public class CorrelationConfirmationEvaluator { @Autowired(required = true) private PrismContext prismContext; + @Autowired + private RelationRegistry relationRegistry; + @Autowired(required = true) private ExpressionFactory expressionFactory; @@ -272,7 +276,7 @@ private boolean matchUserCorrelationRule(Class focusTyp } // we assume userType is already normalized w.r.t. relations - ObjectTypeUtil.normalizeFilter(q.getFilter()); + ObjectTypeUtil.normalizeFilter(q.getFilter(), relationRegistry); return ObjectQuery.match(userType, q.getFilter(), matchingRuleRegistry); } diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/sync/ReconciliationTaskHandler.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/sync/ReconciliationTaskHandler.java index 4142b6b5481..1c51086a69c 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/sync/ReconciliationTaskHandler.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/sync/ReconciliationTaskHandler.java @@ -238,7 +238,7 @@ public TaskWorkBucketProcessingResult run(Task localCoordinatorTask, WorkBucketT long reconStartTimestamp = clock.currentTimeMillis(); AuditEventRecord requestRecord = new AuditEventRecord(AuditEventType.RECONCILIATION, AuditEventStage.REQUEST); - requestRecord.setTarget(resource); + requestRecord.setTarget(resource, prismContext); requestRecord.setMessage("Stage: " + stage + ", Work bucket: " + workBucket); auditService.audit(requestRecord, localCoordinatorTask); @@ -320,7 +320,7 @@ public TaskWorkBucketProcessingResult run(Task localCoordinatorTask, WorkBucketT } AuditEventRecord executionRecord = new AuditEventRecord(AuditEventType.RECONCILIATION, AuditEventStage.EXECUTION); - executionRecord.setTarget(resource); + executionRecord.setTarget(resource, prismContext); executionRecord.setOutcome(OperationResultStatus.SUCCESS); executionRecord.setMessage(requestRecord.getMessage()); auditService.audit(executionRecord, localCoordinatorTask); @@ -391,7 +391,7 @@ public void launch(ResourceType resource, QName objectclass, Task task, Operatio task.setName(polyString); // Set reference to the resource - task.setObjectRef(ObjectTypeUtil.createObjectRef(resource)); + task.setObjectRef(ObjectTypeUtil.createObjectRef(resource, prismContext)); try { task.setExtensionPropertyValue(ModelConstants.OBJECTCLASS_PROPERTY_NAME, objectclass); @@ -453,7 +453,7 @@ private void processErrorFinal(TaskRunResult runResult, String errorDesc, Except runResult.setRunResultStatus(runResultStatus); AuditEventRecord executionRecord = new AuditEventRecord(AuditEventType.RECONCILIATION, AuditEventStage.EXECUTION); - executionRecord.setTarget(resource); + executionRecord.setTarget(resource, prismContext); executionRecord.setOutcome(OperationResultStatus.FATAL_ERROR); executionRecord.setMessage(ex.getMessage()); auditService.audit(executionRecord , task); @@ -553,7 +553,7 @@ private boolean performShadowReconciliation(final PrismObject reso .item(ShadowType.F_FULL_SYNCHRONIZATION_TIMESTAMP).le(XmlTypeConverter.createXMLGregorianCalendar(startTimestamp)) .or().item(ShadowType.F_FULL_SYNCHRONIZATION_TIMESTAMP).isNull() .endBlock() - .and().item(ShadowType.F_RESOURCE_REF).ref(ObjectTypeUtil.createObjectRef(resource).asReferenceValue()) + .and().item(ShadowType.F_RESOURCE_REF).ref(ObjectTypeUtil.createObjectRef(resource, prismContext).asReferenceValue()) .and().item(ShadowType.F_OBJECT_CLASS).eq(objectclassDef.getTypeName()) .build(); diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/validator/ResourceValidatorImpl.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/validator/ResourceValidatorImpl.java index 7cce81316d5..cc44142780a 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/validator/ResourceValidatorImpl.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/validator/ResourceValidatorImpl.java @@ -94,9 +94,10 @@ private static class ResourceValidationContext { ResourceValidationContext( @NotNull PrismObject resourceObject, @NotNull Scope scope, @NotNull Task task, - @NotNull ValidationResult validationResult, ResourceSchema resourceSchema) { + @NotNull ValidationResult validationResult, ResourceSchema resourceSchema, + PrismContext prismContext) { this.resourceObject = resourceObject; - this.resourceRef = ObjectTypeUtil.createObjectRef(resourceObject); + this.resourceRef = ObjectTypeUtil.createObjectRef(resourceObject, prismContext); this.scope = scope; this.task = task; this.validationResult = validationResult; @@ -118,10 +119,10 @@ public ValidationResult validate(@NotNull PrismObject resourceObje } catch (Throwable t) { vr.add(Issue.Severity.WARNING, CAT_SCHEMA, C_NO_SCHEMA, getString(CLASS_DOT + C_NO_SCHEMA, t.getMessage()), - ObjectTypeUtil.createObjectRef(resourceObject), ItemPath.EMPTY_PATH); + ObjectTypeUtil.createObjectRef(resourceObject, prismContext), ItemPath.EMPTY_PATH); } - ResourceValidationContext ctx = new ResourceValidationContext(resourceObject, scope, task, vr, resourceSchema); + ResourceValidationContext ctx = new ResourceValidationContext(resourceObject, scope, task, vr, resourceSchema, prismContext); SchemaHandlingType schemaHandling = resource.getSchemaHandling(); if (schemaHandling != null) { diff --git a/model/model-impl/src/test/java/com/evolveum/midpoint/model/impl/lens/TestAbstractAssignmentEvaluator.java b/model/model-impl/src/test/java/com/evolveum/midpoint/model/impl/lens/TestAbstractAssignmentEvaluator.java index 7e75f58811a..5a7b3211d9e 100644 --- a/model/model-impl/src/test/java/com/evolveum/midpoint/model/impl/lens/TestAbstractAssignmentEvaluator.java +++ b/model/model-impl/src/test/java/com/evolveum/midpoint/model/impl/lens/TestAbstractAssignmentEvaluator.java @@ -37,6 +37,7 @@ import com.evolveum.midpoint.model.impl.lens.projector.Projector; import com.evolveum.midpoint.prism.delta.DeltaSetTriple; import com.evolveum.midpoint.prism.xml.XmlTypeConverter; +import com.evolveum.midpoint.schema.RelationRegistry; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.test.annotation.DirtiesContext; @@ -96,6 +97,9 @@ public abstract class TestAbstractAssignmentEvaluator extends AbstractLensTest { @Autowired private SystemObjectCache systemObjectCache; + @Autowired + private RelationRegistry relationRegistry; + @Autowired private Clock clock; @@ -1002,6 +1006,7 @@ protected AssignmentEvaluator createAssignmentEvaluator(ObjectDeltaObj .focusOdo(focusOdo) .objectResolver(objectResolver) .systemObjectCache(systemObjectCache) + .relationRegistry(relationRegistry) .prismContext(prismContext) .activationComputer(activationComputer) .now(clock.currentTimeXMLGregorianCalendar()) diff --git a/model/model-impl/src/test/java/com/evolveum/midpoint/model/impl/lens/TestAssignmentProcessor2.java b/model/model-impl/src/test/java/com/evolveum/midpoint/model/impl/lens/TestAssignmentProcessor2.java index 082a64ded58..27da9707c51 100644 --- a/model/model-impl/src/test/java/com/evolveum/midpoint/model/impl/lens/TestAssignmentProcessor2.java +++ b/model/model-impl/src/test/java/com/evolveum/midpoint/model/impl/lens/TestAssignmentProcessor2.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010-2017 Evolveum + * Copyright (c) 2010-2018 Evolveum * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -374,7 +374,7 @@ public void test050JackDeputyOfBarbossa() throws Exception { rule.setName("barbossa-0"); policyRuleAssignment.setPolicyRule(rule); @SuppressWarnings({"unchecked", "raw" }) - ObjectDelta objectDelta = (ObjectDelta) DeltaBuilder.deltaFor(UserType.class, prismContext) + ObjectDelta objectDelta = deltaFor(UserType.class) .item(UserType.F_ASSIGNMENT).add( ObjectTypeUtil.createAssignmentTo(ROLE_R1_OID, ObjectTypes.ROLE, prismContext), policyRuleAssignment) @@ -459,7 +459,7 @@ public void test060JackDeputyOfGuybrushDeputyOfBarbossa() throws Exception { rule.setName("guybrush-0"); policyRuleAssignment.setPolicyRule(rule); @SuppressWarnings({"unchecked", "raw" }) - ObjectDelta objectDelta = (ObjectDelta) DeltaBuilder.deltaFor(UserType.class, prismContext) + ObjectDelta objectDelta = deltaFor(UserType.class) .item(UserType.F_ASSIGNMENT).add(deputyOfBarbossaAssignment, policyRuleAssignment) .asObjectDelta(USER_GUYBRUSH_OID); executeChangesAssertSuccess(objectDelta, null, task, result); @@ -534,6 +534,7 @@ public void test062JackDeputyOfGuybrushDeputyOfBarbossaInLoginMode() throws Exce .channel(context.getChannel()) .objectResolver(objectResolver) .systemObjectCache(systemObjectCache) + .relationRegistry(relationRegistry) .prismContext(prismContext) .mappingFactory(mappingFactory) .mappingEvaluator(mappingEvaluator) @@ -2038,7 +2039,7 @@ private void createObjectsInFourthPart(boolean deleteFirst, Task task, Operation assign(org11, org1); assign(org21, org2); // org1->roleAdmin - AssignmentType inducement = ObjectTypeUtil.createAssignmentTo(roleAdmin.asPrismObject()) + AssignmentType inducement = ObjectTypeUtil.createAssignmentTo(roleAdmin.asPrismObject(), prismContext) .beginOrderConstraint() .orderMin("1") .orderMax("unbounded") @@ -2047,7 +2048,7 @@ private void createObjectsInFourthPart(boolean deleteFirst, Task task, Operation org1.getInducement().add(inducement); // org2->roleAdmin - AssignmentType inducement2 = ObjectTypeUtil.createAssignmentTo(roleAdmin.asPrismObject()) + AssignmentType inducement2 = ObjectTypeUtil.createAssignmentTo(roleAdmin.asPrismObject(), prismContext) .beginOrderConstraint() .order(1) .relation(SchemaConstants.ORG_MANAGER) @@ -2068,7 +2069,7 @@ private void createObjectsInFourthPart(boolean deleteFirst, Task task, Operation * Org41 Admin */ assign(org41, org4); - AssignmentType inducement4 = ObjectTypeUtil.createAssignmentTo(roleAdmin.asPrismObject()) + AssignmentType inducement4 = ObjectTypeUtil.createAssignmentTo(roleAdmin.asPrismObject(), prismContext) .beginOrderConstraint() .orderMin("0") .orderMax("unbounded") @@ -2228,7 +2229,7 @@ private String createDumpConditionCode(String text) { } private void induce(AbstractRoleType source, AbstractRoleType target, int inducementOrder) { - AssignmentType inducement = ObjectTypeUtil.createAssignmentTo(target.asPrismObject()); + AssignmentType inducement = ObjectTypeUtil.createAssignmentTo(target.asPrismObject(), prismContext); if (inducementOrder > 1) { inducement.setOrder(inducementOrder); } @@ -2236,12 +2237,12 @@ private void induce(AbstractRoleType source, AbstractRoleType target, int induce } private void assign(AbstractRoleType source, AbstractRoleType target) { - AssignmentType assignment = ObjectTypeUtil.createAssignmentTo(target.asPrismObject()); + AssignmentType assignment = ObjectTypeUtil.createAssignmentTo(target.asPrismObject(), prismContext); source.getAssignment().add(assignment); } private void assign(AbstractRoleType source, AbstractRoleType target, QName relation) { - AssignmentType assignment = ObjectTypeUtil.createAssignmentTo(target.asPrismObject()); + AssignmentType assignment = ObjectTypeUtil.createAssignmentTo(target.asPrismObject(), prismContext); assignment.getTargetRef().setRelation(relation); source.getAssignment().add(assignment); } diff --git a/model/model-impl/src/test/java/com/evolveum/midpoint/model/impl/lens/TestPolicyRules.java b/model/model-impl/src/test/java/com/evolveum/midpoint/model/impl/lens/TestPolicyRules.java index 4a2893b8947..59db6d44d1f 100644 --- a/model/model-impl/src/test/java/com/evolveum/midpoint/model/impl/lens/TestPolicyRules.java +++ b/model/model-impl/src/test/java/com/evolveum/midpoint/model/impl/lens/TestPolicyRules.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010-2017 Evolveum + * Copyright (c) 2010-2018 Evolveum * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -630,7 +630,7 @@ public void test300DrakeChangeEmployeeType() throws Exception { // WHEN TestUtil.displayWhen(TEST_NAME); - ObjectDelta delta = (ObjectDelta) DeltaBuilder.deltaFor(UserType.class, prismContext) + ObjectDelta delta = deltaFor(UserType.class) .item(UserType.F_ASSIGNMENT) .add(ObjectTypeUtil.createAssignmentTo(ROLE_JUDGE_OID, ObjectTypes.ROLE, prismContext)) .item(UserType.F_EMPLOYEE_TYPE).replace("T") diff --git a/model/model-impl/src/test/java/com/evolveum/midpoint/model/impl/lens/TestPolicyRules2.java b/model/model-impl/src/test/java/com/evolveum/midpoint/model/impl/lens/TestPolicyRules2.java index f68c8729b0d..cd63e124e9b 100644 --- a/model/model-impl/src/test/java/com/evolveum/midpoint/model/impl/lens/TestPolicyRules2.java +++ b/model/model-impl/src/test/java/com/evolveum/midpoint/model/impl/lens/TestPolicyRules2.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010-2017 Evolveum + * Copyright (c) 2010-2018 Evolveum * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -244,7 +244,7 @@ public void test120JackAttemptToMoveTo1900AndAssignRoleStudent() throws Exceptio fillContextWithUser(context, USER_JACK_OID, result); AssignmentType assignment = ObjectTypeUtil.createAssignmentTo(roleStudentOid, ObjectTypes.ROLE, prismContext); assignment.beginActivation().validTo("2099-01-01T00:00:00"); - context.getFocusContext().addPrimaryDelta((ObjectDelta) DeltaBuilder.deltaFor(UserType.class, prismContext) + context.getFocusContext().addPrimaryDelta(DeltaBuilder.deltaFor(UserType.class, prismContext) .item(UserType.F_ASSIGNMENT).add(assignment) .item(UserType.F_COST_CENTER).replace("1900") .asObjectDelta(USER_JACK_OID)); @@ -297,7 +297,7 @@ public void test130JackMoveTo1900AndAssignRoleStudent() throws Exception { fillContextWithUser(context, USER_JACK_OID, result); AssignmentType assignment = ObjectTypeUtil.createAssignmentTo(roleStudentOid, ObjectTypes.ROLE, prismContext); assignment.beginActivation().validTo("2099-01-01T00:00:00"); - context.getFocusContext().addPrimaryDelta((ObjectDelta) DeltaBuilder.deltaFor(UserType.class, prismContext) + context.getFocusContext().addPrimaryDelta(DeltaBuilder.deltaFor(UserType.class, prismContext) .item(UserType.F_ASSIGNMENT).add(assignment) .item(UserType.F_COST_CENTER).replace("1900") .asObjectDelta(USER_JACK_OID)); @@ -353,7 +353,7 @@ public void test135JackChangeValidTo() throws Exception { LensContext context = createUserLensContext(); fillContextWithUser(context, USER_JACK_OID, result); - context.getFocusContext().addPrimaryDelta((ObjectDelta) DeltaBuilder.deltaFor(UserType.class, prismContext) + context.getFocusContext().addPrimaryDelta(DeltaBuilder.deltaFor(UserType.class, prismContext) .item(UserType.F_ASSIGNMENT, assignmentId, AssignmentType.F_ACTIVATION, ActivationType.F_VALID_TO).replace() .asObjectDelta(USER_JACK_OID)); display("Input context", context); @@ -501,7 +501,7 @@ public void test150FrankAttemptToAssignRoleStudentButDisabled() throws Exception LensContext context = createUserLensContext(); fillContextWithUser(context, userFrankOid, result); - context.getFocusContext().addPrimaryDelta((ObjectDelta) DeltaBuilder.deltaFor(UserType.class, prismContext) + context.getFocusContext().addPrimaryDelta(DeltaBuilder.deltaFor(UserType.class, prismContext) .item(UserType.F_ASSIGNMENT).add( ObjectTypeUtil.createAssignmentTo(roleStudentOid, ObjectTypes.ROLE, prismContext) .beginActivation() diff --git a/model/model-impl/src/test/java/com/evolveum/midpoint/model/impl/misc/TestRelationRegistry.java b/model/model-impl/src/test/java/com/evolveum/midpoint/model/impl/misc/TestRelationRegistry.java new file mode 100644 index 00000000000..fc9c7539ea9 --- /dev/null +++ b/model/model-impl/src/test/java/com/evolveum/midpoint/model/impl/misc/TestRelationRegistry.java @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2010-2018 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. + */ +package com.evolveum.midpoint.model.impl.misc; + +import com.evolveum.midpoint.model.impl.AbstractInternalModelIntegrationTest; +import com.evolveum.midpoint.schema.RelationRegistry; +import com.evolveum.midpoint.schema.constants.RelationTypes; +import com.evolveum.midpoint.schema.constants.SchemaConstants; +import com.evolveum.midpoint.schema.result.OperationResult; +import com.evolveum.midpoint.task.api.Task; +import com.evolveum.midpoint.test.util.MidPointTestConstants; +import com.evolveum.midpoint.util.exception.SchemaException; +import com.evolveum.midpoint.xml.ns._public.common.common_3.RelationDefinitionType; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.annotation.DirtiesContext.ClassMode; +import org.springframework.test.context.ContextConfiguration; +import org.testng.annotations.Test; + +import java.io.File; + +import static com.evolveum.midpoint.util.QNameUtil.unqualify; +import static org.testng.AssertJUnit.*; + +/** + * @author mederly + * + */ +@ContextConfiguration(locations = {"classpath:ctx-model-test-main.xml"}) +@DirtiesContext(classMode = ClassMode.AFTER_CLASS) +public class TestRelationRegistry extends AbstractInternalModelIntegrationTest { + + protected static final File TEST_DIR = new File(MidPointTestConstants.TEST_RESOURCES_DIR, "misc"); + + @Autowired protected RelationRegistry relationRegistry; + + @Test + public void test100DefaultRelations() throws SchemaException { + final String TEST_NAME = "test100DefaultRelations"; + + Task task = taskManager.createTaskInstance(TEST_NAME); + OperationResult result = task.getResult(); + + assertEquals("Wrong # of default relations", RelationTypes.values().length, relationRegistry.getRelationDefinitions().size()); + + RelationDefinitionType orgDefaultDef = relationRegistry.getRelationDefinition(SchemaConstants.ORG_DEFAULT); + RelationDefinitionType defaultDef = relationRegistry.getRelationDefinition(unqualify(SchemaConstants.ORG_DEFAULT)); + RelationDefinitionType nullDef = relationRegistry.getRelationDefinition(null); + assertNotNull("No definition for null relation", nullDef); + assertEquals("null and 'org:default' definitions differ", nullDef, orgDefaultDef); + assertEquals("null and 'default' definitions differ", nullDef, defaultDef); + + assertTrue(relationRegistry.isManager(SchemaConstants.ORG_MANAGER)); + assertTrue(relationRegistry.isManager(unqualify(SchemaConstants.ORG_MANAGER))); + assertFalse(relationRegistry.isManager(SchemaConstants.ORG_APPROVER)); + assertFalse(relationRegistry.isManager(unqualify(SchemaConstants.ORG_APPROVER))); + assertFalse(relationRegistry.isManager(SchemaConstants.ORG_DEFAULT)); + assertFalse(relationRegistry.isManager(unqualify(SchemaConstants.ORG_DEFAULT))); + assertFalse(relationRegistry.isManager(null)); + + assertTrue(relationRegistry.isMembership(SchemaConstants.ORG_DEFAULT)); + assertTrue(relationRegistry.isMembership(unqualify(SchemaConstants.ORG_DEFAULT))); + assertTrue(relationRegistry.isMembership(null)); + assertTrue(relationRegistry.isMembership(SchemaConstants.ORG_MANAGER)); + assertTrue(relationRegistry.isMembership(unqualify(SchemaConstants.ORG_MANAGER))); + assertFalse(relationRegistry.isMembership(SchemaConstants.ORG_APPROVER)); + assertFalse(relationRegistry.isMembership(unqualify(SchemaConstants.ORG_APPROVER))); + + // TODO + } + +} diff --git a/model/model-impl/src/test/java/com/evolveum/midpoint/model/impl/visualizer/TestVisualizer.java b/model/model-impl/src/test/java/com/evolveum/midpoint/model/impl/visualizer/TestVisualizer.java index d68a41a774f..110344d167d 100644 --- a/model/model-impl/src/test/java/com/evolveum/midpoint/model/impl/visualizer/TestVisualizer.java +++ b/model/model-impl/src/test/java/com/evolveum/midpoint/model/impl/visualizer/TestVisualizer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010-2017 Evolveum + * Copyright (c) 2010-2018 Evolveum * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,7 +22,6 @@ import com.evolveum.midpoint.prism.PrismContext; import com.evolveum.midpoint.prism.PrismObject; import com.evolveum.midpoint.prism.delta.ObjectDelta; -import com.evolveum.midpoint.prism.delta.builder.DeltaBuilder; import com.evolveum.midpoint.prism.util.PrismTestUtil; import com.evolveum.midpoint.prism.xml.XmlTypeConverter; import com.evolveum.midpoint.schema.MidPointPrismContextFactory; @@ -138,7 +137,7 @@ public void test200UserDeltaBasic() throws Exception { final String TEST_NAME = "test200UserDeltaBasic"; Task task = createTask(TEST_NAME); - ObjectDelta delta = DeltaBuilder.deltaFor(UserType.class, prismContext) + ObjectDelta delta = deltaFor(UserType.class) .item(UserType.F_NAME).replace("admin") .asObjectDelta(USER_ADMINISTRATOR_OID); @@ -164,7 +163,7 @@ public void test210UserDeltaContainers() throws Exception { ass1.getActivation().setValidTo(XmlTypeConverter.createXMLGregorianCalendar(2017, 1, 1, 0, 0, 0)); ass1.setTargetRef(createObjectRef(ROLE_SUPERUSER_OID, ROLE)); - ObjectDelta delta = DeltaBuilder.deltaFor(UserType.class, prismContext) + ObjectDelta delta = deltaFor(UserType.class) .item(UserType.F_NAME).replace("admin") .item(UserType.F_ACTIVATION, ActivationType.F_ADMINISTRATIVE_STATUS).replace(ActivationStatusType.ENABLED) .item(UserType.F_ASSIGNMENT, 1, AssignmentType.F_TARGET_REF).replace(createObjectRef("123", ROLE).asReferenceValue()) @@ -188,7 +187,7 @@ public void test212UserDeltaContainerSimple() throws Exception { final String TEST_NAME = "test212UserDeltaContainerSimple"; Task task = createTask(TEST_NAME); - ObjectDelta delta = DeltaBuilder.deltaFor(UserType.class, prismContext) + ObjectDelta delta = deltaFor(UserType.class) .item(UserType.F_ACTIVATION, ActivationType.F_EFFECTIVE_STATUS).replace(ActivationStatusType.ENABLED) .item(UserType.F_ACTIVATION, ActivationType.F_ENABLE_TIMESTAMP).replace(XmlTypeConverter.createXMLGregorianCalendar(new Date())) .asObjectDelta(USER_ADMINISTRATOR_OID); @@ -218,7 +217,7 @@ public void test220UserContainerReplace() throws Exception { ActivationType act1 = new ActivationType(prismContext); act1.setAdministrativeStatus(ActivationStatusType.DISABLED); - ObjectDelta delta = DeltaBuilder.deltaFor(UserType.class, prismContext) + ObjectDelta delta = deltaFor(UserType.class) .item(UserType.F_NAME).replace("admin") .item(UserType.F_ACTIVATION).replace(act1) .item(UserType.F_ASSIGNMENT).replace(ass1) @@ -246,7 +245,7 @@ public void test230UserContainerDelete() throws Exception { AssignmentType ass2 = new AssignmentType(prismContext); ass2.setId(99999L); - ObjectDelta delta = DeltaBuilder.deltaFor(UserType.class, prismContext) + ObjectDelta delta = deltaFor(UserType.class) .item(UserType.F_NAME).replace("admin") .item(UserType.F_ASSIGNMENT).delete(ass1, ass2) .asObjectDelta(USER_ADMINISTRATOR_OID); @@ -274,7 +273,7 @@ public void test300UserAssignmentPreview() throws Exception { ass1.setConstruction(new ConstructionType(prismContext)); ass1.getConstruction().setResourceRef(createObjectRef(RESOURCE_DUMMY_OID, RESOURCE)); - ObjectDelta delta = (ObjectDelta) DeltaBuilder.deltaFor(UserType.class, prismContext) + ObjectDelta delta = deltaFor(UserType.class) .item(UserType.F_ASSIGNMENT).add(ass1) .asObjectDelta(USER_JACK_OID); @@ -309,7 +308,7 @@ public void test305UserAssignmentAdd() throws Exception { ass1.setConstruction(new ConstructionType()); ass1.getConstruction().setResourceRef(createObjectRef(RESOURCE_DUMMY_OID, RESOURCE)); - ObjectDelta delta = (ObjectDelta) DeltaBuilder.deltaFor(UserType.class, prismContext) + ObjectDelta delta = deltaFor(UserType.class) .item(UserType.F_ASSIGNMENT).add(ass1) .asObjectDelta(USER_JACK_OID); @@ -332,7 +331,7 @@ public void test307UserDisablePreview() throws Exception { final String TEST_NAME = "test307UserDisablePreview"; Task task = createTask(TEST_NAME); - ObjectDelta delta = (ObjectDelta) DeltaBuilder.deltaFor(UserType.class, prismContext) + ObjectDelta delta = deltaFor(UserType.class) .item(UserType.F_ACTIVATION, ActivationType.F_ADMINISTRATIVE_STATUS).replace(ActivationStatusType.DISABLED) .asObjectDelta(USER_JACK_OID); @@ -381,7 +380,7 @@ public void test310UserLinkRefDelete() throws Exception { assertEquals("wrong # of linkrefs", 1, jack.getLinkRef().size()); dummyAccountOid = jack.getLinkRef().get(0).getOid(); - ObjectDelta delta = (ObjectDelta) DeltaBuilder.deltaFor(UserType.class, prismContext) + ObjectDelta delta = deltaFor(UserType.class) .item(UserType.F_LINK_REF).delete(createObjectRef(dummyAccountOid, SHADOW).asReferenceValue()) .asObjectDelta(USER_JACK_OID); @@ -401,7 +400,7 @@ public void test320UserLinkRefAdd() throws Exception { final String TEST_NAME = "test320UserLinkRefAdd"; Task task = createTask(TEST_NAME); - ObjectDelta delta = (ObjectDelta) DeltaBuilder.deltaFor(UserType.class, prismContext) + ObjectDelta delta = deltaFor(UserType.class) .item(UserType.F_LINK_REF).add(createObjectRef(dummyAccountOid, SHADOW).asReferenceValue()) .asObjectDelta(USER_JACK_OID); @@ -421,7 +420,7 @@ public void test330UserLinkRefReplaceNoOp() throws Exception { final String TEST_NAME = "test330UserLinkRefReplaceNoOp"; Task task = createTask(TEST_NAME); - ObjectDelta delta = (ObjectDelta) DeltaBuilder.deltaFor(UserType.class, prismContext) + ObjectDelta delta = deltaFor(UserType.class) .item(UserType.F_LINK_REF).replace(createObjectRef(dummyAccountOid, SHADOW).asReferenceValue()) .asObjectDelta(USER_JACK_OID); @@ -441,7 +440,7 @@ public void test340UserLinkRefReplaceOp() throws Exception { final String TEST_NAME = "test340UserLinkRefReplaceOp"; Task task = createTask(TEST_NAME); - ObjectDelta delta = (ObjectDelta) DeltaBuilder.deltaFor(UserType.class, prismContext) + ObjectDelta delta = deltaFor(UserType.class) .item(UserType.F_LINK_REF).replace(createObjectRef("777", SHADOW).asReferenceValue()) .asObjectDelta(USER_JACK_OID); diff --git a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/AbstractConfiguredModelIntegrationTest.java b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/AbstractConfiguredModelIntegrationTest.java index 13bb1d23e5a..315940b9899 100644 --- a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/AbstractConfiguredModelIntegrationTest.java +++ b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/AbstractConfiguredModelIntegrationTest.java @@ -41,10 +41,7 @@ import com.evolveum.midpoint.util.exception.*; import com.evolveum.midpoint.util.logging.Trace; import com.evolveum.midpoint.util.logging.TraceManager; -import com.evolveum.midpoint.xml.ns._public.common.common_3.RoleType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.SystemObjectsType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.TaskType; -import com.evolveum.midpoint.xml.ns._public.common.common_3.UserType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.*; import org.testng.AssertJUnit; import org.testng.IHookCallBack; @@ -297,6 +294,9 @@ public class AbstractConfiguredModelIntegrationTest extends AbstractModelIntegra protected static final File ROLE_ADMINS_FILE = new File(COMMON_DIR, "role-admins.xml"); protected static final String ROLE_ADMINS_OID = "be835a70-e3f4-11e6-82cb-9b47ecb57v15"; + protected static final File ROLE_END_USER_FILE = new File(COMMON_DIR, "role-end-user.xml"); + protected static final String ROLE_END_USER_OID = "00000000-0000-0000-0000-00000000aa0f"; + public static final File USER_JACK_FILE = new File(COMMON_DIR, "user-jack.xml"); public static final String USER_JACK_OID = "c0c010c0-d34d-b33f-f00d-111111111111"; public static final String USER_JACK_USERNAME = "jack"; @@ -557,17 +557,21 @@ public void initSystem(Task initTask, OperationResult initResult) throws Except ManualConnectorInstance.setRandomDelayRange(0); // System Configuration + PrismObject configuration; try { File systemConfigurationFile = getSystemConfigurationFile(); if (systemConfigurationFile != null) { - repoAddObjectFromFile(systemConfigurationFile, initResult); + configuration = repoAddObjectFromFile(systemConfigurationFile, initResult); } else { - addSystemConfigurationObject(initResult); + configuration = addSystemConfigurationObject(initResult); } } catch (ObjectAlreadyExistsException e) { throw new ObjectAlreadyExistsException("System configuration already exists in repository;" + "looks like the previous test haven't cleaned it up", e); } + if (configuration != null) { + relationRegistry.applyRelationConfiguration(configuration.asObjectable()); + } // Users userAdministrator = repoAddObjectFromFile(USER_ADMINISTRATOR_FILE, UserType.class, initResult); @@ -588,8 +592,9 @@ protected File getSystemConfigurationFile() { } // to be used in very specific cases only (it is invoked when getSystemConfigurationFile returns null). - protected void addSystemConfigurationObject(OperationResult initResult) throws IOException, CommonException, + protected PrismObject addSystemConfigurationObject(OperationResult initResult) throws IOException, CommonException, EncryptionException { + return null; } protected PrismObject getDefaultActor() { diff --git a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestActivation.java b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestActivation.java index 28b7034f71d..b3cb5b0a4c1 100644 --- a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestActivation.java +++ b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestActivation.java @@ -2664,7 +2664,7 @@ public void test600AddUser1() throws Exception { PrismObject user1 = prismContext.createObject(UserType.class); DeltaBuilder.deltaFor(UserType.class, prismContext) .item(UserType.F_NAME).replace(new PolyString("user1")) - .item(UserType.F_ASSIGNMENT).add(ObjectTypeUtil.createAssignmentTo(resourceDummyCoral).asPrismContainerValue()) + .item(UserType.F_ASSIGNMENT).add(ObjectTypeUtil.createAssignmentTo(resourceDummyCoral, prismContext).asPrismContainerValue()) .item(ACTIVATION_ADMINISTRATIVE_STATUS_PATH).replace(ActivationStatusType.DISABLED) .asObjectDelta(null) .applyTo((PrismObject) user1); diff --git a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestConsistencySimple.java b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestConsistencySimple.java index df98cd94e6d..b12c3cf4ba9 100644 --- a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestConsistencySimple.java +++ b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestConsistencySimple.java @@ -175,7 +175,7 @@ private void executeTest(final String TEST_NAME, FocusOperation focusOperation, if (shadowOperation != ShadowOperation.KEEP) { @SuppressWarnings("unchecked") - ObjectDelta removeLinkRefDelta = (ObjectDelta) DeltaBuilder.deltaFor(UserType.class, prismContext) + ObjectDelta removeLinkRefDelta = deltaFor(UserType.class) .item(UserType.F_LINK_REF).replace() .asObjectDelta(USER_JACK_OID); executeChanges(removeLinkRefDelta, ModelExecuteOptions.createRaw(), task, result); @@ -188,7 +188,7 @@ private void executeTest(final String TEST_NAME, FocusOperation focusOperation, } else { if (shadowOperation == ShadowOperation.UNLINK_AND_TOMBSTONE) { @SuppressWarnings("unchecked") - ObjectDelta markAsDead = (ObjectDelta) DeltaBuilder.deltaFor(ShadowType.class, prismContext) + ObjectDelta markAsDead = deltaFor(ShadowType.class) .item(ShadowType.F_DEAD).replace(Boolean.TRUE) .asObjectDelta(shadowBefore.getOid()); executeChanges(markAsDead, ModelExecuteOptions.createRaw(), task, result); @@ -280,7 +280,7 @@ private void cleanUpBeforeTest(Task task, OperationResult result) throws Excepti for (ObjectReferenceType ref : jack.asObjectable().getLinkRef()) { deleteObject(ShadowType.class, ref.getOid()); } - ObjectDelta killLinkRefDelta = (ObjectDelta) DeltaBuilder.deltaFor(UserType.class, prismContext) + ObjectDelta killLinkRefDelta = deltaFor(UserType.class) .item(UserType.F_LINK_REF).replace().asObjectDelta(USER_JACK_OID); executeChanges(killLinkRefDelta, ModelExecuteOptions.createRaw(), task, result); } diff --git a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestMisc.java b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestMisc.java index c313cc614f8..f8a75bdc9d8 100644 --- a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestMisc.java +++ b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestMisc.java @@ -287,7 +287,7 @@ public void test320DefaultRelations() throws Exception { // WHEN displayWhen(TEST_NAME); - List relations = modelInteractionService.getRelationDefinitions(result); + List relations = modelInteractionService.getRelationDefinitions(); // THEN displayThen(TEST_NAME); diff --git a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestNotifications.java b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestNotifications.java index e62c6eb397e..39f5e31834b 100644 --- a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestNotifications.java +++ b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestNotifications.java @@ -92,13 +92,15 @@ protected File getSystemConfigurationFile() { } @Override - protected void addSystemConfigurationObject(OperationResult initResult) throws IOException, CommonException, + protected PrismObject addSystemConfigurationObject(OperationResult initResult) throws IOException, CommonException, EncryptionException { List configLines = IOUtils.readLines(new FileReader(SYSTEM_CONFIGURATION_FILE)); String configString = StringUtils.join(configLines, '\n'); int port = startHttpServer(); configString = configString.replaceAll("\\$\\$port\\$\\$", Integer.toString(port)); - repoAddObject(prismContext.parseObject(configString), initResult); + PrismObject sysconfigObject = prismContext.parseObject(configString); + repoAddObject(sysconfigObject, initResult); + return sysconfigObject; } private int startHttpServer() throws IOException { diff --git a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestRaceConditions.java b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestRaceConditions.java index f96d8af30b1..00ea556eadf 100644 --- a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestRaceConditions.java +++ b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestRaceConditions.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010-2017 Evolveum + * Copyright (c) 2010-2018 Evolveum * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -70,7 +70,7 @@ public void test100AssignRoles() throws Exception { // WHEN TestUtil.displayWhen(TEST_NAME); @SuppressWarnings({"unchecked", "raw"}) - ObjectDelta objectDelta = (ObjectDelta) DeltaBuilder.deltaFor(UserType.class, prismContext) + ObjectDelta objectDelta = deltaFor(UserType.class) .item(UserType.F_ASSIGNMENT).add( ObjectTypeUtil.createAssignmentTo(ROLE_PIRATE_OID, ObjectTypes.ROLE, prismContext), ObjectTypeUtil.createAssignmentTo(ROLE_SAILOR_OID, ObjectTypes.ROLE, prismContext)) @@ -131,7 +131,7 @@ private void deleteAssignment(PrismObject user, int index, Task task, try { login(userAdministrator); @SuppressWarnings({ "unchecked", "raw" }) - ObjectDelta objectDelta = (ObjectDelta) DeltaBuilder.deltaFor(UserType.class, prismContext) + ObjectDelta objectDelta = deltaFor(UserType.class) .item(FocusType.F_ASSIGNMENT).delete(user.asObjectable().getAssignment().get(index).clone()) .asObjectDelta(USER_JACK_OID); modelService.executeChanges(Collections.singletonList(objectDelta), null, task, diff --git a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/gensync/TestEditSchema.java b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/gensync/TestEditSchema.java index 51492359737..a75c9653760 100644 --- a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/gensync/TestEditSchema.java +++ b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/gensync/TestEditSchema.java @@ -58,11 +58,9 @@ import com.evolveum.midpoint.schema.RetrieveOption; import com.evolveum.midpoint.schema.SearchResultList; import com.evolveum.midpoint.schema.SelectorOptions; -import com.evolveum.midpoint.schema.internals.InternalCounters; import com.evolveum.midpoint.schema.constants.SchemaConstants; import com.evolveum.midpoint.schema.result.OperationResult; import com.evolveum.midpoint.schema.util.MiscSchemaUtil; -import com.evolveum.midpoint.schema.util.ObjectTypeUtil; import com.evolveum.midpoint.task.api.Task; import com.evolveum.midpoint.test.IntegrationTestTools; import com.evolveum.midpoint.test.util.TestUtil; @@ -1087,36 +1085,28 @@ public void test210UserDefinition() throws Exception { result.computeStatus(); TestUtil.assertSuccess(result); - assertPropertyValues(user, UserType.F_ADDITIONAL_NAME, new Validator>() { - @Override - public void validate(PrismPropertyDefinition propDef, String name) throws Exception { - assertNotNull("No definition for additionalName in user", propDef); - assertEquals("Wrong additionalName displayName", "Middle Name", propDef.getDisplayName()); - assertTrue("additionalName not readable", propDef.canRead()); - } + assertPropertyValues(user, UserType.F_ADDITIONAL_NAME, (propDef, name) -> { + assertNotNull("No definition for additionalName in user", propDef); + assertEquals("Wrong additionalName displayName", "Middle Name", propDef.getDisplayName()); + assertTrue("additionalName not readable", propDef.canRead()); }, PrismTestUtil.createPolyString("Jackie")); - assertPropertyValues(user, UserType.F_COST_CENTER, new Validator>() { - @Override - public void validate(PrismPropertyDefinition propDef, String name) throws Exception { - assertNotNull("No definition for costCenter in user", propDef); - assertEquals("Wrong costCenter displayOrder", (Integer)123, propDef.getDisplayOrder()); - assertTrue("costCenter not readable", propDef.canRead()); - } + assertPropertyValues(user, UserType.F_COST_CENTER, (Validator>) (propDef, name) -> { + assertNotNull("No definition for costCenter in user", propDef); + assertEquals("Wrong costCenter displayOrder", (Integer)123, propDef.getDisplayOrder()); + assertTrue("costCenter not readable", propDef.canRead()); }); - assertPropertyValues(user, UserType.F_PREFERRED_LANGUAGE, new Validator>() { - @Override - public void validate(PrismPropertyDefinition propDef, String name) throws Exception { - assertNotNull("No definition for preferredLanguage in user", propDef); - assertEquals("Wrong preferredLanguage displayName", "Language", propDef.getDisplayName()); - assertTrue("preferredLanguage not readable", propDef.canRead()); - PrismReferenceValue valueEnumerationRef = propDef.getValueEnumerationRef(); - assertNotNull("No valueEnumerationRef for preferredLanguage", valueEnumerationRef); - assertEquals("Wrong valueEnumerationRef OID for preferredLanguage", LOOKUP_LANGUAGES_OID, valueEnumerationRef.getOid()); - } - }); + assertPropertyValues(user, UserType.F_PREFERRED_LANGUAGE, + (Validator>) (propDef, name) -> { + assertNotNull("No definition for preferredLanguage in user", propDef); + assertEquals("Wrong preferredLanguage displayName", "Language", propDef.getDisplayName()); + assertTrue("preferredLanguage not readable", propDef.canRead()); + PrismReferenceValue valueEnumerationRef = propDef.getValueEnumerationRef(); + assertNotNull("No valueEnumerationRef for preferredLanguage", valueEnumerationRef); + assertEquals("Wrong valueEnumerationRef OID for preferredLanguage", LOOKUP_LANGUAGES_OID, valueEnumerationRef.getOid()); + }); assertContainer(user, UserType.F_CREDENTIALS, (credentialsDef, name) -> { assertNotNull("No definition for credentials in user", credentialsDef); @@ -1167,34 +1157,25 @@ public void test213ModifiedUserJack() throws Exception { result.computeStatus(); TestUtil.assertSuccess(result); - assertPropertyValues(user, UserType.F_ADDITIONAL_NAME, new Validator>() { - @Override - public void validate(PrismPropertyDefinition propDef, String name) throws Exception { - assertNotNull("No definition for additionalName in user", propDef); - assertEquals("Wrong additionalName displayName", "Middle Name", propDef.getDisplayName()); - assertTrue("additionalName not readable", propDef.canRead()); - } + assertPropertyValues(user, UserType.F_ADDITIONAL_NAME, (propDef, name) -> { + assertNotNull("No definition for additionalName in user", propDef); + assertEquals("Wrong additionalName displayName", "Middle Name", propDef.getDisplayName()); + assertTrue("additionalName not readable", propDef.canRead()); }, PrismTestUtil.createPolyString("Jackie")); - assertPropertyValues(user, UserType.F_COST_CENTER, new Validator>() { - @Override - public void validate(PrismPropertyDefinition propDef, String name) throws Exception { - assertNotNull("No definition for costCenter in user", propDef); - assertEquals("Wrong costCenter displayOrder", (Integer)123, propDef.getDisplayOrder()); - assertTrue("costCenter not readable", propDef.canRead()); - } + assertPropertyValues(user, UserType.F_COST_CENTER, (propDef, name) -> { + assertNotNull("No definition for costCenter in user", propDef); + assertEquals("Wrong costCenter displayOrder", (Integer)123, propDef.getDisplayOrder()); + assertTrue("costCenter not readable", propDef.canRead()); },"G001"); // This is set by user template - assertPropertyValues(user, UserType.F_PREFERRED_LANGUAGE, new Validator>() { - @Override - public void validate(PrismPropertyDefinition propDef, String name) throws Exception { - assertNotNull("No definition for preferredLanguage in user", propDef); - assertEquals("Wrong preferredLanguage displayName", "Language", propDef.getDisplayName()); - assertTrue("preferredLanguage not readable", propDef.canRead()); - PrismReferenceValue valueEnumerationRef = propDef.getValueEnumerationRef(); - assertNotNull("No valueEnumerationRef for preferredLanguage", valueEnumerationRef); - assertEquals("Wrong valueEnumerationRef OID for preferredLanguage", LOOKUP_LANGUAGES_OID, valueEnumerationRef.getOid()); - } + assertPropertyValues(user, UserType.F_PREFERRED_LANGUAGE, (propDef, name) -> { + assertNotNull("No definition for preferredLanguage in user", propDef); + assertEquals("Wrong preferredLanguage displayName", "Language", propDef.getDisplayName()); + assertTrue("preferredLanguage not readable", propDef.canRead()); + PrismReferenceValue valueEnumerationRef = propDef.getValueEnumerationRef(); + assertNotNull("No valueEnumerationRef for preferredLanguage", valueEnumerationRef); + assertEquals("Wrong valueEnumerationRef OID for preferredLanguage", LOOKUP_LANGUAGES_OID, valueEnumerationRef.getOid()); }, "en_PR"); @@ -1209,12 +1190,7 @@ public void validate(PrismContainerDefinition credentialsDef, S }, true); assertProperty(user, new ItemPath(UserType.F_CREDENTIALS, CredentialsType.F_PASSWORD, PasswordType.F_VALUE), - new Validator>() { - @Override - public void validate(PrismPropertyDefinition propDef, String name) throws Exception { - assertTrue("Password not readable", propDef.canRead()); - } - }); + (Validator>) (propDef, name) -> assertTrue("Password not readable", propDef.canRead())); assertUntouchedUserDefinition(); assertSteadyResources(); @@ -1382,7 +1358,7 @@ public void test300RoleTypes() throws Exception { final String TEST_NAME="test300RoleTypes"; displayTestTitle(TEST_NAME); - assertRoleTypes(getUser(USER_JACK_OID), "application","system","it"); + assertRoleTypes(getUser(USER_JACK_OID), "application","system", "it"); } /** @@ -1398,7 +1374,7 @@ public void test310CustomRelations() throws Exception { // WHEN displayWhen(TEST_NAME); - List relations = modelInteractionService.getRelationDefinitions(result); + List relations = modelInteractionService.getRelationDefinitions(); // THEN displayThen(TEST_NAME); diff --git a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/password/AbstractPasswordTest.java b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/password/AbstractPasswordTest.java index 9241b041645..36c453b25a3 100644 --- a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/password/AbstractPasswordTest.java +++ b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/password/AbstractPasswordTest.java @@ -27,6 +27,7 @@ import com.evolveum.midpoint.prism.delta.builder.DeltaBuilder; import com.evolveum.midpoint.test.DummyResourceContoller; import com.evolveum.midpoint.test.IntegrationTestTools; +import com.evolveum.midpoint.test.asserter.UserAsserter; import com.evolveum.midpoint.test.util.MidPointTestConstants; import com.evolveum.midpoint.util.exception.*; import com.evolveum.midpoint.xml.ns._public.common.common_3.*; @@ -80,6 +81,8 @@ public abstract class AbstractPasswordTest extends AbstractInitializedModelInteg protected static final String USER_PASSWORD_VALID_2 = "abcd223"; protected static final String USER_PASSWORD_VALID_3 = "abcd323"; protected static final String USER_PASSWORD_VALID_4 = "abcd423"; + protected static final String USER_PASSWORD_VALID_5 = "abcd523"; + protected static final String USER_PASSWORD_VALID_6 = "abcd623"; // Very long and very simple password. This is meant to violate the policies. protected static final String USER_PASSWORD_LLL_CLEAR = "lllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll"; @@ -152,6 +155,8 @@ public void initSystem(Task initTask, OperationResult initResult) throws Excepti repoAddObjectFromFile(USER_THREE_HEADED_MONKEY_FILE, UserType.class, true, initResult); + repoAddObjectFromFile(ROLE_END_USER_FILE, initResult); + importObjectFromFile(PASSWORD_POLICY_MAVERICK_FILE); initDummyResourcePirate(RESOURCE_DUMMY_MAVERICK_NAME, RESOURCE_DUMMY_MAVERICK_FILE, RESOURCE_DUMMY_MAVERICK_OID, initTask, initResult); @@ -1280,8 +1285,7 @@ public void test222ModifyUserJackPasswordBadContainer() throws Exception { } // THEN - result.computeStatus(); - TestUtil.assertFailure(result); + assertFailure(result); assertJackPasswordsWithHistory(USER_PASSWORD_VALID_1, USER_PASSWORD_AA_CLEAR); assertNoUserPasswordNotifications(); @@ -1391,8 +1395,7 @@ private void doTestModifyUserJackPasswordSuccessWithHistory(final String TEST_NA modifyUserChangePassword(USER_JACK_OID, newPassword, task, result); // THEN - result.computeStatus(); - TestUtil.assertSuccess(result); + assertSuccess(result); lastPasswordChangeEnd = clock.currentTimeXMLGregorianCalendar(); @@ -1426,8 +1429,7 @@ private void doTestModifyUserJackPasswordFailureWithHistory(final String TEST_NA } // THEN - result.computeStatus(); - TestUtil.assertFailure(result); + assertFailure(result); assertJackPasswordsWithHistory(oldPassword, expectedPasswordHistory); @@ -1478,7 +1480,7 @@ public void test300TwoParentOrgRefs() throws Exception { display("jack", jack); assertEquals("Wrong # of parentOrgRefs", 2, jack.getParentOrgRef().size()); - ObjectDelta orgDelta = (ObjectDelta) DeltaBuilder.deltaFor(OrgType.class, prismContext) + ObjectDelta orgDelta = DeltaBuilder.deltaFor(OrgType.class, prismContext) .item(OrgType.F_PASSWORD_POLICY_REF).replace(new PrismReferenceValue(PASSWORD_POLICY_GLOBAL_OID)) .asObjectDelta(ORG_GOVERNOR_OFFICE_OID); executeChanges(orgDelta, null, task, result); @@ -1498,8 +1500,7 @@ public void test300TwoParentOrgRefs() throws Exception { } // THEN - result.computeStatus(); - TestUtil.assertFailure(result); + assertFailure(result); PrismObject userJack = getUser(USER_JACK_OID); display("User after change execution", userJack); @@ -1779,8 +1780,8 @@ public void test316UserRecompute() throws Exception { } /** - * Change password again so we have predictable password instead of - * randomly-generated one. + * Change password to set predictable password instead of randomly-generated one. + * That will be nicer for future tests. */ @Test public void test318ChangeUserPassword() throws Exception { @@ -1791,27 +1792,33 @@ public void test318ChangeUserPassword() throws Exception { Task task = createTask(TEST_NAME); OperationResult result = task.getResult(); prepareTest(); - + // WHEN - TestUtil.displayWhen(TEST_NAME); + displayWhen(TEST_NAME); modifyUserChangePassword(USER_JACK_OID, USER_PASSWORD_VALID_3, task, result); // THEN - TestUtil.displayThen(TEST_NAME); - result.computeStatus(); - TestUtil.assertSuccess(result); - - PrismObject userAfter = getUser(USER_JACK_OID); - display("User after change execution", userAfter); - assertUserPassword(userAfter, USER_PASSWORD_VALID_3); - assertLinks(userAfter, 4); - - // password mapping is normal - assertDummyPassword(ACCOUNT_JACK_DUMMY_USERNAME, USER_PASSWORD_VALID_3); + displayThen(TEST_NAME); + assertSuccess(result); - // password mapping is strong - assertDummyAccount(RESOURCE_DUMMY_RED_NAME, ACCOUNT_JACK_DUMMY_USERNAME, USER_JACK_FULL_NAME, true); - assertDummyPassword(RESOURCE_DUMMY_RED_NAME, ACCOUNT_JACK_DUMMY_USERNAME, USER_PASSWORD_VALID_3); + PrismObject userAfter = assertUserAfter(USER_JACK_OID) + .assertPassword(USER_PASSWORD_VALID_3, getPasswordStorageType()) + .assertLinks(4) + .getObject(); + + // default password mapping is normal + assertDummyAccountByUsername(null, ACCOUNT_JACK_DUMMY_USERNAME) + .assertPassword(USER_PASSWORD_VALID_3) + // Admin password reset, no runAs + .assertLastModifier(null); + + // RED password mapping is strong + assertDummyAccountByUsername(RESOURCE_DUMMY_RED_NAME, ACCOUNT_JACK_DUMMY_USERNAME) + .assertFullName(USER_JACK_FULL_NAME) + .assertEnabled() + .assertPassword(USER_PASSWORD_VALID_3) + // and RED resource has no runAs capability + .assertLastModifier(null); // password mapping is weak assertDummyAccount(RESOURCE_DUMMY_BLUE_NAME, ACCOUNT_JACK_DUMMY_USERNAME, USER_JACK_FULL_NAME, true); @@ -3486,7 +3493,237 @@ private void testJackManyPasswordChangesAttempt(String TEST_NAME, String passwor assertDummyPassword(ACCOUNT_JACK_DUMMY_USERNAME, newPassword); assertDummyPassword(RESOURCE_DUMMY_RED_NAME, ACCOUNT_JACK_DUMMY_USERNAME, newPassword); } + + /** + * Jack changing his own password. He does it as an admin + * and there is no old password specified. RunAs should NOT be used. + * + * This also sets predictable password for next test. + * + * MID-4661 + */ + @Test + public void test560ChangeJackPasswordSuperuser() throws Exception { + final String TEST_NAME = "test560ChangeJackPasswordSuperuser"; + displayTestTitle(TEST_NAME); + + // GIVEN + prepareTest(); + + assignRole(USER_JACK_OID, ROLE_SUPERUSER_OID); + + // preconditions + assertUserBefore(USER_JACK_OID) + .displayWithProjections() + .assertLinks(4); + + assertDummyAccountByUsername(null, ACCOUNT_JACK_DUMMY_USERNAME) + .assertLastModifier(null); + + login(USER_JACK_USERNAME); + + Task task = createTask(TEST_NAME, getSecurityContextPrincipal()); + task.setChannel(SchemaConstants.CHANNEL_GUI_USER_URI); + OperationResult result = task.getResult(); + + // WHEN + displayWhen(TEST_NAME); + modifyUserChangePassword(USER_JACK_OID, USER_PASSWORD_VALID_4, task, result); + + // THEN + displayThen(TEST_NAME); + login(USER_ADMINISTRATOR_USERNAME); + assertSuccess(result); + + assertUserAfter(USER_JACK_OID) + .assertPassword(USER_PASSWORD_VALID_4, getPasswordStorageType()) + .assertLinks(4) + .getObject(); + + // default password mapping is normal + assertDummyAccountByUsername(null, ACCOUNT_JACK_DUMMY_USERNAME) + .assertPassword(USER_PASSWORD_VALID_4) + .assertLastModifier(null); + + // RED password mapping is strong + assertDummyAccountByUsername(RESOURCE_DUMMY_RED_NAME, ACCOUNT_JACK_DUMMY_USERNAME) + .assertFullName(USER_JACK_FULL_NAME) + .assertEnabled() + .assertPassword(USER_PASSWORD_VALID_4) + // and RED resource has no runAs capability + .assertLastModifier(null); + + // BLUE password mapping is weak, we do not really care about password change here + // we do not really care about ugly resource either + + displayAccountPasswordNotifications(); + assertAccountPasswordNotifications(2); + assertHasAccountPasswordNotification(null, USER_JACK_USERNAME, USER_PASSWORD_VALID_4); + assertHasAccountPasswordNotification(RESOURCE_DUMMY_RED_NAME, USER_JACK_USERNAME, USER_PASSWORD_VALID_4); + // not BLUE, it already has a password + assertSingleUserPasswordNotification(USER_JACK_USERNAME, USER_PASSWORD_VALID_4); + } + + private ObjectDelta createOldNewPasswordDelta(String oid, String oldPassword, String newPassword) throws SchemaException { + ProtectedStringType oldPasswordPs = new ProtectedStringType(); + oldPasswordPs.setClearValue(oldPassword); + + ProtectedStringType newPasswordPs = new ProtectedStringType(); + newPasswordPs.setClearValue(newPassword); + + return deltaFor(UserType.class) + .item(PASSWORD_VALUE_PATH) + .oldRealValue(oldPasswordPs) + .replace(newPasswordPs) + .asObjectDelta(USER_JACK_OID); + } + + /** + * Self-service password change. User's own identity should be used + * to change password on resource that have runAs capability. + * + * MID-4661 + */ + @Test + public void test562ChangeJackPasswordSelfService() throws Exception { + final String TEST_NAME = "test562ChangeJackPasswordSelfService"; + displayTestTitle(TEST_NAME); + + // GIVEN + prepareTest(); + + // preconditions + assertUserBefore(USER_JACK_OID) + .displayWithProjections() + .assertLinks(4); + + assertDummyAccountByUsername(null, ACCOUNT_JACK_DUMMY_USERNAME) + .assertPassword(USER_PASSWORD_VALID_4) + .assertLastModifier(null); + + login(USER_JACK_USERNAME); + + Task task = createTask(TEST_NAME, getSecurityContextPrincipal()); + task.setChannel(SchemaConstants.CHANNEL_GUI_SELF_SERVICE_URI); + OperationResult result = task.getResult(); + + ObjectDelta objectDelta = createOldNewPasswordDelta(USER_JACK_OID, + USER_PASSWORD_VALID_4, USER_PASSWORD_VALID_5); + + // WHEN + displayWhen(TEST_NAME); + executeChanges(objectDelta, null, task, result); + + // THEN + displayThen(TEST_NAME); + login(USER_ADMINISTRATOR_USERNAME); + assertSuccess(result); + + assertUserAfter(USER_JACK_OID) + .assertPassword(USER_PASSWORD_VALID_5, getPasswordStorageType()) + .assertLinks(4) + .getObject(); + + // default password mapping is normal + assertDummyAccountByUsername(null, ACCOUNT_JACK_DUMMY_USERNAME) + .assertPassword(USER_PASSWORD_VALID_5) + .assertLastModifier(ACCOUNT_JACK_DUMMY_USERNAME); + + // RED password mapping is strong + assertDummyAccountByUsername(RESOURCE_DUMMY_RED_NAME, ACCOUNT_JACK_DUMMY_USERNAME) + .assertFullName(USER_JACK_FULL_NAME) + .assertEnabled() + .assertPassword(USER_PASSWORD_VALID_5) + // and RED resource has no runAs capability + .assertLastModifier(null); + + // BLUE password mapping is weak, we do not really care about password change here + // we do not really care about ugly resource either + + displayAccountPasswordNotifications(); + assertAccountPasswordNotifications(2); + assertHasAccountPasswordNotification(null, USER_JACK_USERNAME, USER_PASSWORD_VALID_5); + assertHasAccountPasswordNotification(RESOURCE_DUMMY_RED_NAME, USER_JACK_USERNAME, USER_PASSWORD_VALID_5); + // not BLUE, it already has a password + assertSingleUserPasswordNotification(USER_JACK_USERNAME, USER_PASSWORD_VALID_5); + } + + /** + * Admin is changing Jack's password. + * Old password is (strangely) specified. + * But as this is not user changing its own password then RunAs + * should NOT be used. + * + * MID-4661 + */ + @Test + public void test564ChangeJackPasswordAdmin() throws Exception { + final String TEST_NAME = "test564ChangeJackPasswordAdmin"; + displayTestTitle(TEST_NAME); + + // GIVEN + + prepareTest(); + + // preconditions + assertUserBefore(USER_JACK_OID) + .displayWithProjections() + .assertLinks(4); + + assertDummyAccountByUsername(null, ACCOUNT_JACK_DUMMY_USERNAME) + .assertPassword(USER_PASSWORD_VALID_5) + .assertLastModifier(ACCOUNT_JACK_DUMMY_USERNAME); + + login(USER_ADMINISTRATOR_USERNAME); + + Task task = createTask(TEST_NAME, getSecurityContextPrincipal()); + task.setChannel(SchemaConstants.CHANNEL_GUI_USER_URI); + OperationResult result = task.getResult(); + + ObjectDelta objectDelta = createOldNewPasswordDelta(USER_JACK_OID, + USER_PASSWORD_VALID_5, USER_PASSWORD_VALID_6); + + // WHEN + displayWhen(TEST_NAME); + executeChanges(objectDelta, null, task, result); + + // THEN + displayThen(TEST_NAME); + login(USER_ADMINISTRATOR_USERNAME); + assertSuccess(result); + + assertUserAfter(USER_JACK_OID) + .assertPassword(USER_PASSWORD_VALID_6, getPasswordStorageType()) + .assertLinks(4) + .getObject(); + + // default password mapping is normal + assertDummyAccountByUsername(null, ACCOUNT_JACK_DUMMY_USERNAME) + .assertPassword(USER_PASSWORD_VALID_6) + .assertLastModifier(null); + + // RED password mapping is strong + assertDummyAccountByUsername(RESOURCE_DUMMY_RED_NAME, ACCOUNT_JACK_DUMMY_USERNAME) + .assertFullName(USER_JACK_FULL_NAME) + .assertEnabled() + .assertPassword(USER_PASSWORD_VALID_6) + // and RED resource has no runAs capability + .assertLastModifier(null); + + // BLUE password mapping is weak, we do not really care about password change here + // we do not really care about ugly resource either + + displayAccountPasswordNotifications(); + assertAccountPasswordNotifications(2); + assertHasAccountPasswordNotification(null, USER_JACK_USERNAME, USER_PASSWORD_VALID_6); + assertHasAccountPasswordNotification(RESOURCE_DUMMY_RED_NAME, USER_JACK_USERNAME, USER_PASSWORD_VALID_6); + // not BLUE, it already has a password + assertSingleUserPasswordNotification(USER_JACK_USERNAME, USER_PASSWORD_VALID_6); + } + + + protected ObjectDelta createAccountInitializationDelta(String accountOid, String newAccountPassword) { ObjectDelta shadowDelta = ObjectDelta.createEmptyModifyDelta(ShadowType.class, accountOid, prismContext); ProtectedStringType passwordPs = new ProtectedStringType(); diff --git a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/rbac/TestAssignmentValidity.java b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/rbac/TestAssignmentValidity.java index 9787cfbf486..d4f526708b5 100644 --- a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/rbac/TestAssignmentValidity.java +++ b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/rbac/TestAssignmentValidity.java @@ -1775,7 +1775,7 @@ public void test250JackAssignFocusExistsResource() throws Exception { ActivationType activation = new ActivationType(); activation.setValidFrom(getTimestamp("PT10M")); - AssignmentType assignment = ObjectTypeUtil.createAssignmentTo(resourceDummyFocusExists).activation(activation); + AssignmentType assignment = ObjectTypeUtil.createAssignmentTo(resourceDummyFocusExists, prismContext).activation(activation); // WHEN displayWhen(TEST_NAME); diff --git a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/security/AbstractSecurityTest.java b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/security/AbstractSecurityTest.java index b3edd4562b4..4821aced12f 100644 --- a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/security/AbstractSecurityTest.java +++ b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/security/AbstractSecurityTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010-2017 Evolveum + * Copyright (c) 2010-2018 Evolveum * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -254,9 +254,6 @@ public abstract class AbstractSecurityTest extends AbstractInitializedModelInteg protected static final File ROLE_FILTER_OBJECT_USER_TYPE_SHADOWS_FILE = new File(TEST_DIR, "role-filter-object-user-type-shadow.xml"); protected static final String ROLE_FILTER_OBJECT_USER_TYPE_SHADOWS_OID = "00000000-0000-0000-0000-00000000aa0h"; - protected static final File ROLE_END_USER_FILE = new File(TEST_DIR, "role-end-user.xml"); - protected static final String ROLE_END_USER_OID = "00000000-0000-0000-0000-00000000aa0f"; - protected static final File ROLE_MODIFY_USER_FILE = new File(TEST_DIR, "role-modify-user.xml"); protected static final String ROLE_MODIFY_USER_OID = "00000000-0000-0000-0000-00000000aa0g"; diff --git a/model/model-intest/src/test/resources/common/resource-dummy-red.xml b/model/model-intest/src/test/resources/common/resource-dummy-red.xml index e16bdd305a2..43a4893a2fd 100644 --- a/model/model-intest/src/test/resources/common/resource-dummy-red.xml +++ b/model/model-intest/src/test/resources/common/resource-dummy-red.xml @@ -1,6 +1,6 @@ + has mostly STRONG mappings, therefore it is used in strong mapping tests. Also: + * has pre-create and delayed delete configuration. + * does NOT support runAs + --> red + false useless diff --git a/model/model-intest/src/test/resources/security/role-end-user.xml b/model/model-intest/src/test/resources/common/role-end-user.xml similarity index 100% rename from model/model-intest/src/test/resources/security/role-end-user.xml rename to model/model-intest/src/test/resources/common/role-end-user.xml diff --git a/model/model-intest/src/test/resources/logback-test.xml b/model/model-intest/src/test/resources/logback-test.xml index 34fd61718ea..648dc2323dc 100644 --- a/model/model-intest/src/test/resources/logback-test.xml +++ b/model/model-intest/src/test/resources/logback-test.xml @@ -68,7 +68,7 @@ - + @@ -97,8 +97,8 @@ - - + + diff --git a/model/model-test/src/main/java/com/evolveum/midpoint/model/test/AbstractModelIntegrationTest.java b/model/model-test/src/main/java/com/evolveum/midpoint/model/test/AbstractModelIntegrationTest.java index 48fe34455f6..ef2bdb0e0bc 100644 --- a/model/model-test/src/main/java/com/evolveum/midpoint/model/test/AbstractModelIntegrationTest.java +++ b/model/model-test/src/main/java/com/evolveum/midpoint/model/test/AbstractModelIntegrationTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010-2017 Evolveum + * Copyright (c) 2010-2018 Evolveum * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -47,6 +47,7 @@ import javax.xml.namespace.QName; import com.evolveum.midpoint.prism.*; +import com.evolveum.midpoint.schema.*; import com.evolveum.midpoint.schema.result.OperationResultStatus; import com.evolveum.midpoint.task.api.TaskDebugUtil; import com.evolveum.midpoint.util.*; @@ -123,14 +124,6 @@ import com.evolveum.midpoint.provisioning.api.ProvisioningService; import com.evolveum.midpoint.repo.api.RepositoryService; import com.evolveum.midpoint.repo.common.ObjectResolver; -import com.evolveum.midpoint.schema.GetOperationOptions; -import com.evolveum.midpoint.schema.ObjectDeltaOperation; -import com.evolveum.midpoint.schema.PointInTimeType; -import com.evolveum.midpoint.schema.RepositoryDiag; -import com.evolveum.midpoint.schema.ResultHandler; -import com.evolveum.midpoint.schema.SearchResultList; -import com.evolveum.midpoint.schema.SearchResultMetadata; -import com.evolveum.midpoint.schema.SelectorOptions; import com.evolveum.midpoint.schema.constants.ObjectTypes; import com.evolveum.midpoint.schema.constants.SchemaConstants; import com.evolveum.midpoint.schema.internals.InternalsConfig; @@ -275,6 +268,7 @@ public abstract class AbstractModelIntegrationTest extends AbstractIntegrationTe @Autowired protected ModelPortType modelWeb; @Autowired protected RepositoryService repositoryService; @Autowired protected SystemObjectCache systemObjectCache; + @Autowired protected RelationRegistry relationRegistry; @Autowired protected ProvisioningService provisioningService; @Autowired protected HookRegistry hookRegistry; @Autowired protected Clock clock; @@ -717,7 +711,7 @@ protected void modifyUserSetPassword(String userOid, String newPassword, Task ta userPasswordPs.setClearValue(newPassword); PasswordType passwordType = new PasswordType(); passwordType.setValue(userPasswordPs); - ObjectDelta delta = (ObjectDelta) DeltaBuilder.deltaFor(UserType.class, prismContext) + ObjectDelta delta = DeltaBuilder.deltaFor(UserType.class, prismContext) .item(SchemaConstants.PATH_PASSWORD).add(passwordType) .asObjectDelta(userOid); executeChanges(delta, null, task, result); @@ -975,7 +969,7 @@ protected void assignOrg(Class focusType, String focusO } protected void assignOrg(String userOid, String orgOid) throws ObjectNotFoundException, SchemaException, ExpressionEvaluationException, CommunicationException, ConfigurationException, ObjectAlreadyExistsException, PolicyViolationException, SecurityViolationException { - assignOrg(userOid, orgOid, SchemaConstants.ORG_DEFAULT); + assignOrg(userOid, orgOid, prismContext.getDefaultRelation()); } protected void assignOrg(String userOid, String orgOid, QName relation) @@ -1004,7 +998,7 @@ protected void assignOrg(Class focusType, String focusO } protected void unassignOrg(String userOid, String orgOid) throws ObjectNotFoundException, SchemaException, ExpressionEvaluationException, CommunicationException, ConfigurationException, ObjectAlreadyExistsException, PolicyViolationException, SecurityViolationException { - unassignOrg(userOid, orgOid, SchemaConstants.ORG_DEFAULT); + unassignOrg(userOid, orgOid, prismContext.getDefaultRelation()); } protected void unassignOrg(String userOid, String orgOid, Task task, OperationResult result) @@ -1405,7 +1399,7 @@ protected void unassignParametricRole(String userOid, String roleOid, String org } protected void assertAssignees(String targetOid, int expectedAssignees) throws SchemaException { - assertAssignees(targetOid, SchemaConstants.ORG_DEFAULT, expectedAssignees); + assertAssignees(targetOid, prismContext.getDefaultRelation(), expectedAssignees); } protected void assertAssignees(String targetOid, QName relation, int expectedAssignees) throws SchemaException { @@ -1419,7 +1413,7 @@ protected void assertAssignees(String targetOid, QName relation, int expectedAss } protected int countAssignees(String targetOid, OperationResult result) throws SchemaException { - return countAssignees(targetOid, SchemaConstants.ORG_DEFAULT, result); + return countAssignees(targetOid, prismContext.getDefaultRelation(), result); } protected int countAssignees(String targetOid, QName relation, OperationResult result) throws SchemaException { @@ -1822,7 +1816,7 @@ protected AssignmentType getUserAssignment(String userOid, String roleOid, QName List assignments = user.asObjectable().getAssignment(); for (AssignmentType assignment: assignments) { ObjectReferenceType targetRef = assignment.getTargetRef(); - if (targetRef != null && roleOid.equals(targetRef.getOid()) && ObjectTypeUtil.relationMatches(relation, + if (targetRef != null && roleOid.equals(targetRef.getOid()) && prismContext.relationMatches(relation, targetRef.getRelation())) { return assignment; } @@ -5368,6 +5362,7 @@ protected PendingOperationType findPendingOperation(PrismObject shad protected void initializeAsserter(AbstractAsserter asserter) { asserter.setPrismContext(prismContext); asserter.setObjectResolver(repoSimpleObjectResolver); + asserter.setProtector(protector); } protected UserAsserter assertUserAfter(String oid) throws ObjectNotFoundException, SchemaException, SecurityViolationException, CommunicationException, ConfigurationException, ExpressionEvaluationException { diff --git a/model/report-impl/src/main/java/com/evolveum/midpoint/report/impl/ReportCreateTaskHandler.java b/model/report-impl/src/main/java/com/evolveum/midpoint/report/impl/ReportCreateTaskHandler.java index 05b8e3242cc..fd64be050c3 100644 --- a/model/report-impl/src/main/java/com/evolveum/midpoint/report/impl/ReportCreateTaskHandler.java +++ b/model/report-impl/src/main/java/com/evolveum/midpoint/report/impl/ReportCreateTaskHandler.java @@ -516,7 +516,7 @@ private void saveReportOutputType(String filePath, ReportType reportType, Task t throw new IllegalStateException("Found more than one node with ID " + task.getNode()); } - reportOutputType.setNodeRef(ObjectTypeUtil.createObjectRef(nodes.iterator().next())); + reportOutputType.setNodeRef(ObjectTypeUtil.createObjectRef(nodes.iterator().next(), prismContext)); ObjectDelta objectDelta = null; Collection> deltas = new ArrayList<>(); diff --git a/model/report-impl/src/main/java/com/evolveum/midpoint/report/impl/ReportFunctions.java b/model/report-impl/src/main/java/com/evolveum/midpoint/report/impl/ReportFunctions.java index c756d21505a..ab80567da95 100644 --- a/model/report-impl/src/main/java/com/evolveum/midpoint/report/impl/ReportFunctions.java +++ b/model/report-impl/src/main/java/com/evolveum/midpoint/report/impl/ReportFunctions.java @@ -150,7 +150,7 @@ public List> resolveRoles(Collection assig .filter(as -> as.getTargetRef() != null && as.getTargetRef().getOid() != null && filterOids.contains(as.getTargetRef().getOid())) // filter to default relation only - ignores approvers etc - .filter(as -> ObjectTypeUtil.isDefaultRelation(as.getTargetRef().getRelation())) + .filter(as -> prismContext.isDefaultRelation(as.getTargetRef().getRelation())) .collect(Collectors.toList()); } diff --git a/model/workflow-api/src/main/java/com/evolveum/midpoint/wf/util/QueryUtils.java b/model/workflow-api/src/main/java/com/evolveum/midpoint/wf/util/QueryUtils.java index a62c7630894..3a4c4ed04ce 100644 --- a/model/workflow-api/src/main/java/com/evolveum/midpoint/wf/util/QueryUtils.java +++ b/model/workflow-api/src/main/java/com/evolveum/midpoint/wf/util/QueryUtils.java @@ -22,6 +22,8 @@ import com.evolveum.midpoint.prism.query.builder.S_FilterEntryOrEmpty; import com.evolveum.midpoint.prism.query.builder.S_FilterExit; import com.evolveum.midpoint.repo.api.RepositoryService; +import com.evolveum.midpoint.schema.RelationRegistry; +import com.evolveum.midpoint.schema.constants.ObjectTypes; import com.evolveum.midpoint.schema.result.OperationResult; import com.evolveum.midpoint.schema.util.ObjectTypeUtil; import com.evolveum.midpoint.security.api.DelegatorWithOtherPrivilegesLimitations; @@ -50,33 +52,36 @@ public class QueryUtils { * Note that work item limitations are supported only in the current (crude) form: all or none. */ public static S_AtomicFilterExit filterForAssignees(S_FilterEntryOrEmpty q, MidPointPrincipal principal, - QName limitationItemName) throws SchemaException { + QName limitationItemName, RelationRegistry relationRegistry) { if (principal == null) { return q.none(); } else { - return q.item(WorkItemType.F_ASSIGNEE_REF).ref(getPotentialAssigneesForUser(principal, limitationItemName)); + return q.item(WorkItemType.F_ASSIGNEE_REF).ref(getPotentialAssigneesForUser(principal, limitationItemName, relationRegistry)); } } - public static S_FilterExit filterForGroups(S_FilterEntryOrEmpty q, String userOid, RepositoryService repositoryService, OperationResult result) + public static S_FilterExit filterForGroups(S_FilterEntryOrEmpty q, String userOid, RepositoryService repositoryService, + RelationRegistry relationRegistry, OperationResult result) throws SchemaException { - return q.item(WorkItemType.F_CANDIDATE_REF).ref(getGroupsForUser(userOid, repositoryService, result)); + return q.item(WorkItemType.F_CANDIDATE_REF).ref(getGroupsForUser(userOid, repositoryService, relationRegistry, result)); } private static List getPotentialAssigneesForUser(MidPointPrincipal principal, - QName limitationItemName) throws SchemaException { + QName limitationItemName, RelationRegistry relationRegistry) { + // As for relations, WorkItem.assigneeRef should contain only the default ones. + QName defaultRelation = relationRegistry.getDefaultRelation(); List rv = new ArrayList<>(); - rv.add(new PrismReferenceValue(principal.getOid(), UserType.COMPLEX_TYPE)); + rv.add(ObjectTypeUtil.createObjectRef(principal.getOid(), ObjectTypes.USER).relation(defaultRelation).asReferenceValue()); for (DelegatorWithOtherPrivilegesLimitations delegator : principal.getDelegatorWithOtherPrivilegesLimitationsCollection()) { if (DeputyUtils.limitationsAllow(delegator.getLimitations(), limitationItemName)) { - rv.add(ObjectTypeUtil.createObjectRef(delegator.getDelegator()).asReferenceValue()); + rv.add(ObjectTypeUtil.createObjectRef(delegator.getDelegator(), defaultRelation).asReferenceValue()); } } return rv; } private static List getGroupsForUser(String userOid, RepositoryService repositoryService, - OperationResult result) throws SchemaException { + RelationRegistry relationRegistry, OperationResult result) throws SchemaException { List rv = new ArrayList<>(); UserType userType; try { @@ -84,14 +89,13 @@ private static List getGroupsForUser(String userOid, Reposi } catch (ObjectNotFoundException e) { return rv; } - userType.getRoleMembershipRef().forEach(ref -> rv.add(ref.clone().asReferenceValue())); - userType.getDelegatedRef().forEach(ref -> - { - if (!QNameUtil.match(ref.getType(), UserType.COMPLEX_TYPE)) { - rv.add(ref.clone().asReferenceValue()); - } - } - ); + userType.getRoleMembershipRef().stream() + .filter(ref -> relationRegistry.isMembership(ref.getRelation())) + .forEach(ref -> rv.add(ref.clone().asReferenceValue())); + userType.getDelegatedRef().stream() + .filter(ref -> relationRegistry.isMembership(ref.getRelation())) + .filter(ref -> !QNameUtil.match(ref.getType(), UserType.COMPLEX_TYPE)) // we are not interested in deputies (but this should be treated above) + .forEach(ref -> rv.add(ref.clone().asReferenceValue())); return rv; } diff --git a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/ApprovalSchemaExecutionInformationHelper.java b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/ApprovalSchemaExecutionInformationHelper.java index d4a0b9a3d5c..ec24e0eeab3 100644 --- a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/ApprovalSchemaExecutionInformationHelper.java +++ b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/ApprovalSchemaExecutionInformationHelper.java @@ -94,7 +94,7 @@ List getApprovalSchemaPreview(ModelConte private ApprovalSchemaExecutionInformationType getApprovalSchemaExecutionInformation(TaskType wfTask, boolean purePreview, Task opTask, OperationResult result) { ApprovalSchemaExecutionInformationType rv = new ApprovalSchemaExecutionInformationType(prismContext); - rv.setTaskRef(ObjectTypeUtil.createObjectRefWithFullObject(wfTask)); + rv.setTaskRef(ObjectTypeUtil.createObjectRefWithFullObject(wfTask, prismContext)); WfContextType wfc = wfTask.getWorkflowContext(); if (wfc == null) { result.recordFatalError("Workflow context in " + wfTask + " is missing or not accessible."); diff --git a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/activiti/dao/WorkItemManager.java b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/activiti/dao/WorkItemManager.java index a5bd54a717d..35dfa03c254 100644 --- a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/activiti/dao/WorkItemManager.java +++ b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/activiti/dao/WorkItemManager.java @@ -249,7 +249,7 @@ public void delegateWorkItem(String workItemId, List delega ObjectReferenceType initiator = causeInformation == null || causeInformation.getType() == WorkItemEventCauseTypeType.USER_ACTION ? - ObjectTypeUtil.createObjectRef(principal.getUser()) : null; + ObjectTypeUtil.createObjectRef(principal.getUser(), prismContext) : null; LOGGER.trace("Delegating work item {} to {}: escalation={}; cause={}", workItemId, delegates, escalation != null ? escalation.getName() + "/" + escalation.getDisplayName() : "none", causeInformation); diff --git a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processes/common/ActivitiUtil.java b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processes/common/ActivitiUtil.java index 2bfbdd1b348..9b55ef1ad60 100644 --- a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processes/common/ActivitiUtil.java +++ b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processes/common/ActivitiUtil.java @@ -176,8 +176,8 @@ public static List toLightweightReferences(Collection variables, PrismContext prismContext) { if (currentUser != null) { - event.setInitiatorRef(ObjectTypeUtil.createObjectRef(currentUser.getUser())); - event.setAttorneyRef(ObjectTypeUtil.createObjectRef(currentUser.getAttorney())); + event.setInitiatorRef(ObjectTypeUtil.createObjectRef(currentUser.getUser(), prismContext)); + event.setAttorneyRef(ObjectTypeUtil.createObjectRef(currentUser.getAttorney(), prismContext)); } event.setTimestamp(XmlTypeConverter.createXMLGregorianCalendar(new Date())); event.setExternalWorkItemId(workItemId); diff --git a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processes/itemApproval/MidpointUtil.java b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processes/itemApproval/MidpointUtil.java index 204fd929044..ef0bbb683e0 100644 --- a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processes/itemApproval/MidpointUtil.java +++ b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processes/itemApproval/MidpointUtil.java @@ -130,7 +130,7 @@ private static Collection expandAbstractRole(ObjectReferenc return getCacheRepositoryService() .searchObjects(UserType.class, query, null, new OperationResult("dummy")) .stream() - .map(o -> ObjectTypeUtil.createObjectRef(o)) + .map(o -> ObjectTypeUtil.createObjectRef(o, prismContext)) .collect(Collectors.toList()); } catch (SchemaException e) { throw new SystemException("Couldn't resolve " + approverRef + ": " + e.getMessage(), e); diff --git a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processes/itemApproval/RelationResolver.java b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processes/itemApproval/RelationResolver.java index ddc60b3ab38..20a1889ed10 100644 --- a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processes/itemApproval/RelationResolver.java +++ b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processes/itemApproval/RelationResolver.java @@ -3,6 +3,7 @@ import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectReferenceType; import javax.xml.namespace.QName; +import java.util.Collection; import java.util.List; /** @@ -11,5 +12,5 @@ @FunctionalInterface public interface RelationResolver { // Must return parent-less values - List getApprovers(List relations); + List getApprovers(Collection relations); } diff --git a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/BaseAuditHelper.java b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/BaseAuditHelper.java index 69b95755634..b813e7ca0a7 100644 --- a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/BaseAuditHelper.java +++ b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/BaseAuditHelper.java @@ -111,7 +111,7 @@ private ObjectReferenceType resolveIfNeeded(ObjectReferenceType ref, OperationRe } try { return ObjectTypeUtil.createObjectRef( - repositoryService.getObject(types.getClassDefinition(), ref.getOid(), null, result)); + repositoryService.getObject(types.getClassDefinition(), ref.getOid(), null, result), prismContext); } catch (ObjectNotFoundException|SchemaException e) { LoggingUtils.logUnexpectedException(LOGGER, "Couldn't resolve {}", e, ref); return ref; diff --git a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/BaseChangeProcessor.java b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/BaseChangeProcessor.java index eae0b0489bd..9b2016e02a8 100644 --- a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/BaseChangeProcessor.java +++ b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/BaseChangeProcessor.java @@ -1,6 +1,7 @@ package com.evolveum.midpoint.wf.impl.processors; import com.evolveum.midpoint.prism.PrismContext; +import com.evolveum.midpoint.schema.RelationRegistry; import com.evolveum.midpoint.util.logging.Trace; import com.evolveum.midpoint.util.logging.TraceManager; import com.evolveum.midpoint.wf.impl.util.MiscDataUtil; @@ -26,13 +27,11 @@ public abstract class BaseChangeProcessor implements ChangeProcessor, BeanNameAw private String beanName; private BeanFactory beanFactory; - @Autowired - private MiscDataUtil miscDataUtil; + @Autowired private MiscDataUtil miscDataUtil; + @Autowired private PrismContext prismContext; + @Autowired private RelationRegistry relationRegistry; - @Autowired - private PrismContext prismContext; - - private boolean enabled = false; + private boolean enabled = false; public String getBeanName() { return beanName; @@ -72,4 +71,9 @@ public MiscDataUtil getMiscDataUtil() { public PrismContext getPrismContext() { return prismContext; } + + @Override + public RelationRegistry getRelationRegistry() { + return relationRegistry; + } } diff --git a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/ChangeProcessor.java b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/ChangeProcessor.java index 64d8a15938a..3802a4b5b4e 100644 --- a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/ChangeProcessor.java +++ b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/ChangeProcessor.java @@ -21,6 +21,7 @@ import com.evolveum.midpoint.model.api.context.ModelContext; import com.evolveum.midpoint.model.api.hooks.HookOperationMode; import com.evolveum.midpoint.prism.PrismContext; +import com.evolveum.midpoint.schema.RelationRegistry; import com.evolveum.midpoint.schema.result.OperationResult; import com.evolveum.midpoint.task.api.Task; import com.evolveum.midpoint.util.exception.CommunicationException; @@ -126,5 +127,7 @@ AuditEventRecord prepareWorkItemDeletedAuditRecord(WorkItemType workItem, WorkIt MiscDataUtil getMiscDataUtil(); PrismContext getPrismContext(); + + RelationRegistry getRelationRegistry(); } diff --git a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/primary/PcpChildWfTaskCreationInstruction.java b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/primary/PcpChildWfTaskCreationInstruction.java index 80542555a28..61dfa0368e2 100644 --- a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/primary/PcpChildWfTaskCreationInstruction.java +++ b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/primary/PcpChildWfTaskCreationInstruction.java @@ -84,7 +84,7 @@ public void prepareCommonAttributes(PrimaryChangeAspect aspect, ModelContext CaseCreationEventType event = new CaseCreationEventType(); event.setTimestamp(XmlTypeConverter.createXMLGregorianCalendar(new Date())); if (requester != null) { - event.setInitiatorRef(ObjectTypeUtil.createObjectRef(requester)); + event.setInitiatorRef(ObjectTypeUtil.createObjectRef(requester, getPrismContext())); // attorney does not need to be set here (for now) } event.setBusinessContext(((LensContext) modelContext).getRequestBusinessContext()); diff --git a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/primary/aspect/BasePrimaryChangeAspect.java b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/primary/aspect/BasePrimaryChangeAspect.java index ad4b5019291..1d4429bbeb4 100644 --- a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/primary/aspect/BasePrimaryChangeAspect.java +++ b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/primary/aspect/BasePrimaryChangeAspect.java @@ -35,13 +35,12 @@ import com.evolveum.midpoint.prism.query.builder.S_AtomicFilterExit; import com.evolveum.midpoint.repo.api.RepositoryService; import com.evolveum.midpoint.schema.ObjectTreeDeltas; +import com.evolveum.midpoint.schema.RelationRegistry; import com.evolveum.midpoint.schema.SearchResultList; -import com.evolveum.midpoint.schema.constants.SchemaConstants; import com.evolveum.midpoint.schema.result.OperationResult; import com.evolveum.midpoint.schema.util.ObjectTypeUtil; import com.evolveum.midpoint.task.api.Task; import com.evolveum.midpoint.util.DebugUtil; -import com.evolveum.midpoint.util.QNameUtil; import com.evolveum.midpoint.util.exception.CommunicationException; import com.evolveum.midpoint.util.exception.ConfigurationException; import com.evolveum.midpoint.util.exception.ExpressionEvaluationException; @@ -108,6 +107,9 @@ public abstract class BasePrimaryChangeAspect implements PrimaryChangeAspect, Be @Autowired protected PrismContext prismContext; + @Autowired + protected RelationRegistry relationRegistry; + @Autowired protected ItemApprovalProcessInterface itemApprovalProcessInterface; @@ -196,7 +198,7 @@ private List r SearchResultList> targets = repositoryService.searchObjects(clazz, ObjectQuery.createObjectQuery(evaluatedFilter), null, result); return targets.stream() - .map(ObjectTypeUtil::createObjectRef) + .map(object -> ObjectTypeUtil.createObjectRef(object, prismContext)) .collect(Collectors.toList()); } finally { @@ -241,7 +243,7 @@ public RelationResolver createRelationResolver(PrismObject object, OperationR S_AtomicFilterExit q = QueryBuilder.queryFor(FocusType.class, prismContext).none(); for (QName approverRelation : relations) { PrismReferenceValue approverReference = new PrismReferenceValue(object.getOid()); - approverReference.setRelation(QNameUtil.qualifyIfNeeded(approverRelation, SchemaConstants.NS_ORG)); + approverReference.setRelation(relationRegistry.normalizeRelation(approverRelation)); q = q.or().item(FocusType.F_ROLE_MEMBERSHIP_REF).ref(approverReference); } ObjectQuery query = q.build(); @@ -255,7 +257,7 @@ public RelationResolver createRelationResolver(PrismObject object, OperationR Set> distinctObjects = new HashSet<>(objects); LOGGER.trace("Found {} approver(s): {}", distinctObjects.size(), DebugUtil.toStringLazily(distinctObjects)); return distinctObjects.stream() - .map(ObjectTypeUtil::createObjectRef) + .map(object1 -> ObjectTypeUtil.createObjectRef(object1, prismContext)) .collect(Collectors.toList()); }; } diff --git a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/primary/assignments/AddAssignmentAspect.java b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/primary/assignments/AddAssignmentAspect.java index 2abc42e304d..229b2bacbd8 100644 --- a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/primary/assignments/AddAssignmentAspect.java +++ b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/primary/assignments/AddAssignmentAspect.java @@ -246,7 +246,7 @@ private List prepareTaskInstructions(ModelCon instruction.setDeltasToProcess(delta); instruction.setObjectRef(modelContext, result); - instruction.setTargetRef(createObjectRef(target), result); + instruction.setTargetRef(createObjectRef(target, prismContext), result); String andExecuting = instruction.isExecuteApprovedChangeImmediately() ? "and execution " : ""; instruction.setTaskName("Approval " + andExecuting + "of assigning " + targetName + " to " + assigneeName); diff --git a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/primary/assignments/ModifyAssignmentAspect.java b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/primary/assignments/ModifyAssignmentAspect.java index 6781245c2f1..8d0dfb87f38 100644 --- a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/primary/assignments/ModifyAssignmentAspect.java +++ b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/primary/assignments/ModifyAssignmentAspect.java @@ -228,7 +228,7 @@ private List prepareJobCreateInstructions(Mod instruction.setDeltasToProcess(delta); instruction.setObjectRef(modelContext, result); - instruction.setTargetRef(ObjectTypeUtil.createObjectRef(target), result); + instruction.setTargetRef(ObjectTypeUtil.createObjectRef(target, prismContext), result); // set the names of midPoint task and activiti process instance String andExecuting = instruction.isExecuteApprovedChangeImmediately() ? "and execution " : ""; diff --git a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/primary/entitlements/AddAssociationAspect.java b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/primary/entitlements/AddAssociationAspect.java index d1253941b4e..a670d68ffe2 100644 --- a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/primary/entitlements/AddAssociationAspect.java +++ b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/primary/entitlements/AddAssociationAspect.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010-2015 Evolveum + * Copyright (c) 2010-2018 Evolveum * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -248,7 +248,7 @@ private boolean existsEquivalentValue(PrismObject shadowOld, PrismCo instruction.setDeltasToProcesses(objectTreeDeltas); instruction.setObjectRef(modelContext, result); // TODO - or should we take shadow as an object? - instruction.setTargetRef(ObjectTypeUtil.createObjectRef(target), result); + instruction.setTargetRef(ObjectTypeUtil.createObjectRef(target, prismContext), result); // set the names of midPoint task and activiti process instance String andExecuting = instruction.isExecuteApprovedChangeImmediately() ? "and execution " : ""; @@ -270,7 +270,7 @@ private ObjectTreeDeltas associationAdditionToDelta(ModelContext modelContext ResourceShadowDiscriminator shadowDiscriminator = ResourceShadowDiscriminator.fromResourceShadowDiscriminatorType(addition.getResourceShadowDiscriminator()); String projectionOid = modelContext.findProjectionContext(shadowDiscriminator).getOid(); - ObjectDelta objectDelta = (ObjectDelta) DeltaBuilder.deltaFor(ShadowType.class, prismContext) + ObjectDelta objectDelta = DeltaBuilder.deltaFor(ShadowType.class, prismContext) .item(ShadowType.F_ASSOCIATION).add(addition.getAssociation().clone()) .asObjectDelta(projectionOid); diff --git a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/primary/policy/ApprovalSchemaBuilder.java b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/primary/policy/ApprovalSchemaBuilder.java index 09d6de02d5b..5d2a0f096ff 100644 --- a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/primary/policy/ApprovalSchemaBuilder.java +++ b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/primary/policy/ApprovalSchemaBuilder.java @@ -21,6 +21,7 @@ import com.evolveum.midpoint.prism.PrismContext; import com.evolveum.midpoint.prism.PrismObject; import com.evolveum.midpoint.prism.util.CloneUtil; +import com.evolveum.midpoint.schema.RelationRegistry; import com.evolveum.midpoint.schema.result.OperationResult; import com.evolveum.midpoint.util.MiscUtil; import com.evolveum.midpoint.util.exception.SchemaException; @@ -137,9 +138,9 @@ private boolean isAddOnFragment(ApprovalCompositionStrategyType cs) { } // checks the existence of approvers beforehand, because we don't want to have an empty stage - boolean addPredefined(PrismObject targetObject, @NotNull QName relationName, OperationResult result) { + boolean addPredefined(PrismObject targetObject, RelationKindType relationKind, OperationResult result) { RelationResolver resolver = primaryChangeAspect.createRelationResolver(targetObject, result); - List approvers = resolver.getApprovers(Collections.singletonList(relationName)); + List approvers = resolver.getApprovers(getRelationRegistry().getAllRelationsFor(relationKind)); if (!approvers.isEmpty()) { ApprovalStageDefinitionType stageDef = new ApprovalStageDefinitionType(); stageDef.getApproverRef().addAll(approvers); @@ -150,6 +151,10 @@ boolean addPredefined(PrismObject targetObject, @NotNull QName relationName, } } + private RelationRegistry getRelationRegistry() { + return primaryChangeAspect.getChangeProcessor().getRelationRegistry(); + } + void addPredefined(PrismObject targetObject, ApprovalStageDefinitionType stageDef) { ApprovalSchemaType schema = new ApprovalSchemaType(); schema.getStage().add(stageDef); @@ -241,7 +246,7 @@ private void processFragmentGroup(List fragments, ApprovalSchemaType r if (firstFragment.policyRule != null) { List rules = new ArrayList<>(); firstFragment.policyRule.addToEvaluatedPolicyRuleTypes(rules, new PolicyRuleExternalizationOptions(FULL, - false, true), null); + false, true), null, ctx.prismContext); for (EvaluatedPolicyRuleType rule : rules) { SchemaAttachedPolicyRuleType attachedRule = new SchemaAttachedPolicyRuleType(); attachedRule.setStageMin(from); diff --git a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/primary/policy/AssignmentPolicyAspectPart.java b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/primary/policy/AssignmentPolicyAspectPart.java index e129f9648e4..286fd76dab9 100644 --- a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/primary/policy/AssignmentPolicyAspectPart.java +++ b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/primary/policy/AssignmentPolicyAspectPart.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010-2017 Evolveum + * Copyright (c) 2010-2018 Evolveum * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -265,7 +265,7 @@ private ApprovalSchemaBuilder.Result createSchemaWithRules(List prepareAs instruction.setDeltasToProcess(deltaToApprove); instruction.setObjectRef(modelContext, result); - instruction.setTargetRef(createObjectRef(target), result); + instruction.setTargetRef(createObjectRef(target, prismContext), result); String taskNameInDefaultLocale = localizationService.translate( new LocalizableMessageBuilder() @@ -348,7 +348,7 @@ private ObjectDelta assignmentToDelta(Class) op.asObjectDelta(objectOid); + return op.asObjectDelta(objectOid); } } diff --git a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/primary/policy/ObjectPolicyAspectPart.java b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/primary/policy/ObjectPolicyAspectPart.java index 0ba7ce84916..86a417fb7ff 100644 --- a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/primary/policy/ObjectPolicyAspectPart.java +++ b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/primary/policy/ObjectPolicyAspectPart.java @@ -115,7 +115,7 @@ void extractObjectBasedInstructions(@NotNull ObjectTreeDe } else if (baseConfigurationHelper.getUseDefaultApprovalPolicyRules(ctx.wfConfiguration) != DefaultApprovalPolicyRulesUsageType.NEVER) { // default rule ApprovalSchemaBuilder builder = new ApprovalSchemaBuilder(main, approvalSchemaHelper); - if (builder.addPredefined(object, SchemaConstants.ORG_OWNER, result)) { + if (builder.addPredefined(object, RelationKindType.OWNER, result)) { LOGGER.trace("Added default approval action, as no explicit one was found"); generateObjectOidIfNeeded(focusDelta, ctx.modelContext); List> deltasToApprove = singletonList(focusDelta.clone()); diff --git a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/primary/policy/PolicyRuleBasedAspect.java b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/primary/policy/PolicyRuleBasedAspect.java index 2cf684ddb9b..e67fd9e6673 100644 --- a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/primary/policy/PolicyRuleBasedAspect.java +++ b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/processors/primary/policy/PolicyRuleBasedAspect.java @@ -180,7 +180,7 @@ private LocalizableMessage processNameFromTriggers(ApprovalSchemaBuilder.Result if (actionWithRule.getRight() != null) { for (EvaluatedPolicyRuleTrigger trigger : actionWithRule.getRight().getAllTriggers()) { // we don't care about options; these converted triggers will be thrown away - triggers.add(trigger.toEvaluatedPolicyRuleTriggerType(new PolicyRuleExternalizationOptions())); + triggers.add(trigger.toEvaluatedPolicyRuleTriggerType(new PolicyRuleExternalizationOptions(), prismContext)); } } } diff --git a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/tasks/WfTaskCreationInstruction.java b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/tasks/WfTaskCreationInstruction.java index 32dc17df135..2da506f467b 100644 --- a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/tasks/WfTaskCreationInstruction.java +++ b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/tasks/WfTaskCreationInstruction.java @@ -276,10 +276,10 @@ public void setObjectRef(ModelContext modelContext, OperationResult result) { ObjectType focus = MiscDataUtil.getFocusObjectNewOrOld(modelContext); ObjectDelta primaryDelta = modelContext.getFocusContext().getPrimaryDelta(); if (primaryDelta != null && primaryDelta.isAdd()) { - ObjectReferenceType ref = ObjectTypeUtil.createObjectRefWithFullObject(focus); + ObjectReferenceType ref = ObjectTypeUtil.createObjectRefWithFullObject(focus, getPrismContext()); wfContext.setObjectRef(ref); } else { - setObjectRef(ObjectTypeUtil.createObjectRef(focus), result); + setObjectRef(ObjectTypeUtil.createObjectRef(focus, getPrismContext()), result); } } @@ -289,7 +289,7 @@ public void setTargetRef(ObjectReferenceType ref, OperationResult result) { } public void setRequesterRef(PrismObject requester) { - wfContext.setRequesterRef(createObjectRef(requester)); + wfContext.setRequesterRef(createObjectRef(requester, getPrismContext())); } public void setProcessInterfaceBean(ProcessMidPointInterface processInterfaceBean) { @@ -373,7 +373,7 @@ public Task createTask(WfTaskController taskController, Task parentTask, WfConfi if (taskObject != null) { //noinspection unchecked - task.setObjectRef(ObjectTypeUtil.createObjectRef(taskObject)); + task.setObjectRef(ObjectTypeUtil.createObjectRef(taskObject, getPrismContext())); } else if (parentTask != null && parentTask.getObjectRef() != null) { task.setObjectRef(parentTask.getObjectRef().clone()); } diff --git a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/util/MiscDataUtil.java b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/util/MiscDataUtil.java index 3c700dca9e4..79a8b0b8ff9 100644 --- a/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/util/MiscDataUtil.java +++ b/model/workflow-impl/src/main/java/com/evolveum/midpoint/wf/impl/util/MiscDataUtil.java @@ -22,6 +22,7 @@ import com.evolveum.midpoint.model.api.context.ModelElementContext; import com.evolveum.midpoint.model.api.util.DeputyUtils; import com.evolveum.midpoint.model.api.util.ModelContextUtil; +import com.evolveum.midpoint.schema.RelationRegistry; import com.evolveum.midpoint.model.common.SystemObjectCache; import com.evolveum.midpoint.model.impl.lens.LensFocusContext; import com.evolveum.midpoint.model.impl.lens.LensProjectionContext; @@ -93,6 +94,7 @@ public class MiscDataUtil { @Autowired private WfConfiguration wfConfiguration; @Autowired private ActivitiEngine activitiEngine; @Autowired private BaseModelInvocationProcessingHelper baseModelInvocationProcessingHelper; + @Autowired private RelationRegistry relationRegistry; public static ObjectReferenceType toObjectReferenceType(LightweightObjectRef ref) { if (ref != null) { @@ -317,16 +319,17 @@ public boolean isAuthorized(WorkItemType workItem, RequestedOperation operation, throw new SystemException(e.getMessage(), e); } for (ObjectReferenceType assignee : workItem.getAssigneeRef()) { - if (isEqualOrDeputyOf(principal, assignee.getOid())) { + if (isEqualOrDeputyOf(principal, assignee.getOid(), relationRegistry)) { return true; } } return isAmongCandidates(principal, workItem.getExternalId()); } - public boolean isEqualOrDeputyOf(MidPointPrincipal principal, String eligibleUserOid) { + public boolean isEqualOrDeputyOf(MidPointPrincipal principal, String eligibleUserOid, + RelationRegistry relationRegistry) { return principal.getOid().equals(eligibleUserOid) - || DeputyUtils.isDelegationPresent(principal.getUser(), eligibleUserOid); + || DeputyUtils.isDelegationPresent(principal.getUser(), eligibleUserOid, relationRegistry); } public WfConfigurationType getWorkflowConfiguration(SystemObjectCache systemObjectCache, OperationResult result) throws SchemaException { @@ -403,7 +406,7 @@ public boolean isMemberOfActivitiGroup(UserType userType, String activitiGroupId } public boolean matches(ObjectReferenceType groupRef, ObjectReferenceType targetRef) { - return (ObjectTypeUtil.isMembershipRelation(targetRef.getRelation())) // TODO reconsider if we allow managers here + return (relationRegistry.isMembership(targetRef.getRelation())) // TODO reconsider if we allow managers here && targetRef.getOid().equals(groupRef.getOid()); } diff --git a/model/workflow-impl/src/test/java/com/evolveum/midpoint/wf/impl/policy/AbstractWfTestPolicy.java b/model/workflow-impl/src/test/java/com/evolveum/midpoint/wf/impl/policy/AbstractWfTestPolicy.java index 4bbc1043b3c..2c8d59208f0 100644 --- a/model/workflow-impl/src/test/java/com/evolveum/midpoint/wf/impl/policy/AbstractWfTestPolicy.java +++ b/model/workflow-impl/src/test/java/com/evolveum/midpoint/wf/impl/policy/AbstractWfTestPolicy.java @@ -20,6 +20,7 @@ import com.evolveum.midpoint.model.api.context.ModelContext; import com.evolveum.midpoint.model.api.context.ModelState; import com.evolveum.midpoint.model.api.hooks.HookOperationMode; +import com.evolveum.midpoint.model.common.SystemObjectCache; import com.evolveum.midpoint.model.impl.AbstractModelImplementationIntegrationTest; import com.evolveum.midpoint.model.impl.controller.ModelOperationTaskHandler; import com.evolveum.midpoint.model.impl.lens.Clockwork; @@ -31,6 +32,7 @@ import com.evolveum.midpoint.prism.query.builder.S_AtomicFilterExit; import com.evolveum.midpoint.prism.util.PrismUtil; import com.evolveum.midpoint.schema.GetOperationOptions; +import com.evolveum.midpoint.schema.RelationRegistry; import com.evolveum.midpoint.schema.SearchResultList; import com.evolveum.midpoint.schema.SelectorOptions; import com.evolveum.midpoint.schema.constants.ObjectTypes; @@ -185,6 +187,8 @@ public class AbstractWfTestPolicy extends AbstractModelImplementationIntegration @Autowired protected MiscDataUtil miscDataUtil; @Autowired protected PrimaryChangeProcessor primaryChangeProcessor; @Autowired protected GeneralChangeProcessor generalChangeProcessor; + @Autowired protected SystemObjectCache systemObjectCache; + @Autowired protected RelationRegistry relationRegistry; protected PrismObject userAdministrator; @@ -1025,7 +1029,7 @@ protected void checkVisibleWorkItem(ExpectedWorkItem expectedWorkItem, int count throws SchemaException, ObjectNotFoundException, ConfigurationException, SecurityViolationException, ExpressionEvaluationException, CommunicationException { S_AtomicFilterExit q = QueryUtils .filterForAssignees(QueryBuilder.queryFor(WorkItemType.class, prismContext), SecurityUtil.getPrincipal(), - OtherPrivilegesLimitationType.F_APPROVAL_WORK_ITEMS); + OtherPrivilegesLimitationType.F_APPROVAL_WORK_ITEMS, relationRegistry); List currentWorkItems = modelService.searchContainers(WorkItemType.class, q.build(), null, task, result); long found = currentWorkItems.stream().filter(wi -> expectedWorkItem == null || expectedWorkItem.matches(wi)).count(); assertEquals("Wrong # of matching work items", count, found); diff --git a/model/workflow-impl/src/test/java/com/evolveum/midpoint/wf/impl/policy/assignments/AbstractTestAssignmentApproval.java b/model/workflow-impl/src/test/java/com/evolveum/midpoint/wf/impl/policy/assignments/AbstractTestAssignmentApproval.java index eaff8805155..68545ecbf04 100644 --- a/model/workflow-impl/src/test/java/com/evolveum/midpoint/wf/impl/policy/assignments/AbstractTestAssignmentApproval.java +++ b/model/workflow-impl/src/test/java/com/evolveum/midpoint/wf/impl/policy/assignments/AbstractTestAssignmentApproval.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010-2017 Evolveum + * Copyright (c) 2010-2018 Evolveum * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -100,7 +100,7 @@ public void test020DeleteRole1Assignment() throws Exception { LensContext context = createUserLensContext(); fillContextWithUser(context, userJackOid, result); addFocusDeltaToContext(context, - (ObjectDelta) DeltaBuilder.deltaFor(UserType.class, prismContext) + DeltaBuilder.deltaFor(UserType.class, prismContext) .item(UserType.F_ASSIGNMENT).delete(createAssignmentTo(getRoleOid(1), ObjectTypes.ROLE, prismContext)) .asObjectDelta(userJackOid)); clockwork.run(context, task, result); @@ -288,7 +288,7 @@ private void executeAssignRole1ToJack(String TEST_NAME, boolean immediate, boole PrismObject jack = getUser(userJackOid); AssignmentType assignment = createAssignmentTo(getRoleOid(1), ObjectTypes.ROLE, prismContext); assignment.getTargetRef().setRelation(relation); - ObjectDelta addRole1Delta = (ObjectDelta) DeltaBuilder + ObjectDelta addRole1Delta = DeltaBuilder .deltaFor(UserType.class, prismContext) .item(UserType.F_ASSIGNMENT).add(assignment) .asObjectDelta(userJackOid); @@ -367,8 +367,8 @@ protected Boolean decideOnApproval(String executionId, org.activiti.engine.task. protected List getPotentialAssignees(PrismObject user) { List rv = new ArrayList<>(); - rv.add(ObjectTypeUtil.createObjectRef(user).asReferenceValue()); - rv.addAll(DeputyUtils.getDelegatorReferences(user.asObjectable())); + rv.add(ObjectTypeUtil.createObjectRef(user, prismContext).asReferenceValue()); + rv.addAll(DeputyUtils.getDelegatorReferences(user.asObjectable(), relationRegistry)); return rv; } @@ -387,27 +387,27 @@ protected void assertActiveWorkItems(String approverOid, int expectedCount) thro private void executeAssignRoles123ToJack(String TEST_NAME, boolean immediate, boolean approve1, boolean approve2, boolean approve3) throws Exception { PrismObject jack = getUser(userJackOid); @SuppressWarnings("unchecked") - ObjectDelta addRole1Delta = (ObjectDelta) DeltaBuilder + ObjectDelta addRole1Delta = DeltaBuilder .deltaFor(UserType.class, prismContext) .item(UserType.F_ASSIGNMENT).add(createAssignmentTo(getRoleOid(1), ObjectTypes.ROLE, prismContext)) .asObjectDelta(userJackOid); @SuppressWarnings("unchecked") - ObjectDelta addRole2Delta = (ObjectDelta) DeltaBuilder + ObjectDelta addRole2Delta = DeltaBuilder .deltaFor(UserType.class, prismContext) .item(UserType.F_ASSIGNMENT).add(createAssignmentTo(getRoleOid(2), ObjectTypes.ROLE, prismContext)) .asObjectDelta(userJackOid); @SuppressWarnings("unchecked") - ObjectDelta addRole3Delta = (ObjectDelta) DeltaBuilder + ObjectDelta addRole3Delta = DeltaBuilder .deltaFor(UserType.class, prismContext) .item(UserType.F_ASSIGNMENT).add(createAssignmentTo(getRoleOid(3), ObjectTypes.ROLE, prismContext)) .asObjectDelta(userJackOid); @SuppressWarnings("unchecked") - ObjectDelta addRole4Delta = (ObjectDelta) DeltaBuilder + ObjectDelta addRole4Delta = DeltaBuilder .deltaFor(UserType.class, prismContext) .item(UserType.F_ASSIGNMENT).add(createAssignmentTo(getRoleOid(4), ObjectTypes.ROLE, prismContext)) .asObjectDelta(userJackOid); @SuppressWarnings("unchecked") - ObjectDelta changeDescriptionDelta = (ObjectDelta) DeltaBuilder + ObjectDelta changeDescriptionDelta = DeltaBuilder .deltaFor(UserType.class, prismContext) .item(UserType.F_DESCRIPTION).replace(TEST_NAME) .asObjectDelta(userJackOid); diff --git a/model/workflow-impl/src/test/java/com/evolveum/midpoint/wf/impl/policy/assignments/metarole/TestAssignmentsWithDifferentMetaroles.java b/model/workflow-impl/src/test/java/com/evolveum/midpoint/wf/impl/policy/assignments/metarole/TestAssignmentsWithDifferentMetaroles.java index 5c4eb308ad2..1c922e6b4ac 100644 --- a/model/workflow-impl/src/test/java/com/evolveum/midpoint/wf/impl/policy/assignments/metarole/TestAssignmentsWithDifferentMetaroles.java +++ b/model/workflow-impl/src/test/java/com/evolveum/midpoint/wf/impl/policy/assignments/metarole/TestAssignmentsWithDifferentMetaroles.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010-2017 Evolveum + * Copyright (c) 2010-2018 Evolveum * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -1044,22 +1044,22 @@ private void executeAssignRoles123ToJack(String TEST_NAME, boolean immediate, Task task = createTask("executeAssignRoles123ToJack"); PrismObject jack = getUser(userJackOid); @SuppressWarnings("unchecked") - ObjectDelta addRole1Delta = (ObjectDelta) DeltaBuilder + ObjectDelta addRole1Delta = DeltaBuilder .deltaFor(UserType.class, prismContext) .item(UserType.F_ASSIGNMENT).add(createAssignmentTo(roleRole21Oid, ObjectTypes.ROLE, prismContext)) .asObjectDelta(userJackOid); @SuppressWarnings("unchecked") - ObjectDelta addRole2Delta = (ObjectDelta) DeltaBuilder + ObjectDelta addRole2Delta = DeltaBuilder .deltaFor(UserType.class, prismContext) .item(UserType.F_ASSIGNMENT).add(createAssignmentTo(roleRole22Oid, ObjectTypes.ROLE, prismContext)) .asObjectDelta(userJackOid); @SuppressWarnings("unchecked") - ObjectDelta addRole3Delta = (ObjectDelta) DeltaBuilder + ObjectDelta addRole3Delta = DeltaBuilder .deltaFor(UserType.class, prismContext) .item(UserType.F_ASSIGNMENT).add(createAssignmentTo(roleRole23Oid, ObjectTypes.ROLE, prismContext)) .asObjectDelta(userJackOid); @SuppressWarnings("unchecked") - ObjectDelta changeDescriptionDelta = (ObjectDelta) DeltaBuilder + ObjectDelta changeDescriptionDelta = DeltaBuilder .deltaFor(UserType.class, prismContext) .item(UserType.F_DESCRIPTION).replace(TEST_NAME) .asObjectDelta(userJackOid); @@ -1194,7 +1194,7 @@ private void previewAssignRolesToJack(String TEST_NAME, boolean immediate, boole assignmentsToAdd.add(createAssignmentTo(roleRole24Oid, ObjectTypes.ROLE, prismContext)); } @SuppressWarnings("unchecked") - ObjectDelta primaryDelta = (ObjectDelta) DeltaBuilder + ObjectDelta primaryDelta = DeltaBuilder .deltaFor(UserType.class, prismContext) .item(UserType.F_ASSIGNMENT).addRealValues(assignmentsToAdd) .item(UserType.F_DESCRIPTION).replace(TEST_NAME) @@ -1307,22 +1307,22 @@ private void executeUnassignRoles123ToJack(String TEST_NAME, boolean immediate, AssignmentType del2 = toDelete(a2, byId); AssignmentType del3 = toDelete(a3, byId); @SuppressWarnings("unchecked") - ObjectDelta deleteRole1Delta = has1and2 ? (ObjectDelta) DeltaBuilder + ObjectDelta deleteRole1Delta = has1and2 ? DeltaBuilder .deltaFor(UserType.class, prismContext) .item(UserType.F_ASSIGNMENT).delete(del1) .asObjectDelta(userJackOid) : null; @SuppressWarnings("unchecked") - ObjectDelta deleteRole2Delta = has1and2 ? (ObjectDelta) DeltaBuilder + ObjectDelta deleteRole2Delta = has1and2 ? DeltaBuilder .deltaFor(UserType.class, prismContext) .item(UserType.F_ASSIGNMENT).delete(del2) .asObjectDelta(userJackOid) : null; @SuppressWarnings("unchecked") - ObjectDelta deleteRole3Delta = (ObjectDelta) DeltaBuilder + ObjectDelta deleteRole3Delta = DeltaBuilder .deltaFor(UserType.class, prismContext) .item(UserType.F_ASSIGNMENT).delete(del3) .asObjectDelta(userJackOid); @SuppressWarnings("unchecked") - ObjectDelta changeDescriptionDelta = (ObjectDelta) DeltaBuilder + ObjectDelta changeDescriptionDelta = DeltaBuilder .deltaFor(UserType.class, prismContext) .item(UserType.F_DESCRIPTION).replace(TEST_NAME) .asObjectDelta(userJackOid); diff --git a/model/workflow-impl/src/test/java/com/evolveum/midpoint/wf/impl/policy/assignments/plain/TestAssignmentApprovalPlainExplicit.java b/model/workflow-impl/src/test/java/com/evolveum/midpoint/wf/impl/policy/assignments/plain/TestAssignmentApprovalPlainExplicit.java index 2538494e6e5..682a6847afd 100644 --- a/model/workflow-impl/src/test/java/com/evolveum/midpoint/wf/impl/policy/assignments/plain/TestAssignmentApprovalPlainExplicit.java +++ b/model/workflow-impl/src/test/java/com/evolveum/midpoint/wf/impl/policy/assignments/plain/TestAssignmentApprovalPlainExplicit.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010-2017 Evolveum + * Copyright (c) 2010-2018 Evolveum * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -59,7 +59,7 @@ protected String getRoleName(int number) { @Override protected void importLead10(Task task, OperationResult result) throws Exception { super.importLead10(task, result); - executeChangesAssertSuccess((ObjectDelta) DeltaBuilder.deltaFor(RoleType.class, prismContext) + executeChangesAssertSuccess(DeltaBuilder.deltaFor(RoleType.class, prismContext) .item(RoleType.F_APPROVER_REF) .add(prv(userLead10Oid)) .asObjectDelta(getRoleOid(10)), null, task, result); diff --git a/model/workflow-impl/src/test/java/com/evolveum/midpoint/wf/impl/policy/lifecycle/AbstractTestLifecycle.java b/model/workflow-impl/src/test/java/com/evolveum/midpoint/wf/impl/policy/lifecycle/AbstractTestLifecycle.java index 8fd1c7c2f10..aea7b322898 100644 --- a/model/workflow-impl/src/test/java/com/evolveum/midpoint/wf/impl/policy/lifecycle/AbstractTestLifecycle.java +++ b/model/workflow-impl/src/test/java/com/evolveum/midpoint/wf/impl/policy/lifecycle/AbstractTestLifecycle.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010-2017 Evolveum + * Copyright (c) 2010-2018 Evolveum * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -103,7 +103,7 @@ public void test010CreateRolePirate() throws Exception { PrismReferenceValue pirateOwner = new PrismReferenceValue(rolePirateOid, RoleType.COMPLEX_TYPE); pirateOwner.setRelation(SchemaConstants.ORG_OWNER); - executeChanges((ObjectDelta) DeltaBuilder.deltaFor(UserType.class, prismContext) + executeChanges(DeltaBuilder.deltaFor(UserType.class, prismContext) .item(UserType.F_ASSIGNMENT).add(ObjectTypeUtil.createAssignmentTo(pirateOwner, prismContext)) .asObjectDelta(userPirateOwnerOid), null, task, result); @@ -128,7 +128,7 @@ public void test100ModifyRolePirateDescription() throws Exception { TestUtil.displayTestTitle(this, TEST_NAME); login(userAdministrator); - ObjectDelta descriptionDelta = (ObjectDelta) DeltaBuilder.deltaFor(RoleType.class, prismContext) + ObjectDelta descriptionDelta = DeltaBuilder.deltaFor(RoleType.class, prismContext) .item(RoleType.F_DESCRIPTION).replace("Bloody pirate") .asObjectDelta(rolePirateOid); ObjectDelta delta0 = ObjectDelta.createModifyDelta(rolePirateOid, Collections.emptyList(), RoleType.class, prismContext); diff --git a/model/workflow-impl/src/test/java/com/evolveum/midpoint/wf/impl/policy/object/TestObjectConstraints.java b/model/workflow-impl/src/test/java/com/evolveum/midpoint/wf/impl/policy/object/TestObjectConstraints.java index 8ca75daa07f..306c5ac0186 100644 --- a/model/workflow-impl/src/test/java/com/evolveum/midpoint/wf/impl/policy/object/TestObjectConstraints.java +++ b/model/workflow-impl/src/test/java/com/evolveum/midpoint/wf/impl/policy/object/TestObjectConstraints.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010-2017 Evolveum + * Copyright (c) 2010-2018 Evolveum * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -177,7 +177,7 @@ protected Boolean decideOnApproval(String executionId, org.activiti.engine.task. roleEmployeeOid = searchObjectByName(RoleType.class, "employee").getOid(); PrismReferenceValue employeeOwner = new PrismReferenceValue(roleEmployeeOid, RoleType.COMPLEX_TYPE).relation(SchemaConstants.ORG_OWNER); - executeChanges((ObjectDelta) DeltaBuilder.deltaFor(UserType.class, prismContext) + executeChanges(DeltaBuilder.deltaFor(UserType.class, prismContext) .item(UserType.F_ASSIGNMENT).add(ObjectTypeUtil.createAssignmentTo(employeeOwner, prismContext)) .asObjectDelta(userEmployeeOwnerOid), null, task, result); @@ -195,7 +195,7 @@ public void test020ActivateIncompleteRole() throws Exception { OperationResult result = task.getResult(); @SuppressWarnings({"unchecked", "raw"}) - ObjectDelta activateRoleDelta = (ObjectDelta) DeltaBuilder.deltaFor(RoleType.class, prismContext) + ObjectDelta activateRoleDelta = DeltaBuilder.deltaFor(RoleType.class, prismContext) .item(RoleType.F_LIFECYCLE_STATE).replace(SchemaConstants.LIFECYCLE_ACTIVE) .asObjectDelta(roleEmployeeOid); @@ -230,7 +230,7 @@ public void test030ActivateIncompleteRoleAgain() throws Exception { OperationResult result = task.getResult(); @SuppressWarnings({"unchecked", "raw"}) - ObjectDelta activateRoleDelta = (ObjectDelta) DeltaBuilder.deltaFor(RoleType.class, prismContext) + ObjectDelta activateRoleDelta = DeltaBuilder.deltaFor(RoleType.class, prismContext) .item(RoleType.F_LIFECYCLE_STATE).replace(SchemaConstants.LIFECYCLE_ACTIVE) .item(RoleType.F_DESCRIPTION).replace("hi") .asObjectDelta(roleEmployeeOid); @@ -278,7 +278,7 @@ public void test045ActivateCompleteRole() throws Exception { OperationResult result = task.getResult(); @SuppressWarnings({"unchecked", "raw"}) - ObjectDelta activateRoleDelta = (ObjectDelta) DeltaBuilder.deltaFor(RoleType.class, prismContext) + ObjectDelta activateRoleDelta = DeltaBuilder.deltaFor(RoleType.class, prismContext) .item(RoleType.F_LIFECYCLE_STATE).replace(SchemaConstants.LIFECYCLE_ACTIVE) .item(RoleType.F_DESCRIPTION).replace("hi") .asObjectDelta(roleEmployeeOid); diff --git a/model/workflow-impl/src/test/java/com/evolveum/midpoint/wf/impl/policy/other/TestMiscellaneous.java b/model/workflow-impl/src/test/java/com/evolveum/midpoint/wf/impl/policy/other/TestMiscellaneous.java index eb154717ec3..ac45d2230bc 100644 --- a/model/workflow-impl/src/test/java/com/evolveum/midpoint/wf/impl/policy/other/TestMiscellaneous.java +++ b/model/workflow-impl/src/test/java/com/evolveum/midpoint/wf/impl/policy/other/TestMiscellaneous.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010-2017 Evolveum + * Copyright (c) 2010-2018 Evolveum * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -116,7 +116,7 @@ public void test100RequesterComment() throws Exception { display("assignment after creation", assignment); MetadataType metadata = assignment.getMetadata(); assertNotNull("Null request timestamp in metadata", metadata.getRequestTimestamp()); - assertRefEquals("Wrong requestorRef in metadata", ObjectTypeUtil.createObjectRef(userAdministrator), metadata.getRequestorRef()); + assertRefEquals("Wrong requestorRef in metadata", ObjectTypeUtil.createObjectRef(userAdministrator, prismContext), metadata.getRequestorRef()); assertEquals("Wrong requestorComment in metadata", REQUESTER_COMMENT, metadata.getRequestorComment()); } @@ -183,7 +183,7 @@ public void test105RequesterCommentImmediate() throws Exception { display("assignment after creation", assignment); MetadataType metadata = assignment.getMetadata(); assertNotNull("Null request timestamp in metadata", metadata.getRequestTimestamp()); - assertRefEquals("Wrong requestorRef in metadata", ObjectTypeUtil.createObjectRef(userAdministrator), metadata.getRequestorRef()); + assertRefEquals("Wrong requestorRef in metadata", ObjectTypeUtil.createObjectRef(userAdministrator, prismContext), metadata.getRequestorRef()); assertEquals("Wrong requestorComment in metadata", REQUESTER_COMMENT, metadata.getRequestorComment()); } @@ -315,7 +315,7 @@ public void test250SkippingApprovals() throws Exception { // WHEN @SuppressWarnings({"raw", "unchecked"}) ObjectDelta delta = - (ObjectDelta) DeltaBuilder.deltaFor(UserType.class, prismContext) + DeltaBuilder.deltaFor(UserType.class, prismContext) .item(UserType.F_ASSIGNMENT) .add(ObjectTypeUtil.createAssignmentTo(roleRole1aOid, ObjectTypes.ROLE, prismContext)) .asObjectDelta(userJackOid); diff --git a/model/workflow-impl/src/test/java/com/evolveum/midpoint/wf/impl/policy/sod/AbstractTestSoD.java b/model/workflow-impl/src/test/java/com/evolveum/midpoint/wf/impl/policy/sod/AbstractTestSoD.java index d1bcb70b502..cd36bf8641d 100644 --- a/model/workflow-impl/src/test/java/com/evolveum/midpoint/wf/impl/policy/sod/AbstractTestSoD.java +++ b/model/workflow-impl/src/test/java/com/evolveum/midpoint/wf/impl/policy/sod/AbstractTestSoD.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010-2017 Evolveum + * Copyright (c) 2010-2018 Evolveum * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -119,12 +119,12 @@ public void test020AssignRolePirate() throws Exception { String originalDescription = jack.asObjectable().getDescription(); @SuppressWarnings("unchecked") - ObjectDelta addPirateDelta = (ObjectDelta) DeltaBuilder + ObjectDelta addPirateDelta = DeltaBuilder .deltaFor(UserType.class, prismContext) .item(UserType.F_ASSIGNMENT).add(createAssignmentTo(rolePirateOid, ObjectTypes.ROLE, prismContext)) .asObjectDelta(userJackOid); @SuppressWarnings("unchecked") - ObjectDelta changeDescriptionDelta = (ObjectDelta) DeltaBuilder + ObjectDelta changeDescriptionDelta = DeltaBuilder .deltaFor(UserType.class, prismContext) .item(UserType.F_DESCRIPTION).replace("Pirate Judge") .asObjectDelta(userJackOid); @@ -240,7 +240,7 @@ public void test030AssignRoleRespectable() throws Exception { // WHEN+THEN PrismObject jack = getUser(userJackOid); @SuppressWarnings("unchecked") - ObjectDelta addRespectableDelta = (ObjectDelta) DeltaBuilder + ObjectDelta addRespectableDelta = DeltaBuilder .deltaFor(UserType.class, prismContext) .item(UserType.F_ASSIGNMENT).add(createAssignmentTo(roleRespectableOid, ObjectTypes.ROLE, prismContext)) .asObjectDelta(userJackOid); diff --git a/provisioning/provisioning-api/src/main/java/com/evolveum/midpoint/provisioning/api/ProvisioningOperationOptions.java b/provisioning/provisioning-api/src/main/java/com/evolveum/midpoint/provisioning/api/ProvisioningOperationOptions.java index 48da97ad134..ee9f54eecd0 100644 --- a/provisioning/provisioning-api/src/main/java/com/evolveum/midpoint/provisioning/api/ProvisioningOperationOptions.java +++ b/provisioning/provisioning-api/src/main/java/com/evolveum/midpoint/provisioning/api/ProvisioningOperationOptions.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010-2017 Evolveum + * Copyright (c) 2010-2018 Evolveum * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -37,6 +37,24 @@ public class ProvisioningOperationOptions implements Serializable { private Boolean overwrite; + /** + * Run the operations on resource using the specified identity. + * The value is a OID of an account shadow. + * + * This option should be considered a suggestion, not a command. + * Therefore if the connector can run operation as specified user + * the it should run it. But if it is not capable to run such + * operation as specified user but it can run it as administrator + * then it should run the operation as administrator. + * That case may happen e.g. if account cleartext password is not + * known at that time. + * + * Note: maybe later we need some kind of flag that makes this + * option "critical", i.e. that an error is thrown if the + * operation cannot be executed as specified identity. + */ + private String runAsAccountOid; + public Boolean getCompletePostponed() { return completePostponed; } @@ -182,6 +200,20 @@ public static ProvisioningOperationOptions createRaw() { opts.setRaw(true); return opts; } + + public String getRunAsAccountOid() { + return runAsAccountOid; + } + + public void setRunAsAccountOid(String runAsAccountOid) { + this.runAsAccountOid = runAsAccountOid; + } + + public static ProvisioningOperationOptions createRunAsAccountOid(String runAsAccountOid) { + ProvisioningOperationOptions opts = new ProvisioningOperationOptions(); + opts.setRunAsAccountOid(runAsAccountOid); + return opts; + } @Override public String toString() { @@ -192,6 +224,9 @@ public String toString() { appendFlag(sb, "postpone", postpone); appendFlag(sb, "doNotDiscovery", doNotDiscovery); appendFlag(sb, "overwrite", overwrite); + if (runAsAccountOid != null) { + sb.append("runAsAccountOid=").append(runAsAccountOid).append(","); + } if (sb.charAt(sb.length() - 1) == ',') { sb.deleteCharAt(sb.length() - 1); } diff --git a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ProvisioningContext.java b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ProvisioningContext.java index e5506c70308..9993432a2d5 100644 --- a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ProvisioningContext.java +++ b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ProvisioningContext.java @@ -24,6 +24,7 @@ import com.evolveum.midpoint.schema.SelectorOptions; import com.evolveum.midpoint.schema.processor.ObjectClassComplexTypeDefinition; import com.evolveum.midpoint.schema.result.OperationResult; +import com.evolveum.midpoint.schema.util.ResourceTypeUtil; import com.evolveum.midpoint.task.api.StateReporter; import com.evolveum.midpoint.util.exception.*; import com.evolveum.midpoint.util.logging.Trace; @@ -313,7 +314,11 @@ private ConnectorInstance getConnectorInstance(Class< throw e; } } - + + public T getResourceEffectiveCapability(Class capabilityClass) throws ObjectNotFoundException, SchemaException, CommunicationException, ConfigurationException, ExpressionEvaluationException { + return ResourceTypeUtil.getEffectiveCapability(getResource(), capabilityClass); + } + public CapabilitiesType getConnectorCapabilities(Class operationCapabilityClass) { return resourceManager.getConnectorCapabilities(resource.asPrismObject(), operationCapabilityClass); } 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 5d6957fc1a8..97c2843f040 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 @@ -31,13 +31,11 @@ import com.evolveum.midpoint.prism.util.JavaTypeConverter; import com.evolveum.midpoint.prism.util.PrismUtil; import com.evolveum.midpoint.provisioning.api.GenericConnectorException; +import com.evolveum.midpoint.provisioning.api.ProvisioningOperationOptions; import com.evolveum.midpoint.provisioning.ucf.api.*; import com.evolveum.midpoint.provisioning.util.ProvisioningUtil; import com.evolveum.midpoint.repo.cache.RepositoryCache; -import com.evolveum.midpoint.schema.CapabilityUtil; -import com.evolveum.midpoint.schema.ResourceShadowDiscriminator; -import com.evolveum.midpoint.schema.ResultHandler; -import com.evolveum.midpoint.schema.SearchResultMetadata; +import com.evolveum.midpoint.schema.*; import com.evolveum.midpoint.schema.constants.SchemaConstants; import com.evolveum.midpoint.schema.internals.InternalsConfig; import com.evolveum.midpoint.schema.processor.*; @@ -113,6 +111,7 @@ public class ResourceObjectConverter { @Autowired private ShadowCaretaker shadowCaretaker; @Autowired private Clock clock; @Autowired private PrismContext prismContext; + @Autowired private RelationRegistry relationRegistry; private static final Trace LOGGER = TraceManager.getTrace(ResourceObjectConverter.class); @@ -234,9 +233,10 @@ private boolean hasAllIdentifiers(Collection> att public AsynchronousOperationReturnValue> addResourceObject(ProvisioningContext ctx, - PrismObject shadow, OperationProvisioningScriptsType scripts, boolean skipExplicitUniquenessCheck, OperationResult parentResult) - throws ObjectNotFoundException, SchemaException, CommunicationException, - ObjectAlreadyExistsException, ConfigurationException, SecurityViolationException, ExpressionEvaluationException { + PrismObject shadow, OperationProvisioningScriptsType scripts, ConnectorOperationOptions connOptions, + boolean skipExplicitUniquenessCheck, OperationResult parentResult) + throws ObjectNotFoundException, SchemaException, CommunicationException, + ObjectAlreadyExistsException, ConfigurationException, SecurityViolationException, ExpressionEvaluationException { OperationResult result = parentResult.createSubresult(OPERATION_ADD_RESOURCE_OBJECT); @@ -251,7 +251,8 @@ public AsynchronousOperationReturnValue> addResourceObje Collection> resourceAttributesAfterAdd = null; - if (ProvisioningUtil.isProtectedShadow(ctx.getObjectClassDefinition(), shadowClone, matchingRuleRegistry)) { + if (ProvisioningUtil.isProtectedShadow(ctx.getObjectClassDefinition(), shadowClone, matchingRuleRegistry, + relationRegistry)) { LOGGER.error("Attempt to add protected shadow " + shadowType + "; ignoring the request"); SecurityViolationException e = new SecurityViolationException("Cannot get protected shadow " + shadowType); result.recordFatalError(e); @@ -308,7 +309,7 @@ public AsynchronousOperationReturnValue> addResourceObje } // Execute entitlement modification on other objects (if needed) - executeEntitlementChangesAdd(ctx, shadowClone, scripts, result); + executeEntitlementChangesAdd(ctx, shadowClone, scripts, connOptions, result); LOGGER.trace("Added resource object {}", shadow); @@ -375,7 +376,7 @@ private void checkForAddConflicts(ProvisioningContext ctx, PrismObject shadow, - OperationProvisioningScriptsType scripts, OperationResult parentResult) + OperationProvisioningScriptsType scripts, ConnectorOperationOptions connOptions, OperationResult parentResult) throws ObjectNotFoundException, SchemaException, CommunicationException, ConfigurationException, SecurityViolationException, ExpressionEvaluationException { @@ -388,7 +389,7 @@ public AsynchronousOperationResult deleteResourceObject(ProvisioningContext ctx, Collection> identifiers = ShadowUtil .getAllIdentifiers(shadow); - if (ProvisioningUtil.isProtectedShadow(ctx.getObjectClassDefinition(), shadow, matchingRuleRegistry)) { + if (ProvisioningUtil.isProtectedShadow(ctx.getObjectClassDefinition(), shadow, matchingRuleRegistry, relationRegistry)) { LOGGER.error("Attempt to delete protected resource object " + ctx.getObjectClassDefinition() + ": " + identifiers + "; ignoring the request"); SecurityViolationException e = new SecurityViolationException("Cannot delete protected resource object " @@ -404,7 +405,7 @@ public AsynchronousOperationResult deleteResourceObject(ProvisioningContext ctx, } // Execute entitlement modification on other objects (if needed) - executeEntitlementChangesDelete(ctx, shadow, scripts, result); + executeEntitlementChangesDelete(ctx, shadow, scripts, connOptions, result); Collection additionalOperations = new ArrayList<>(); addExecuteScriptOperation(additionalOperations, ProvisioningOperationTypeType.DELETE, scripts, ctx.getResource(), @@ -483,6 +484,7 @@ public AsynchronousOperationReturnValue repoShadow, OperationProvisioningScriptsType scripts, + ConnectorOperationOptions connOptions, Collection itemDeltas, XMLGregorianCalendar now, OperationResult parentResult) @@ -503,7 +505,8 @@ public AsynchronousOperationReturnValue> identifiers = ShadowUtil.getAllIdentifiers(repoShadow); Collection> primaryIdentifiers = ShadowUtil.getPrimaryIdentifiers(repoShadow); - if (ProvisioningUtil.isProtectedShadow(ctx.getObjectClassDefinition(), repoShadow, matchingRuleRegistry)) { + if (ProvisioningUtil.isProtectedShadow(ctx.getObjectClassDefinition(), repoShadow, matchingRuleRegistry, + relationRegistry)) { if (hasChangesOnResource(itemDeltas)) { LOGGER.error("Attempt to modify protected resource object " + objectClassDefinition + ": " + identifiers); @@ -608,7 +611,7 @@ public AsynchronousOperationReturnValue> convertToPropertyDelta( @SuppressWarnings("rawtypes") private AsynchronousOperationReturnValue> executeModify(ProvisioningContext ctx, PrismObject currentShadow, Collection> identifiers, - Collection operations, OperationResult parentResult) + Collection operations, ConnectorOperationOptions connOptions, OperationResult parentResult) throws ObjectNotFoundException, CommunicationException, SchemaException, SecurityViolationException, ConfigurationException, ObjectAlreadyExistsException, ExpressionEvaluationException { Collection sideEffectChanges = new HashSet<>(); @@ -816,7 +819,8 @@ private AsynchronousOperationReturnValue sideEffects = connectorAsyncOpRet.getReturnValue(); if (sideEffects != null) { sideEffectChanges.addAll(sideEffects); @@ -1100,21 +1104,22 @@ private boolean isIdentifierDelta(ProvisioningContext ctx, PropertyDelta ctx.getObjectClassDefinition().isSecondaryIdentifier(propertyDelta.getElementName()); } - private PrismObject executeEntitlementChangesAdd(ProvisioningContext ctx, PrismObject shadow, OperationProvisioningScriptsType scripts, + private PrismObject executeEntitlementChangesAdd(ProvisioningContext ctx, PrismObject shadow, + OperationProvisioningScriptsType scripts, ConnectorOperationOptions connOptions, OperationResult parentResult) throws SchemaException, ObjectNotFoundException, CommunicationException, SecurityViolationException, ConfigurationException, ObjectAlreadyExistsException, ExpressionEvaluationException { Map roMap = new HashMap<>(); shadow = entitlementConverter.collectEntitlementsAsObjectOperationInShadowAdd(ctx, roMap, shadow, parentResult); - executeEntitlements(ctx, roMap, parentResult); + executeEntitlements(ctx, roMap, connOptions, parentResult); return shadow; } private PrismObject executeEntitlementChangesModify(ProvisioningContext ctx, PrismObject subjectShadowBefore, PrismObject subjectShadowAfter, - OperationProvisioningScriptsType scripts, Collection subjectDeltas, OperationResult parentResult) throws SchemaException, ObjectNotFoundException, CommunicationException, SecurityViolationException, ConfigurationException, ObjectAlreadyExistsException, ExpressionEvaluationException { + OperationProvisioningScriptsType scripts, ConnectorOperationOptions connOptions, Collection subjectDeltas, OperationResult parentResult) throws SchemaException, ObjectNotFoundException, CommunicationException, SecurityViolationException, ConfigurationException, ObjectAlreadyExistsException, ExpressionEvaluationException { Map roMap = new HashMap<>(); @@ -1177,13 +1182,13 @@ private PrismObject executeEntitlementChangesModify(ProvisioningCont } } - executeEntitlements(ctx, roMap, parentResult); + executeEntitlements(ctx, roMap, connOptions, parentResult); return subjectShadowAfter; } private void executeEntitlementChangesDelete(ProvisioningContext ctx, PrismObject subjectShadow, - OperationProvisioningScriptsType scripts, + OperationProvisioningScriptsType scripts, ConnectorOperationOptions connOptions, OperationResult parentResult) throws SchemaException { try { @@ -1193,7 +1198,7 @@ private void executeEntitlementChangesDelete(ProvisioningContext ctx, PrismObjec entitlementConverter.collectEntitlementsAsObjectOperationDelete(ctx, roMap, subjectShadow, parentResult); - executeEntitlements(ctx, roMap, parentResult); + executeEntitlements(ctx, roMap, connOptions, parentResult); // TODO: now just log the errors, but not NOT re-throw the exception (except for some exceptions) // we want the original delete to take place, throwing an exception would spoil that @@ -1206,7 +1211,7 @@ private void executeEntitlementChangesDelete(ProvisioningContext ctx, PrismObjec } private void executeEntitlements(ProvisioningContext subjectCtx, - Map roMap, OperationResult parentResult) throws ObjectNotFoundException, CommunicationException, SchemaException, SecurityViolationException, ConfigurationException, ObjectAlreadyExistsException { + Map roMap, ConnectorOperationOptions connOptions, OperationResult parentResult) throws ObjectNotFoundException, CommunicationException, SchemaException, SecurityViolationException, ConfigurationException, ObjectAlreadyExistsException { if (LOGGER.isTraceEnabled()) { LOGGER.trace("Excuting entitlement chanes, roMap:\n{}", DebugUtil.debugDump(roMap, 1)); @@ -1230,7 +1235,7 @@ private void executeEntitlements(ProvisioningContext subjectCtx, OperationResult result = parentResult.createMinorSubresult(OPERATION_MODIFY_ENTITLEMENT); try { - executeModify(entitlementCtx, entry.getValue().getCurrentShadow(), allIdentifiers, operations, result); + executeModify(entitlementCtx, entry.getValue().getCurrentShadow(), allIdentifiers, operations, connOptions, result); result.recordSuccess(); @@ -1888,7 +1893,7 @@ private PrismObject postProcessResourceObjectRead(ProvisioningContex } ShadowType resourceObjectType = resourceObject.asObjectable(); - ProvisioningUtil.setProtectedFlag(ctx, resourceObject, matchingRuleRegistry); + ProvisioningUtil.setProtectedFlag(ctx, resourceObject, matchingRuleRegistry, relationRegistry); if (resourceObjectType.isExists() != Boolean.FALSE) { resourceObjectType.setExists(true); 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 981df025ba9..190f66f937f 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 @@ -24,8 +24,6 @@ import com.evolveum.midpoint.prism.crypto.EncryptionException; import com.evolveum.midpoint.prism.crypto.Protector; import com.evolveum.midpoint.prism.delta.*; -import com.evolveum.midpoint.prism.delta.builder.DeltaBuilder; -import com.evolveum.midpoint.prism.delta.builder.S_ItemEntry; import com.evolveum.midpoint.prism.match.MatchingRuleRegistry; import com.evolveum.midpoint.prism.path.IdItemPathSegment; import com.evolveum.midpoint.prism.path.ItemPath; @@ -37,6 +35,7 @@ import com.evolveum.midpoint.provisioning.impl.errorhandling.ErrorHandlerLocator; import com.evolveum.midpoint.provisioning.ucf.api.Change; import com.evolveum.midpoint.provisioning.ucf.api.ConnectorInstance; +import com.evolveum.midpoint.provisioning.ucf.api.ConnectorOperationOptions; import com.evolveum.midpoint.provisioning.ucf.api.GenericFrameworkException; import com.evolveum.midpoint.provisioning.util.ProvisioningUtil; import com.evolveum.midpoint.repo.api.RepositoryService; @@ -67,6 +66,7 @@ import com.evolveum.midpoint.xml.ns._public.resource.capabilities_3.CountObjectsCapabilityType; import com.evolveum.midpoint.xml.ns._public.resource.capabilities_3.CountObjectsSimulateType; import com.evolveum.midpoint.xml.ns._public.resource.capabilities_3.ReadCapabilityType; +import com.evolveum.midpoint.xml.ns._public.resource.capabilities_3.RunAsCapabilityType; import com.evolveum.prism.xml.ns._public.types_3.ChangeTypeType; import com.evolveum.prism.xml.ns._public.types_3.ObjectDeltaType; import com.evolveum.prism.xml.ns._public.types_3.PolyStringType; @@ -121,6 +121,7 @@ public class ShadowCache { @Autowired private ResourceObjectConverter resouceObjectConverter; @Autowired private ShadowCaretaker shadowCaretaker; @Autowired private MatchingRuleRegistry matchingRuleRegistry; + @Autowired private RelationRegistry relationRegistry; @Autowired protected ShadowManager shadowManager; @Autowired private ChangeNotificationDispatcher operationListener; @Autowired private AccessChecker accessChecker; @@ -559,13 +560,15 @@ private String addShadowAttempt(ProvisioningContext ctx, if (shouldExecuteResourceOperationDirectly(ctx)) { + ConnectorOperationOptions connOptions = createConnectorOperationOptions(ctx, options, parentResult); + LOGGER.trace("ADD {}: resource operation, execution starting", shadowToAdd); try { // RESOURCE OPERATION: add AsynchronousOperationReturnValue> asyncReturnValue = - resouceObjectConverter.addResourceObject(ctx, shadowToAdd, scripts, false, parentResult); + resouceObjectConverter.addResourceObject(ctx, shadowToAdd, scripts, connOptions, false, parentResult); opState.processAsyncResult(asyncReturnValue); addedShadow = asyncReturnValue.getReturnValue(); @@ -595,7 +598,7 @@ private String addShadowAttempt(ProvisioningContext ctx, LOGGER.trace("ADD {}: retrying resource operation without uniquness check (previous dead shadow found), execution starting", shadowToAdd); AsynchronousOperationReturnValue> asyncReturnValue = - resouceObjectConverter.addResourceObject(ctx, shadowToAdd, scripts, true, parentResult); + resouceObjectConverter.addResourceObject(ctx, shadowToAdd, scripts, connOptions, true, parentResult); opState.processAsyncResult(asyncReturnValue); addedShadow = asyncReturnValue.getReturnValue(); @@ -937,7 +940,8 @@ public String modifyShadow(PrismObject repoShadow, } private String modifyShadowAttempt(ProvisioningContext ctx, - Collection modifications, OperationProvisioningScriptsType scripts, + Collection modifications, + OperationProvisioningScriptsType scripts, ProvisioningOperationOptions options, ProvisioningOperationState>>> opState, Task task, OperationResult parentResult) @@ -973,10 +977,12 @@ private String modifyShadowAttempt(ProvisioningContext ctx, LOGGER.trace("MODIFY {}: resource modification, execution starting\n{}", repoShadow, DebugUtil.debugDump(modifications)); } + ConnectorOperationOptions connOptions = createConnectorOperationOptions(ctx, options, parentResult); + try { AsynchronousOperationReturnValue>> asyncReturnValue = - resouceObjectConverter.modifyResourceObject(ctx, repoShadow, scripts, modifications, now, parentResult); + resouceObjectConverter.modifyResourceObject(ctx, repoShadow, scripts, connOptions, modifications, now, parentResult); opState.processAsyncResult(asyncReturnValue); Collection> sideEffectChanges = asyncReturnValue.getReturnValue(); @@ -1051,6 +1057,8 @@ private ProvisioningOperationState>>> opState = new ProvisioningOperationState<>(); opState.setRepoShadow(repoShadow); + ConnectorOperationOptions connOptions = createConnectorOperationOptions(ctx, options, parentResult); + try { if (LOGGER.isTraceEnabled()) { @@ -1058,7 +1066,7 @@ private ProvisioningOperationState>> asyncReturnValue = - resouceObjectConverter.modifyResourceObject(ctx, repoShadow, scripts, modifications, now, parentResult); + resouceObjectConverter.modifyResourceObject(ctx, repoShadow, scripts, connOptions, modifications, now, parentResult); opState.processAsyncResult(asyncReturnValue); Collection> sideEffectChanges = asyncReturnValue.getReturnValue(); @@ -1160,11 +1168,13 @@ private PrismObject deleteShadowAttempt(ProvisioningContext ctx, } else { + ConnectorOperationOptions connOptions = createConnectorOperationOptions(ctx, options, parentResult); + LOGGER.trace("DELETE {}: resource deletion, execution starting", repoShadow); try { - AsynchronousOperationResult asyncReturnValue = resouceObjectConverter.deleteResourceObject(ctx, repoShadow, scripts, parentResult); + AsynchronousOperationResult asyncReturnValue = resouceObjectConverter.deleteResourceObject(ctx, repoShadow, scripts, connOptions, parentResult); opState.processAsyncResult(asyncReturnValue); resourceManager.modifyResourceAvailabilityStatus(ctx.getResource().asPrismObject(), @@ -1226,9 +1236,11 @@ private ProvisioningOperationState executeResourceD if (shadow.asObjectable().getFailedOperationType() == null || (shadow.asObjectable().getFailedOperationType() != null && FailedOperationTypeType.ADD != shadow.asObjectable().getFailedOperationType())) { + + ConnectorOperationOptions connOptions = createConnectorOperationOptions(ctx, options, parentResult); try { - AsynchronousOperationResult asyncReturnValue = resouceObjectConverter.deleteResourceObject(ctx, shadow, scripts, parentResult); + AsynchronousOperationResult asyncReturnValue = resouceObjectConverter.deleteResourceObject(ctx, shadow, scripts, connOptions , parentResult); opState.processAsyncResult(asyncReturnValue); } catch (Exception ex) { @@ -1244,7 +1256,6 @@ private ProvisioningOperationState executeResourceD return opState; } - private void notifyAfterDelete( ProvisioningContext ctx, PrismObject shadow, @@ -1708,7 +1719,7 @@ public void setProtectedShadow(PrismObject shadow, OperationResult p throws ObjectNotFoundException, SchemaException, CommunicationException, ConfigurationException, ExpressionEvaluationException { ProvisioningContext ctx = ctxFactory.create(shadow, null, parentResult); ctx.assertDefinition(); - ProvisioningUtil.setProtectedFlag(ctx, shadow, matchingRuleRegistry); + ProvisioningUtil.setProtectedFlag(ctx, shadow, matchingRuleRegistry, relationRegistry); } public void applyDefinition(final ObjectQuery query, OperationResult result) @@ -2036,7 +2047,7 @@ private SearchResultMetadata searchObjectsIterativeRepository(final Provisioning shadowCaretaker.applyAttributesDefinition(ctx, shadow); // fixing MID-1640; hoping that the protected object filter uses only identifiers // (that are stored in repo) - ProvisioningUtil.setProtectedFlag(ctx, shadow, matchingRuleRegistry); + ProvisioningUtil.setProtectedFlag(ctx, shadow, matchingRuleRegistry, relationRegistry); validateShadow(shadow, true); @@ -2598,7 +2609,7 @@ void processChange(ProvisioningContext ctx, Change change, PrismObject completeShadow(ProvisioningContext ctx, resultShadowType.setObjectClass(resourceAttributesContainer.getDefinition().getTypeName()); } if (resultShadowType.getResource() == null) { - resultShadowType.setResourceRef(ObjectTypeUtil.createObjectRef(ctx.getResource())); + resultShadowType.setResourceRef(ObjectTypeUtil.createObjectRef(ctx.getResource(), prismContext)); } // Attributes @@ -2724,7 +2735,7 @@ private PrismObject completeShadow(ProvisioningContext ctx, transplantPasswordMetadata(repoShadowType, resultAccountShadow); // protected - ProvisioningUtil.setProtectedFlag(ctx, resultShadow, matchingRuleRegistry); + ProvisioningUtil.setProtectedFlag(ctx, resultShadow, matchingRuleRegistry, relationRegistry); // exists, dead // This may seem strange, but always take exists and dead flags from the repository. @@ -2834,7 +2845,7 @@ private PrismObject completeShadow(ProvisioningContext ctx, entitlementRepoShadow = lookupOrCreateLiveShadowInRepository(ctxEntitlement, entitlementShadow, false, isDoDiscovery, parentResult); } - ObjectReferenceType shadowRefType = ObjectTypeUtil.createObjectRef(entitlementRepoShadow); + ObjectReferenceType shadowRefType = ObjectTypeUtil.createObjectRef(entitlementRepoShadow, prismContext); shadowAssociationType.setShadowRef(shadowRefType); } } @@ -3168,6 +3179,34 @@ private PasswordCompareStrategyType getPasswordCompareStrategy(RefinedObjectClas return passwordDefinition.getCompareStrategy(); } + private ConnectorOperationOptions createConnectorOperationOptions(ProvisioningContext ctx, ProvisioningOperationOptions options, OperationResult result) throws SchemaException, ConfigurationException, ObjectNotFoundException, CommunicationException, ExpressionEvaluationException { + if (options == null) { + return null; + } + String runAsAccountOid = options.getRunAsAccountOid(); + if (runAsAccountOid == null) { + return null; + } + RunAsCapabilityType capRunAs = ctx.getResourceEffectiveCapability(RunAsCapabilityType.class); + if (capRunAs == null) { + LOGGER.trace("Operation runAs requested, but resource does not have the capability. Ignoring runAs"); + return null; + } + PrismObject runAsShadow; + try { + runAsShadow = shadowManager.getRepoShadow(runAsAccountOid, result); + } catch (ObjectNotFoundException e) { + throw new ConfigurationException("Requested non-existing 'runAs' shadow", e); + } + ProvisioningContext runAsCtx = ctxFactory.create(runAsShadow, null, ctx.getTask(), result); + shadowCaretaker.applyAttributesDefinition(runAsCtx, runAsShadow); + ResourceObjectIdentification runAsIdentification = ResourceObjectIdentification.createFromShadow(runAsCtx.getObjectClassDefinition(), runAsShadow.asObjectable()); + ConnectorOperationOptions connOptions = new ConnectorOperationOptions(); + connOptions.setRunAsIdentification(runAsIdentification); + return connOptions; + } + + // ----------------------- LEGACY ------ to be removed later (MID-4780) private void cleanLegacyShadowInRepository(PrismObject shadow, OperationResult parentResult) throws SchemaException, ObjectAlreadyExistsException, ObjectNotFoundException{ @@ -3197,31 +3236,5 @@ private void cleanLegacyShadowInRepository(PrismObject shadow, Opera // throw ex; // } } - - private List> createShadowLegacyCleanupAndReconciliationDeltas(PrismObject currentShadow, - PrismObject repoShadowBefore) throws SchemaException { - List> itemDeltas = new ArrayList<>(); - S_ItemEntry i = DeltaBuilder.deltaFor(ShadowType.class, prismContext); - ShadowType repo = repoShadowBefore.asObjectable(); - if (repo.getAttemptNumber() != null) { - i = i.item(ShadowType.F_ATTEMPT_NUMBER).replace(); - } - if (repo.getFailedOperationType() != null) { - i = i.item(ShadowType.F_FAILED_OPERATION_TYPE).replace(); - } - if (repo.getObjectChange() != null) { - i = i.item(ShadowType.F_OBJECT_CHANGE).replace(); - } - if (repo.getResult() != null) { - i = i.item(ShadowType.F_RESULT).replace(); - } - if (repo.getCredentials() != null) { - i = i.item(ShadowType.F_CREDENTIALS).replace(); - } - itemDeltas.addAll(i.asItemDeltas()); - itemDeltas.addAll(ProvisioningUtil.createShadowAttributesReconciliationDeltas(currentShadow, repoShadowBefore, getPrismContext())); - itemDeltas.addAll(ProvisioningUtil.createShadowActivationCleanupDeltas(repo, getPrismContext())); - return itemDeltas; - } } diff --git a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ShadowCaretaker.java b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ShadowCaretaker.java index 75847606100..6baec6b1e4d 100644 --- a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ShadowCaretaker.java +++ b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ShadowCaretaker.java @@ -42,10 +42,14 @@ import com.evolveum.midpoint.provisioning.util.ProvisioningUtil; import com.evolveum.midpoint.schema.DeltaConvertor; import com.evolveum.midpoint.schema.constants.SchemaConstants; +import com.evolveum.midpoint.schema.processor.ObjectClassComplexTypeDefinition; import com.evolveum.midpoint.schema.processor.ResourceAttributeContainer; import com.evolveum.midpoint.schema.processor.ResourceAttributeContainerDefinition; import com.evolveum.midpoint.schema.processor.ResourceAttributeDefinition; +import com.evolveum.midpoint.schema.processor.ResourceObjectIdentification; +import com.evolveum.midpoint.schema.result.OperationResult; import com.evolveum.midpoint.schema.util.ShadowUtil; +import com.evolveum.midpoint.task.api.Task; import com.evolveum.midpoint.util.QNameUtil; import com.evolveum.midpoint.util.exception.CommunicationException; import com.evolveum.midpoint.util.exception.ConfigurationException; @@ -76,6 +80,7 @@ public class ShadowCaretaker { @Autowired private Clock clock; @Autowired private PrismContext prismContext; + @Autowired private ProvisioningContextFactory ctxFactory; private static final Trace LOGGER = TraceManager.getTrace(ShadowCaretaker.class); diff --git a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ShadowManager.java b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ShadowManager.java index 14d98d5cce4..95fc8f772f1 100644 --- a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ShadowManager.java +++ b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ShadowManager.java @@ -20,12 +20,10 @@ import java.util.Arrays; import java.util.Collection; import java.util.List; -import java.util.function.Supplier; import javax.xml.datatype.XMLGregorianCalendar; import javax.xml.namespace.QName; -import com.evolveum.midpoint.util.QNameUtil; import org.apache.commons.lang.BooleanUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; @@ -68,7 +66,6 @@ import com.evolveum.midpoint.prism.query.builder.S_AtomicFilterEntry; import com.evolveum.midpoint.prism.query.builder.S_FilterEntry; import com.evolveum.midpoint.provisioning.api.ProvisioningOperationOptions; -import com.evolveum.midpoint.provisioning.api.ResourceOperationDescription; import com.evolveum.midpoint.provisioning.ucf.api.Change; import com.evolveum.midpoint.provisioning.util.ProvisioningUtil; import com.evolveum.midpoint.repo.api.ModificationPrecondition; @@ -125,7 +122,6 @@ import com.evolveum.midpoint.xml.ns._public.common.common_3.ResourceType; import com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowType; import com.evolveum.midpoint.xml.ns._public.common.common_3.UserType; -import com.evolveum.prism.xml.ns._public.types_3.ChangeTypeType; import com.evolveum.prism.xml.ns._public.types_3.ObjectDeltaType; import com.evolveum.prism.xml.ns._public.types_3.PolyStringType; import com.evolveum.prism.xml.ns._public.types_3.ProtectedStringType; @@ -158,7 +154,10 @@ public class ShadowManager { @Autowired private Protector protector; private static final Trace LOGGER = TraceManager.getTrace(ShadowManager.class); - + + public PrismObject getRepoShadow(String oid, OperationResult result) throws ObjectNotFoundException, SchemaException { + return repositoryService.getObject(ShadowType.class, oid, null, result); + } public void deleteConflictedShadowFromRepo(PrismObject shadow, OperationResult parentResult){ @@ -1493,13 +1492,13 @@ private PrismObject createRepositoryShadow(ProvisioningContext ctx, // convert to the resource reference. if (repoShadowType.getResource() != null) { repoShadowType.setResource(null); - repoShadowType.setResourceRef(ObjectTypeUtil.createObjectRef(ctx.getResource())); + repoShadowType.setResourceRef(ObjectTypeUtil.createObjectRef(ctx.getResource(), prismContext)); } // if shadow does not contain resource or resource reference, create it // now if (repoShadowType.getResourceRef() == null) { - repoShadowType.setResourceRef(ObjectTypeUtil.createObjectRef(ctx.getResource())); + repoShadowType.setResourceRef(ObjectTypeUtil.createObjectRef(ctx.getResource(), prismContext)); } if (repoShadowType.getName() == null) { 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 e6a2c9b3164..ae40770e65c 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 @@ -59,10 +59,7 @@ import com.evolveum.midpoint.provisioning.ucf.api.AttributesToReturn; import com.evolveum.midpoint.provisioning.ucf.api.ExecuteProvisioningScriptOperation; import com.evolveum.midpoint.provisioning.ucf.api.ExecuteScriptArgument; -import com.evolveum.midpoint.schema.CapabilityUtil; -import com.evolveum.midpoint.schema.GetOperationOptions; -import com.evolveum.midpoint.schema.PointInTimeType; -import com.evolveum.midpoint.schema.SelectorOptions; +import com.evolveum.midpoint.schema.*; import com.evolveum.midpoint.schema.constants.SchemaConstants; import com.evolveum.midpoint.schema.processor.ResourceAttribute; import com.evolveum.midpoint.schema.processor.ResourceAttributeContainer; @@ -313,8 +310,9 @@ public static RefinedResourceSchema getRefinedSchema(ResourceType resourceType) return refinedSchema; } - public static boolean isProtectedShadow(RefinedObjectClassDefinition objectClassDefinition, PrismObject shadow, MatchingRuleRegistry matchingRuleRegistry) throws SchemaException { - boolean isProtected = false; + public static boolean isProtectedShadow(RefinedObjectClassDefinition objectClassDefinition, PrismObject shadow, + MatchingRuleRegistry matchingRuleRegistry, RelationRegistry relationRegistry) throws SchemaException { + boolean isProtected; if (objectClassDefinition == null) { isProtected = false; } else { @@ -322,16 +320,17 @@ public static boolean isProtectedShadow(RefinedObjectClassDefinition objectClass if (protectedAccountPatterns == null) { isProtected = false; } else { - isProtected = ResourceObjectPattern.matches(shadow, protectedAccountPatterns, matchingRuleRegistry); + isProtected = ResourceObjectPattern.matches(shadow, protectedAccountPatterns, matchingRuleRegistry, relationRegistry); } } - LOGGER.trace("isProtectedShadow: {}: {} = {}", new Object[] { objectClassDefinition, - shadow, isProtected }); + LOGGER.trace("isProtectedShadow: {}: {} = {}", objectClassDefinition, shadow, isProtected); return isProtected; } - public static void setProtectedFlag(ProvisioningContext ctx, PrismObject resourceObject, MatchingRuleRegistry matchingRuleRegistry) throws SchemaException, ConfigurationException, ObjectNotFoundException, CommunicationException, ExpressionEvaluationException { - if (isProtectedShadow(ctx.getObjectClassDefinition(), resourceObject, matchingRuleRegistry)) { + public static void setProtectedFlag(ProvisioningContext ctx, PrismObject resourceObject, + MatchingRuleRegistry matchingRuleRegistry, RelationRegistry relationRegistry) throws SchemaException, + ConfigurationException, ObjectNotFoundException, CommunicationException, ExpressionEvaluationException { + if (isProtectedShadow(ctx.getObjectClassDefinition(), resourceObject, matchingRuleRegistry, relationRegistry)) { resourceObject.asObjectable().setProtectedObject(true); } } diff --git a/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/impl/TestConnectorManager.java b/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/impl/TestConnectorManager.java index e5237c235c6..c47ca2d1361 100644 --- a/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/impl/TestConnectorManager.java +++ b/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/impl/TestConnectorManager.java @@ -44,19 +44,16 @@ @DirtiesContext public class TestConnectorManager extends AbstractIntegrationTest { - private static final String CONNID_FRAMEWORK_VERSION = "1.4.3.41"; + private static final String CONNID_FRAMEWORK_VERSION = "1.4.3.43"; - @Autowired - private ProvisioningService provisioningService; - - @Autowired - private ConnectorManager connectorManager; + @Autowired private ProvisioningService provisioningService; + @Autowired private ConnectorManager connectorManager; private static Trace LOGGER = TraceManager.getTrace(TestConnectorManager.class); @Override public void initSystem(Task initTask, OperationResult initResult) throws Exception { - // do NOT postInit proviosioning. postInit would start connector disovery + // do NOT postInit provisioning. postInit would start connector discovery // we want to test the state before discovery // provisioningService.postInit(initResult); } diff --git a/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/impl/dummy/AbstractBasicDummyTest.java b/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/impl/dummy/AbstractBasicDummyTest.java index 78054b03135..8aefebf2fc8 100644 --- a/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/impl/dummy/AbstractBasicDummyTest.java +++ b/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/impl/dummy/AbstractBasicDummyTest.java @@ -121,6 +121,7 @@ import com.evolveum.midpoint.xml.ns._public.resource.capabilities_3.CredentialsCapabilityType; import com.evolveum.midpoint.xml.ns._public.resource.capabilities_3.PasswordCapabilityType; import com.evolveum.midpoint.xml.ns._public.resource.capabilities_3.ReadCapabilityType; +import com.evolveum.midpoint.xml.ns._public.resource.capabilities_3.RunAsCapabilityType; import com.evolveum.midpoint.xml.ns._public.resource.capabilities_3.ScriptCapabilityType; import com.evolveum.midpoint.xml.ns._public.resource.capabilities_3.TestConnectionCapabilityType; import com.evolveum.midpoint.xml.ns._public.resource.capabilities_3.UpdateCapabilityType; @@ -594,12 +595,10 @@ public void test028Capabilities() throws Exception { display("Resource", resourceType); List nativeCapabilitiesList = nativeCapabilities.getAny(); assertFalse("Empty capabilities returned", nativeCapabilitiesList.isEmpty()); - CredentialsCapabilityType capCred = CapabilityUtil.getCapability(nativeCapabilitiesList, - CredentialsCapabilityType.class); + CredentialsCapabilityType capCred = CapabilityUtil.getCapability(nativeCapabilitiesList, CredentialsCapabilityType.class); assertNativeCredentialsCapability(capCred); - ActivationCapabilityType capAct = CapabilityUtil.getCapability(nativeCapabilitiesList, - ActivationCapabilityType.class); + ActivationCapabilityType capAct = CapabilityUtil.getCapability(nativeCapabilitiesList, ActivationCapabilityType.class); if (supportsActivation()) { assertNotNull("native activation capability not present", capAct); assertNotNull("native activation status capability not present", capAct.getStatus()); @@ -607,20 +606,20 @@ public void test028Capabilities() throws Exception { assertNull("native activation capability sneaked in", capAct); } - TestConnectionCapabilityType capTest = CapabilityUtil.getCapability(nativeCapabilitiesList, - TestConnectionCapabilityType.class); + TestConnectionCapabilityType capTest = CapabilityUtil.getCapability(nativeCapabilitiesList, TestConnectionCapabilityType.class); assertNotNull("native test capability not present", capTest); - ScriptCapabilityType capScript = CapabilityUtil.getCapability(nativeCapabilitiesList, - ScriptCapabilityType.class); + ScriptCapabilityType capScript = CapabilityUtil.getCapability(nativeCapabilitiesList, ScriptCapabilityType.class); assertNotNull("native script capability not present", capScript); assertNotNull("No host in native script capability", capScript.getHost()); assertFalse("No host in native script capability", capScript.getHost().isEmpty()); // TODO: better look inside - UpdateCapabilityType capUpdate = CapabilityUtil.getCapability(nativeCapabilitiesList, - UpdateCapabilityType.class); + UpdateCapabilityType capUpdate = CapabilityUtil.getCapability(nativeCapabilitiesList, UpdateCapabilityType.class); assertUpdateCapability(capUpdate); + RunAsCapabilityType capRunAs = CapabilityUtil.getCapability(nativeCapabilitiesList, RunAsCapabilityType.class); + assertRunAsCapability(capRunAs); + capabilitiesCachingMetadataType = resourceType.getCapabilities().getCachingMetadata(); assertNotNull("No capabilities caching metadata", capabilitiesCachingMetadataType); assertNotNull("No capabilities caching metadata timestamp", capabilitiesCachingMetadataType.getRetrievalTimestamp()); @@ -663,6 +662,10 @@ protected void assertUpdateCapability(UpdateCapabilityType capUpdate) { assertTrue("native update capability is NOT delta", capUpdate.isDelta()); } + protected void assertRunAsCapability(RunAsCapabilityType capRunAs) { + assertNotNull("native runAs capability not present", capRunAs); + } + protected void assertCountConfiguredCapability(CountObjectsCapabilityType capCount) { CountObjectsSimulateType expectedCountSimulation = getCountSimulationMode(); if (expectedCountSimulation == null) { diff --git a/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/impl/dummy/AbstractDummyTest.java b/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/impl/dummy/AbstractDummyTest.java index c06783014b9..ca8be3454da 100644 --- a/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/impl/dummy/AbstractDummyTest.java +++ b/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/impl/dummy/AbstractDummyTest.java @@ -87,7 +87,8 @@ public abstract class AbstractDummyTest extends AbstractProvisioningIntegrationT protected static final String ACCOUNT_WILL_OID = "c0c010c0-d34d-b44f-f11d-33322212dddd"; protected static final String ACCOUNT_WILL_USERNAME = "Will"; protected static final String ACCOUNT_WILL_PASSWORD = "3lizab3th"; - protected static final String ACCOUNT_WILL_PASSWORD_NEW = "3lizab3th123"; + protected static final String ACCOUNT_WILL_PASSWORD_123 = "3lizab3th123"; + protected static final String ACCOUNT_WILL_PASSWORD_321 = "3lizab3th321"; protected static final XMLGregorianCalendar ACCOUNT_WILL_ENABLE_TIMESTAMP = XmlTypeConverter.createXMLGregorianCalendar(2013, 5, 30, 12, 30, 42); protected static final File ACCOUNT_ELIZABETH_FILE = new File(TEST_DIR, "account-elizabeth.xml"); diff --git a/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/impl/dummy/TestDummy.java b/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/impl/dummy/TestDummy.java index 320bee6f907..a610df19a07 100644 --- a/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/impl/dummy/TestDummy.java +++ b/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/impl/dummy/TestDummy.java @@ -73,6 +73,7 @@ import com.evolveum.midpoint.prism.util.PrismTestUtil; import com.evolveum.midpoint.prism.xml.XmlTypeConverter; import com.evolveum.midpoint.provisioning.api.ItemComparisonResult; +import com.evolveum.midpoint.provisioning.api.ProvisioningOperationOptions; import com.evolveum.midpoint.provisioning.api.ResourceObjectShadowChangeDescription; import com.evolveum.midpoint.provisioning.impl.ProvisioningTestUtil; import com.evolveum.midpoint.schema.GetOperationOptions; @@ -1126,7 +1127,7 @@ public void test126ModifyAccountWillPassword() throws Exception { OperationResult result = task.getResult(); syncServiceMock.reset(); - ObjectDelta delta = createAccountPaswordDelta(ACCOUNT_WILL_OID, ACCOUNT_WILL_PASSWORD_NEW); + ObjectDelta delta = createAccountPaswordDelta(ACCOUNT_WILL_OID, ACCOUNT_WILL_PASSWORD_123, null); display("ObjectDelta", delta); // WHEN @@ -1138,11 +1139,11 @@ public void test126ModifyAccountWillPassword() throws Exception { displayThen(TEST_NAME); assertSuccess(result); - // Check if the account was created in the dummy resource - DummyAccount dummyAccount = getDummyAccountAssert(transformNameFromResource(ACCOUNT_WILL_USERNAME), willIcfUid); - assertNotNull("No dummy account", dummyAccount); - assertEquals("Wrong password", ACCOUNT_WILL_PASSWORD_NEW, dummyAccount.getPassword()); - accountWillCurrentPassword = ACCOUNT_WILL_PASSWORD_NEW; + assertDummyAccount(transformNameFromResource(ACCOUNT_WILL_USERNAME), willIcfUid) + .assertPassword(ACCOUNT_WILL_PASSWORD_123) + .assertLastModifier(null); + + accountWillCurrentPassword = ACCOUNT_WILL_PASSWORD_123; // Check if the shadow is in the repo PrismObject repoShadow = getShadowRepo(ACCOUNT_WILL_OID); @@ -1150,7 +1151,7 @@ public void test126ModifyAccountWillPassword() throws Exception { display("Repository shadow", repoShadow); checkRepoAccountShadow(repoShadow); - assertRepoShadowCredentials(repoShadow, ACCOUNT_WILL_PASSWORD_NEW); + assertRepoShadowCredentials(repoShadow, ACCOUNT_WILL_PASSWORD_123); syncServiceMock.assertNotifySuccessOnly(); @@ -3649,6 +3650,57 @@ public void test310ModifyMorganEnlistTimestamp() throws Exception { assertSteadyResource(); } + + /** + * Change password, using runAsAccountOid option. + * MID-4397 + */ + @Test + public void test330ModifyAccountWillPasswordSelfService() throws Exception { + final String TEST_NAME = "test330ModifyAccountWillPasswordSelfService"; + displayTestTitle(TEST_NAME); + + Task task = createTask(TEST_NAME); + OperationResult result = task.getResult(); + syncServiceMock.reset(); + + ObjectDelta delta = createAccountPaswordDelta(ACCOUNT_WILL_OID, ACCOUNT_WILL_PASSWORD_321, ACCOUNT_WILL_PASSWORD_123); + display("ObjectDelta", delta); + + ProvisioningOperationOptions options = ProvisioningOperationOptions.createRunAsAccountOid(ACCOUNT_WILL_OID); + + // WHEN + displayWhen(TEST_NAME); + provisioningService.modifyObject(ShadowType.class, delta.getOid(), delta.getModifications(), + new OperationProvisioningScriptsType(), options, task, result); + + // THEN + displayThen(TEST_NAME); + assertSuccess(result); + + // Check if the account was created in the dummy resource + assertDummyAccount(transformNameFromResource(ACCOUNT_WILL_USERNAME), willIcfUid) + .assertPassword(ACCOUNT_WILL_PASSWORD_321) + .assertLastModifier(getLastModifierName(ACCOUNT_WILL_USERNAME)); + + accountWillCurrentPassword = ACCOUNT_WILL_PASSWORD_321; + + // Check if the shadow is in the repo + PrismObject repoShadow = getShadowRepo(ACCOUNT_WILL_OID); + assertNotNull("Shadow was not created in the repository", repoShadow); + display("Repository shadow", repoShadow); + + checkRepoAccountShadow(repoShadow); + assertRepoShadowCredentials(repoShadow, ACCOUNT_WILL_PASSWORD_321); + + syncServiceMock.assertNotifySuccessOnly(); + + assertSteadyResource(); + } + + protected String getLastModifierName(String expected) { + return transformNameToResource(expected); + } // test4xx reserved for subclasses diff --git a/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/impl/dummy/TestDummyLimited.java b/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/impl/dummy/TestDummyLimited.java index 81ac299f65f..59532a682ca 100644 --- a/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/impl/dummy/TestDummyLimited.java +++ b/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/impl/dummy/TestDummyLimited.java @@ -15,6 +15,7 @@ */ package com.evolveum.midpoint.provisioning.impl.dummy; +import static org.testng.AssertJUnit.assertNotNull; import static org.testng.AssertJUnit.assertNull; import static org.testng.AssertJUnit.assertTrue; @@ -40,12 +41,14 @@ import com.evolveum.midpoint.xml.ns._public.common.common_3.OperationProvisioningScriptsType; import com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowType; import com.evolveum.midpoint.xml.ns._public.resource.capabilities_3.CountObjectsSimulateType; +import com.evolveum.midpoint.xml.ns._public.resource.capabilities_3.RunAsCapabilityType; /** * Almost the same as TestDummy but quite limited: * - no activation support * - no paging * - no count simulation using sequential search + * - no runAs * Let's test that we are able to do all the operations without NPEs and other side effects. * * @author Radovan Semancik @@ -85,7 +88,19 @@ public void initSystem(Task initTask, OperationResult initResult) throws Excepti protected CountObjectsSimulateType getCountSimulationMode() { return CountObjectsSimulateType.SEQUENTIAL_SEARCH; } + + @Override + protected void assertRunAsCapability(RunAsCapabilityType capRunAs) { + assertNull("Unexpected native runAs capability", capRunAs); + } + // No runAs capability, modifier is always the default one. + // No matter what kind of runAs was requested. + @Override + protected String getLastModifierName(String expected) { + return null; + } + @Test @Override public void test150DisableAccount() throws Exception { diff --git a/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/impl/dummy/TestDummyUuidNonUniqueName.java b/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/impl/dummy/TestDummyUuidNonUniqueName.java index 6f74ee4105b..fd8aa08b049 100644 --- a/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/impl/dummy/TestDummyUuidNonUniqueName.java +++ b/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/impl/dummy/TestDummyUuidNonUniqueName.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2017 Evolveum + * Copyright (c) 2013-2018 Evolveum * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,6 +17,7 @@ import static org.testng.AssertJUnit.assertEquals; import static org.testng.AssertJUnit.assertNotNull; +import static org.testng.AssertJUnit.assertNull; import java.io.File; import java.io.IOException; @@ -52,6 +53,7 @@ import com.evolveum.midpoint.util.exception.SecurityViolationException; import com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowKindType; import com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowType; +import com.evolveum.midpoint.xml.ns._public.resource.capabilities_3.RunAsCapabilityType; /** * Almost the same as TestDummy but this is using a UUID as ICF UID. @@ -84,6 +86,18 @@ protected File getResourceDummyFile() { protected boolean isNameUnique() { return false; } + + // runAs is using name as an identifier. But name is not unique in this case. runAs won't work. + @Override + protected void assertRunAsCapability(RunAsCapabilityType capRunAs) { + assertNull("Unexpected native runAs capability", capRunAs); + } + + // runAs is using name as an identifier. But name is not unique in this case. runAs won't work. + @Override + protected String getLastModifierName(String expected) { + return null; + } @Test public void test770AddAccountFettuciniAlfredo() throws Exception { diff --git a/provisioning/provisioning-impl/src/test/resources/dummy/dummy-limited/resource-dummy.xml b/provisioning/provisioning-impl/src/test/resources/dummy/dummy-limited/resource-dummy.xml index 9189c65b540..c00bbd0ff51 100644 --- a/provisioning/provisioning-impl/src/test/resources/dummy/dummy-limited/resource-dummy.xml +++ b/provisioning/provisioning-impl/src/test/resources/dummy/dummy-limited/resource-dummy.xml @@ -1,6 +1,6 @@ false + false none false Shiver me timbers! diff --git a/provisioning/provisioning-impl/src/test/resources/dummy/dummy-uuid-nonunique-name/resource-dummy.xml b/provisioning/provisioning-impl/src/test/resources/dummy/dummy-uuid-nonunique-name/resource-dummy.xml index 1143e131457..c346fc64c5d 100644 --- a/provisioning/provisioning-impl/src/test/resources/dummy/dummy-uuid-nonunique-name/resource-dummy.xml +++ b/provisioning/provisioning-impl/src/test/resources/dummy/dummy-uuid-nonunique-name/resource-dummy.xml @@ -34,6 +34,8 @@ uuid false + + false Shiver me timbers! Dead men tell no tales diff --git a/provisioning/ucf-api/src/main/java/com/evolveum/midpoint/provisioning/ucf/api/ConnectorInstance.java b/provisioning/ucf-api/src/main/java/com/evolveum/midpoint/provisioning/ucf/api/ConnectorInstance.java index a826434d647..573a40bf8ae 100644 --- a/provisioning/ucf-api/src/main/java/com/evolveum/midpoint/provisioning/ucf/api/ConnectorInstance.java +++ b/provisioning/ucf-api/src/main/java/com/evolveum/midpoint/provisioning/ucf/api/ConnectorInstance.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010-2017 Evolveum + * Copyright (c) 2010-2018 Evolveum * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -264,14 +264,14 @@ AsynchronousOperationReturnValue>> addObject(Pri * E.g. in case of connect timeout or connection refused. Timeout during operation should not cause the * exception as something might have been done already. * - * @param identifiers The set of identifiers. Their values may change as a result of the operation, e.g. when the resource object is renamed. - * @param changes - * @throws CommunicationException - * @throws SchemaException * @throws ObjectAlreadyExistsException in case that the modified object conflicts with another existing object (e.g. while renaming an object) */ - AsynchronousOperationReturnValue> modifyObject(ObjectClassComplexTypeDefinition objectClass, PrismObject shadow, Collection> identifiers, Collection changes, StateReporter reporter, - OperationResult parentResult) + AsynchronousOperationReturnValue> modifyObject( + ResourceObjectIdentification identification, + PrismObject shadow, + Collection changes, + ConnectorOperationOptions options, + StateReporter reporter, OperationResult parentResult) throws ObjectNotFoundException, CommunicationException, GenericFrameworkException, SchemaException, SecurityViolationException, ObjectAlreadyExistsException, ConfigurationException; diff --git a/provisioning/ucf-api/src/main/java/com/evolveum/midpoint/provisioning/ucf/api/ConnectorOperationOptions.java b/provisioning/ucf-api/src/main/java/com/evolveum/midpoint/provisioning/ucf/api/ConnectorOperationOptions.java new file mode 100644 index 00000000000..59aecc0fe85 --- /dev/null +++ b/provisioning/ucf-api/src/main/java/com/evolveum/midpoint/provisioning/ucf/api/ConnectorOperationOptions.java @@ -0,0 +1,39 @@ +/** + * Copyright (c) 2018 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. + */ +package com.evolveum.midpoint.provisioning.ucf.api; + +import com.evolveum.midpoint.schema.processor.ResourceObjectIdentification; + +/** + * @author semancik + * + */ +public class ConnectorOperationOptions { + + /** + * Run the operations on resource using the specified identity. + * Provided identification should identify valid, active account. + */ + private ResourceObjectIdentification runAsIdentification; + + public ResourceObjectIdentification getRunAsIdentification() { + return runAsIdentification; + } + + public void setRunAsIdentification(ResourceObjectIdentification runAsIdentification) { + this.runAsIdentification = runAsIdentification; + } +} diff --git a/provisioning/ucf-api/src/main/java/com/evolveum/midpoint/provisioning/ucf/api/Operation.java b/provisioning/ucf-api/src/main/java/com/evolveum/midpoint/provisioning/ucf/api/Operation.java index cceabfaba1e..93e90985e21 100644 --- a/provisioning/ucf-api/src/main/java/com/evolveum/midpoint/provisioning/ucf/api/Operation.java +++ b/provisioning/ucf-api/src/main/java/com/evolveum/midpoint/provisioning/ucf/api/Operation.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010-2013 Evolveum + * Copyright (c) 2010-2018 Evolveum * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -30,9 +30,4 @@ */ public abstract class Operation implements DebugDumpable { - @Override - public String debugDump() { - return debugDump(0); - } - } \ No newline at end of file diff --git a/provisioning/ucf-api/src/main/java/com/evolveum/midpoint/provisioning/ucf/api/PasswordChangeOperation.java b/provisioning/ucf-api/src/main/java/com/evolveum/midpoint/provisioning/ucf/api/PasswordChangeOperation.java deleted file mode 100644 index 90e4db3f045..00000000000 --- a/provisioning/ucf-api/src/main/java/com/evolveum/midpoint/provisioning/ucf/api/PasswordChangeOperation.java +++ /dev/null @@ -1,123 +0,0 @@ -/* - * 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. - */ -package com.evolveum.midpoint.provisioning.ucf.api; - -import com.evolveum.midpoint.schema.util.SchemaDebugUtil; -import com.evolveum.prism.xml.ns._public.types_3.ProtectedStringType; - -/** - * @author Radovan Semancik - * - */ -public class PasswordChangeOperation extends Operation { - - private ProtectedStringType newPassword; - private ProtectedStringType oldPassword; - - public PasswordChangeOperation(ProtectedStringType newPassword) { - super(); - this.newPassword = newPassword; - } - - public PasswordChangeOperation(ProtectedStringType newPassword, ProtectedStringType oldPassword) { - super(); - this.newPassword = newPassword; - this.oldPassword = oldPassword; - } - - public ProtectedStringType getNewPassword() { - return newPassword; - } - - public void setNewPassword(ProtectedStringType newPassword) { - this.newPassword = newPassword; - } - - public ProtectedStringType getOldPassword() { - return oldPassword; - } - - public void setOldPassword(ProtectedStringType oldPassword) { - this.oldPassword = oldPassword; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((newPassword == null) ? 0 : newPassword.hashCode()); - result = prime * result + ((oldPassword == null) ? 0 : oldPassword.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - PasswordChangeOperation other = (PasswordChangeOperation) obj; - if (newPassword == null) { - if (other.newPassword != null) { - return false; - } - } else if (!newPassword.equals(other.newPassword)) { - return false; - } - if (oldPassword == null) { - if (other.oldPassword != null) { - return false; - } - } else if (!oldPassword.equals(other.oldPassword)) { - return false; - } - return true; - } - - @Override - public String debugDump(int indent) { - StringBuilder sb = new StringBuilder(); - SchemaDebugUtil.indentDebugDump(sb, indent); - sb.append("Password change: new password "); - appendPasswordDescription(sb,newPassword); - sb.append("; old password "); - appendPasswordDescription(sb,oldPassword); - return sb.toString(); - } - - private void appendPasswordDescription(StringBuilder sb, ProtectedStringType passwd) { - if (passwd != null) { - sb.append("present"); - if (passwd.getClearValue() != null) { - sb.append(" in clear"); - if (passwd.getClearValue().isEmpty()) { - sb.append(" and empty"); - } - } - if (passwd.getEncryptedDataType() != null) { - sb.append(" encrypted"); - } - } else { - sb.append("null"); - } - } - -} diff --git a/provisioning/ucf-api/src/main/java/com/evolveum/midpoint/provisioning/ucf/api/connectors/AbstractManualConnectorInstance.java b/provisioning/ucf-api/src/main/java/com/evolveum/midpoint/provisioning/ucf/api/connectors/AbstractManualConnectorInstance.java index 9d97f60df3d..b7de86e97a6 100644 --- a/provisioning/ucf-api/src/main/java/com/evolveum/midpoint/provisioning/ucf/api/connectors/AbstractManualConnectorInstance.java +++ b/provisioning/ucf-api/src/main/java/com/evolveum/midpoint/provisioning/ucf/api/connectors/AbstractManualConnectorInstance.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2017 Evolveum + * Copyright (c) 2017-2018 Evolveum * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -26,6 +26,7 @@ import com.evolveum.midpoint.prism.query.ObjectQuery; import com.evolveum.midpoint.provisioning.ucf.api.AttributesToReturn; import com.evolveum.midpoint.provisioning.ucf.api.Change; +import com.evolveum.midpoint.provisioning.ucf.api.ConnectorOperationOptions; import com.evolveum.midpoint.provisioning.ucf.api.ExecuteProvisioningScriptOperation; import com.evolveum.midpoint.provisioning.ucf.api.GenericFrameworkException; import com.evolveum.midpoint.provisioning.ucf.api.ManagedConnector; @@ -139,8 +140,10 @@ public AsynchronousOperationReturnValue>> addObj @Override public AsynchronousOperationReturnValue> modifyObject( - ObjectClassComplexTypeDefinition objectClass, PrismObject shadow, - Collection> identifiers, Collection changes, + ResourceObjectIdentification identification, + PrismObject shadow, + Collection changes, + ConnectorOperationOptions options, StateReporter reporter, OperationResult parentResult) throws ObjectNotFoundException, CommunicationException, GenericFrameworkException, SchemaException, SecurityViolationException, ObjectAlreadyExistsException, ConfigurationException { @@ -154,7 +157,7 @@ public AsynchronousOperationReturnValue covertAuxiliaryObjectClassValuesToConnId(pvals, midPointAttributeName, auxiliaryObjectClassMap)); } - PropertyDelta passwordDelta = null; - PasswordChangeOperation passwordChangeOperation = null; - for (Operation operation : changes) { if (operation instanceof PropertyModificationOperation) { PropertyModificationOperation change = (PropertyModificationOperation) operation; @@ -256,8 +243,7 @@ public void convert() throws SchemaException { } else if (delta.getParentPath().equivalent(new ItemPath(ShadowType.F_ACTIVATION))) { convertFromActivation(delta); - } else if (delta.getParentPath().equivalent( - new ItemPath(new ItemPath(ShadowType.F_CREDENTIALS), CredentialsType.F_PASSWORD))) { + } else if (delta.getParentPath().equivalent(SchemaConstants.PATH_PASSWORD)) { convertFromPassword((PropertyDelta) delta); } else if (delta.getPath().equivalent(new ItemPath(ShadowType.F_AUXILIARY_OBJECT_CLASS))) { // already processed @@ -265,10 +251,6 @@ public void convert() throws SchemaException { throw new SchemaException("Change of unknown attribute " + delta.getPath()); } - } else if (operation instanceof PasswordChangeOperation) { - passwordChangeOperation = (PasswordChangeOperation) operation; - // TODO: check for multiple occurrences and fail - } else if (operation instanceof ExecuteProvisioningScriptOperation) { ExecuteProvisioningScriptOperation scriptOperation = (ExecuteProvisioningScriptOperation) operation; additionalOperations.add(scriptOperation); diff --git a/provisioning/ucf-impl-connid/src/main/java/com/evolveum/midpoint/provisioning/ucf/impl/connid/ConnectorInstanceConnIdImpl.java b/provisioning/ucf-impl-connid/src/main/java/com/evolveum/midpoint/provisioning/ucf/impl/connid/ConnectorInstanceConnIdImpl.java index 47a7e5113f9..db82a1c9aff 100644 --- a/provisioning/ucf-impl-connid/src/main/java/com/evolveum/midpoint/provisioning/ucf/impl/connid/ConnectorInstanceConnIdImpl.java +++ b/provisioning/ucf-impl-connid/src/main/java/com/evolveum/midpoint/provisioning/ucf/impl/connid/ConnectorInstanceConnIdImpl.java @@ -81,6 +81,7 @@ import org.identityconnectors.framework.impl.api.local.operations.ConnectorOperationalContext; import org.identityconnectors.framework.spi.Connector; import org.identityconnectors.framework.spi.PoolableConnector; +import org.identityconnectors.framework.spi.operations.UpdateAttributeValuesOp; import org.jfree.util.Log; import com.evolveum.midpoint.prism.ComplexTypeDefinition; @@ -111,6 +112,7 @@ import com.evolveum.midpoint.provisioning.ucf.api.AttributesToReturn; import com.evolveum.midpoint.provisioning.ucf.api.Change; import com.evolveum.midpoint.provisioning.ucf.api.ConnectorInstance; +import com.evolveum.midpoint.provisioning.ucf.api.ConnectorOperationOptions; import com.evolveum.midpoint.provisioning.ucf.api.ExecuteProvisioningScriptOperation; import com.evolveum.midpoint.provisioning.ucf.api.ExecuteScriptArgument; import com.evolveum.midpoint.provisioning.ucf.api.GenericFrameworkException; @@ -181,6 +183,7 @@ import com.evolveum.midpoint.xml.ns._public.resource.capabilities_3.PagedSearchCapabilityType; import com.evolveum.midpoint.xml.ns._public.resource.capabilities_3.PasswordCapabilityType; import com.evolveum.midpoint.xml.ns._public.resource.capabilities_3.ReadCapabilityType; +import com.evolveum.midpoint.xml.ns._public.resource.capabilities_3.RunAsCapabilityType; import com.evolveum.midpoint.xml.ns._public.resource.capabilities_3.SchemaCapabilityType; import com.evolveum.midpoint.xml.ns._public.resource.capabilities_3.ScriptCapabilityType; import com.evolveum.midpoint.xml.ns._public.resource.capabilities_3.ScriptCapabilityType.Host; @@ -690,7 +693,7 @@ private void addBasicReadCapability() { } } - private void parseResourceSchema(org.identityconnectors.framework.common.objects.Schema icfSchema, List generateObjectClasses) { + private void parseResourceSchema(org.identityconnectors.framework.common.objects.Schema connIdSchema, List generateObjectClasses) { AttributeInfo passwordAttributeInfo = null; AttributeInfo enableAttributeInfo = null; @@ -703,12 +706,12 @@ private void parseResourceSchema(org.identityconnectors.framework.common.objects setResourceSchema(new ResourceSchemaImpl(getSchemaNamespace(), prismContext)); if (legacySchema == null) { - legacySchema = detectLegacySchema(icfSchema); + legacySchema = detectLegacySchema(connIdSchema); } LOGGER.trace("Converting resource schema (legacy mode: {})", legacySchema); LOGGER.trace("Generating object classes: {}", generateObjectClasses); - Set objectClassInfoSet = icfSchema.getObjectClassInfo(); + Set objectClassInfoSet = connIdSchema.getObjectClassInfo(); // Let's convert every objectclass in the ConnId schema ... for (ObjectClassInfo objectClassInfo : objectClassInfoSet) { @@ -1000,7 +1003,7 @@ private void parseResourceSchema(org.identityconnectors.framework.common.objects boolean canPageOffset = false; boolean canSort = false; boolean supportsReturnDefaultAttributes = false; - for (OperationOptionInfo searchOption: icfSchema.getSupportedOptionsByOperation(SearchApiOp.class)) { + for (OperationOptionInfo searchOption: connIdSchema.getSupportedOptionsByOperation(SearchApiOp.class)) { switch (searchOption.getName()) { case OperationOptions.OP_PAGE_SIZE: canPageSize = true; @@ -1015,23 +1018,42 @@ private void parseResourceSchema(org.identityconnectors.framework.common.objects supportsReturnDefaultAttributes = true; break; } - + } + if (canPageSize || canPageOffset || canSort) { + PagedSearchCapabilityType capPage = new PagedSearchCapabilityType(); + capabilities.add(CAPABILITY_OBJECT_FACTORY.createPagedSearch(capPage)); } Set> supportedOperations = connIdConnectorFacade.getSupportedOperations(); - if (supportedOperations.contains(GetApiOp.class) || supportedOperations.contains(SearchApiOp.class)){ + if (supportedOperations.contains(GetApiOp.class) || supportedOperations.contains(SearchApiOp.class)) { ReadCapabilityType capRead = new ReadCapabilityType(); capRead.setReturnDefaultAttributesOption(supportsReturnDefaultAttributes); capabilities.add(CAPABILITY_OBJECT_FACTORY.createRead(capRead)); } - - if (canPageSize || canPageOffset || canSort) { - PagedSearchCapabilityType capPage = new PagedSearchCapabilityType(); - capabilities.add(CAPABILITY_OBJECT_FACTORY.createPagedSearch(capPage)); + if (supportedOperations.contains(UpdateDeltaApiOp.class)) { + processUpdateOperationOptions(connIdSchema.getSupportedOptionsByOperation(UpdateDeltaApiOp.class)); + } else if (supportedOperations.contains(UpdateApiOp.class)) { + processUpdateOperationOptions(connIdSchema.getSupportedOptionsByOperation(UpdateApiOp.class)); } } + private void processUpdateOperationOptions(Set supportedOptions) { + boolean canRunAsUser = false; + for (OperationOptionInfo searchOption: supportedOptions) { + switch (searchOption.getName()) { + case OperationOptions.OP_RUN_AS_USER: + canRunAsUser = true; + break; + // TODO: run as password + } + } + if (canRunAsUser) { + RunAsCapabilityType capRunAs = new RunAsCapabilityType(); + capabilities.add(CAPABILITY_OBJECT_FACTORY.createRunAs(capRunAs)); + } + } + private boolean detectLegacySchema(Schema icfSchema) { Set objectClassInfoSet = icfSchema.getObjectClassInfo(); for (ObjectClassInfo objectClassInfo : objectClassInfoSet) { @@ -1549,19 +1571,17 @@ private void validateShadow(PrismObject shadow, String ope @Override public AsynchronousOperationReturnValue> modifyObject( - ObjectClassComplexTypeDefinition objectClassDef, + ResourceObjectIdentification identification, PrismObject shadow, - Collection> identifiers, Collection changes, + ConnectorOperationOptions options, StateReporter reporter, OperationResult parentResult) throws ObjectNotFoundException, CommunicationException, GenericFrameworkException, SchemaException, SecurityViolationException, ObjectAlreadyExistsException { - OperationResult result = parentResult.createSubresult(ConnectorInstance.class.getName() - + ".modifyObject"); - result.addArbitraryObjectAsParam("objectClass", objectClassDef); - result.addArbitraryObjectCollectionAsParam("identifiers", identifiers); + OperationResult result = parentResult.createSubresult(ConnectorInstance.class.getName() + ".modifyObject"); + result.addArbitraryObjectAsParam("identification", identification); result.addArbitraryObjectCollectionAsParam("changes", changes); if (changes.isEmpty()){ @@ -1570,25 +1590,25 @@ public AsynchronousOperationReturnValue(0), result); } - ObjectClass objClass = connIdNameMapper.objectClassToIcf(objectClassDef, getSchemaNamespace(), connectorType, legacySchema); + ObjectClass objClass = connIdNameMapper.objectClassToIcf(identification.getObjectClassDefinition(), getSchemaNamespace(), connectorType, legacySchema); Uid uid; try { - uid = getUid(objectClassDef, identifiers); + uid = getUid(identification); } catch (SchemaException e) { result.recordFatalError(e); throw e; } if (uid == null) { - result.recordFatalError("Cannot detemine UID from identifiers: " + identifiers); - throw new IllegalArgumentException("Cannot detemine UID from identifiers: " + identifiers); + result.recordFatalError("Cannot detemine UID from identification: " + identification); + throw new IllegalArgumentException("Cannot detemine UID from identification: " + identification); } if (supportsDeltaUpdateOp()) { - return modifyObjectDelta(objectClassDef, objClass, uid, shadow, identifiers, changes, reporter, result); + return modifyObjectDelta(identification, objClass, uid, shadow, changes, options, reporter, result); } else { - return modifyObjectUpdate(objectClassDef, objClass, uid, shadow, identifiers, changes, reporter, result); + return modifyObjectUpdate(identification, objClass, uid, shadow, changes, options, reporter, result); } } @@ -1596,17 +1616,18 @@ public AsynchronousOperationReturnValue> modifyObjectDelta( - ObjectClassComplexTypeDefinition objectClassDef, + ResourceObjectIdentification identification, ObjectClass objClass, Uid uid, PrismObject shadow, - Collection> identifiers, Collection changes, + ConnectorOperationOptions options, StateReporter reporter, OperationResult result) throws ObjectNotFoundException, CommunicationException, GenericFrameworkException, SchemaException, SecurityViolationException, ObjectAlreadyExistsException { + ObjectClassComplexTypeDefinition objectClassDef = identification.getObjectClassDefinition(); Set sideEffect = new HashSet<>(); String originalUid = uid.getUidValue(); @@ -1639,12 +1660,12 @@ private AsynchronousOperationReturnValue attributesDelta = converter.getAttributesDelta(); if (!attributesDelta.isEmpty()) { - OperationOptions options = new OperationOptionsBuilder().build(); + OperationOptions connIdOptions = createConnIdOptions(options, changes); connIdResult = result.createSubresult(ConnectorFacade.class.getName() + ".updateDelta"); connIdResult.addParam("objectClass", objectClassDef.toString()); connIdResult.addParam("uid", uid==null? "null":uid.getUidValue()); connIdResult.addParam("attributesDelta", attributesDelta.toString()); - connIdResult.addArbitraryObjectAsParam("options", options); + connIdResult.addArbitraryObjectAsParam("options", connIdOptions); connIdResult.addContext("connector", connIdConnectorFacade.getClass()); if (LOGGER.isTraceEnabled()) { @@ -1657,7 +1678,7 @@ private AsynchronousOperationReturnValue uidDelta = createUidDelta(newUid, getUidDefinition(objectClassDef, identifiers)); + PropertyDelta uidDelta = createUidDelta(newUid, getUidDefinition(identification)); PropertyModificationOperation uidMod = new PropertyModificationOperation(uidDelta); sideEffectChanges.add(uidMod); - replaceUidValue(objectClassDef, identifiers, newUid); + replaceUidValue(identification, newUid); } else if(name.equals(Name.NAME)){ Name newName = new Name((String)attrDeltaSideEffect.getValuesToReplace().get(0)); - PropertyDelta nameDelta = createNameDelta(newName, getNameDefinition(objectClassDef, identifiers)); + PropertyDelta nameDelta = createNameDelta(newName, getNameDefinition(identification)); PropertyModificationOperation nameMod = new PropertyModificationOperation(nameDelta); sideEffectChanges.add(nameMod); - replaceNameValue(objectClassDef, identifiers, new Name((String)attrDeltaSideEffect.getValuesToReplace().get(0))); + replaceNameValue(identification, new Name((String)attrDeltaSideEffect.getValuesToReplace().get(0))); } else { ResourceAttributeDefinition definition = objectClassDef.findAttributeDefinition(name); @@ -1754,18 +1775,19 @@ private AsynchronousOperationReturnValue> modifyObjectUpdate( - ObjectClassComplexTypeDefinition objectClassDef, + ResourceObjectIdentification identification, ObjectClass objClass, Uid uid, PrismObject shadow, - Collection> identifiers, Collection changes, + ConnectorOperationOptions options, StateReporter reporter, OperationResult result) throws ObjectNotFoundException, CommunicationException, GenericFrameworkException, SchemaException, SecurityViolationException, ObjectAlreadyExistsException { + ObjectClassComplexTypeDefinition objectClassDef = identification.getObjectClassDefinition(); String originalUid = uid.getUidValue(); UpdateModificationConverter converter = new UpdateModificationConverter(); @@ -1801,12 +1823,12 @@ private AsynchronousOperationReturnValue attributesToAdd = converter.getAttributesToAdd(); if (!attributesToAdd.isEmpty()) { - OperationOptions options = new OperationOptionsBuilder().build(); + OperationOptions connIdOptions = createConnIdOptions(options, changes); connIdResult = result.createSubresult(ConnectorFacade.class.getName() + ".addAttributeValues"); connIdResult.addArbitraryObjectAsParam("objectClass", objectClassDef); connIdResult.addParam("uid", uid.getUidValue()); connIdResult.addArbitraryObjectAsParam("attributes", attributesToAdd); - connIdResult.addArbitraryObjectAsParam("options", options); + connIdResult.addArbitraryObjectAsParam("options", connIdOptions); connIdResult.addContext("connector", connIdConnectorFacade.getClass()); if (LOGGER.isTraceEnabled()) { @@ -1821,7 +1843,7 @@ private AsynchronousOperationReturnValue attributesToUpdate = converter.getAttributesToUpdate(); if (!attributesToUpdate.isEmpty()) { - OperationOptions options = new OperationOptionsBuilder().build(); + OperationOptions connIdOptions = createConnIdOptions(options, changes); connIdResult = result.createSubresult(ConnectorFacade.class.getName() + ".update"); connIdResult.addArbitraryObjectAsParam("objectClass", objectClassDef); connIdResult.addParam("uid", uid==null?"null":uid.getUidValue()); connIdResult.addArbitraryObjectAsParam("attributes", attributesToUpdate); - connIdResult.addArbitraryObjectAsParam("options", options); + connIdResult.addArbitraryObjectAsParam("options", connIdOptions); connIdResult.addContext("connector", connIdConnectorFacade.getClass()); if (LOGGER.isTraceEnabled()) { @@ -1879,7 +1901,7 @@ private AsynchronousOperationReturnValue attributesToRemove = converter.getAttributesToRemove(); if (!attributesToRemove.isEmpty()) { - OperationOptions options = new OperationOptionsBuilder().build(); + OperationOptions connIdOptions = createConnIdOptions(options, changes); connIdResult = result.createSubresult(ConnectorFacade.class.getName() + ".removeAttributeValues"); connIdResult.addArbitraryObjectAsParam("objectClass", objectClassDef); connIdResult.addParam("uid", uid.getUidValue()); connIdResult.addArbitraryObjectAsParam("attributes", attributesToRemove); - connIdResult.addArbitraryObjectAsParam("options", options); + connIdResult.addArbitraryObjectAsParam("options", connIdOptions); connIdResult.addContext("connector", connIdConnectorFacade.getClass()); if (LOGGER.isTraceEnabled()) { @@ -1938,7 +1960,7 @@ private AsynchronousOperationReturnValue uidDelta = createUidDelta(uid, getUidDefinition(objectClassDef, identifiers)); + PropertyDelta uidDelta = createUidDelta(uid, getUidDefinition(identification)); PropertyModificationOperation uidMod = new PropertyModificationOperation(uidDelta); // TODO what about matchingRuleQName ? sideEffectChanges.add(uidMod); - replaceUidValue(objectClassDef, identifiers, uid); + replaceUidValue(identification, uid); } return AsynchronousOperationReturnValue.wrap(sideEffectChanges, result); } - private void replaceNameValue(ObjectClassComplexTypeDefinition objectClass, Collection> identifiers, Name newName){ - if (identifiers.size() == 0) { - throw new IllegalStateException("No identifiers"); - } - if (identifiers.size() == 1) { - return; - } - for (ResourceAttribute attr : identifiers) { - if (objectClass.isSecondaryIdentifier(attr.getElementName())) { - ((ResourceAttribute) attr).setValue(new PrismPropertyValue(newName.getNameValue())); - return; - } - } - // fallback, compatibility - for (ResourceAttribute attr : identifiers) { - if (attr.getElementName().equals(SchemaConstants.ICFS_NAME)) { - attr.setValue(new PrismPropertyValue(newName.getNameValue())); // expecting the NAME property is of type String - return; + private void replaceNameValue(ResourceObjectIdentification identification, Name newName) throws SchemaException { + ResourceAttribute secondaryIdentifier = identification.getSecondaryIdentifier(); + if (secondaryIdentifier == null) { + // fallback, compatibility + for (ResourceAttribute attr : identification.getAllIdentifiers()) { + if (attr.getElementName().equals(SchemaConstants.ICFS_NAME)) { + attr.setValue(new PrismPropertyValue(newName.getNameValue())); // expecting the NAME property is of type String + return; + } } + throw new IllegalStateException("No identifiers"); } + secondaryIdentifier.setValue(new PrismPropertyValue(newName.getNameValue())); } private PropertyDelta createNameDelta(Name name, ResourceAttributeDefinition nameDefinition) { @@ -2717,11 +2732,7 @@ private Uid getUid(ResourceObjectIdentification resourceObjectIdentification) th return null; } String uidValue = primaryIdentifier.getRealValue(); - String nameValue = null; - Collection> secondaryIdentifiers = resourceObjectIdentification.getSecondaryIdentifiers(); - if (secondaryIdentifiers != null && secondaryIdentifiers.size() == 1) { - nameValue = (String) secondaryIdentifiers.iterator().next().getRealValue(); - } + String nameValue = getNameValue(resourceObjectIdentification); if (uidValue != null) { if (nameValue == null) { return new Uid(uidValue); @@ -2731,6 +2742,15 @@ private Uid getUid(ResourceObjectIdentification resourceObjectIdentification) th } return null; } + + private String getNameValue(ResourceObjectIdentification resourceObjectIdentification) { + String nameValue = null; + Collection> secondaryIdentifiers = resourceObjectIdentification.getSecondaryIdentifiers(); + if (secondaryIdentifiers != null && secondaryIdentifiers.size() == 1) { + nameValue = (String) secondaryIdentifiers.iterator().next().getRealValue(); + } + return nameValue; + } /** * Looks up ConnId Uid identifier in a (potentially multi-valued) set of @@ -2782,70 +2802,48 @@ private Uid getUid(ObjectClassComplexTypeDefinition objectClass, Collection> identifiers, Uid newUid) { - if (identifiers.size() == 0) { - throw new IllegalStateException("No identifiers"); - } - if (identifiers.size() == 1) { - identifiers.iterator().next().setValue(new PrismPropertyValue(newUid.getUidValue())); - return; - } - for (ResourceAttribute attr : identifiers) { - if (objectClass.isPrimaryIdentifier(attr.getElementName())) { - ((ResourceAttribute) attr).setValue(new PrismPropertyValue(newUid.getUidValue())); - return; - } - } - // fallback, compatibility - for (ResourceAttribute attr : identifiers) { - if (attr.getElementName().equals(SchemaConstants.ICFS_UID)) { - attr.setValue(new PrismPropertyValue(newUid.getUidValue())); // expecting the UID property is of type String - return; + private void replaceUidValue(ResourceObjectIdentification identification, Uid newUid) throws SchemaException { + ResourceAttribute primaryIdentifier = identification.getPrimaryIdentifier(); + if (primaryIdentifier == null) { + // fallback, compatibility + Collection> identifiers = identification.getAllIdentifiers(); + for (ResourceAttribute attr : identifiers) { + if (attr.getElementName().equals(SchemaConstants.ICFS_UID)) { + attr.setValue(new PrismPropertyValue(newUid.getUidValue())); // expecting the UID property is of type String + return; + } } + throw new IllegalStateException("No UID attribute in " + identifiers); } - throw new IllegalStateException("No UID attribute in " + identifiers); + primaryIdentifier.setValue(new PrismPropertyValue(newUid.getUidValue())); } - private ResourceAttributeDefinition getNameDefinition(ObjectClassComplexTypeDefinition objectClass, Collection> identifiers) { - if (identifiers.size() == 0) { - return null; - } - if (identifiers.size() == 1) { - return null; - } - for (ResourceAttribute attr : identifiers) { - if (objectClass.isSecondaryIdentifier(attr.getElementName())) { - return ((ResourceAttribute) attr).getDefinition(); - } - } - // fallback, compatibility - for (ResourceAttribute attr : identifiers) { - if (attr.getElementName().equals(SchemaConstants.ICFS_NAME)) { - return attr.getDefinition(); + private ResourceAttributeDefinition getNameDefinition(ResourceObjectIdentification identification) throws SchemaException { + ResourceAttribute secondaryIdentifier = identification.getSecondaryIdentifier(); + if (secondaryIdentifier == null) { + // fallback, compatibility + for (ResourceAttribute attr : identification.getAllIdentifiers()) { + if (attr.getElementName().equals(SchemaConstants.ICFS_NAME)) { + return attr.getDefinition(); + } } + return null; } - return null; + return secondaryIdentifier.getDefinition(); } - private ResourceAttributeDefinition getUidDefinition(ObjectClassComplexTypeDefinition objectClass, Collection> identifiers) { - if (identifiers.size() == 0) { - return null; - } - if (identifiers.size() == 1) { - return identifiers.iterator().next().getDefinition(); - } - for (ResourceAttribute attr : identifiers) { - if (objectClass.isPrimaryIdentifier(attr.getElementName())) { - return ((ResourceAttribute) attr).getDefinition(); - } - } - // fallback, compatibility - for (ResourceAttribute attr : identifiers) { - if (attr.getElementName().equals(SchemaConstants.ICFS_UID)) { - return attr.getDefinition(); + private ResourceAttributeDefinition getUidDefinition(ResourceObjectIdentification identification) throws SchemaException { + ResourceAttribute primaryIdentifier = identification.getPrimaryIdentifier(); + if (primaryIdentifier == null) { + // fallback, compatibility + for (ResourceAttribute attr : identification.getAllIdentifiers()) { + if (attr.getElementName().equals(SchemaConstants.ICFS_UID)) { + return attr.getDefinition(); + } } + return null; } - return null; + return primaryIdentifier.getDefinition(); } @@ -3218,5 +3216,37 @@ private void recordIcfOperationEnd(StateReporter reporter, ProvisioningOperation LOGGER.warn("Couldn't record ConnId operation end as reporter is null."); } } + + private OperationOptions createConnIdOptions(ConnectorOperationOptions options, Collection changes) { + OperationOptionsBuilder connIdOptionsBuilder = new OperationOptionsBuilder(); + if (options != null) { + ResourceObjectIdentification runAsIdentification = options.getRunAsIdentification(); + if (runAsIdentification != null) { + connIdOptionsBuilder.setRunAsUser(getNameValue(runAsIdentification)); + // We are going to figure out what the runAsPassword may be. + // If there is a password change then there should be old value in the delta. + // This is quite a black magic. But we do not have a better way now. + for (Operation change : changes) { + if (change instanceof PropertyModificationOperation) { + PropertyDelta propertyDelta = ((PropertyModificationOperation)change).getPropertyDelta(); + if (!propertyDelta.getPath().equivalent(SchemaConstants.PATH_PASSWORD_VALUE)) { + continue; + } + Collection> oldValues = propertyDelta.getEstimatedOldValues(); + if (oldValues == null || oldValues.isEmpty()) { + continue; + } + ProtectedStringType oldPassword = oldValues.iterator().next().getValue(); + if (oldPassword != null) { + GuardedString oldPasswordGs = ConnIdUtil.toGuardedString(oldPassword, "runAs password", protector); + connIdOptionsBuilder.setRunWithPassword(oldPasswordGs); + } + } + } + } + } + return connIdOptionsBuilder.build(); + } + } diff --git a/provisioning/ucf-impl-connid/src/test/java/com/evolveum/midpoint/provisioning/ucf/impl/connid/TestUcfOpenDj.java b/provisioning/ucf-impl-connid/src/test/java/com/evolveum/midpoint/provisioning/ucf/impl/connid/TestUcfOpenDj.java index 055675b891b..3f9e4f751e4 100644 --- a/provisioning/ucf-impl-connid/src/test/java/com/evolveum/midpoint/provisioning/ucf/impl/connid/TestUcfOpenDj.java +++ b/provisioning/ucf-impl-connid/src/test/java/com/evolveum/midpoint/provisioning/ucf/impl/connid/TestUcfOpenDj.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010-2017 Evolveum + * Copyright (c) 2010-2018 Evolveum * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -351,11 +351,11 @@ public void test110ChangeModifyObject() throws Exception { changes.add(createDeleteAttributeChange("givenName", "John")); ObjectClassComplexTypeDefinition accountDefinition = resourceSchema.findObjectClassDefinition(OpenDJController.OBJECT_CLASS_INETORGPERSON_NAME); - - cc.modifyObject(accountDefinition, null, identifiers, changes, null, result); - ResourceObjectIdentification identification = ResourceObjectIdentification.createFromAttributes( accountDefinition, identifiers); + + cc.modifyObject(identification, null, changes, null, null, result); + PrismObject shadow = cc.fetchObject(identification, null, null, result); ResourceAttributeContainer resObj = ShadowUtil.getAttributesContainer(shadow); @@ -747,13 +747,14 @@ public void test610ChangePassword() throws Exception { //set the modificaion type propMod.setModificationType(ModificationTypeType.REPLACE); - PropertyDelta passDelta = (PropertyDelta)DeltaConvertor.createItemDelta(propMod, shadow.getDefinition()); - PropertyModificationOperation passwordModification = new PropertyModificationOperation(passDelta); + PropertyDelta passDelta = (PropertyDelta)DeltaConvertor.createItemDelta(propMod, shadow.getDefinition()); + PropertyModificationOperation passwordModification = new PropertyModificationOperation(passDelta); changes.add(passwordModification); + + ResourceObjectIdentification identification = ResourceObjectIdentification.createFromAttributes( + accountDefinition, identifiers); -// PasswordChangeOperation passwordChange = new PasswordChangeOperation(passPs); -// changes.add(passwordChange); - cc.modifyObject(accountDefinition, null, identifiers, changes, null, result); + cc.modifyObject(identification, null, changes, null, null, result); // THEN diff --git a/repo/audit-api/src/main/java/com/evolveum/midpoint/audit/api/AuditEventRecord.java b/repo/audit-api/src/main/java/com/evolveum/midpoint/audit/api/AuditEventRecord.java index 52c1fdc5f79..5e3a569eac0 100644 --- a/repo/audit-api/src/main/java/com/evolveum/midpoint/audit/api/AuditEventRecord.java +++ b/repo/audit-api/src/main/java/com/evolveum/midpoint/audit/api/AuditEventRecord.java @@ -258,9 +258,9 @@ public void setTarget(PrismReferenceValue target) { } // Compatibility and convenience - public void setTarget(PrismObject targetObject) { + public void setTarget(PrismObject targetObject, PrismContext prismContext) { if (targetObject != null) { - this.target = ObjectTypeUtil.createObjectRef((ObjectType) targetObject.asObjectable()).asReferenceValue(); + this.target = ObjectTypeUtil.createObjectRef((ObjectType) targetObject.asObjectable(), prismContext).asReferenceValue(); } else { this.target = null; } diff --git a/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/BaseSQLRepoTest.java b/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/BaseSQLRepoTest.java index 93c6fa73a2e..d0a26e5552b 100644 --- a/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/BaseSQLRepoTest.java +++ b/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/BaseSQLRepoTest.java @@ -29,6 +29,7 @@ import com.evolveum.midpoint.repo.sql.util.HibernateToSqlTranslator; import com.evolveum.midpoint.repo.sql.util.RUtil; import com.evolveum.midpoint.schema.MidPointPrismContextFactory; +import com.evolveum.midpoint.schema.RelationRegistry; import com.evolveum.midpoint.schema.constants.MidPointConstants; import com.evolveum.midpoint.schema.result.OperationResult; import com.evolveum.midpoint.test.util.TestUtil; @@ -71,6 +72,7 @@ public class BaseSQLRepoTest extends AbstractTestNGSpringContextTests { @Autowired protected BaseHelper baseHelper; @Autowired protected AuditService auditService; @Autowired protected PrismContext prismContext; + @Autowired protected RelationRegistry relationRegistry; @Autowired protected SessionFactory factory; @Autowired protected ExtItemDictionary extItemDictionary; diff --git a/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/ObjectDeltaUpdaterTest.java b/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/ObjectDeltaUpdaterTest.java index 7712fe82bcb..db9112131e0 100644 --- a/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/ObjectDeltaUpdaterTest.java +++ b/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/ObjectDeltaUpdaterTest.java @@ -41,6 +41,7 @@ import com.evolveum.midpoint.repo.sql.data.common.embedded.RPolyString; import com.evolveum.midpoint.repo.sql.data.common.enums.RActivationStatus; import com.evolveum.midpoint.repo.sql.testing.QueryCountInterceptor; +import com.evolveum.midpoint.schema.RelationRegistry; import com.evolveum.midpoint.schema.constants.SchemaConstants; import com.evolveum.midpoint.schema.result.OperationResult; import com.evolveum.midpoint.util.DOMUtil; @@ -84,8 +85,8 @@ public class ObjectDeltaUpdaterTest extends BaseSQLRepoTest { private static final QName LOOT = new QName(NS_P, "loot"); private static final QName WEAPON = new QName(NS_P, "weapon"); - @Autowired - private QueryCountInterceptor queryCountInterceptor; + @Autowired private QueryCountInterceptor queryCountInterceptor; + @Autowired private RelationRegistry relationRegistry; private String userOid; @@ -291,7 +292,8 @@ public void test140AddDeleteAssignment() throws Exception { AssertJUnit.assertEquals(createRef(OrgType.COMPLEX_TYPE, "444", SchemaConstants.ORG_DEFAULT), targetRef); assertReferences((Collection) a.getModifyApproverRef(), - RObjectReference.copyFromJAXB(createRef(UserType.COMPLEX_TYPE, "555", SchemaConstants.ORG_DEFAULT), new RObjectReference()) + RObjectReference.copyFromJAXB(createRef(UserType.COMPLEX_TYPE, "555", SchemaConstants.ORG_DEFAULT), new RObjectReference(), + relationRegistry) ); } finally { session.close(); @@ -356,8 +358,10 @@ public void test150AddDeleteLinkRef() throws Exception { RUser u = session.get(RUser.class, userOid); assertReferences((Collection) u.getLinkRef(), - RObjectReference.copyFromJAXB(createRef(ShadowType.COMPLEX_TYPE, "123", SchemaConstants.ORG_DEFAULT), new RObjectReference()), - RObjectReference.copyFromJAXB(createRef(ShadowType.COMPLEX_TYPE, "789", SchemaConstants.ORG_DEFAULT), new RObjectReference())); + RObjectReference.copyFromJAXB(createRef(ShadowType.COMPLEX_TYPE, "123", SchemaConstants.ORG_DEFAULT), new RObjectReference(), + relationRegistry), + RObjectReference.copyFromJAXB(createRef(ShadowType.COMPLEX_TYPE, "789", SchemaConstants.ORG_DEFAULT), new RObjectReference(), + relationRegistry)); } finally { session.close(); } @@ -386,8 +390,10 @@ public void test160AddDeleteParentRef() throws Exception { RUser u = session.get(RUser.class, userOid); assertReferences((Collection) u.getParentOrgRef(), - RObjectReference.copyFromJAXB(createRef(OrgType.COMPLEX_TYPE, "123", SchemaConstants.ORG_DEFAULT), new RObjectReference()), - RObjectReference.copyFromJAXB(createRef(OrgType.COMPLEX_TYPE, "789", SchemaConstants.ORG_DEFAULT), new RObjectReference())); + RObjectReference.copyFromJAXB(createRef(OrgType.COMPLEX_TYPE, "123", SchemaConstants.ORG_DEFAULT), new RObjectReference(), + relationRegistry), + RObjectReference.copyFromJAXB(createRef(OrgType.COMPLEX_TYPE, "789", SchemaConstants.ORG_DEFAULT), new RObjectReference(), + relationRegistry)); } finally { session.close(); } @@ -474,7 +480,8 @@ public void test180ModifyMetadataChannel() throws Exception { AssertJUnit.assertEquals(1, u.getCreateApproverRef().size()); assertReferences((Collection) u.getCreateApproverRef(), - RObjectReference.copyFromJAXB(createRef(UserType.COMPLEX_TYPE, "111", SchemaConstants.ORG_DEFAULT), new RObjectReference())); + RObjectReference.copyFromJAXB(createRef(UserType.COMPLEX_TYPE, "111", SchemaConstants.ORG_DEFAULT), new RObjectReference(), + relationRegistry)); } @Test diff --git a/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/QueryInterpreter2Test.java b/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/QueryInterpreter2Test.java index fb3f03d571b..d0652433a98 100644 --- a/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/QueryInterpreter2Test.java +++ b/repo/repo-sql-impl-test/src/test/java/com/evolveum/midpoint/repo/sql/QueryInterpreter2Test.java @@ -73,6 +73,7 @@ import static com.evolveum.midpoint.prism.query.OrderDirection.DESCENDING; import static com.evolveum.midpoint.schema.GetOperationOptions.*; import static com.evolveum.midpoint.schema.SelectorOptions.createCollection; +import static com.evolveum.midpoint.util.QNameUtil.unqualify; import static com.evolveum.midpoint.xml.ns._public.common.common_3.AbstractWorkItemType.F_STAGE_NUMBER; import static com.evolveum.midpoint.xml.ns._public.common.common_3.AccessCertificationCampaignStateType.IN_REVIEW_STAGE; import static com.evolveum.midpoint.xml.ns._public.common.common_3.AccessCertificationCampaignType.F_OWNER_REF; @@ -1302,13 +1303,18 @@ public void test0150QueryUserAssignmentTargetRef() throws Exception { @SuppressWarnings("unchecked") Collection relationParameter = (Collection) rQuery.getQuerySource().getParameters().get("relation").getValue(); assertEquals("Wrong relation parameter value", - new HashSet<>(Arrays.asList("#", RUtil.qnameToString(SchemaConstants.ORG_DEFAULT))), + new HashSet<>(getVariantsOfDefaultRelation()), new HashSet<>(relationParameter)); } finally { close(session); } } + @NotNull + private List getVariantsOfDefaultRelation() { + return Arrays.asList("#", RUtil.qnameToString(unqualify(SchemaConstants.ORG_DEFAULT)), RUtil.qnameToString(SchemaConstants.ORG_DEFAULT)); + } + @Test public void test0152QueryUserAssignmentTargetRefManagerStandardQualified() throws Exception { Session session = open(); @@ -1882,9 +1888,7 @@ public void test0341QueryOrgTreeFindUsersRelationDefault() throws Exception { @SuppressWarnings("unchecked") Collection relationParameter = (Collection) rQuery.getQuerySource().getParameters().get("relation").getValue(); assertEquals("Wrong relation parameter value", - new HashSet<>(Arrays.asList( - "#", - RUtil.qnameToString(SchemaConstants.ORG_DEFAULT))), + new HashSet<>(getVariantsOfDefaultRelation()), new HashSet<>(relationParameter)); } finally { @@ -1996,9 +2000,7 @@ public void test0346QueryOrgTreeFindUsersRelationDefault() throws Exception { @SuppressWarnings("unchecked") Collection relationParameter = (Collection) rQuery.getQuerySource().getParameters().get("relation").getValue(); assertEquals("Wrong relation parameter value", - new HashSet<>(Arrays.asList( - "#", - RUtil.qnameToString(SchemaConstants.ORG_DEFAULT))), + new HashSet<>(getVariantsOfDefaultRelation()), new HashSet<>(relationParameter)); } finally { @@ -5133,7 +5135,7 @@ private RQuery getInterpretedQuery2Whole(Session sessi LOGGER.info("QUERY TYPE TO CONVERT :\n{}", (query.getFilter() != null ? query.getFilter().debugDump(3) : null)); } - QueryEngine2 engine = new QueryEngine2(baseHelper.getConfiguration(), extItemDictionary, prismContext); + QueryEngine2 engine = new QueryEngine2(baseHelper.getConfiguration(), extItemDictionary, prismContext, relationRegistry); RQuery rQuery = engine.interpret(query, type, options, interpretCount, session); //just test if DB will handle it or throws some exception if (interpretCount) { diff --git a/repo/repo-sql-impl-test/src/test/resources/ctx-configuration-sql-test.xml b/repo/repo-sql-impl-test/src/test/resources/ctx-configuration-sql-test.xml index fce8ef624e4..34fe7236ac4 100644 --- a/repo/repo-sql-impl-test/src/test/resources/ctx-configuration-sql-test.xml +++ b/repo/repo-sql-impl-test/src/test/resources/ctx-configuration-sql-test.xml @@ -56,5 +56,10 @@ + + + + + diff --git a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/SqlAuditServiceImpl.java b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/SqlAuditServiceImpl.java index a98b7fb9468..a21c06c032a 100644 --- a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/SqlAuditServiceImpl.java +++ b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/SqlAuditServiceImpl.java @@ -234,7 +234,8 @@ private void listRecordsIterativeAttempt(String query, Map param // TODO what if original name (in audit log) differs from the current one (in repo) ? audit.setInitiator(resolve(session, raudit.getInitiatorOid(), raudit.getInitiatorName(), defaultIfNull(raudit.getInitiatorType(), RObjectType.USER))); audit.setAttorney(resolve(session, raudit.getAttorneyOid(), raudit.getAttorneyName(), RObjectType.USER)); - audit.setTarget(resolve(session, raudit.getTargetOid(), raudit.getTargetName(), raudit.getTargetType())); + audit.setTarget(resolve(session, raudit.getTargetOid(), raudit.getTargetName(), raudit.getTargetType()), + getPrismContext()); audit.setTargetOwner(resolve(session, raudit.getTargetOwnerOid(), raudit.getTargetOwnerName(), raudit.getTargetOwnerType())); count++; if (!handler.handle(audit)) { diff --git a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/SqlRepositoryServiceImpl.java b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/SqlRepositoryServiceImpl.java index b37857bf85f..a9b1515fbcb 100644 --- a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/SqlRepositoryServiceImpl.java +++ b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/SqlRepositoryServiceImpl.java @@ -129,6 +129,7 @@ public class SqlRepositoryServiceImpl extends SqlBaseService implements Reposito @Autowired private MatchingRuleRegistry matchingRuleRegistry; @Autowired private MidpointConfiguration midpointConfiguration; @Autowired private PrismContext prismContext; + @Autowired private RelationRegistry relationRegistry; private final ThreadLocal> conflictWatchersThreadLocal = new ThreadLocal<>(); @@ -1056,7 +1057,7 @@ public boolean selectorMatches(ObjectSelectorType objectS if (filterEvaluator != null) { specFilter = filterEvaluator.evaluate(specFilter); } - ObjectTypeUtil.normalizeFilter(specFilter); // we assume object is already normalized + ObjectTypeUtil.normalizeFilter(specFilter, relationRegistry); // we assume object is already normalized if (specFilter != null) { ObjectQueryUtil.assertPropertyOnly(specFilter, logMessagePrefix + " filter is not property-only filter"); } @@ -1121,7 +1122,7 @@ public void applyFullTextSearchConfiguration(FullTextSearchConfigurationType ful fullTextSearchConfiguration = fullTextSearch; } - @Override + @Override public FullTextSearchConfigurationType getFullTextSearchConfiguration() { return fullTextSearchConfiguration; } @@ -1129,6 +1130,8 @@ public FullTextSearchConfigurationType getFullTextSearchConfiguration() { @Override public void postInit(OperationResult result) throws SchemaException { + LOGGER.info("Executing repository postInit method"); + SystemConfigurationType systemConfiguration; try { systemConfiguration = getObject(SystemConfigurationType.class, @@ -1152,6 +1155,7 @@ public void postInit(OperationResult result) throws SchemaException { } } applyFullTextSearchConfiguration(systemConfiguration.getFullTextSearch()); + relationRegistry.applyRelationConfiguration(systemConfiguration); SystemConfigurationTypeUtil.applyOperationResultHandling(systemConfiguration); applyPrismConfiguration(systemConfiguration); } diff --git a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/RepositoryContext.java b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/RepositoryContext.java index 61b3d2a5592..a2142c663f1 100644 --- a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/RepositoryContext.java +++ b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/RepositoryContext.java @@ -19,6 +19,7 @@ import com.evolveum.midpoint.prism.PrismContext; import com.evolveum.midpoint.repo.api.RepositoryService; import com.evolveum.midpoint.repo.sql.data.common.dictionary.ExtItemDictionary; +import com.evolveum.midpoint.schema.RelationRegistry; import org.jetbrains.annotations.NotNull; /** @@ -27,11 +28,14 @@ public class RepositoryContext { @NotNull public final RepositoryService repositoryService; @NotNull public final PrismContext prismContext; + @NotNull public final RelationRegistry relationRegistry; @NotNull public final ExtItemDictionary extItemDictionary; - public RepositoryContext(@NotNull RepositoryService repositoryService, @NotNull PrismContext prismContext, @NotNull ExtItemDictionary extItemDictionary) { + public RepositoryContext(@NotNull RepositoryService repositoryService, @NotNull PrismContext prismContext, + @NotNull RelationRegistry relationRegistry, @NotNull ExtItemDictionary extItemDictionary) { this.repositoryService = repositoryService; this.prismContext = prismContext; + this.relationRegistry = relationRegistry; this.extItemDictionary = extItemDictionary; } } diff --git a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/RAbstractRole.java b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/RAbstractRole.java index 1c4efb44b79..4037eaf0142 100644 --- a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/RAbstractRole.java +++ b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/RAbstractRole.java @@ -183,8 +183,9 @@ public int hashCode() { return result; } + // dynamically called public static void copyFromJAXB(AbstractRoleType jaxb, RAbstractRole repo, - RepositoryContext repositoryContext, IdGeneratorResult generatorResult) + RepositoryContext repositoryContext, IdGeneratorResult generatorResult) throws DtoTranslationException { RFocus.copyFromJAXB(jaxb, repo, repositoryContext, generatorResult); @@ -196,19 +197,19 @@ public static void copyFromJAXB(AbstractRoleType ja if (jaxb.getAutoassign() != null) { RAutoassignSpecification aa = new RAutoassignSpecification(); - RAutoassignSpecification.copyFromJAXB(jaxb.getAutoassign(), aa); + RAutoassignSpecification.formJaxb(jaxb.getAutoassign(), aa); repo.setAutoassign(aa); } for (AssignmentType inducement : jaxb.getInducement()) { RAssignment rInducement = new RAssignment(repo, RAssignmentOwner.ABSTRACT_ROLE); - RAssignment.copyFromJAXB(inducement, rInducement, jaxb, repositoryContext, generatorResult); + RAssignment.fromJaxb(inducement, rInducement, jaxb, repositoryContext, generatorResult); repo.getAssignments().add(rInducement); } for (ObjectReferenceType approverRef : jaxb.getApproverRef()) { - RObjectReference ref = RUtil.jaxbRefToRepo(approverRef, repositoryContext.prismContext, repo, RReferenceOwner.ROLE_APPROVER); + RObjectReference ref = RUtil.jaxbRefToRepo(approverRef, repo, RReferenceOwner.ROLE_APPROVER, repositoryContext.relationRegistry); if (ref != null) { repo.getApproverRef().add(ref); } @@ -218,6 +219,6 @@ public static void copyFromJAXB(AbstractRoleType ja repo.setApprovalProcess(jaxb.getApprovalProcess()); - repo.setOwnerRef(RUtil.jaxbRefToEmbeddedRepoRef(jaxb.getOwnerRef(), repositoryContext.prismContext)); + repo.setOwnerRef(RUtil.jaxbRefToEmbeddedRepoRef(jaxb.getOwnerRef(), repositoryContext.relationRegistry)); } } diff --git a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/RAccessCertificationCampaign.java b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/RAccessCertificationCampaign.java index 937ec654452..483acac72f3 100644 --- a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/RAccessCertificationCampaign.java +++ b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/RAccessCertificationCampaign.java @@ -194,13 +194,14 @@ public int hashCode() { stageNumber); } + // dynamically called public static void copyFromJAXB(AccessCertificationCampaignType jaxb, RAccessCertificationCampaign repo, RepositoryContext repositoryContext, IdGeneratorResult generatorResult) throws DtoTranslationException { RObject.copyFromJAXB(jaxb, repo, repositoryContext, generatorResult); repo.setNameCopy(RPolyString.copyFromJAXB(jaxb.getName())); - repo.setDefinitionRef(RUtil.jaxbRefToEmbeddedRepoRef(jaxb.getDefinitionRef(), repositoryContext.prismContext)); + repo.setDefinitionRef(RUtil.jaxbRefToEmbeddedRepoRef(jaxb.getDefinitionRef(), repositoryContext.relationRegistry)); List cases = jaxb.getCase(); if (!cases.isEmpty()) { @@ -211,7 +212,7 @@ public static void copyFromJAXB(AccessCertificationCampaignType jaxb, RAccessCer } } - repo.setOwnerRefCampaign(RUtil.jaxbRefToEmbeddedRepoRef(jaxb.getOwnerRef(), repositoryContext.prismContext)); + repo.setOwnerRefCampaign(RUtil.jaxbRefToEmbeddedRepoRef(jaxb.getOwnerRef(), repositoryContext.relationRegistry)); repo.setHandlerUri(jaxb.getHandlerUri()); repo.setStart(jaxb.getStartTimestamp()); repo.setEnd(jaxb.getEndTimestamp()); diff --git a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/RAccessCertificationDefinition.java b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/RAccessCertificationDefinition.java index 0b90becb3eb..c39bddd3e7d 100644 --- a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/RAccessCertificationDefinition.java +++ b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/RAccessCertificationDefinition.java @@ -140,6 +140,7 @@ public int hashCode() { return result; } + // dynamically called public static void copyFromJAXB(AccessCertificationDefinitionType jaxb, RAccessCertificationDefinition repo, RepositoryContext repositoryContext, IdGeneratorResult generatorResult) throws DtoTranslationException { @@ -148,7 +149,7 @@ public static void copyFromJAXB(AccessCertificationDefinitionType jaxb, RAccessC repo.setNameCopy(RPolyString.copyFromJAXB(jaxb.getName())); repo.setHandlerUri(jaxb.getHandlerUri()); - repo.setOwnerRefDefinition(RUtil.jaxbRefToEmbeddedRepoRef(jaxb.getOwnerRef(), repositoryContext.prismContext)); + repo.setOwnerRefDefinition(RUtil.jaxbRefToEmbeddedRepoRef(jaxb.getOwnerRef(), repositoryContext.relationRegistry)); repo.setLastCampaignStartedTimestamp(jaxb.getLastCampaignStartedTimestamp()); repo.setLastCampaignClosedTimestamp(jaxb.getLastCampaignClosedTimestamp()); } diff --git a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/RCase.java b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/RCase.java index dec2ce7399f..e0c12e59650 100644 --- a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/RCase.java +++ b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/RCase.java @@ -128,13 +128,14 @@ public String toString() { '}'; } + // dynamically called public static void copyFromJAXB(CaseType jaxb, RCase repo, RepositoryContext context, IdGeneratorResult generatorResult) throws DtoTranslationException { RObject.copyFromJAXB(jaxb, repo, context, generatorResult); repo.setNameCopy(RPolyString.copyFromJAXB(jaxb.getName())); - repo.setObjectRef(RUtil.jaxbRefToEmbeddedRepoRef(jaxb.getObjectRef(), context.prismContext)); + repo.setObjectRef(RUtil.jaxbRefToEmbeddedRepoRef(jaxb.getObjectRef(), context.relationRegistry)); repo.setState(jaxb.getState()); for (CaseWorkItemType workItem : jaxb.getWorkItem()) { repo.getWorkItems().add(RCaseWorkItem.toRepo(repo, workItem, context)); diff --git a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/RConnector.java b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/RConnector.java index 82291bb3418..39d01eceab1 100644 --- a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/RConnector.java +++ b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/RConnector.java @@ -159,6 +159,7 @@ public int hashCode() { return result; } + // dynamically called public static void copyFromJAXB(ConnectorType jaxb, RConnector repo, RepositoryContext repositoryContext, IdGeneratorResult generatorResult) throws DtoTranslationException { RObject.copyFromJAXB(jaxb, repo, repositoryContext, generatorResult); @@ -168,7 +169,7 @@ public static void copyFromJAXB(ConnectorType jaxb, RConnector repo, RepositoryC repo.setConnectorType(jaxb.getConnectorType()); repo.setConnectorVersion(jaxb.getConnectorVersion()); repo.setFramework(jaxb.getFramework()); - repo.setConnectorHostRef(RUtil.jaxbRefToEmbeddedRepoRef(jaxb.getConnectorHostRef(), repositoryContext.prismContext)); + repo.setConnectorHostRef(RUtil.jaxbRefToEmbeddedRepoRef(jaxb.getConnectorHostRef(), repositoryContext.relationRegistry)); if (jaxb.getConnectorHost() != null) { LOGGER.warn("Connector host from connector type won't be saved. It should be " + diff --git a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/RConnectorHost.java b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/RConnectorHost.java index 498ab8e19a6..facc3130bd0 100644 --- a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/RConnectorHost.java +++ b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/RConnectorHost.java @@ -99,6 +99,7 @@ public int hashCode() { return result; } + // dynamically called public static void copyFromJAXB(ConnectorHostType jaxb, RConnectorHost repo, RepositoryContext repositoryContext, IdGeneratorResult generatorResult) throws DtoTranslationException { RObject.copyFromJAXB(jaxb, repo, repositoryContext, generatorResult); diff --git a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/RFocus.java b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/RFocus.java index acfa585c349..64376c86df9 100644 --- a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/RFocus.java +++ b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/RFocus.java @@ -306,6 +306,7 @@ public int hashCode() { return result; } + // dynamically called public static void copyFromJAXB(FocusType jaxb, RFocus repo, RepositoryContext repositoryContext, IdGeneratorResult generatorResult) throws DtoTranslationException { @@ -315,29 +316,29 @@ public static void copyFromJAXB(FocusType jaxb, RFocus repo.setCostCenter(jaxb.getCostCenter()); repo.getLinkRef().addAll( - RUtil.safeListReferenceToSet(jaxb.getLinkRef(), repositoryContext.prismContext, repo, RReferenceOwner.USER_ACCOUNT)); + RUtil.safeListReferenceToSet(jaxb.getLinkRef(), repo, RReferenceOwner.USER_ACCOUNT, repositoryContext.relationRegistry)); repo.getRoleMembershipRef().addAll( - RUtil.safeListReferenceToSet(jaxb.getRoleMembershipRef(), repositoryContext.prismContext, repo, RReferenceOwner.ROLE_MEMBER)); + RUtil.safeListReferenceToSet(jaxb.getRoleMembershipRef(), repo, RReferenceOwner.ROLE_MEMBER, repositoryContext.relationRegistry)); repo.getDelegatedRef().addAll( - RUtil.safeListReferenceToSet(jaxb.getDelegatedRef(), repositoryContext.prismContext, repo, RReferenceOwner.DELEGATED)); + RUtil.safeListReferenceToSet(jaxb.getDelegatedRef(), repo, RReferenceOwner.DELEGATED, repositoryContext.relationRegistry)); repo.getPersonaRef().addAll( - RUtil.safeListReferenceToSet(jaxb.getPersonaRef(), repositoryContext.prismContext, repo, RReferenceOwner.PERSONA)); + RUtil.safeListReferenceToSet(jaxb.getPersonaRef(), repo, RReferenceOwner.PERSONA, repositoryContext.relationRegistry)); repo.setPolicySituation(RUtil.listToSet(jaxb.getPolicySituation())); for (AssignmentType assignment : jaxb.getAssignment()) { RAssignment rAssignment = new RAssignment(repo, RAssignmentOwner.FOCUS); - RAssignment.copyFromJAXB(assignment, rAssignment, jaxb, repositoryContext, generatorResult); + RAssignment.fromJaxb(assignment, rAssignment, jaxb, repositoryContext, generatorResult); repo.getAssignments().add(rAssignment); } if (jaxb.getActivation() != null) { RActivation activation = new RActivation(); - RActivation.copyFromJAXB(jaxb.getActivation(), activation, repositoryContext); + RActivation.fromJaxb(jaxb.getActivation(), activation, repositoryContext); repo.setActivation(activation); } diff --git a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/RForm.java b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/RForm.java index 963bf33b8e5..959a31a7cce 100644 --- a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/RForm.java +++ b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/RForm.java @@ -75,6 +75,7 @@ public int hashCode() { return Objects.hash(super.hashCode(), nameCopy); } + // dynamically called public static void copyFromJAXB(FormType jaxb, RForm repo, RepositoryContext repositoryContext, IdGeneratorResult generatorResult) throws DtoTranslationException { RObject.copyFromJAXB(jaxb, repo, repositoryContext, generatorResult); diff --git a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/RFunctionLibrary.java b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/RFunctionLibrary.java index 21311bd5667..2436c6db471 100644 --- a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/RFunctionLibrary.java +++ b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/RFunctionLibrary.java @@ -76,6 +76,7 @@ public int hashCode() { return Objects.hash(super.hashCode(), nameCopy); } + // dynamically called public static void copyFromJAXB(FunctionLibraryType jaxb, RFunctionLibrary repo, RepositoryContext repositoryContext, IdGeneratorResult generatorResult) throws DtoTranslationException { RObject.copyFromJAXB(jaxb, repo, repositoryContext, generatorResult); diff --git a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/RGenericObject.java b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/RGenericObject.java index ccda8a1119e..5b2d302c277 100644 --- a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/RGenericObject.java +++ b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/RGenericObject.java @@ -88,6 +88,7 @@ public int hashCode() { return result; } + // dynamically called public static void copyFromJAXB(GenericObjectType jaxb, RGenericObject repo, RepositoryContext repositoryContext, IdGeneratorResult generatorResult) throws DtoTranslationException { RObject.copyFromJAXB(jaxb, repo, repositoryContext, generatorResult); diff --git a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/RLookupTable.java b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/RLookupTable.java index 4bf0f9ad814..afc93a90ff3 100644 --- a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/RLookupTable.java +++ b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/RLookupTable.java @@ -57,6 +57,7 @@ public void setRows(Set rows) { this.rows = rows; } + // dynamically called public static void copyFromJAXB(LookupTableType jaxb, RLookupTable repo, RepositoryContext repositoryContext, IdGeneratorResult generatorResult) throws DtoTranslationException, SchemaException { RObject.copyFromJAXB(jaxb, repo, repositoryContext, generatorResult); diff --git a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/RNode.java b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/RNode.java index 0724b472238..68ba35b4c56 100644 --- a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/RNode.java +++ b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/RNode.java @@ -89,6 +89,7 @@ public int hashCode() { return result; } + // dynamically called public static void copyFromJAXB(NodeType jaxb, RNode repo, RepositoryContext repositoryContext, IdGeneratorResult generatorResult) throws DtoTranslationException { RObject.copyFromJAXB(jaxb, repo, repositoryContext, generatorResult); diff --git a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/RObject.java b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/RObject.java index a98ac3530a6..981dddf7a83 100644 --- a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/RObject.java +++ b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/RObject.java @@ -689,6 +689,7 @@ protected static void copyToJAXB(RObject repo, ObjectT } } + // dynamically called public static void copyFromJAXB(ObjectType jaxb, RObject repo, RepositoryContext repositoryContext, IdGeneratorResult generatorResult) throws DtoTranslationException { @@ -709,18 +710,18 @@ public static void copyFromJAXB(ObjectType jaxb, RObject< .getVersion()) : 0; repo.setVersion(version); - repo.getParentOrgRef().addAll(RUtil.safeListReferenceToSet(jaxb.getParentOrgRef(), repositoryContext.prismContext, - repo, RReferenceOwner.OBJECT_PARENT_ORG)); + repo.getParentOrgRef().addAll(RUtil.safeListReferenceToSet(jaxb.getParentOrgRef(), + repo, RReferenceOwner.OBJECT_PARENT_ORG, repositoryContext.relationRegistry)); for (TriggerType trigger : jaxb.getTrigger()) { RTrigger rTrigger = new RTrigger(null); - RTrigger.copyFromJAXB(trigger, rTrigger, jaxb, repositoryContext, generatorResult); + RTrigger.fromJaxb(trigger, rTrigger, jaxb, repositoryContext, generatorResult); repo.getTrigger().add(rTrigger); } - MetadataFactory.fromJAXB(jaxb.getMetadata(), repo, repositoryContext.prismContext); - repo.setTenantRef(RUtil.jaxbRefToEmbeddedRepoRef(jaxb.getTenantRef(), repositoryContext.prismContext)); + MetadataFactory.fromJAXB(jaxb.getMetadata(), repo, repositoryContext.prismContext, repositoryContext.relationRegistry); + repo.setTenantRef(RUtil.jaxbRefToEmbeddedRepoRef(jaxb.getTenantRef(), repositoryContext.relationRegistry)); if (jaxb.getExtension() != null) { copyFromJAXB(jaxb.getExtension().asPrismContainerValue(), repo, repositoryContext, RObjectExtensionType.EXTENSION, generatorResult); @@ -729,7 +730,7 @@ public static void copyFromJAXB(ObjectType jaxb, RObject< repo.getTextInfoItems().addAll(RObjectTextInfo.createItemsSet(jaxb, repo, repositoryContext)); for (OperationExecutionType opExec : jaxb.getOperationExecution()) { ROperationExecution rOpExec = new ROperationExecution(repo); - ROperationExecution.copyFromJAXB(opExec, rOpExec, jaxb, repositoryContext, generatorResult); + ROperationExecution.fromJaxb(opExec, rOpExec, jaxb, repositoryContext, generatorResult); repo.getOperationExecutions().add(rOpExec); } } @@ -739,6 +740,7 @@ public String toString() { return RUtil.getDebugString(this); } + // dynamically called public static void copyFromJAXB(PrismContainerValue containerValue, RObject repo, RepositoryContext repositoryContext, RObjectExtensionType ownerType, IdGeneratorResult generatorResult) throws DtoTranslationException { RAnyConverter converter = new RAnyConverter(repositoryContext.prismContext, repositoryContext.extItemDictionary); diff --git a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/RObjectCollection.java b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/RObjectCollection.java index 5013159e834..7f668aeea15 100644 --- a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/RObjectCollection.java +++ b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/RObjectCollection.java @@ -76,6 +76,7 @@ public int hashCode() { return Objects.hash(super.hashCode(), nameCopy); } + // dynamically called public static void copyFromJAXB(ObjectCollectionType jaxb, RObjectCollection repo, RepositoryContext repositoryContext, IdGeneratorResult generatorResult) throws DtoTranslationException { RObject.copyFromJAXB(jaxb, repo, repositoryContext, generatorResult); diff --git a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/RObjectReference.java b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/RObjectReference.java index a64150f75c2..8a621dde3e6 100644 --- a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/RObjectReference.java +++ b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/RObjectReference.java @@ -26,6 +26,7 @@ import com.evolveum.midpoint.repo.sql.util.EntityState; import com.evolveum.midpoint.repo.sql.util.MidPointSingleTablePersister; import com.evolveum.midpoint.repo.sql.util.RUtil; +import com.evolveum.midpoint.schema.RelationRegistry; import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectReferenceType; import org.apache.commons.lang.Validate; @@ -36,7 +37,6 @@ import javax.persistence.*; import static com.evolveum.midpoint.repo.sql.util.RUtil.qnameToString; -import static com.evolveum.midpoint.schema.util.ObjectTypeUtil.normalizeRelation; /** * @author lazyman @@ -216,13 +216,13 @@ public static void copyToJAXB(RObjectReference repo, ObjectReferenceType jaxb) { jaxb.setRelation(RUtil.stringToQName(repo.getRelation())); } - public static ObjectReference copyFromJAXB(ObjectReferenceType jaxb, ObjectReference repo) { + public static ObjectReference copyFromJAXB(ObjectReferenceType jaxb, ObjectReference repo, RelationRegistry relationRegistry) { Validate.notNull(repo, "Repo object must not be null."); Validate.notNull(jaxb, "JAXB object must not be null."); Validate.notEmpty(jaxb.getOid(), "Target oid must not be null."); repo.setType(ClassMapper.getHQLTypeForQName(jaxb.getType())); - repo.setRelation(qnameToString(normalizeRelation(jaxb.getRelation()))); + repo.setRelation(qnameToString(relationRegistry.normalizeRelation(jaxb.getRelation()))); repo.setTargetOid(jaxb.getOid()); return repo; diff --git a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/RObjectTemplate.java b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/RObjectTemplate.java index 1a97bd777b1..fd9844aff52 100644 --- a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/RObjectTemplate.java +++ b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/RObjectTemplate.java @@ -116,6 +116,7 @@ public int hashCode() { return result; } + // dynamically called public static void copyFromJAXB(ObjectTemplateType jaxb, RObjectTemplate repo, RepositoryContext repositoryContext, IdGeneratorResult generatorResult) throws DtoTranslationException { RObject.copyFromJAXB(jaxb, repo, repositoryContext, generatorResult); @@ -124,6 +125,6 @@ public static void copyFromJAXB(ObjectTemplateType jaxb, RObjectTemplate repo, R repo.setNameCopy(RPolyString.copyFromJAXB(jaxb.getName())); repo.getIncludeRef().addAll(RUtil.safeListReferenceToSet( - jaxb.getIncludeRef(), repositoryContext.prismContext, repo, RReferenceOwner.INCLUDE)); + jaxb.getIncludeRef(), repo, RReferenceOwner.INCLUDE, repositoryContext.relationRegistry)); } } diff --git a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/ROrg.java b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/ROrg.java index f8aee955892..6ea3333c906 100644 --- a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/ROrg.java +++ b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/ROrg.java @@ -120,6 +120,7 @@ public int hashCode() { return result; } + // dynamically called public static void copyFromJAXB(OrgType jaxb, ROrg repo, RepositoryContext repositoryContext, IdGeneratorResult generatorResult) throws DtoTranslationException { RAbstractRole.copyFromJAXB(jaxb, repo, repositoryContext, generatorResult); diff --git a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/RReport.java b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/RReport.java index ee5d8d5e78c..dbdadf1ddab 100644 --- a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/RReport.java +++ b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/RReport.java @@ -116,6 +116,7 @@ public int hashCode() { return result; } + // dynamically called public static void copyFromJAXB(ReportType jaxb, RReport repo, RepositoryContext repositoryContext, IdGeneratorResult generatorResult) throws DtoTranslationException { diff --git a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/RReportOutput.java b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/RReportOutput.java index 3fee5a6e3b2..586e2023595 100644 --- a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/RReportOutput.java +++ b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/RReportOutput.java @@ -74,11 +74,12 @@ public int hashCode() { return result; } + // dynamically called public static void copyFromJAXB(ReportOutputType jaxb, RReportOutput repo, RepositoryContext repositoryContext, IdGeneratorResult generatorResult) throws DtoTranslationException { RObject.copyFromJAXB(jaxb, repo, repositoryContext, generatorResult); repo.setNameCopy(RPolyString.copyFromJAXB(jaxb.getName())); - repo.setReportRef(RUtil.jaxbRefToEmbeddedRepoRef(jaxb.getReportRef(), repositoryContext.prismContext)); + repo.setReportRef(RUtil.jaxbRefToEmbeddedRepoRef(jaxb.getReportRef(), repositoryContext.relationRegistry)); } } \ No newline at end of file diff --git a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/RResource.java b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/RResource.java index 35beecce586..29899eab303 100644 --- a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/RResource.java +++ b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/RResource.java @@ -146,12 +146,13 @@ public int hashCode() { return result; } + // dynamically called public static void copyFromJAXB(ResourceType jaxb, RResource repo, RepositoryContext repositoryContext, IdGeneratorResult generatorResult) throws DtoTranslationException { RObject.copyFromJAXB(jaxb, repo, repositoryContext, generatorResult); repo.setNameCopy(RPolyString.copyFromJAXB(jaxb.getName())); - repo.setConnectorRef(RUtil.jaxbRefToEmbeddedRepoRef(jaxb.getConnectorRef(), repositoryContext.prismContext)); + repo.setConnectorRef(RUtil.jaxbRefToEmbeddedRepoRef(jaxb.getConnectorRef(), repositoryContext.relationRegistry)); if (jaxb.getConnector() != null) { LOGGER.warn("Connector from resource type won't be saved. It should be translated to connector reference."); @@ -161,13 +162,13 @@ public static void copyFromJAXB(ResourceType jaxb, RResource repo, RepositoryCon if (jaxb.getBusiness() != null) { ResourceBusinessConfigurationType business = jaxb.getBusiness(); repo.getApproverRef().addAll(RUtil.safeListReferenceToSet(business.getApproverRef(), - repositoryContext.prismContext, repo, RReferenceOwner.RESOURCE_BUSINESS_CONFIGURATON_APPROVER)); + repo, RReferenceOwner.RESOURCE_BUSINESS_CONFIGURATON_APPROVER, repositoryContext.relationRegistry)); repo.setAdministrativeState(RUtil.getRepoEnumValue(business.getAdministrativeState(), RResourceAdministrativeState.class)); } if (jaxb.getOperationalState() != null) { ROperationalState repoOpState = new ROperationalState(); - ROperationalState.copyFromJAXB(jaxb.getOperationalState(), repoOpState); + ROperationalState.fromJaxb(jaxb.getOperationalState(), repoOpState); repo.setOperationalState(repoOpState); } } catch (Exception ex) { diff --git a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/RRole.java b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/RRole.java index bf99203b414..5679bd9150f 100644 --- a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/RRole.java +++ b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/RRole.java @@ -94,6 +94,7 @@ public int hashCode() { return result; } + // dynamically called public static void copyFromJAXB(RoleType jaxb, RRole repo, RepositoryContext repositoryContext, IdGeneratorResult generatorResult) throws DtoTranslationException { RAbstractRole.copyFromJAXB(jaxb, repo, repositoryContext, generatorResult); diff --git a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/RSecurityPolicy.java b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/RSecurityPolicy.java index accf73f7c7f..06a92774071 100644 --- a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/RSecurityPolicy.java +++ b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/RSecurityPolicy.java @@ -58,6 +58,7 @@ public int hashCode() { return result; } + // dynamically called public static void copyFromJAXB(SecurityPolicyType jaxb, RSecurityPolicy repo, RepositoryContext repositoryContext, IdGeneratorResult generatorResult) throws DtoTranslationException { RObject.copyFromJAXB(jaxb, repo, repositoryContext, generatorResult); diff --git a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/RSequence.java b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/RSequence.java index 662f6de55ab..658836585dd 100644 --- a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/RSequence.java +++ b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/RSequence.java @@ -77,6 +77,7 @@ public int hashCode() { return result; } + // dynamically called public static void copyFromJAXB(SequenceType jaxb, RSequence repo, RepositoryContext repositoryContext, IdGeneratorResult generatorResult) throws DtoTranslationException { RObject.copyFromJAXB(jaxb, repo, repositoryContext, generatorResult); diff --git a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/RService.java b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/RService.java index 5a184d6a77b..e631f26e914 100644 --- a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/RService.java +++ b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/RService.java @@ -104,6 +104,7 @@ public int hashCode() { return Arrays.hashCode(new Object[]{nameCopy, serviceType, displayOrder}); } + // dynamically called public static void copyFromJAXB(ServiceType jaxb, RService repo, RepositoryContext repositoryContext, IdGeneratorResult generatorResult) throws DtoTranslationException { RAbstractRole.copyFromJAXB(jaxb, repo, repositoryContext, generatorResult); diff --git a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/RShadow.java b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/RShadow.java index 52ebefb8099..f4197d5640f 100644 --- a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/RShadow.java +++ b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/RShadow.java @@ -259,6 +259,7 @@ public int hashCode() { return result1; } + // dynamically called public static void copyFromJAXB(ShadowType jaxb, RShadow repo, RepositoryContext repositoryContext, IdGeneratorResult generatorResult) throws DtoTranslationException { RObject.copyFromJAXB(jaxb, repo, repositoryContext, generatorResult); @@ -277,7 +278,7 @@ public static void copyFromJAXB(ShadowType jaxb, RShadow< } repo.setSynchronizationTimestamp(jaxb.getSynchronizationTimestamp()); - repo.setResourceRef(RUtil.jaxbRefToEmbeddedRepoRef(jaxb.getResourceRef(), repositoryContext.prismContext)); + repo.setResourceRef(RUtil.jaxbRefToEmbeddedRepoRef(jaxb.getResourceRef(), repositoryContext.relationRegistry)); repo.setAttemptNumber(jaxb.getAttemptNumber()); repo.setExists(jaxb.isExists()); diff --git a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/RSystemConfiguration.java b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/RSystemConfiguration.java index 0b0b33be4bc..b0f10be3f0f 100644 --- a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/RSystemConfiguration.java +++ b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/RSystemConfiguration.java @@ -77,6 +77,7 @@ public int hashCode() { return result; } + // dynamically called public static void copyFromJAXB(SystemConfigurationType jaxb, RSystemConfiguration repo, RepositoryContext repositoryContext, IdGeneratorResult generatorResult) throws DtoTranslationException { RObject.copyFromJAXB(jaxb, repo, repositoryContext, generatorResult); diff --git a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/RTask.java b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/RTask.java index 19352f690c5..324eca03d62 100644 --- a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/RTask.java +++ b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/RTask.java @@ -414,8 +414,9 @@ public int hashCode() { return result1; } + // dynamically called public static void copyFromJAXB(TaskType jaxb, RTask repo, RepositoryContext repositoryContext, - IdGeneratorResult generatorResult) throws DtoTranslationException { + IdGeneratorResult generatorResult) throws DtoTranslationException { RObject.copyFromJAXB(jaxb, repo, repositoryContext, generatorResult); PrismObjectDefinition taskDefinition = jaxb.asPrismObject().getDefinition(); @@ -435,17 +436,17 @@ public static void copyFromJAXB(TaskType jaxb, RTask repo, RepositoryContext rep repo.setCategory(jaxb.getCategory()); repo.setParent(jaxb.getParent()); - repo.setObjectRef(RUtil.jaxbRefToEmbeddedRepoRef(jaxb.getObjectRef(), repositoryContext.prismContext)); - repo.setOwnerRefTask(RUtil.jaxbRefToEmbeddedRepoRef(jaxb.getOwnerRef(), repositoryContext.prismContext)); + repo.setObjectRef(RUtil.jaxbRefToEmbeddedRepoRef(jaxb.getObjectRef(), repositoryContext.relationRegistry)); + repo.setOwnerRefTask(RUtil.jaxbRefToEmbeddedRepoRef(jaxb.getOwnerRef(), repositoryContext.relationRegistry)); repo.setWaitingReason(RUtil.getRepoEnumValue(jaxb.getWaitingReason(), RTaskWaitingReason.class)); repo.setDependent(RUtil.listToSet(jaxb.getDependent())); WfContextType wfc = jaxb.getWorkflowContext(); if (wfc != null) { repo.setWfProcessInstanceId(wfc.getProcessInstanceId()); - repo.setWfRequesterRef(RUtil.jaxbRefToEmbeddedRepoRef(wfc.getRequesterRef(), repositoryContext.prismContext)); - repo.setWfObjectRef(RUtil.jaxbRefToEmbeddedRepoRef(wfc.getObjectRef(), repositoryContext.prismContext)); - repo.setWfTargetRef(RUtil.jaxbRefToEmbeddedRepoRef(wfc.getTargetRef(), repositoryContext.prismContext)); + repo.setWfRequesterRef(RUtil.jaxbRefToEmbeddedRepoRef(wfc.getRequesterRef(), repositoryContext.relationRegistry)); + repo.setWfObjectRef(RUtil.jaxbRefToEmbeddedRepoRef(wfc.getObjectRef(), repositoryContext.relationRegistry)); + repo.setWfTargetRef(RUtil.jaxbRefToEmbeddedRepoRef(wfc.getTargetRef(), repositoryContext.relationRegistry)); repo.setWfStartTimestamp(wfc.getStartTimestamp()); repo.setWfEndTimestamp(wfc.getEndTimestamp()); } diff --git a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/RUser.java b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/RUser.java index 070822d2a39..c589810e901 100644 --- a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/RUser.java +++ b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/RUser.java @@ -243,8 +243,9 @@ public int hashCode() { return result; } + // dynamically called public static void copyFromJAXB(UserType jaxb, RUser repo, RepositoryContext repositoryContext, - IdGeneratorResult generatorResult) throws DtoTranslationException { + IdGeneratorResult generatorResult) throws DtoTranslationException { RFocus.copyFromJAXB(jaxb, repo, repositoryContext, generatorResult); repo.setNameCopy(RPolyString.copyFromJAXB(jaxb.getName())); diff --git a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/RValuePolicy.java b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/RValuePolicy.java index 166c9bf76f1..985d892d89e 100644 --- a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/RValuePolicy.java +++ b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/RValuePolicy.java @@ -77,6 +77,7 @@ public int hashCode() { return result; } + // dynamically called public static void copyFromJAXB(ValuePolicyType jaxb, RValuePolicy repo, RepositoryContext repositoryContext, IdGeneratorResult generatorResult) throws DtoTranslationException { RObject.copyFromJAXB(jaxb, repo, repositoryContext, generatorResult); diff --git a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/any/RAssignmentExtension.java b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/any/RAssignmentExtension.java index e8d66123d04..c4219e84a46 100644 --- a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/any/RAssignmentExtension.java +++ b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/any/RAssignmentExtension.java @@ -281,15 +281,15 @@ public int hashCode() { return result; } - public static void copyFromJAXB(ExtensionType jaxb, RAssignmentExtension repo, RAssignmentExtensionType type, - RepositoryContext repositoryContext) throws DtoTranslationException { + public static void fromJaxb(ExtensionType jaxb, RAssignmentExtension repo, RAssignmentExtensionType type, + RepositoryContext repositoryContext) throws DtoTranslationException { Validate.notNull(repo, "Repo object must not be null."); Validate.notNull(jaxb, "JAXB object must not be null."); - copyFromJAXB(jaxb.asPrismContainerValue(), repo, type, repositoryContext); + fromJaxb(jaxb.asPrismContainerValue(), repo, type, repositoryContext); } - private static void copyFromJAXB(PrismContainerValue containerValue, RAssignmentExtension repo, + private static void fromJaxb(PrismContainerValue containerValue, RAssignmentExtension repo, RAssignmentExtensionType type, RepositoryContext repositoryContext) throws DtoTranslationException { RAnyConverter converter = new RAnyConverter(repositoryContext.prismContext, repositoryContext.extItemDictionary); diff --git a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/container/RAccessCertificationCase.java b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/container/RAccessCertificationCase.java index 42f9b99e339..6faa85d5975 100644 --- a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/container/RAccessCertificationCase.java +++ b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/container/RAccessCertificationCase.java @@ -334,13 +334,13 @@ private static RAccessCertificationCase toRepo(RAccessCertificationCase rCase, A RepositoryContext context) throws DtoTranslationException { rCase.setTransient(null); // we don't try to advise hibernate - let it do its work, even if it would cost some SELECTs rCase.setId(RUtil.toInteger(case1.getId())); - rCase.setObjectRef(RUtil.jaxbRefToEmbeddedRepoRef(case1.getObjectRef(), context.prismContext)); - rCase.setTargetRef(RUtil.jaxbRefToEmbeddedRepoRef(case1.getTargetRef(), context.prismContext)); - rCase.setTenantRef(RUtil.jaxbRefToEmbeddedRepoRef(case1.getTenantRef(), context.prismContext)); - rCase.setOrgRef(RUtil.jaxbRefToEmbeddedRepoRef(case1.getOrgRef(), context.prismContext)); + rCase.setObjectRef(RUtil.jaxbRefToEmbeddedRepoRef(case1.getObjectRef(), context.relationRegistry)); + rCase.setTargetRef(RUtil.jaxbRefToEmbeddedRepoRef(case1.getTargetRef(), context.relationRegistry)); + rCase.setTenantRef(RUtil.jaxbRefToEmbeddedRepoRef(case1.getTenantRef(), context.relationRegistry)); + rCase.setOrgRef(RUtil.jaxbRefToEmbeddedRepoRef(case1.getOrgRef(), context.relationRegistry)); if (case1.getActivation() != null) { RActivation activation = new RActivation(); - RActivation.copyFromJAXB(case1.getActivation(), activation, context); + RActivation.fromJaxb(case1.getActivation(), activation, context); rCase.setActivation(activation); } for (AccessCertificationWorkItemType workItem : case1.getWorkItem()) { diff --git a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/container/RAccessCertificationWorkItem.java b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/container/RAccessCertificationWorkItem.java index 953d50120fb..9add2135545 100644 --- a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/container/RAccessCertificationWorkItem.java +++ b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/container/RAccessCertificationWorkItem.java @@ -256,8 +256,8 @@ private static void toRepo(RAccessCertificationWorkItem rWorkItem, rWorkItem.setIteration(norm(workItem.getIteration())); rWorkItem.setStageNumber(workItem.getStageNumber()); rWorkItem.getAssigneeRef().addAll(RCertWorkItemReference.safeListReferenceToSet( - workItem.getAssigneeRef(), context.prismContext, rWorkItem)); - rWorkItem.setPerformerRef(RUtil.jaxbRefToEmbeddedRepoRef(workItem.getPerformerRef(), context.prismContext)); + workItem.getAssigneeRef(), rWorkItem, context.relationRegistry)); + rWorkItem.setPerformerRef(RUtil.jaxbRefToEmbeddedRepoRef(workItem.getPerformerRef(), context.relationRegistry)); rWorkItem.setOutcome(WorkItemTypeUtil.getOutcome(workItem)); rWorkItem.setOutputChangeTimestamp(workItem.getOutputChangeTimestamp()); rWorkItem.setCloseTimestamp(workItem.getCloseTimestamp()); diff --git a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/container/RAssignment.java b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/container/RAssignment.java index 7b8107421d3..9d0ca25f161 100644 --- a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/container/RAssignment.java +++ b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/container/RAssignment.java @@ -433,20 +433,19 @@ public int hashCode() { return result; } - public static void copyFromJAXB(AssignmentType jaxb, RAssignment repo, RObject parent, - RepositoryContext repositoryContext) throws DtoTranslationException{ - copyFromJAXB(jaxb, repo, repositoryContext, null); + public static void fromJaxb(AssignmentType jaxb, RAssignment repo, RObject parent, + RepositoryContext repositoryContext) throws DtoTranslationException{ + fromJaxb(jaxb, repo, repositoryContext, null); repo.setOwner(parent); } - public static void copyFromJAXB(AssignmentType jaxb, RAssignment repo, ObjectType parent, RepositoryContext repositoryContext, - IdGeneratorResult generatorResult) throws DtoTranslationException { - - copyFromJAXB(jaxb, repo, repositoryContext, generatorResult); + public static void fromJaxb(AssignmentType jaxb, RAssignment repo, ObjectType parent, RepositoryContext repositoryContext, + IdGeneratorResult generatorResult) throws DtoTranslationException { + fromJaxb(jaxb, repo, repositoryContext, generatorResult); repo.setOwnerOid(parent.getOid()); } - private static void copyFromJAXB(AssignmentType jaxb, RAssignment repo, RepositoryContext repositoryContext, + private static void fromJaxb(AssignmentType jaxb, RAssignment repo, RepositoryContext repositoryContext, IdGeneratorResult generatorResult) throws DtoTranslationException { Validate.notNull(repo, "Repo object must not be null."); Validate.notNull(jaxb, "JAXB object must not be null."); @@ -465,13 +464,13 @@ private static void copyFromJAXB(AssignmentType jaxb, RAssignment repo, Reposito extension.setOwner(repo); repo.setExtension(extension); - RAssignmentExtension.copyFromJAXB(jaxb.getExtension(), extension, RAssignmentExtensionType.EXTENSION, + RAssignmentExtension.fromJaxb(jaxb.getExtension(), extension, RAssignmentExtensionType.EXTENSION, repositoryContext); } if (jaxb.getActivation() != null) { RActivation activation = new RActivation(); - RActivation.copyFromJAXB(jaxb.getActivation(), activation, repositoryContext); + RActivation.fromJaxb(jaxb.getActivation(), activation, repositoryContext); repo.setActivation(activation); } @@ -479,17 +478,17 @@ private static void copyFromJAXB(AssignmentType jaxb, RAssignment repo, Reposito LOGGER.warn("Target from assignment type won't be saved. It should be translated to target reference."); } - repo.setTargetRef(RUtil.jaxbRefToEmbeddedRepoRef(jaxb.getTargetRef(), repositoryContext.prismContext)); + repo.setTargetRef(RUtil.jaxbRefToEmbeddedRepoRef(jaxb.getTargetRef(), repositoryContext.relationRegistry)); - repo.setTenantRef(RUtil.jaxbRefToEmbeddedRepoRef(jaxb.getTenantRef(), repositoryContext.prismContext)); + repo.setTenantRef(RUtil.jaxbRefToEmbeddedRepoRef(jaxb.getTenantRef(), repositoryContext.relationRegistry)); - repo.setOrgRef(RUtil.jaxbRefToEmbeddedRepoRef(jaxb.getOrgRef(), repositoryContext.prismContext)); + repo.setOrgRef(RUtil.jaxbRefToEmbeddedRepoRef(jaxb.getOrgRef(), repositoryContext.relationRegistry)); if (jaxb.getConstruction() != null) { - repo.setResourceRef(RUtil.jaxbRefToEmbeddedRepoRef(jaxb.getConstruction().getResourceRef(), repositoryContext.prismContext)); + repo.setResourceRef(RUtil.jaxbRefToEmbeddedRepoRef(jaxb.getConstruction().getResourceRef(), repositoryContext.relationRegistry)); } - MetadataFactory.fromJAXB(jaxb.getMetadata(), repo, repositoryContext.prismContext); + MetadataFactory.fromJAXB(jaxb.getMetadata(), repo, repositoryContext.prismContext, repositoryContext.relationRegistry); } @Override diff --git a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/container/RCaseWorkItem.java b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/container/RCaseWorkItem.java index 203e0a9bfaa..759a0191ba9 100644 --- a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/container/RCaseWorkItem.java +++ b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/container/RCaseWorkItem.java @@ -233,10 +233,10 @@ private static void toRepo(RCaseWorkItem rWorkItem, CaseWorkItemType workItem, R } rWorkItem.setId(idInt); rWorkItem.setStageNumber(workItem.getStageNumber()); - rWorkItem.setOriginalAssigneeRef(RUtil.jaxbRefToEmbeddedRepoRef(workItem.getOriginalAssigneeRef(), context.prismContext)); + rWorkItem.setOriginalAssigneeRef(RUtil.jaxbRefToEmbeddedRepoRef(workItem.getOriginalAssigneeRef(), context.relationRegistry)); rWorkItem.getAssigneeRef().addAll(RCaseWorkItemReference.safeListReferenceToSet( - workItem.getAssigneeRef(), context.prismContext, rWorkItem)); - rWorkItem.setPerformerRef(RUtil.jaxbRefToEmbeddedRepoRef(workItem.getPerformerRef(), context.prismContext)); + workItem.getAssigneeRef(), rWorkItem, context.relationRegistry)); + rWorkItem.setPerformerRef(RUtil.jaxbRefToEmbeddedRepoRef(workItem.getPerformerRef(), context.relationRegistry)); rWorkItem.setOutcome(WorkItemTypeUtil.getOutcome(workItem)); rWorkItem.setCloseTimestamp(workItem.getCloseTimestamp()); rWorkItem.setDeadline(workItem.getDeadline()); diff --git a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/container/RCaseWorkItemReference.java b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/container/RCaseWorkItemReference.java index 4b4be890c62..ae1eb30657c 100644 --- a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/container/RCaseWorkItemReference.java +++ b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/data/common/container/RCaseWorkItemReference.java @@ -16,7 +16,6 @@ package com.evolveum.midpoint.repo.sql.data.common.container; -import com.evolveum.midpoint.prism.PrismContext; import com.evolveum.midpoint.repo.sql.data.common.RObject; import com.evolveum.midpoint.repo.sql.data.common.id.RCaseWorkItemReferenceId; import com.evolveum.midpoint.repo.sql.data.common.other.RObjectType; @@ -24,6 +23,7 @@ import com.evolveum.midpoint.repo.sql.query2.definition.NotQueryable; import com.evolveum.midpoint.repo.sql.util.MidPointSingleTablePersister; import com.evolveum.midpoint.repo.sql.util.RUtil; +import com.evolveum.midpoint.schema.RelationRegistry; import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectReferenceType; import org.apache.commons.lang.Validate; import org.hibernate.annotations.ForeignKey; @@ -124,15 +124,15 @@ public RObjectType getType() { return super.getType(); } - public static Set safeListReferenceToSet(List list, PrismContext prismContext, - RCaseWorkItem owner) { + public static Set safeListReferenceToSet(List list, + RCaseWorkItem owner, RelationRegistry relationRegistry) { Set set = new HashSet<>(); if (list == null || list.isEmpty()) { return set; } for (ObjectReferenceType ref : list) { - RCaseWorkItemReference rRef = jaxbRefToRepo(ref, prismContext, owner); + RCaseWorkItemReference rRef = jaxbRefToRepo(ref, owner, relationRegistry); if (rRef != null) { set.add(rRef); } @@ -140,8 +140,8 @@ public static Set safeListReferenceToSet(List safeListReferenceToSet(List list, PrismContext prismContext, - RAccessCertificationWorkItem owner) { + public static Set safeListReferenceToSet(List list, + RAccessCertificationWorkItem owner, RelationRegistry relationRegistry) { Set set = new HashSet<>(); if (list == null || list.isEmpty()) { return set; } for (ObjectReferenceType ref : list) { - RCertWorkItemReference rRef = jaxbRefToRepo(ref, prismContext, owner); + RCertWorkItemReference rRef = jaxbRefToRepo(ref, owner, relationRegistry); if (rRef != null) { set.add(rRef); } @@ -152,8 +152,8 @@ public static Set safeListReferenceToSet(List safeListReferenceToSet(List list, PrismContext prismContext, - RAssignment owner, RCReferenceOwner refOwner) { + public static Set safeListReferenceToSet(List list, + RAssignment owner, RCReferenceOwner refOwner, RelationRegistry relationRegistry) { Set set = new HashSet<>(); if (list == null || list.isEmpty()) { return set; } for (ObjectReferenceType ref : list) { - RAssignmentReference rRef = jaxbRefToRepo(ref, prismContext, owner, refOwner); + RAssignmentReference rRef = jaxbRefToRepo(ref, owner, refOwner, relationRegistry); if (rRef != null) { set.add(rRef); } @@ -148,8 +150,8 @@ public static Set safeListReferenceToSet(List void handleObjectCommonAttributes(Class type, idGenerator.generate(prismObject); // normalize all relations - ObjectTypeUtil.normalizeAllRelations(prismObject); + ObjectTypeUtil.normalizeAllRelations(prismObject, relationRegistry); // full object column will be updated later } @@ -396,7 +392,7 @@ private void handleObjectTextInfoChanges(Class type, C } Set infos = RObjectTextInfo.createItemsSet((ObjectType) prismObject.asObjectable(), object, - new RepositoryContext(repositoryService, prismContext, extItemDictionary)); + new RepositoryContext(repositoryService, prismContext, relationRegistry, extItemDictionary)); if (infos == null || infos.isEmpty()) { object.getTextInfoItems().clear(); @@ -914,7 +910,9 @@ private Collection processDeltaValues(Collection results = new ArrayList(); for (PrismValue value : values) { MapperContext context = new MapperContext(); - context.setRepositoryContext(new RepositoryContext(repositoryService, prismContext, extItemDictionary)); + context.setRepositoryContext(new RepositoryContext(repositoryService, prismContext, relationRegistry, + extItemDictionary + )); context.setDelta(delta); context.setOwner(bean); diff --git a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/helpers/ObjectRetriever.java b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/helpers/ObjectRetriever.java index 0162c537240..efa82c18677 100644 --- a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/helpers/ObjectRetriever.java +++ b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/helpers/ObjectRetriever.java @@ -31,7 +31,6 @@ import com.evolveum.midpoint.repo.sql.data.common.any.RExtItem; import com.evolveum.midpoint.repo.sql.data.common.any.RItemKind; import com.evolveum.midpoint.repo.sql.data.common.dictionary.ExtItemDictionary; -import com.evolveum.midpoint.repo.sql.data.common.enums.ROperationResultStatus; import com.evolveum.midpoint.repo.sql.data.common.type.RObjectExtensionType; import com.evolveum.midpoint.repo.sql.query.QueryException; import com.evolveum.midpoint.repo.sql.query.RQuery; @@ -85,6 +84,7 @@ public class ObjectRetriever { @Autowired private BaseHelper baseHelper; @Autowired private NameResolutionHelper nameResolutionHelper; @Autowired private PrismContext prismContext; + @Autowired private RelationRegistry relationRegistry; @Autowired private ExtItemDictionary extItemDictionary; @Autowired @Qualifier("repositoryService") @@ -320,7 +320,7 @@ public int countObjectsAttempt(Class type, ObjectQuery longCount = (Number) sqlQuery.uniqueResult(); } else { RQuery rQuery; - QueryEngine2 engine = new QueryEngine2(getConfiguration(), extItemDictionary, prismContext); + QueryEngine2 engine = new QueryEngine2(getConfiguration(), extItemDictionary, prismContext, relationRegistry); rQuery = engine.interpret(query, type, options, true, session); longCount = (Number) rQuery.uniqueResult(); @@ -352,7 +352,7 @@ public int countContainersAttempt(Class type, Objec try { session = baseHelper.beginReadOnlyTransaction(); - QueryEngine2 engine = new QueryEngine2(getConfiguration(), extItemDictionary, prismContext); + QueryEngine2 engine = new QueryEngine2(getConfiguration(), extItemDictionary, prismContext, relationRegistry); RQuery rQuery = engine.interpret(query, type, options, true, session); Number longCount = (Number) rQuery.uniqueResult(); LOGGER.trace("Found {} objects.", longCount); @@ -376,7 +376,7 @@ public SearchResultList> searchObjectsAtte session = baseHelper.beginReadOnlyTransaction(); RQuery rQuery; - QueryEngine2 engine = new QueryEngine2(getConfiguration(), extItemDictionary, prismContext); + QueryEngine2 engine = new QueryEngine2(getConfiguration(), extItemDictionary, prismContext, relationRegistry); rQuery = engine.interpret(query, type, options, false, session); @SuppressWarnings({"unchecked", "raw"}) @@ -440,7 +440,7 @@ public SearchResultList searchContainersAttempt(Cla try { session = baseHelper.beginReadOnlyTransaction(); - QueryEngine2 engine = new QueryEngine2(getConfiguration(), extItemDictionary, prismContext); + QueryEngine2 engine = new QueryEngine2(getConfiguration(), extItemDictionary, prismContext, relationRegistry); RQuery rQuery = engine.interpret(query, type, options, false, session); if (cases) { @@ -492,7 +492,7 @@ public SearchResultList searchContainersAttempt(Cla baseHelper.cleanupSessionAndResult(session, result); } - list.forEach(c -> ObjectTypeUtil.normalizeAllRelations(c.asPrismContainerValue())); + list.forEach(c -> ObjectTypeUtil.normalizeAllRelations(c.asPrismContainerValue(), relationRegistry)); return new SearchResultList<>(list); } @@ -594,7 +594,7 @@ private PrismObject updateLoadedObject(GetObjectResult nameResolutionHelper.resolveNamesIfRequested(session, prismObject.getValue(), options); validateObjectType(prismObject, type); - ObjectTypeUtil.normalizeAllRelations(prismObject); + ObjectTypeUtil.normalizeAllRelations(prismObject, relationRegistry); return prismObject; } @@ -739,7 +739,7 @@ public void searchObjectsIterativeAttempt(Class type, try { session = baseHelper.beginReadOnlyTransaction(); RQuery rQuery; - QueryEngine2 engine = new QueryEngine2(getConfiguration(), extItemDictionary, prismContext); + QueryEngine2 engine = new QueryEngine2(getConfiguration(), extItemDictionary, prismContext, relationRegistry); rQuery = engine.interpret(query, type, options, false, session); ScrollableResults results = rQuery.scroll(ScrollMode.FORWARD_ONLY); @@ -938,7 +938,7 @@ public RepositoryQueryDiagResponse executeQueryDiagnosticsRequest(RepositoryQuer final org.hibernate.Query query; final boolean isMidpointQuery = request.getImplementationLevelQuery() == null; if (isMidpointQuery) { - QueryEngine2 engine = new QueryEngine2(getConfiguration(), extItemDictionary, prismContext); + QueryEngine2 engine = new QueryEngine2(getConfiguration(), extItemDictionary, prismContext, relationRegistry); RQueryImpl rQuery = (RQueryImpl) engine.interpret(request.getQuery(), request.getType(), null, false, session); query = rQuery.getQuery(); implementationLevelQuery = query.getQueryString(); diff --git a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/helpers/ObjectUpdater.java b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/helpers/ObjectUpdater.java index b22fdac41d2..78d5c012761 100644 --- a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/helpers/ObjectUpdater.java +++ b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/helpers/ObjectUpdater.java @@ -35,6 +35,7 @@ import com.evolveum.midpoint.repo.sql.util.PrismIdentifierGenerator; import com.evolveum.midpoint.repo.sql.util.RUtil; import com.evolveum.midpoint.schema.GetOperationOptions; +import com.evolveum.midpoint.schema.RelationRegistry; import com.evolveum.midpoint.schema.RetrieveOption; import com.evolveum.midpoint.schema.SelectorOptions; import com.evolveum.midpoint.schema.result.OperationResult; @@ -76,29 +77,15 @@ public class ObjectUpdater { @Qualifier("repositoryService") private RepositoryService repositoryService; - @Autowired - private BaseHelper baseHelper; - - @Autowired - private ObjectRetriever objectRetriever; - - @Autowired - private LookupTableHelper lookupTableHelper; - - @Autowired - private CertificationCaseHelper caseHelper; - - @Autowired - private OrgClosureManager closureManager; - - @Autowired - private ObjectDeltaUpdater objectDeltaUpdater; - - @Autowired - private PrismContext prismContext; - - @Autowired - private ExtItemDictionary extItemDictionary; + @Autowired private BaseHelper baseHelper; + @Autowired private ObjectRetriever objectRetriever; + @Autowired private LookupTableHelper lookupTableHelper; + @Autowired private CertificationCaseHelper caseHelper; + @Autowired private OrgClosureManager closureManager; + @Autowired private ObjectDeltaUpdater objectDeltaUpdater; + @Autowired private PrismContext prismContext; + @Autowired private RelationRegistry relationRegistry; + @Autowired private ExtItemDictionary extItemDictionary; public String addObjectAttempt(PrismObject object, RepoAddOptions options, OperationResult result) throws ObjectAlreadyExistsException, SchemaException { @@ -117,7 +104,7 @@ public String addObjectAttempt(PrismObject object, Rep if (LOGGER.isTraceEnabled()) { LOGGER.trace("Object\n{}", object.debugDump()); } - ObjectTypeUtil.normalizeAllRelations(object); + ObjectTypeUtil.normalizeAllRelations(object, relationRegistry); LOGGER.trace("Translating JAXB to data type."); PrismIdentifierGenerator.Operation operation = options.isOverwrite() ? @@ -432,7 +419,7 @@ public void modifyObjectAttempt(Class type, String oid // merge and update object LOGGER.trace("Translating JAXB to data type."); - ObjectTypeUtil.normalizeAllRelations(prismObject); + ObjectTypeUtil.normalizeAllRelations(prismObject, relationRegistry); PrismIdentifierGenerator idGenerator = new PrismIdentifierGenerator<>(PrismIdentifierGenerator.Operation.MODIFY); RObject rObject = createDataObjectFromJAXB(prismObject, idGenerator); rObject.setVersion(rObject.getVersion() + 1); @@ -547,9 +534,12 @@ public RObject createDataObjectFromJAXB(PrismObject pr Class clazz = ClassMapper.getHQLTypeClass(object.getClass()); try { rObject = clazz.newInstance(); + // Note that methods named "copyFromJAXB" that were _not_ called from this point were renamed e.g. to "fromJaxb", + // in order to avoid confusion with dynamically called "copyFromJAXB" method. Method method = clazz.getMethod("copyFromJAXB", object.getClass(), clazz, RepositoryContext.class, IdGeneratorResult.class); - method.invoke(clazz, object, rObject, new RepositoryContext(repositoryService, prismContext, extItemDictionary), generatorResult); + method.invoke(clazz, object, rObject, new RepositoryContext(repositoryService, prismContext, relationRegistry, + extItemDictionary), generatorResult); } catch (Exception ex) { SerializationRelatedException serializationException = ExceptionUtil.findCause(ex, SerializationRelatedException.class); if (serializationException != null) { diff --git a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/helpers/mapper/ActivationMapper.java b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/helpers/mapper/ActivationMapper.java index d2f8a27d83b..6f51b163811 100644 --- a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/helpers/mapper/ActivationMapper.java +++ b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/helpers/mapper/ActivationMapper.java @@ -31,7 +31,7 @@ public class ActivationMapper implements Mapper { public RActivation map(ActivationType input, MapperContext context) { try { RActivation ractivation = new RActivation(); - RActivation.copyFromJAXB(input, ractivation, null); + RActivation.fromJaxb(input, ractivation, null); return ractivation; } catch (DtoTranslationException ex) { diff --git a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/helpers/mapper/AssignmentMapper.java b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/helpers/mapper/AssignmentMapper.java index 2d04bef5d88..a2a072f6a95 100644 --- a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/helpers/mapper/AssignmentMapper.java +++ b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/helpers/mapper/AssignmentMapper.java @@ -48,7 +48,7 @@ public RAssignment map(AssignmentType input, MapperContext context) { RObject owner = (RObject) context.getOwner(); try { - RAssignment.copyFromJAXB(input, ass, owner, context.getRepositoryContext()); + RAssignment.fromJaxb(input, ass, owner, context.getRepositoryContext()); } catch (DtoTranslationException ex) { throw new SystemException("Couldn't translate assignment to entity", ex); } diff --git a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/helpers/mapper/AutoassignSpecificationMapper.java b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/helpers/mapper/AutoassignSpecificationMapper.java index 8090b065aed..e5fb892b854 100644 --- a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/helpers/mapper/AutoassignSpecificationMapper.java +++ b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/helpers/mapper/AutoassignSpecificationMapper.java @@ -28,7 +28,7 @@ public class AutoassignSpecificationMapper implements Mapper { public Metadata map(MetadataType input, MapperContext context) { Metadata metadata = (Metadata) context.getOwner(); try { - MetadataFactory.fromJAXB(input, metadata, context.getPrismContext()); + MetadataFactory.fromJAXB(input, metadata, context.getPrismContext(), context.getRelationRegistry()); } catch (DtoTranslationException ex) { throw new SystemException("Couldn't translate metadata to entity"); } diff --git a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/helpers/mapper/ObjectReferenceMapper.java b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/helpers/mapper/ObjectReferenceMapper.java index fe8b3345a1e..f6b2cb1ef0f 100644 --- a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/helpers/mapper/ObjectReferenceMapper.java +++ b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/helpers/mapper/ObjectReferenceMapper.java @@ -44,7 +44,7 @@ public RObjectReference map(Referencable input, MapperContext context) { objectRef.setupReferenceValue(input.asReferenceValue()); } - ObjectTypeUtil.normalizeRelation(objectRef); + ObjectTypeUtil.normalizeRelation(objectRef, context.getRelationRegistry()); RObject owner = (RObject) context.getOwner(); @@ -54,7 +54,7 @@ public RObjectReference map(Referencable input, MapperContext context) { NameItemPathSegment last = named.lastNamed(); RReferenceOwner refType = RReferenceOwner.getOwnerByQName(jaxbObjectType, last.getName()); - return RUtil.jaxbRefToRepo(objectRef, context.getPrismContext(), owner, refType); + return RUtil.jaxbRefToRepo(objectRef, owner, refType, context.getRelationRegistry()); } } diff --git a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/helpers/mapper/OperationExecutionMapper.java b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/helpers/mapper/OperationExecutionMapper.java index 7a6d8238bb7..6e709d70bd0 100644 --- a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/helpers/mapper/OperationExecutionMapper.java +++ b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/helpers/mapper/OperationExecutionMapper.java @@ -35,7 +35,7 @@ public ROperationExecution map(OperationExecutionType input, MapperContext conte RObject owner = (RObject) context.getOwner(); try { - ROperationExecution.copyFromJAXB(input, execution, owner, context.getRepositoryContext()); + ROperationExecution.fromJaxb(input, execution, owner, context.getRepositoryContext()); } catch (DtoTranslationException ex) { throw new SystemException("Couldn't translate trigger to entity", ex); } diff --git a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/helpers/mapper/OperationalStateMapper.java b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/helpers/mapper/OperationalStateMapper.java index 1b5057965ef..781dd41823b 100644 --- a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/helpers/mapper/OperationalStateMapper.java +++ b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/helpers/mapper/OperationalStateMapper.java @@ -31,7 +31,7 @@ public class OperationalStateMapper implements Mapper O map(I input, Class outputType, MapperContext context) { if (context == null) { context = new MapperContext(); } - context.setRepositoryContext(new RepositoryContext(repositoryService, prismContext, extItemDictionary)); + context.setRepositoryContext(new RepositoryContext(repositoryService, prismContext, relationRegistry, extItemDictionary)); Key key = buildKey(input.getClass(), outputType); Mapper mapper = mappers.get(key); diff --git a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/query2/InterpretationContext.java b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/query2/InterpretationContext.java index 3c8b5415a4c..794ab27256d 100644 --- a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/query2/InterpretationContext.java +++ b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/query2/InterpretationContext.java @@ -23,6 +23,7 @@ import com.evolveum.midpoint.repo.sql.query2.definition.JpaEntityDefinition; import com.evolveum.midpoint.repo.sql.query2.hqm.RootHibernateQuery; import com.evolveum.midpoint.repo.sql.query2.resolution.ItemPathResolver; +import com.evolveum.midpoint.schema.RelationRegistry; import com.evolveum.midpoint.util.logging.Trace; import com.evolveum.midpoint.util.logging.TraceManager; import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectType; @@ -39,6 +40,7 @@ public class InterpretationContext { private QueryInterpreter2 interpreter; private PrismContext prismContext; + private RelationRegistry relationRegistry; private Session session; private ExtItemDictionary extItemDictionary; @@ -56,17 +58,20 @@ public class InterpretationContext { private JpaEntityDefinition rootEntityDefinition; public InterpretationContext(QueryInterpreter2 interpreter, Class type, - PrismContext prismContext, ExtItemDictionary extItemDictionary, Session session) throws QueryException { + PrismContext prismContext, RelationRegistry relationRegistry, + ExtItemDictionary extItemDictionary, Session session) throws QueryException { Validate.notNull(interpreter, "interpreter"); Validate.notNull(type, "type"); Validate.notNull(prismContext, "prismContext"); + Validate.notNull(relationRegistry, "relationRegistry"); Validate.notNull(extItemDictionary, "extItemDictionary"); Validate.notNull(session, "session"); this.interpreter = interpreter; this.type = type; this.prismContext = prismContext; + this.relationRegistry = relationRegistry; this.extItemDictionary = extItemDictionary; this.session = session; @@ -85,6 +90,10 @@ public PrismContext getPrismContext() { return prismContext; } + public RelationRegistry getRelationRegistry() { + return relationRegistry; + } + public Session getSession() { return session; } diff --git a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/query2/QueryEngine2.java b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/query2/QueryEngine2.java index 51d9f3106de..306a60bb02e 100644 --- a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/query2/QueryEngine2.java +++ b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/query2/QueryEngine2.java @@ -25,6 +25,7 @@ import com.evolveum.midpoint.repo.sql.query.RQuery; import com.evolveum.midpoint.repo.sql.query2.hqm.RootHibernateQuery; import com.evolveum.midpoint.schema.GetOperationOptions; +import com.evolveum.midpoint.schema.RelationRegistry; import com.evolveum.midpoint.schema.SelectorOptions; import com.evolveum.midpoint.util.DebugUtil; import com.evolveum.midpoint.util.logging.Trace; @@ -44,11 +45,14 @@ public class QueryEngine2 { private SqlRepositoryConfiguration repoConfiguration; private ExtItemDictionary extItemDictionary; private PrismContext prismContext; + private final RelationRegistry relationRegistry; - public QueryEngine2(SqlRepositoryConfiguration config, ExtItemDictionary extItemDictionary, PrismContext prismContext) { + public QueryEngine2(SqlRepositoryConfiguration config, ExtItemDictionary extItemDictionary, PrismContext prismContext, + RelationRegistry relationRegistry) { this.repoConfiguration = config; this.extItemDictionary = extItemDictionary; this.prismContext = prismContext; + this.relationRegistry = relationRegistry; } public RQuery interpret(ObjectQuery query, Class type, @@ -56,7 +60,7 @@ public RQuery interpret(ObjectQuery query, Class type, boolean countingObjects, Session session) throws QueryException { QueryInterpreter2 interpreter = new QueryInterpreter2(repoConfiguration, extItemDictionary); - RootHibernateQuery hibernateQuery = interpreter.interpret(query, type, options, prismContext, countingObjects, session); + RootHibernateQuery hibernateQuery = interpreter.interpret(query, type, options, prismContext, relationRegistry, countingObjects, session); Query hqlQuery = hibernateQuery.getAsHqlQuery(session); if (LOGGER.isTraceEnabled()) { diff --git a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/query2/QueryInterpreter2.java b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/query2/QueryInterpreter2.java index c8a11b58f90..00543d67c6d 100644 --- a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/query2/QueryInterpreter2.java +++ b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/query2/QueryInterpreter2.java @@ -40,6 +40,7 @@ import com.evolveum.midpoint.repo.sql.query2.restriction.*; import com.evolveum.midpoint.repo.sql.util.*; import com.evolveum.midpoint.schema.GetOperationOptions; +import com.evolveum.midpoint.schema.RelationRegistry; import com.evolveum.midpoint.schema.SelectorOptions; import com.evolveum.midpoint.util.logging.Trace; import com.evolveum.midpoint.util.logging.TraceManager; @@ -48,7 +49,6 @@ import com.evolveum.midpoint.xml.ns._public.common.common_3.CaseWorkItemType; import org.apache.commons.lang3.StringUtils; import org.hibernate.Session; -import org.hibernate.criterion.Projections; import org.jetbrains.annotations.NotNull; import java.util.*; @@ -110,12 +110,12 @@ public SqlRepositoryConfiguration getRepoConfiguration() { } public RootHibernateQuery interpret(ObjectQuery query, @NotNull Class type, - Collection> options, @NotNull PrismContext prismContext, - boolean countingObjects, @NotNull Session session) throws QueryException { + Collection> options, @NotNull PrismContext prismContext, + @NotNull RelationRegistry relationRegistry, boolean countingObjects, @NotNull Session session) throws QueryException { boolean distinctRequested = GetOperationOptions.isDistinct(SelectorOptions.findRootOptions(options)); LOGGER.trace("Interpreting query for type '{}' (counting={}, distinctRequested={}), query:\n{}", type, countingObjects, distinctRequested, query); - InterpretationContext context = new InterpretationContext(this, type, prismContext, extItemDictionary, session); + InterpretationContext context = new InterpretationContext(this, type, prismContext, relationRegistry, extItemDictionary, session); interpretQueryFilter(context, query); String rootAlias = context.getHibernateQuery().getPrimaryEntityAlias(); ResultStyle resultStyle = getResultStyle(context); @@ -144,7 +144,8 @@ u.oid in (select distinct u.oid from RUser u where ...) hibernateQuery.addProjectionElementsFor(resultStyle.getIdentifiers(rootAlias)); if (distinct && !distinctBlobCapable) { String subqueryText = "\n" + hibernateQuery.getAsHqlText(2, true); - InterpretationContext wrapperContext = new InterpretationContext(this, type, prismContext, extItemDictionary, session); + InterpretationContext wrapperContext = new InterpretationContext(this, type, prismContext, relationRegistry, + extItemDictionary, session); interpretPagingAndSorting(wrapperContext, query, false); RootHibernateQuery wrapperQuery = wrapperContext.getHibernateQuery(); if (repoConfiguration.isUsingSQLServer() && resultStyle.getIdentifiers("").size() > 1) { diff --git a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/query2/restriction/OrgRestriction.java b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/query2/restriction/OrgRestriction.java index e96541e6fb5..a9a5fde7209 100644 --- a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/query2/restriction/OrgRestriction.java +++ b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/query2/restriction/OrgRestriction.java @@ -58,7 +58,7 @@ public Condition interpret() throws QueryException { String relationParamName = ""; QName relation = filter.getOrgRef().getRelation(); if (doesRelationRestrictionExist(relation)) { - relationParamName = hibernateQuery.addParameter("relation", ReferenceRestriction.getRelationsToTest(relation)); + relationParamName = hibernateQuery.addParameter("relation", ReferenceRestriction.getRelationsToTest(relation, context)); } String oidQueryText; // oid in ... switch (filter.getScope()) { diff --git a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/query2/restriction/ReferenceRestriction.java b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/query2/restriction/ReferenceRestriction.java index df04f5b3d96..ac3ccb39cfa 100644 --- a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/query2/restriction/ReferenceRestriction.java +++ b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/query2/restriction/ReferenceRestriction.java @@ -33,8 +33,6 @@ import com.evolveum.midpoint.repo.sql.query2.hqm.condition.OrCondition; import com.evolveum.midpoint.repo.sql.util.ClassMapper; import com.evolveum.midpoint.repo.sql.util.RUtil; -import com.evolveum.midpoint.schema.constants.SchemaConstants; -import com.evolveum.midpoint.schema.util.ObjectTypeUtil; import com.evolveum.midpoint.util.MiscUtil; import com.evolveum.midpoint.util.QNameUtil; import com.evolveum.midpoint.util.exception.SchemaException; @@ -45,8 +43,7 @@ import javax.xml.namespace.QName; import java.util.*; - -import static com.evolveum.midpoint.repo.sql.util.RUtil.qnameToString; +import java.util.stream.Collectors; /** * @author lazyman @@ -85,7 +82,7 @@ public Condition interpretInternal() throws QueryException { } oids.add(value.getOid()); if (value.getRelation() == null) { - relations.add(SchemaConstants.ORG_DEFAULT); + relations.add(context.getPrismContext().getDefaultRelation()); } else { // we intentionally don't normalize relations namespaces, to be able to do namespace-insensitive searches // so the caller is responsible to unify namespaces if he needs to optimize queries (use IN instead of OR) @@ -135,7 +132,7 @@ private Condition createRefCondition(RootHibernateQuery hibernateQuery, AndCondition conjunction = hibernateQuery.createAnd(); conjunction.add(hibernateQuery.createEqOrInOrNull(hqlDataInstance.getHqlPath() + "." + TARGET_OID_HQL_PROPERTY, oids)); - List relationsToTest = getRelationsToTest(relation); + List relationsToTest = getRelationsToTest(relation, getContext()); if (!relationsToTest.isEmpty()) { conjunction.add(hibernateQuery.createEqOrInOrNull(hqlPath + "." + RELATION_HQL_PROPERTY, relationsToTest)); } @@ -151,26 +148,13 @@ private Condition createRefCondition(RootHibernateQuery hibernateQuery, // // Return: empty list means "nothing to test". @NotNull - static List getRelationsToTest(QName relation) { - if (ObjectTypeUtil.isDefaultRelation(relation)) { - // Return references without relation or with "default" relation - return Arrays.asList(RUtil.QNAME_DELIMITER, qnameToString(SchemaConstants.ORG_DEFAULT)); - } else if (QNameUtil.match(relation, PrismConstants.Q_ANY)) { - // Return all relations => no restriction - return Collections.emptyList(); - } else { - // return references with specific relation - List rv = new ArrayList<>(); - rv.add(qnameToString(relation)); - if (QNameUtil.noNamespace(relation)) { - rv.add(qnameToString(QNameUtil.setNamespaceIfMissing(relation, SchemaConstants.NS_ORG, null))); - } else if (SchemaConstants.NS_ORG.equals(relation.getNamespaceURI())) { - rv.add(qnameToString(new QName(relation.getLocalPart()))); - } else { - // non-empty non-standard NS => nothing to add - } - return rv; - } + static List getRelationsToTest(QName relation, InterpretationContext context) { + if (QNameUtil.match(relation, PrismConstants.Q_ANY)) { + return Collections.emptyList(); // Return all relations => no restriction + } else { + Collection aliases = context.getRelationRegistry().getAliases(relation); + return aliases.stream().map(RUtil::qnameToString).collect(Collectors.toList()); + } } private Condition handleEqInOrNull(RootHibernateQuery hibernateQuery, String propertyName, Object value) { diff --git a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/util/RUtil.java b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/util/RUtil.java index beab9676051..805d980653f 100644 --- a/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/util/RUtil.java +++ b/repo/repo-sql-impl/src/main/java/com/evolveum/midpoint/repo/sql/util/RUtil.java @@ -28,13 +28,13 @@ import com.evolveum.midpoint.repo.sql.data.common.container.RAssignment; import com.evolveum.midpoint.repo.sql.data.common.container.RAssignmentReference; import com.evolveum.midpoint.repo.sql.data.common.container.RTrigger; -import com.evolveum.midpoint.repo.sql.data.common.embedded.REmbeddedNamedReference; import com.evolveum.midpoint.repo.sql.data.common.embedded.REmbeddedReference; import com.evolveum.midpoint.repo.sql.data.common.embedded.RPolyString; import com.evolveum.midpoint.repo.sql.data.common.enums.ROperationResultStatus; import com.evolveum.midpoint.repo.sql.data.common.enums.SchemaEnum; import com.evolveum.midpoint.repo.sql.data.common.other.RObjectType; import com.evolveum.midpoint.repo.sql.data.common.other.RReferenceOwner; +import com.evolveum.midpoint.schema.RelationRegistry; import com.evolveum.midpoint.util.DOMUtil; import com.evolveum.midpoint.util.exception.SchemaException; import com.evolveum.midpoint.util.exception.SystemException; @@ -158,15 +158,15 @@ public static List safeSetReferencesToList(Set list, PrismContext prismContext, - RObject owner, RReferenceOwner refOwner) { + public static Set safeListReferenceToSet(List list, + RObject owner, RReferenceOwner refOwner, RelationRegistry relationRegistry) { Set set = new HashSet<>(); if (list == null || list.isEmpty()) { return set; } for (ObjectReferenceType ref : list) { - RObjectReference rRef = RUtil.jaxbRefToRepo(ref, prismContext, owner, refOwner); + RObjectReference rRef = RUtil.jaxbRefToRepo(ref, owner, refOwner, relationRegistry); if (rRef != null) { set.add(rRef); } @@ -174,8 +174,8 @@ public static Set safeListReferenceToSet(List list, PrismCo return set; } - public static RObjectReference jaxbRefToRepo(ObjectReferenceType reference, PrismContext prismContext, - RObject owner, RReferenceOwner refOwner) { + public static RObjectReference jaxbRefToRepo(ObjectReferenceType reference, + RObject owner, RReferenceOwner refOwner, RelationRegistry relationRegistry) { if (reference == null) { return null; } @@ -186,31 +186,31 @@ public static RObjectReference jaxbRefToRepo(ObjectReferenceType reference, Pris RObjectReference repoRef = new RObjectReference(); repoRef.setReferenceType(refOwner); repoRef.setOwner(owner); - RObjectReference.copyFromJAXB(reference, repoRef); + RObjectReference.copyFromJAXB(reference, repoRef, relationRegistry); return repoRef; } public static REmbeddedReference jaxbRefToEmbeddedRepoRef(ObjectReferenceType jaxb, - PrismContext prismContext) { + RelationRegistry relationRegistry) { if (jaxb == null) { return null; } REmbeddedReference ref = new REmbeddedReference(); - REmbeddedReference.copyFromJAXB(jaxb, ref); + REmbeddedReference.fromJaxb(jaxb, ref, relationRegistry); return ref; } - public static REmbeddedNamedReference jaxbRefToEmbeddedNamedRepoRef(ObjectReferenceType jaxb) { - if (jaxb == null) { - return null; - } - REmbeddedNamedReference ref = new REmbeddedNamedReference(); - REmbeddedNamedReference.copyFromJAXB(jaxb, ref); - - return ref; - } +// public static REmbeddedNamedReference jaxbRefToEmbeddedNamedRepoRef(ObjectReferenceType jaxb) { +// if (jaxb == null) { +// return null; +// } +// REmbeddedNamedReference ref = new REmbeddedNamedReference(); +// REmbeddedNamedReference.copyFromJAXB(jaxb, ref); +// +// return ref; +// } public static Integer getIntegerFromString(String val) { if (val == null || !val.matches("[0-9]+")) { diff --git a/repo/repo-test-util/src/main/java/com/evolveum/midpoint/test/AbstractIntegrationTest.java b/repo/repo-test-util/src/main/java/com/evolveum/midpoint/test/AbstractIntegrationTest.java index 614e7658246..ffa3c7737cd 100644 --- a/repo/repo-test-util/src/main/java/com/evolveum/midpoint/test/AbstractIntegrationTest.java +++ b/repo/repo-test-util/src/main/java/com/evolveum/midpoint/test/AbstractIntegrationTest.java @@ -1392,36 +1392,7 @@ protected void assertUserNoPassword(PrismObject user) throws Encryptio } protected void assertProtectedString(String message, String expectedClearValue, ProtectedStringType actualValue, CredentialsStorageTypeType storageType) throws EncryptionException, SchemaException { - switch (storageType) { - - case NONE: - assertNull(message+": unexpected value: "+actualValue, actualValue); - break; - - case ENCRYPTION: - assertNotNull(message+": no value", actualValue); - assertTrue(message+": unencrypted value: "+actualValue, actualValue.isEncrypted()); - String actualClearPassword = protector.decryptString(actualValue); - assertEquals(message+": wrong value", expectedClearValue, actualClearPassword); - assertFalse(message+": unexpected hashed value: "+actualValue, actualValue.isHashed()); - assertNull(message+": unexpected clear value: "+actualValue, actualValue.getClearValue()); - break; - - case HASHING: - assertNotNull(message+": no value", actualValue); - assertTrue(message+": value not hashed: "+actualValue, actualValue.isHashed()); - ProtectedStringType expectedPs = new ProtectedStringType(); - expectedPs.setClearValue(expectedClearValue); - assertTrue(message+": hash does not match, expected "+expectedClearValue+", but was "+actualValue, - protector.compare(actualValue, expectedPs)); - assertFalse(message+": unexpected encrypted value: "+actualValue, actualValue.isEncrypted()); - assertNull(message+": unexpected clear value: "+actualValue, actualValue.getClearValue()); - break; - - default: - throw new IllegalArgumentException("Unknown storage "+storageType); - } - + IntegrationTestTools.assertProtectedString(message, expectedClearValue, actualValue, storageType, protector); } protected boolean compareProtectedString(String expectedClearValue, ProtectedStringType actualValue, CredentialsStorageTypeType storageType) throws EncryptionException, SchemaException { @@ -2086,7 +2057,7 @@ protected void assertRoleMembershipRef(PrismObject focu if (!expectedOid.equals(hasRef.getOid())) { return false; } - if (!ObjectTypeUtil.relationMatches(relation, hasRef.getRelation())) { + if (!prismContext.relationMatches(relation, hasRef.getRelation())) { return false; } return true; @@ -2358,10 +2329,19 @@ protected ItemPath getAttributePath(PrismObject resource, String a return new ItemPath(ShadowType.F_ATTRIBUTES, getAttributeQName(resource, attributeLocalName)); } - protected ObjectDelta createAccountPaswordDelta(String shadowOid, String newPassword) { - ProtectedStringType userPasswordPs = new ProtectedStringType(); - userPasswordPs.setClearValue(newPassword); - return ObjectDelta.createModificationReplaceProperty(ShadowType.class, shadowOid, SchemaConstants.PATH_PASSWORD_VALUE, prismContext, userPasswordPs); + protected ObjectDelta createAccountPaswordDelta(String shadowOid, String newPassword, String oldPassword) throws SchemaException { + ProtectedStringType newPasswordPs = new ProtectedStringType(); + newPasswordPs.setClearValue(newPassword); + ProtectedStringType oldPasswordPs = null; + if (oldPassword != null) { + oldPasswordPs = new ProtectedStringType(); + oldPasswordPs.setClearValue(oldPassword); + } + return deltaFor(ShadowType.class) + .item(SchemaConstants.PATH_PASSWORD_VALUE) + .oldRealValue(oldPasswordPs) + .replace(newPasswordPs) + .asObjectDelta(shadowOid); } protected PrismObject getShadowRepo(String shadowOid) throws ObjectNotFoundException, SchemaException { diff --git a/repo/repo-test-util/src/main/java/com/evolveum/midpoint/test/IntegrationTestTools.java b/repo/repo-test-util/src/main/java/com/evolveum/midpoint/test/IntegrationTestTools.java index 20af933c452..33864abac35 100644 --- a/repo/repo-test-util/src/main/java/com/evolveum/midpoint/test/IntegrationTestTools.java +++ b/repo/repo-test-util/src/main/java/com/evolveum/midpoint/test/IntegrationTestTools.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010-2017 Evolveum + * Copyright (c) 2010-2018 Evolveum * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,6 +20,8 @@ import com.evolveum.midpoint.common.refinery.RefinedResourceSchema; import com.evolveum.midpoint.common.refinery.RefinedResourceSchemaImpl; import com.evolveum.midpoint.prism.*; +import com.evolveum.midpoint.prism.crypto.EncryptionException; +import com.evolveum.midpoint.prism.crypto.Protector; import com.evolveum.midpoint.prism.delta.ObjectDelta; import com.evolveum.midpoint.prism.match.MatchingRule; import com.evolveum.midpoint.prism.path.ItemPath; @@ -61,6 +63,7 @@ import com.evolveum.midpoint.util.logging.TraceManager; import com.evolveum.midpoint.xml.ns._public.common.common_3.*; import com.evolveum.prism.xml.ns._public.types_3.PolyStringType; +import com.evolveum.prism.xml.ns._public.types_3.ProtectedStringType; import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.lang.StringUtils; @@ -1049,4 +1052,36 @@ public static void clearLog() throws IOException { System.out.println("Log cleared."); } + public static void assertProtectedString(String message, String expectedClearValue, ProtectedStringType actualValue, CredentialsStorageTypeType storageType, Protector protector) throws EncryptionException, SchemaException { + switch (storageType) { + + case NONE: + assertNull(message+": unexpected value: "+actualValue, actualValue); + break; + + case ENCRYPTION: + assertNotNull(message+": no value", actualValue); + assertTrue(message+": unencrypted value: "+actualValue, actualValue.isEncrypted()); + String actualClearPassword = protector.decryptString(actualValue); + assertEquals(message+": wrong value", expectedClearValue, actualClearPassword); + assertFalse(message+": unexpected hashed value: "+actualValue, actualValue.isHashed()); + assertNull(message+": unexpected clear value: "+actualValue, actualValue.getClearValue()); + break; + + case HASHING: + assertNotNull(message+": no value", actualValue); + assertTrue(message+": value not hashed: "+actualValue, actualValue.isHashed()); + ProtectedStringType expectedPs = new ProtectedStringType(); + expectedPs.setClearValue(expectedClearValue); + assertTrue(message+": hash does not match, expected "+expectedClearValue+", but was "+actualValue, + protector.compare(actualValue, expectedPs)); + assertFalse(message+": unexpected encrypted value: "+actualValue, actualValue.isEncrypted()); + assertNull(message+": unexpected clear value: "+actualValue, actualValue.getClearValue()); + break; + + default: + throw new IllegalArgumentException("Unknown storage "+storageType); + } + + } } diff --git a/repo/repo-test-util/src/main/java/com/evolveum/midpoint/test/asserter/AbstractAsserter.java b/repo/repo-test-util/src/main/java/com/evolveum/midpoint/test/asserter/AbstractAsserter.java index bc544bba91a..0645deca846 100644 --- a/repo/repo-test-util/src/main/java/com/evolveum/midpoint/test/asserter/AbstractAsserter.java +++ b/repo/repo-test-util/src/main/java/com/evolveum/midpoint/test/asserter/AbstractAsserter.java @@ -19,6 +19,7 @@ import com.evolveum.midpoint.prism.PrismContext; import com.evolveum.midpoint.prism.PrismObject; +import com.evolveum.midpoint.prism.crypto.Protector; import com.evolveum.midpoint.schema.result.OperationResult; import com.evolveum.midpoint.schema.util.SimpleObjectResolver; import com.evolveum.midpoint.util.exception.ObjectNotFoundException; @@ -35,6 +36,7 @@ public abstract class AbstractAsserter { private RA returnAsserter; private PrismContext prismContext; private SimpleObjectResolver objectResolver; + private Protector protector; public AbstractAsserter() { this(null); @@ -67,6 +69,14 @@ public void setObjectResolver(SimpleObjectResolver objectResolver) { this.objectResolver = objectResolver; } + protected Protector getProtector() { + return protector; + } + + public void setProtector(Protector protector) { + this.protector = protector; + } + protected String getDetails() { return details; } @@ -98,7 +108,8 @@ protected PrismObject resolveObject(Class type, Str abstract protected String desc(); protected void copySetupTo(AbstractAsserter other) { - other.setPrismContext(getPrismContext()); - other.setObjectResolver(getObjectResolver()); + other.setPrismContext(this.getPrismContext()); + other.setObjectResolver(this.getObjectResolver()); + other.setProtector(this.getProtector()); } } diff --git a/repo/repo-test-util/src/main/java/com/evolveum/midpoint/test/asserter/DummyAccountAsserter.java b/repo/repo-test-util/src/main/java/com/evolveum/midpoint/test/asserter/DummyAccountAsserter.java index cc7a2480508..d27392ca27c 100644 --- a/repo/repo-test-util/src/main/java/com/evolveum/midpoint/test/asserter/DummyAccountAsserter.java +++ b/repo/repo-test-util/src/main/java/com/evolveum/midpoint/test/asserter/DummyAccountAsserter.java @@ -78,6 +78,12 @@ public DummyAccountAsserter assertEnabled() { return this; } + @Override + public DummyAccountAsserter assertLastModifier(String expected) { + super.assertLastModifier(expected); + return this; + } + public DummyAccountAsserter assertFullName(String expected) { assertAttribute(DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_FULLNAME_NAME, expected); return this; diff --git a/repo/repo-test-util/src/main/java/com/evolveum/midpoint/test/asserter/DummyObjectAsserter.java b/repo/repo-test-util/src/main/java/com/evolveum/midpoint/test/asserter/DummyObjectAsserter.java index 4afbe7e992a..149771584a5 100644 --- a/repo/repo-test-util/src/main/java/com/evolveum/midpoint/test/asserter/DummyObjectAsserter.java +++ b/repo/repo-test-util/src/main/java/com/evolveum/midpoint/test/asserter/DummyObjectAsserter.java @@ -114,6 +114,11 @@ public DummyObjectAsserter assertEnabled() { return this; } + public DummyObjectAsserter assertLastModifier(String expected) { + assertEquals("Wrong lastModifier in " + desc(), expected, getDummyObjectAssertExists().getLastModifier()); + return this; + } + protected String desc() { if (dummyResourceName == null) { return descWithDetails(dummyObject) + " on default dummy resource"; diff --git a/repo/repo-test-util/src/main/java/com/evolveum/midpoint/test/asserter/UserAsserter.java b/repo/repo-test-util/src/main/java/com/evolveum/midpoint/test/asserter/UserAsserter.java index 8aafdc1f4a5..cf868d8dbdd 100644 --- a/repo/repo-test-util/src/main/java/com/evolveum/midpoint/test/asserter/UserAsserter.java +++ b/repo/repo-test-util/src/main/java/com/evolveum/midpoint/test/asserter/UserAsserter.java @@ -27,16 +27,22 @@ import com.evolveum.midpoint.prism.PrismObject; import com.evolveum.midpoint.prism.PrismReference; +import com.evolveum.midpoint.prism.crypto.EncryptionException; import com.evolveum.midpoint.prism.util.PrismAsserts; +import com.evolveum.midpoint.test.IntegrationTestTools; import com.evolveum.midpoint.util.exception.ObjectNotFoundException; import com.evolveum.midpoint.util.exception.SchemaException; import com.evolveum.midpoint.xml.ns._public.common.common_3.ActivationStatusType; import com.evolveum.midpoint.xml.ns._public.common.common_3.ActivationType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.CredentialsStorageTypeType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.CredentialsType; import com.evolveum.midpoint.xml.ns._public.common.common_3.FocusType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.PasswordType; import com.evolveum.midpoint.xml.ns._public.common.common_3.PendingOperationType; import com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowKindType; import com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowType; import com.evolveum.midpoint.xml.ns._public.common.common_3.UserType; +import com.evolveum.prism.xml.ns._public.types_3.ProtectedStringType; /** * @author semancik @@ -129,6 +135,21 @@ private ActivationType getActivation() { return getObject().asObjectable().getActivation(); } + public UserAsserter assertPassword(String expectedClearPassword) throws SchemaException, EncryptionException { + assertPassword(expectedClearPassword, CredentialsStorageTypeType.ENCRYPTION); + return this; + } + + public UserAsserter assertPassword(String expectedClearPassword, CredentialsStorageTypeType storageType) throws SchemaException, EncryptionException { + CredentialsType creds = getObject().asObjectable().getCredentials(); + assertNotNull("No credentials in "+desc(), creds); + PasswordType password = creds.getPassword(); + assertNotNull("No password in "+desc(), password); + ProtectedStringType protectedActualPassword = password.getValue(); + IntegrationTestTools.assertProtectedString("Password for "+desc(), expectedClearPassword, protectedActualPassword, storageType, getProtector()); + return this; + } + public UserAsserter display() { super.display(); return this; diff --git a/repo/repo-test-util/src/main/resources/ctx-configuration-test-no-repo.xml b/repo/repo-test-util/src/main/resources/ctx-configuration-test-no-repo.xml index 4f90a32761d..53971a1aad9 100644 --- a/repo/repo-test-util/src/main/resources/ctx-configuration-test-no-repo.xml +++ b/repo/repo-test-util/src/main/resources/ctx-configuration-test-no-repo.xml @@ -55,6 +55,8 @@ + + diff --git a/repo/repo-test-util/src/main/resources/ctx-configuration-test.xml b/repo/repo-test-util/src/main/resources/ctx-configuration-test.xml index f0e5b4dfdb8..dca231803d8 100644 --- a/repo/repo-test-util/src/main/resources/ctx-configuration-test.xml +++ b/repo/repo-test-util/src/main/resources/ctx-configuration-test.xml @@ -66,6 +66,8 @@ + + diff --git a/repo/security-enforcer-impl/src/main/java/com/evolveum/midpoint/security/enforcer/impl/SecurityEnforcerImpl.java b/repo/security-enforcer-impl/src/main/java/com/evolveum/midpoint/security/enforcer/impl/SecurityEnforcerImpl.java index 5fbb7409c61..ac6a3989a37 100644 --- a/repo/security-enforcer-impl/src/main/java/com/evolveum/midpoint/security/enforcer/impl/SecurityEnforcerImpl.java +++ b/repo/security-enforcer-impl/src/main/java/com/evolveum/midpoint/security/enforcer/impl/SecurityEnforcerImpl.java @@ -16,13 +16,13 @@ package com.evolveum.midpoint.security.enforcer.impl; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collection; import java.util.List; import java.util.function.Consumer; import javax.xml.namespace.QName; +import com.evolveum.midpoint.schema.RelationRegistry; import org.apache.commons.lang.BooleanUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; @@ -66,9 +66,7 @@ import com.evolveum.midpoint.schema.constants.SchemaConstants; import com.evolveum.midpoint.schema.internals.InternalsConfig; import com.evolveum.midpoint.schema.result.OperationResult; -import com.evolveum.midpoint.schema.util.MiscSchemaUtil; import com.evolveum.midpoint.schema.util.ObjectQueryUtil; -import com.evolveum.midpoint.schema.util.ObjectTypeUtil; import com.evolveum.midpoint.security.api.Authorization; import com.evolveum.midpoint.security.api.AuthorizationConstants; import com.evolveum.midpoint.security.api.MidPointPrincipal; @@ -129,7 +127,8 @@ public class SecurityEnforcerImpl implements SecurityEnforcer { @Autowired private TaskManager taskManager; @Autowired private ExpressionFactory expressionFactory; @Autowired private PrismContext prismContext; - + @Autowired private RelationRegistry relationRegistry; + @Autowired @Qualifier("securityContextManager") private SecurityContextManager securityContextManager; @@ -679,7 +678,7 @@ private boolean isApplicable(SubjectedObjectSelectorType continue; } if (principal.getOid().equals(objectAssignmentTargetRef.getOid())) { - if (QNameUtil.match(SchemaConstants.ORG_DEPUTY, objectAssignmentTargetRef.getRelation())) { + if (relationRegistry.isDelegation(objectAssignmentTargetRef.getRelation())) { found = true; break; } @@ -750,7 +749,7 @@ private boolean isSelf(SubjectedObjectSelectorType spec) throws SchemaException private boolean matchesOrgRelation(PrismObject object, ObjectReferenceType subjectParentOrgRef, OrgRelationObjectSpecificationType specOrgRelation, String autzHumanReadableDesc, String desc) throws SchemaException { - if (!MiscSchemaUtil.compareRelation(specOrgRelation.getSubjectRelation(), subjectParentOrgRef.getRelation())) { + if (!prismContext.relationMatches(specOrgRelation.getSubjectRelation(), subjectParentOrgRef.getRelation())) { return false; } if (BooleanUtils.isTrue(specOrgRelation.isIncludeReferenceOrg()) && subjectParentOrgRef.getOid().equals(object.getOid())) { @@ -783,7 +782,7 @@ private boolean hasParentOrgRef(PrismObject object, St private boolean matchesRoleRelation(PrismObject object, ObjectReferenceType subjectRoleMembershipRef, RoleRelationObjectSpecificationType specRoleRelation, String autzHumanReadableDesc, String desc) throws SchemaException { - if (!MiscSchemaUtil.compareRelation(specRoleRelation.getSubjectRelation(), subjectRoleMembershipRef.getRelation())) { + if (!prismContext.relationMatches(specRoleRelation.getSubjectRelation(), subjectRoleMembershipRef.getRelation())) { return false; } if (BooleanUtils.isTrue(specRoleRelation.isIncludeReferenceRole()) && subjectRoleMembershipRef.getOid().equals(object.getOid())) { @@ -797,7 +796,7 @@ private boolean matchesRoleRelation(PrismObject object if (!subjectRoleMembershipRef.getOid().equals(objectRoleMembershipRef.getOid())) { continue; } - if (!MiscSchemaUtil.compareRelation(specRoleRelation.getObjectRelation(), objectRoleMembershipRef.getRelation())) { + if (!prismContext.relationMatches(specRoleRelation.getObjectRelation(), objectRoleMembershipRef.getRelation())) { continue; } return true; @@ -1254,7 +1253,7 @@ private ObjectFilter preProcessObje ObjectFilter objSpecOrgRelationFilter = null; QName subjectRelation = specOrgRelation.getSubjectRelation(); for (ObjectReferenceType subjectParentOrgRef: principal.getUser().getParentOrgRef()) { - if (MiscSchemaUtil.compareRelation(subjectRelation, subjectParentOrgRef.getRelation())) { + if (prismContext.relationMatches(subjectRelation, subjectParentOrgRef.getRelation())) { S_FilterEntryOrEmpty q = QueryBuilder.queryFor(ObjectType.class, prismContext); S_AtomicFilterExit q2; if (specOrgRelation.getScope() == null || specOrgRelation.getScope() == OrgScopeType.ALL_DESCENDANTS) { @@ -1484,7 +1483,7 @@ private ObjectFilter processRoleRelationFilter(MidPointPrincipal principal, Auth QName subjectRelation = specRoleRelation.getSubjectRelation(); boolean isRoleOidOk = false; for (ObjectReferenceType subjectRoleMembershipRef: principal.getUser().getRoleMembershipRef()) { - if (!MiscSchemaUtil.compareRelation(subjectRelation, subjectRoleMembershipRef.getRelation())) { + if (!prismContext.relationMatches(subjectRelation, subjectRoleMembershipRef.getRelation())) { continue; } if (!PrismReferenceValue.containsOid(queryRoleRefs, subjectRoleMembershipRef.getOid())) { @@ -1533,7 +1532,7 @@ private ObjectFilter applyOwnerFilterOwnerRef(ItemPath ow .item(ownerRefPath, ownerRefDef).ref(principal.getUser().getOid()); // TODO don't understand this code for (ObjectReferenceType subjectParentOrgRef: principal.getUser().getParentOrgRef()) { - if (ObjectTypeUtil.isDefaultRelation(subjectParentOrgRef.getRelation())) { + if (prismContext.isDefaultRelation(subjectParentOrgRef.getRelation())) { builder = builder.or().item(ownerRefPath, ownerRefDef).ref(subjectParentOrgRef.getOid()); } } diff --git a/repo/system-init/src/main/resources/ctx-configuration.xml b/repo/system-init/src/main/resources/ctx-configuration.xml index c6bdc448596..992dc93ca5f 100644 --- a/repo/system-init/src/main/resources/ctx-configuration.xml +++ b/repo/system-init/src/main/resources/ctx-configuration.xml @@ -60,6 +60,7 @@ + diff --git a/repo/task-quartz-impl/src/main/java/com/evolveum/midpoint/task/quartzimpl/TaskManagerQuartzImpl.java b/repo/task-quartz-impl/src/main/java/com/evolveum/midpoint/task/quartzimpl/TaskManagerQuartzImpl.java index afe4c822493..9836bfca612 100644 --- a/repo/task-quartz-impl/src/main/java/com/evolveum/midpoint/task/quartzimpl/TaskManagerQuartzImpl.java +++ b/repo/task-quartz-impl/src/main/java/com/evolveum/midpoint/task/quartzimpl/TaskManagerQuartzImpl.java @@ -38,6 +38,7 @@ import com.evolveum.midpoint.prism.delta.builder.DeltaBuilder; import com.evolveum.midpoint.repo.api.PreconditionViolationException; import com.evolveum.midpoint.repo.api.RepoAddOptions; +import com.evolveum.midpoint.schema.*; import com.evolveum.midpoint.task.api.*; import com.evolveum.midpoint.task.quartzimpl.handlers.PartitioningTaskHandler; import com.evolveum.midpoint.task.quartzimpl.work.WorkStateManager; @@ -71,11 +72,6 @@ import com.evolveum.midpoint.prism.query.builder.S_AtomicFilterEntry; import com.evolveum.midpoint.prism.xml.XmlTypeConverter; import com.evolveum.midpoint.repo.api.RepositoryService; -import com.evolveum.midpoint.schema.GetOperationOptions; -import com.evolveum.midpoint.schema.ResultHandler; -import com.evolveum.midpoint.schema.SearchResultList; -import com.evolveum.midpoint.schema.SearchResultMetadata; -import com.evolveum.midpoint.schema.SelectorOptions; import com.evolveum.midpoint.schema.result.OperationResult; import com.evolveum.midpoint.schema.result.OperationResultStatus; import com.evolveum.midpoint.security.api.SecurityContextManager; @@ -176,6 +172,7 @@ public class TaskManagerQuartzImpl implements TaskManager, BeanFactoryAware { @Autowired private PrismContext prismContext; @Autowired private WorkStateManager workStateManager; @Autowired private WorkersManager workersManager; + @Autowired private RelationRegistry relationRegistry; @Autowired @Qualifier("securityContextManager") @@ -1742,7 +1739,11 @@ public RepositoryService getRepositoryService() { return repositoryService; } - public ExecutionManager getExecutionManager() { + public RelationRegistry getRelationRegistry() { + return relationRegistry; + } + + public ExecutionManager getExecutionManager() { return executionManager; } diff --git a/repo/task-quartz-impl/src/main/java/com/evolveum/midpoint/task/quartzimpl/cluster/ClusterManager.java b/repo/task-quartz-impl/src/main/java/com/evolveum/midpoint/task/quartzimpl/cluster/ClusterManager.java index f022fc73489..f998c994cb6 100644 --- a/repo/task-quartz-impl/src/main/java/com/evolveum/midpoint/task/quartzimpl/cluster/ClusterManager.java +++ b/repo/task-quartz-impl/src/main/java/com/evolveum/midpoint/task/quartzimpl/cluster/ClusterManager.java @@ -213,13 +213,10 @@ public void startClusterManagerThread() { clusterManagerThread.start(); } - - private RepositoryService getRepositoryService() { return taskManager.getRepositoryService(); } - public String dumpNodeInfo(NodeType node) { return node.getNodeIdentifier() + " (" + node.getHostname() + ")"; } @@ -299,6 +296,7 @@ public void checkSystemConfigurationChanged(OperationResult parentResult) { SecurityUtil.setRemoteHostAddressHeaders(config.asObjectable()); getRepositoryService().applyFullTextSearchConfiguration(config.asObjectable().getFullTextSearch()); + taskManager.getRelationRegistry().applyRelationConfiguration(config.asObjectable()); SystemConfigurationTypeUtil.applyOperationResultHandling(config.asObjectable()); } else { if (LOGGER.isTraceEnabled()) { diff --git a/testing/story/src/test/java/com/evolveum/midpoint/testing/story/TestConsistencyMechanism.java b/testing/story/src/test/java/com/evolveum/midpoint/testing/story/TestConsistencyMechanism.java index 61bdfc03ba5..652bb162218 100644 --- a/testing/story/src/test/java/com/evolveum/midpoint/testing/story/TestConsistencyMechanism.java +++ b/testing/story/src/test/java/com/evolveum/midpoint/testing/story/TestConsistencyMechanism.java @@ -2023,7 +2023,7 @@ public void test511AssignAccountMorgan() throws Exception { ConstructionType construction = new ConstructionType(); construction.getAttribute().add(attrDefType); - construction.setResourceRef(ObjectTypeUtil.createObjectRef(resourceTypeOpenDjrepo)); + construction.setResourceRef(ObjectTypeUtil.createObjectRef(resourceTypeOpenDjrepo, prismContext)); AssignmentType assignment = new AssignmentType(); assignment.setConstruction(construction); diff --git a/testing/story/src/test/java/com/evolveum/midpoint/testing/story/TestPlentyOfAssignments.java b/testing/story/src/test/java/com/evolveum/midpoint/testing/story/TestPlentyOfAssignments.java index 9962a248bbc..ace4552d945 100644 --- a/testing/story/src/test/java/com/evolveum/midpoint/testing/story/TestPlentyOfAssignments.java +++ b/testing/story/src/test/java/com/evolveum/midpoint/testing/story/TestPlentyOfAssignments.java @@ -748,7 +748,7 @@ private void assertRoleMembershipRef(PrismObject user, String roleOidF private void assertRoleMembershipRef(PrismObject user, String roleOid, QName relation) { List roleMembershipRefs = user.asObjectable().getRoleMembershipRef(); for (ObjectReferenceType roleMembershipRef: roleMembershipRefs) { - if (ObjectTypeUtil.referenceMatches(roleMembershipRef, roleOid, RoleType.COMPLEX_TYPE, relation)) { + if (ObjectTypeUtil.referenceMatches(roleMembershipRef, roleOid, RoleType.COMPLEX_TYPE, relation, prismContext)) { return; } } diff --git a/testing/story/src/test/java/com/evolveum/midpoint/testing/story/notorious/AbstractNotoriousTest.java b/testing/story/src/test/java/com/evolveum/midpoint/testing/story/notorious/AbstractNotoriousTest.java index 1b6c3bbd194..190c9088549 100644 --- a/testing/story/src/test/java/com/evolveum/midpoint/testing/story/notorious/AbstractNotoriousTest.java +++ b/testing/story/src/test/java/com/evolveum/midpoint/testing/story/notorious/AbstractNotoriousTest.java @@ -15,16 +15,10 @@ */ package com.evolveum.midpoint.testing.story.notorious; -import static org.testng.AssertJUnit.assertEquals; - import java.io.File; -import java.io.IOException; import java.util.ArrayList; import java.util.Collection; -import java.util.HashMap; import java.util.List; -import java.util.Map; -import java.util.function.Consumer; import javax.xml.namespace.QName; @@ -35,13 +29,10 @@ import com.evolveum.midpoint.model.api.context.ModelContext; import com.evolveum.midpoint.prism.PrismObject; -import com.evolveum.midpoint.prism.PrismObjectDefinition; import com.evolveum.midpoint.prism.delta.ItemDelta; import com.evolveum.midpoint.prism.delta.ObjectDelta; -import com.evolveum.midpoint.prism.util.PrismTestUtil; import com.evolveum.midpoint.schema.constants.SchemaConstants; import com.evolveum.midpoint.schema.internals.InternalCounters; -import com.evolveum.midpoint.schema.internals.InternalInspector; import com.evolveum.midpoint.schema.internals.InternalMonitor; import com.evolveum.midpoint.schema.internals.InternalOperationClasses; import com.evolveum.midpoint.schema.internals.InternalsConfig; @@ -53,13 +44,9 @@ import com.evolveum.midpoint.test.util.MidPointTestConstants; import com.evolveum.midpoint.testing.story.AbstractStoryTest; import com.evolveum.midpoint.testing.story.CountingInspector; -import com.evolveum.midpoint.util.DebugDumpable; -import com.evolveum.midpoint.util.DebugUtil; -import com.evolveum.midpoint.util.exception.SchemaException; 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.AssignmentType; import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectReferenceType; import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectType; import com.evolveum.midpoint.xml.ns._public.common.common_3.OrgType; @@ -1214,7 +1201,7 @@ private void assertRoleMembershipRefs(PrismObject user, String oidForm private void assertRoleMembershipRefNonExclusive(PrismObject user, String roleOid, QName roleType, QName relation) { List roleMembershipRefs = user.asObjectable().getRoleMembershipRef(); for (ObjectReferenceType roleMembershipRef: roleMembershipRefs) { - if (ObjectTypeUtil.referenceMatches(roleMembershipRef, roleOid, roleType, relation)) { + if (ObjectTypeUtil.referenceMatches(roleMembershipRef, roleOid, roleType, relation, prismContext)) { return; } }