Skip to content

Commit

Permalink
Improve prototype for outliers and match rules analysis
Browse files Browse the repository at this point in the history
  • Loading branch information
tchrapovic committed Feb 16, 2024
1 parent 6e82d76 commit 964aa06
Show file tree
Hide file tree
Showing 73 changed files with 3,554 additions and 187 deletions.
1 change: 1 addition & 0 deletions config/sql/native/postgres-audit.sql
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ DO $$ BEGIN
'ROLE',
'ROLE_ANALYSIS_CLUSTER',
'ROLE_ANALYSIS_SESSION',
'ROLE_ANALYSIS_OUTLIER',
'SECURITY_POLICY',
'SEQUENCE',
'SERVICE',
Expand Down
27 changes: 27 additions & 0 deletions config/sql/native/postgres.sql
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ CREATE TYPE ObjectType AS ENUM (
'ROLE',
'ROLE_ANALYSIS_CLUSTER',
'ROLE_ANALYSIS_SESSION',
'ROLE_ANALYSIS_OUTLIER',
'SECURITY_POLICY',
'SEQUENCE',
'SERVICE',
Expand Down Expand Up @@ -1252,6 +1253,32 @@ CREATE TRIGGER m_role_analysis_session_update_tr BEFORE UPDATE ON m_role_analysi
CREATE TRIGGER m_role_analysis_session_oid_delete_tr AFTER DELETE ON m_role_analysis_session
FOR EACH ROW EXECUTE FUNCTION delete_object_oid();

CREATE TABLE m_role_analysis_outlier (
oid UUID NOT NULL PRIMARY KEY REFERENCES m_object_oid(oid),
objectType ObjectType GENERATED ALWAYS AS ('ROLE_ANALYSIS_OUTLIER') STORED
CHECK (objectType = 'ROLE_ANALYSIS_OUTLIER'),
targetObjectRefTargetOid UUID,
targetObjectRefTargetType ObjectType,
targetObjectRefRelationId INTEGER REFERENCES m_uri(id),
targetClusterRefTargetOid UUID,
targetClusterRefTargetType ObjectType,
targetClusterRefRelationId INTEGER REFERENCES m_uri(id)
)
INHERITS (m_assignment_holder);

CREATE TRIGGER m_role_analysis_outlier_oid_insert_tr BEFORE INSERT ON m_role_analysis_outlier
FOR EACH ROW EXECUTE FUNCTION insert_object_oid();
CREATE TRIGGER m_role_analysis_outlier_update_tr BEFORE UPDATE ON m_role_analysis_outlier
FOR EACH ROW EXECUTE FUNCTION before_update_object();
CREATE TRIGGER m_role_analysis_outlier_oid_delete_tr AFTER DELETE ON m_role_analysis_outlier
FOR EACH ROW EXECUTE FUNCTION delete_object_oid();

CREATE INDEX m_role_analysis_outlier_targetObjectRefTargetOid_idx ON m_role_analysis_outlier (targetObjectRefTargetOid);
CREATE INDEX m_role_analysis_outlier_targetObjectRefTargetType_idx ON m_role_analysis_outlier (targetObjectRefTargetType);
CREATE INDEX m_role_analysis_outlier_targetObjectRefRelationId_idx ON m_role_analysis_outlier (targetObjectRefRelationId);
CREATE INDEX m_role_analysis_outlier_targetClusterRefTargetOid_idx ON m_role_analysis_outlier (targetClusterRefTargetOid);
CREATE INDEX m_role_analysis_outlier_targetClusterRefTargetType_idx ON m_role_analysis_outlier (targetClusterRefTargetType);
CREATE INDEX m_role_analysis_outlier_targetClusterRefRelationId_idx ON m_role_analysis_outlier (targetClusterRefRelationId);


-- Represents LookupTableType, see https://docs.evolveum.com/midpoint/reference/misc/lookup-tables/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -298,4 +298,6 @@ public class GuiStyleConstants {
public static final String CLASS_MARK = "fa-solid fa-tag";

public static final String CLASS_AUDIT = "fa-solid fa-magnifying-glass-chart";

public static final String CLASS_ICON_OUTLIER = "fa fa-user-circle";
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
*/
package com.evolveum.midpoint.gui.api.component.autocomplete;

import java.io.Serial;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
Expand All @@ -24,7 +25,7 @@

public class AutoCompleteItemDefinitionPanel extends AbstractAutoCompletePanel {

private static final long serialVersionUID = 1L;
@Serial private static final long serialVersionUID = 1L;
private static final String ID_INPUT = "input";

public AutoCompleteItemDefinitionPanel(String id, final IModel<ItemDefinition<?>> model) {
Expand All @@ -34,10 +35,10 @@ public AutoCompleteItemDefinitionPanel(String id, final IModel<ItemDefinition<?>

private void initLayout(final IModel<ItemDefinition<?>> model) {
final Model<String> itemDefinitionAsStringModel = new Model<>(null);
AutoCompleteTextField<String> input = new AutoCompleteTextField<String>(
AutoCompleteTextField<String> input = new AutoCompleteTextField<>(
ID_INPUT, itemDefinitionAsStringModel, String.class, createAutoCompleteSettings()) {

private static final long serialVersionUID = 1L;
@Serial private static final long serialVersionUID = 1L;

@Override
protected Iterator<String> getChoices(String input) {
Expand All @@ -52,7 +53,7 @@ protected Iterator<String> getChoices(String input) {
};

input.add(new OnChangeAjaxBehavior() {
private static final long serialVersionUID = 1L;
@Serial private static final long serialVersionUID = 1L;

@Override
protected void onUpdate(AjaxRequestTarget target) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,16 @@ protected Map<QName, Collection<ItemDefinition<?>>> getSchemaDefinitionMap() {
protected void onUpdateAutoCompletePanel(AjaxRequestTarget target) {
ItemPathPanel.this.onUpdate(ItemPathPanel.this.getModelObject());
}

@Override
protected boolean isRoleAnalysis() {
return ItemPathPanel.this.isRoleAnalysis();
}

@Override
protected boolean isRoleAnalysisSimple() {
return ItemPathPanel.this.isRoleAnalysisSimple();
}
};
itemDefPanel.getBaseFormComponent().add(new EmptyOnBlurAjaxFormUpdatingBehaviour());
itemDefPanel.setOutputMarkupId(true);
Expand All @@ -163,6 +173,9 @@ public void onClick(AjaxRequestTarget target) {

@Override
public boolean isVisible() {
if (isRoleAnalysisSimple()) {
return false;
}
if (getModelObject().getParentPath() == null || getModelObject().getParentPath().toItemPath() == null) {
return true;
}
Expand All @@ -187,6 +200,10 @@ public void onClick(AjaxRequestTarget target) {

@Override
public boolean isVisible() {

if (isRoleAnalysisSimple()) {
return false;
}
return getModelObject().getParentPath() != null && getModelObject().getParentPath().toItemPath() != null;
}
});
Expand Down Expand Up @@ -390,4 +407,12 @@ public boolean isTextMode() {
protected ItemPathPanelMode getPanelMode() {
return panelMode;
}

protected boolean isRoleAnalysis() {
return false;
}

protected boolean isRoleAnalysisSimple() {
return false;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.xml.namespace.QName;

Expand All @@ -25,6 +26,8 @@
import com.evolveum.midpoint.prism.PrismContainerDefinition;
import com.evolveum.midpoint.web.component.util.VisibleEnableBehaviour;
import com.evolveum.midpoint.web.page.admin.configuration.component.EmptyOnBlurAjaxFormUpdatingBehaviour;
import com.evolveum.prism.xml.ns._public.types_3.ObjectReferenceType;
import com.evolveum.prism.xml.ns._public.types_3.PolyStringType;

public class ItemPathSegmentPanel extends BasePanel<ItemPathDto> {

Expand Down Expand Up @@ -111,11 +114,68 @@ private Map<String, ItemDefinition<?>> collectAvailableDefinitions(String input)
}
} else {
Collection<ItemDefinition<?>> definitions = getSchemaDefinitionMap().get(getModelObject().getObjectType());
collectItems(definitions, input, toSelect);
if (isRoleAnalysis() || isRoleAnalysisSimple()) {
collectSipmleDefinition(definitions, input, toSelect);
} else {
collectItems(definitions, input, toSelect);
}
}
return toSelect;
}

protected boolean isRoleAnalysis() {
return false;
}

protected boolean isRoleAnalysisSimple() {
return false;
}

private void collectSipmleDefinition(Collection<? extends ItemDefinition> definitions, String input, Map<String, ItemDefinition<?>> toSelect) {
if (definitions == null) {
return;
}

for (ItemDefinition<?> def : definitions) {
if (isEligibleItemDefinition(def)) {
putDefinition(def, input, toSelect);
} else if(!isRoleAnalysisSimple()) {
if (def instanceof PrismContainerDefinition<?>) {
List<? extends ItemDefinition<?>> innerDefinitions = ((PrismContainerDefinition<?>) def).getDefinitions();
for (ItemDefinition<?> innerDef : innerDefinitions) {
if (isEligibleItemDefinition(innerDef)) {
putDefinition(def, input, toSelect);
}
}
}
}
}
}

private boolean isPolyStringOrString(ItemDefinition<?> def) {
return def.getTypeName().getLocalPart().equals(PolyStringType.COMPLEX_TYPE.getLocalPart())
|| def.getTypeName().getLocalPart().equals("string")
||def.getTypeName().getLocalPart().equals("PolyString");
}

private boolean isReference(ItemDefinition<?> def) {
return def.getTypeName().getLocalPart().equals(ObjectReferenceType.COMPLEX_TYPE.getLocalPart());
}

public void putDefinition(ItemDefinition<?> def, String input, Map<String, ItemDefinition<?>> toSelect) {
if (StringUtils.isBlank(input)) {
toSelect.put(def.getItemName().getLocalPart(), def);
} else {
if (def.getItemName().getLocalPart().startsWith(input)) {
toSelect.put(def.getItemName().getLocalPart(), def);
}
}
}

private boolean isEligibleItemDefinition(ItemDefinition<?> def) {
return def.isSingleValue() && (isPolyStringOrString(def) || isReference(def));
}

private void collectItems(Collection<? extends ItemDefinition> definitions, String input, Map<String, ItemDefinition<?>> toSelect) {
if (definitions == null) {
return;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,10 +57,15 @@ protected void onUpdate(ItemPathDto itemPathDto) {
}

@Override
protected boolean isNamespaceVisible() {
protected boolean isRoleAnalysis() {
return true;
}

@Override
protected boolean isNamespaceVisible() {
return false;
}

@Override
protected boolean isNamespaceEnable() {
return false;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/*
* Copyright (C) 2010-2023 Evolveum and contributors
*
* This work is dual-licensed under the Apache License 2.0
* and European Union Public License. See LICENSE file for details.
*/
package com.evolveum.midpoint.gui.impl.factory.panel;

import java.io.Serializable;

import jakarta.annotation.PostConstruct;
import org.springframework.stereotype.Component;

import com.evolveum.midpoint.gui.api.prism.wrapper.ItemWrapper;
import com.evolveum.midpoint.gui.api.prism.wrapper.PrismValueWrapper;
import com.evolveum.midpoint.prism.path.ItemPath;
import com.evolveum.midpoint.web.component.input.TextPanel;
import com.evolveum.midpoint.web.component.prism.InputPanel;
import com.evolveum.midpoint.xml.ns._public.common.common_3.RoleAnalysisMatchingRuleType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.RoleAnalysisSessionType;

//TODO check serializable
@Component
public class RoleAnalysisWeightPanelFactory extends AbstractInputGuiComponentFactory<Double> implements Serializable {

@PostConstruct
public void register() {
getRegistry().addToRegistry(this);
}

@Override
public <IW extends ItemWrapper<?, ?>, VW extends PrismValueWrapper<?>> boolean match(IW wrapper, VW valueWrapper) {
ItemPath itemPath = wrapper.getPath().namedSegmentsOnly();
ItemPath wrapperPath = ItemPath.create(RoleAnalysisSessionType.F_MATCHING_RULE, RoleAnalysisMatchingRuleType.F_WEIGHT);
return itemPath.equivalent(wrapperPath);
}

@Override
protected InputPanel getPanel(PrismPropertyPanelContext<Double> panelCtx) {
if (panelCtx.getRealValueModel().getObject() == null) {
panelCtx.getRealValueModel().setObject(1.0);
}
return new TextPanel<>(panelCtx.getComponentId(),
panelCtx.getRealValueModel(), panelCtx.getTypeClass(), false);
}

@Override
public Integer getOrder() {
return 10000;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -506,7 +506,8 @@ protected boolean isButtonEnabled() {
RoleAnalysisSessionType value = model.getObject().getValue();
if (value != null
&& value.getAnalysisOption() != null && value.getAnalysisOption().getProcessMode() != null) {
return Model.of(value.getAnalysisOption().getProcessMode().value());
return Model.of(value.getAnalysisOption().getProcessMode().value()
+ "/" + value.getAnalysisOption().getAnalysisCategory().value());
}

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
package com.evolveum.midpoint.gui.impl.page.admin.role.mining.page.page;

import java.io.Serial;
import java.util.List;

import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.behavior.AttributeAppender;
Expand All @@ -16,6 +17,7 @@
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.StringResourceModel;
import org.apache.wicket.request.mapper.parameter.PageParameters;
import org.jetbrains.annotations.NotNull;

import com.evolveum.midpoint.authentication.api.authorization.AuthorizationAction;
import com.evolveum.midpoint.authentication.api.authorization.PageDescriptor;
Expand All @@ -39,11 +41,7 @@
import com.evolveum.midpoint.task.api.Task;
import com.evolveum.midpoint.web.component.AjaxCompositedIconSubmitButton;
import com.evolveum.midpoint.web.util.OnePageParameterEncoder;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectReferenceType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.RoleAnalysisClusterType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.RoleAnalysisSessionType;

import org.jetbrains.annotations.NotNull;
import com.evolveum.midpoint.xml.ns._public.common.common_3.*;

//TODO correct authorizations
@PageDescriptor(
Expand Down Expand Up @@ -191,5 +189,37 @@ protected IModel<String> createPageTitleModel() {
return createStringResource("PageMiningOperation.title");
}

@Override
public IModel<List<ContainerPanelConfigurationType>> getPanelConfigurations() {

IModel<List<ContainerPanelConfigurationType>> panelConfigurations = super.getPanelConfigurations();
@NotNull RoleAnalysisClusterType cluster = getObjectDetailsModels()
.getObjectWrapper()
.getObject()
.asObjectable();

RoleAnalysisService roleAnalysisService = getRoleAnalysisService();
PageBase pageBase = (PageBase) getPage();
Task task = pageBase.createSimpleTask("Resolving cluster option type");

RoleAnalysisOptionType roleAnalysisOptionType = roleAnalysisService
.resolveClusterOptionType(cluster.asPrismObject(), task, task.getResult());

RoleAnalysisCategoryType analysisCategory = roleAnalysisOptionType.getAnalysisCategory();
if (analysisCategory == null) {
return super.getPanelConfigurations();
}

List<ContainerPanelConfigurationType> object = panelConfigurations.getObject();
for (ContainerPanelConfigurationType containerPanelConfigurationType : object) {
if (containerPanelConfigurationType.getIdentifier().equals("outlierPanel")) {
if (!analysisCategory.equals(RoleAnalysisCategoryType.OUTLIERS)) {
containerPanelConfigurationType.setVisibility(UserInterfaceElementVisibilityType.HIDDEN);
}
}
}
return panelConfigurations;
}

}

0 comments on commit 964aa06

Please sign in to comment.