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 d16d1136e47..248787be64b 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 @@ -48,9 +48,13 @@ import com.evolveum.midpoint.gui.api.SubscriptionType; import com.evolveum.midpoint.gui.api.model.ReadOnlyValueModel; import com.evolveum.midpoint.model.api.ModelExecuteOptions; +import com.evolveum.midpoint.model.api.ModelInteractionService; +import com.evolveum.midpoint.model.api.RoleSelectionSpecification; +import com.evolveum.midpoint.prism.query.ObjectFilter; import com.evolveum.midpoint.schema.GetOperationOptions; import com.evolveum.midpoint.schema.SelectorOptions; import com.evolveum.midpoint.schema.util.LocalizationUtil; +import com.evolveum.midpoint.task.api.Task; import com.evolveum.midpoint.util.*; import com.evolveum.midpoint.web.component.data.SelectableBeanObjectDataProvider; import com.evolveum.midpoint.web.component.prism.*; @@ -2391,6 +2395,27 @@ public static boolean isAllNulls(Iterable array) { return StreamSupport.stream(array.spliterator(), true).allMatch(o -> o == null); } + public static ObjectFilter getAssignableRolesFilter(PrismObject focusObject, Class type, + OperationResult result, Task task, PageBase pageBase) { + ObjectFilter filter = null; + LOGGER.debug("Loading objects which can be assigned"); + try { + ModelInteractionService mis = pageBase.getModelInteractionService(); + RoleSelectionSpecification roleSpec = + mis.getAssignableRoleSpecification(focusObject, task, result); + filter = roleSpec.getFilter(); + } catch (Exception ex) { + LoggingUtils.logUnexpectedException(LOGGER, "Couldn't load available roles", ex); + result.recordFatalError("Couldn't load available roles", ex); + } finally { + result.recomputeStatus(); + } + if (!result.isSuccess() && !result.isHandledError()) { + pageBase.showResult(result); + } + return filter; + } + private static IModel> createChoices() { return new AbstractReadOnlyModel>() { diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/orgs/AbstractOrgTabPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/orgs/AbstractOrgTabPanel.java index eb345cf8b7e..b355665a688 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/orgs/AbstractOrgTabPanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/orgs/AbstractOrgTabPanel.java @@ -18,6 +18,7 @@ import java.util.ArrayList; import java.util.List; +import com.evolveum.midpoint.prism.query.ObjectFilter; import com.evolveum.midpoint.web.component.util.SelectableBean; import org.apache.wicket.ajax.AjaxEventBehavior; import org.apache.wicket.ajax.AjaxRequestTarget; @@ -56,6 +57,7 @@ public abstract class AbstractOrgTabPanel extends BasePanel { private static final String DOT_CLASS = OrgTreeAssignablePanel.class.getName() + "."; private static final String OPERATION_LOAD_ORG_UNIT = DOT_CLASS + "loadOrgUnit"; + private static final String OPERATION_LOAD_ASSIGNABLE_ITEMS = DOT_CLASS + "loadAssignableOrgs"; private String ID_TABS = "tabs"; private List> roots; @@ -169,6 +171,10 @@ private List> loadOrgRoots() { List> list = new ArrayList<>(); try { ObjectQuery query = ObjectQueryUtil.createRootOrgQuery(getPageBase().getPrismContext()); + ObjectFilter assignableItemsFilter = getAssignableItemsFilter(); + if (assignableItemsFilter != null){ + query.addFilter(assignableItemsFilter); + } list = getPageBase().getModelService().searchObjects(OrgType.class, query, null, task, result); // Sort org roots by displayOrder, if not set push the org to the end list.sort((o1, o2) -> (o1.getRealValue().getDisplayOrder() == null ? Integer.MAX_VALUE : o1.getRealValue().getDisplayOrder()) @@ -190,6 +196,10 @@ private List> loadOrgRoots() { return list; } + protected ObjectFilter getAssignableItemsFilter(){ + return null; + } + protected boolean isWarnMessageVisible(){ return true; } diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/orgs/OrgTreeAssignablePanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/orgs/OrgTreeAssignablePanel.java index 79446f92e6f..f8f79e73ed3 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/orgs/OrgTreeAssignablePanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/orgs/OrgTreeAssignablePanel.java @@ -18,6 +18,11 @@ import java.util.ArrayList; import java.util.List; +import com.evolveum.midpoint.gui.api.util.WebComponentUtil; +import com.evolveum.midpoint.prism.query.ObjectFilter; +import com.evolveum.midpoint.schema.result.OperationResult; +import com.evolveum.midpoint.task.api.Task; +import com.evolveum.midpoint.xml.ns._public.common.common_3.FocusType; import org.apache.wicket.Component; import org.apache.wicket.ajax.AjaxRequestTarget; import org.apache.wicket.markup.html.panel.Panel; @@ -43,6 +48,7 @@ public class OrgTreeAssignablePanel extends BasePanel implements Popupa public static final String PARAM_ORG_RETURN = "org"; private static final String DOT_CLASS = OrgTreeAssignablePanel.class.getName() + "."; + private static final String OPERATION_LOAD_ASSIGNABLE_ITEMS = DOT_CLASS + "loadAssignableOrgs"; private static final String ID_ORG_TABS = "orgTabs"; private static final String ID_ASSIGN = "assign"; @@ -71,6 +77,11 @@ protected void selectTreeItemPerformed(SelectableBean selected, AjaxRequestTarget target) { onItemSelect(selected, target); } + + @Override + protected ObjectFilter getCustomFilter(){ + return getAssignableItemsFilter(); + } }; panel.setOutputMarkupId(true); @@ -82,6 +93,10 @@ protected boolean isWarnMessageVisible(){ return false; } + @Override + protected ObjectFilter getAssignableItemsFilter(){ + return OrgTreeAssignablePanel.this.getAssignableItemsFilter(); + } }; tabbedPanel.setOutputMarkupId(true); @@ -125,6 +140,20 @@ protected void onItemSelect(SelectableBean selected, AjaxRequestTarget } + private ObjectFilter getAssignableItemsFilter(){ + if (getAssignmentOwnerObject() == null){ + return null; + } + Task task = getPageBase().createSimpleTask(OPERATION_LOAD_ASSIGNABLE_ITEMS); + OperationResult result = task.getResult(); + return WebComponentUtil.getAssignableRolesFilter(getAssignmentOwnerObject().asPrismObject(), OrgType.class, + result, task, getPageBase()); + } + + protected F getAssignmentOwnerObject(){ + return null; + } + @Override public int getWidth() { return 900; diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/orgs/OrgTreePanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/orgs/OrgTreePanel.java index dea350e9c4a..91970812cd7 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/orgs/OrgTreePanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/orgs/OrgTreePanel.java @@ -18,6 +18,7 @@ import java.io.Serializable; import java.util.*; +import com.evolveum.midpoint.prism.query.ObjectFilter; import com.evolveum.midpoint.web.page.admin.users.PageOrgTree; import com.evolveum.midpoint.web.session.OrgTreeStateStorage; import org.apache.commons.lang3.StringUtils; @@ -146,6 +147,11 @@ private void initLayout(ModelServiceLocator serviceLocator) { protected List createInlineMenuItems(OrgType org) { return createTreeChildrenMenu(org); } + + @Override + protected ObjectFilter getCustomFilter(){ + return OrgTreePanel.this.getCustomFilter(); + } }; List, String>> columns = new ArrayList<>(); @@ -262,6 +268,10 @@ protected void onModelChanged() { treeContainer.add(tree); } + protected ObjectFilter getCustomFilter(){ + return null; + } + private static class TreeStateModel extends AbstractReadOnlyModel>> { private static final long serialVersionUID = 1L; diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/users/component/OrgTreeProvider.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/users/component/OrgTreeProvider.java index e1649abe65f..92e7817eea8 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/users/component/OrgTreeProvider.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/users/component/OrgTreeProvider.java @@ -21,6 +21,7 @@ import com.evolveum.midpoint.gui.api.util.WebModelServiceUtils; import com.evolveum.midpoint.model.api.ModelService; import com.evolveum.midpoint.prism.PrismObject; +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.schema.result.OperationResult; @@ -112,6 +113,10 @@ public Iterator> getChildren(SelectableBean> orgs = getModelService().searchObjects(OrgType.class, query, null, task, result); LOGGER.debug("Found {} sub-orgs.", orgs.size()); @@ -138,6 +143,10 @@ public Iterator> getChildren(SelectableBean createObjectWrapper(SelectableBean parent, PrismObject unit) { if (unit == null) { return null; 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 cbdb960565e..a75bd65c600 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 @@ -149,12 +149,6 @@ private List createTreeMenu() { private List createTreeChildrenMenu(OrgType org) { List items = new ArrayList<>(); try { - boolean allowModify = org == null || - // TODO: the modify authorization here is probably wrong. - // It is a model autz. UI autz should be here instead? - parentPage.isAuthorized(ModelAuthorizationAction.MODIFY.getUrl(), - AuthorizationPhaseType.REQUEST, org.asPrismObject(), - null, null, null); boolean allowRead = org == null || // TODO: the authorization URI here is probably wrong. // It is a model autz. UI autz should be here instead? @@ -162,7 +156,7 @@ private List createTreeChildrenMenu(OrgType org) { AuthorizationPhaseType.REQUEST, org.asPrismObject(), null, null, null); InlineMenuItem item; - if (allowModify) { + if (WebComponentUtil.isAuthorized(AuthorizationConstants.AUTZ_UI_ADMIN_ORG_MOVE_ACTION_URI)) { item = new InlineMenuItem(createStringResource("TreeTablePanel.move"), new ColumnMenuAction>() { private static final long serialVersionUID = 1L; @@ -173,7 +167,8 @@ public void onClick(AjaxRequestTarget target) { } }); items.add(item); - + } + if (WebComponentUtil.isAuthorized(AuthorizationConstants.AUTZ_UI_ADMIN_ORG_MAKE_ROOT_ACTION_URI)) { item = new InlineMenuItem(createStringResource("TreeTablePanel.makeRoot"), new ColumnMenuAction>() { private static final long serialVersionUID = 1L; @@ -204,6 +199,12 @@ public void onClick(AjaxRequestTarget target) { }); items.add(item); } + boolean allowModify = org == null || + // TODO: the modify authorization here is probably wrong. + // It is a model autz. UI autz should be here instead? + parentPage.isAuthorized(ModelAuthorizationAction.MODIFY.getUrl(), + AuthorizationPhaseType.REQUEST, org.asPrismObject(), + null, null, null); if (allowModify) { item = new InlineMenuItem(createStringResource("TreeTablePanel.recompute"), new ColumnMenuAction>() { @@ -309,10 +310,6 @@ private void selectTreeItemPerformed(SelectableBean selected, AjaxReque } private void moveRootPerformed(SelectableBean root, AjaxRequestTarget target) { - if (root == null) { - root = getTreePanel().getRootFromProvider(); - } - final SelectableBean orgToMove = root; OrgTreeAssignablePanel orgAssignablePanel = new OrgTreeAssignablePanel( @@ -323,6 +320,12 @@ private void moveRootPerformed(SelectableBean root, AjaxRequestTarget t protected void onItemSelect(SelectableBean selected, AjaxRequestTarget target) { moveConfirmPerformed(orgToMove, selected, target); } + + @Override + protected OrgType getAssignmentOwnerObject(){ + return root.getValue(); + } + }; parentPage.showMainPopup(orgAssignablePanel, target); diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/self/PageAssignmentShoppingKart.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/self/PageAssignmentShoppingKart.java index 9fa4c41123c..ff83c6fcf94 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/self/PageAssignmentShoppingKart.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/self/PageAssignmentShoppingKart.java @@ -16,10 +16,12 @@ package com.evolveum.midpoint.web.page.self; import com.evolveum.midpoint.gui.api.model.LoadableModel; +import com.evolveum.midpoint.gui.api.util.WebComponentUtil; import com.evolveum.midpoint.model.api.ModelInteractionService; import com.evolveum.midpoint.model.api.RoleSelectionSpecification; import com.evolveum.midpoint.prism.PrismObject; import com.evolveum.midpoint.prism.query.*; +import com.evolveum.midpoint.schema.constants.ObjectTypes; import com.evolveum.midpoint.schema.result.OperationResult; import com.evolveum.midpoint.schema.util.ObjectQueryUtil; import com.evolveum.midpoint.security.api.AuthorizationConstants; @@ -513,25 +515,10 @@ private void addViewTypeFilter(ObjectQuery query) { } private ObjectFilter getAssignableRolesFilter() { - ObjectFilter filter = null; - LOGGER.debug("Loading roles which the current user has right to assign"); Task task = createSimpleTask(OPERATION_LOAD_ASSIGNABLE_ROLES); OperationResult result = task.getResult(); - try { - ModelInteractionService mis = getModelInteractionService(); - RoleSelectionSpecification roleSpec = - mis.getAssignableRoleSpecification(getTargetUser().asPrismObject(), task, result); - filter = roleSpec.getFilter(); - } catch (Exception ex) { - LoggingUtils.logUnexpectedException(LOGGER, "Couldn't load available roles", ex); - result.recordFatalError("Couldn't load available roles", ex); - } finally { - result.recomputeStatus(); - } - if (!result.isSuccess() && !result.isHandledError()) { - showResult(result); - } - return filter; + return WebComponentUtil.getAssignableRolesFilter(getTargetUser().asPrismObject(), AbstractRoleType.class, + result, task, PageAssignmentShoppingKart.this); } private ObjectQuery addOrgMembersFilter(String oid, ObjectQuery query) { diff --git a/repo/security-api/src/main/java/com/evolveum/midpoint/security/api/AuthorizationConstants.java b/repo/security-api/src/main/java/com/evolveum/midpoint/security/api/AuthorizationConstants.java index e7229385459..7707f1668c6 100644 --- a/repo/security-api/src/main/java/com/evolveum/midpoint/security/api/AuthorizationConstants.java +++ b/repo/security-api/src/main/java/com/evolveum/midpoint/security/api/AuthorizationConstants.java @@ -419,7 +419,13 @@ public class AuthorizationConstants { //ui authorization for CSV export button (will be applied everywhere over mp) public static final QName AUTZ_UI_ADMIN_CSV_EXPORT_ACTION_QNAME = new QName(NS_AUTHORIZATION_UI, "adminCSVexport"); public static final String AUTZ_UI_ADMIN_CSV_EXPORT_ACTION_URI = QNameUtil.qNameToUri(AUTZ_UI_ADMIN_CSV_EXPORT_ACTION_QNAME); - + + public static final QName AUTZ_UI_ADMIN_ORG_MAKE_ROOT_ACTION_QNAME = new QName(NS_AUTHORIZATION_UI, "adminOrgMakeRoot"); + public static final String AUTZ_UI_ADMIN_ORG_MAKE_ROOT_ACTION_URI = QNameUtil.qNameToUri(AUTZ_UI_ADMIN_ORG_MAKE_ROOT_ACTION_QNAME); + + public static final QName AUTZ_UI_ADMIN_ORG_MOVE_ACTION_QNAME = new QName(NS_AUTHORIZATION_UI, "adminOrgMove"); + public static final String AUTZ_UI_ADMIN_ORG_MOVE_ACTION_URI = QNameUtil.qNameToUri(AUTZ_UI_ADMIN_ORG_MOVE_ACTION_QNAME); + /** * Those are the items that midPoint logic controls directly. They have exception from execution-phase * authorization enforcement. Their modification in execution phase is always allowed. If it was not