Skip to content

Commit

Permalink
Merge remote-tracking branch 'refs/remotes/origin/master'
Browse files Browse the repository at this point in the history
  • Loading branch information
skublik committed Aug 25, 2023
2 parents fc95432 + 97b8d7e commit 30da7b2
Show file tree
Hide file tree
Showing 14 changed files with 314 additions and 107 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import java.util.List;
import java.util.stream.Collectors;

import com.evolveum.midpoint.gui.impl.page.self.requestAccess.ChooseRelationPanel;
import com.evolveum.midpoint.util.logging.Trace;
import com.evolveum.midpoint.util.logging.TraceManager;

Expand Down Expand Up @@ -43,6 +44,8 @@
import com.evolveum.prism.xml.ns._public.types_3.PolyStringTranslationType;
import com.evolveum.prism.xml.ns._public.types_3.PolyStringType;

import javax.xml.namespace.QName;

@PageDescriptor(urls = {
@Url(mountUrl = "/archetypeSelection", matchUrlForSecurity = "/archetypeSelection")
}, permitAll = true, loginPage = true, authModule = AuthenticationModuleNameConstants.ARCHETYPE_SELECTION)
Expand Down Expand Up @@ -215,24 +218,25 @@ protected void onClick(AjaxRequestTarget target) {
target.add(getArchetypesContainer());
}
};
// tilePanel.add(AttributeModifier.append("class", getActiveClassModel(tileModel.getObject())));
return tilePanel;
}

private void archetypeSelected(IModel<Tile<ArchetypeType>> tileModel, AjaxRequestTarget target) {
archetypeOidModel.setObject(getArchetypeOid(tileModel));
tileModel.getObject().setSelected(true);

Tile<ArchetypeType> tile = tileModel.getObject();
boolean tileState = tile.isSelected();

tilesModel.getObject().forEach(t -> t.setSelected(false));
tile.setSelected(!tileState);

target.add(getArchetypeOidField());
}

private String getArchetypeOid(IModel<Tile<ArchetypeType>> tileModel) {
return tileModel.getObject().getValue().getOid();
}

// private IModel<String> getActiveClassModel(Tile<ArchetypeType> tile) {
// var isArchetypeSelected = tile.getValue().isSelected();
// return isArchetypeSelected ? Model.of("active") : Model.of();
// }

private WebMarkupContainer getArchetypesContainer() {
return (WebMarkupContainer) getForm().get(ID_ARCHETYPE_SELECTION_PANEL);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@
import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectReferenceType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.UserType;

/**
* See https://docs.evolveum.com/midpoint/reference/security/authorization/configuration/selectors/delegator/.
*/
public class DelegatorClause extends SelectorClause {

@NotNull private final ValueSelector selector;
Expand Down Expand Up @@ -69,7 +72,7 @@ public boolean matches(@NotNull PrismValue value, @NotNull MatchingContext ctx)
}

if (allowInactive) {
for (AssignmentType assignment : ((UserType) object).getAssignment()) {
for (AssignmentType assignment : user.getAssignment()) {
ObjectReferenceType assignmentTargetRef = assignment.getTargetRef();
if (assignmentTargetRef == null) {
continue;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,39 +7,101 @@

package com.evolveum.midpoint.schema.selector.spec;

import com.evolveum.midpoint.prism.PrismContext;
import com.evolveum.midpoint.prism.PrismValue;
import javax.xml.namespace.QName;

import org.jetbrains.annotations.NotNull;

import com.evolveum.midpoint.prism.*;
import com.evolveum.midpoint.schema.RelationRegistry;
import com.evolveum.midpoint.schema.SchemaService;
import com.evolveum.midpoint.schema.selector.eval.FilteringContext;
import com.evolveum.midpoint.schema.selector.eval.MatchingContext;
import com.evolveum.midpoint.schema.util.ObjectTypeUtil;
import com.evolveum.midpoint.util.exception.*;

import com.evolveum.midpoint.xml.ns._public.common.common_3.AssignmentType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectType;

import org.jetbrains.annotations.NotNull;

public class SelfClause extends SelectorClause {

@NotNull private final RelationRegistry relationRegistry = SchemaService.get().relationRegistry();
@NotNull private final Matching matching;

private SelfClause(@NotNull Matching matching) {
this.matching = matching;
}

static SelfClause object() {
return new SelfClause(Matching.OBJECT);
}

static SelfClause deputyAssignment() {
return new SelfClause(Matching.DEPUTY_ASSIGNMENT);
}

static SelfClause deputyReference() {
return new SelfClause(Matching.DEPUTY_REFERENCE);
}

@Override
public @NotNull String getName() {
return "self";
return "self(%s)".formatted(matching);
}

@Override
public boolean matches(@NotNull PrismValue value, @NotNull MatchingContext ctx)
throws SchemaException, ExpressionEvaluationException, CommunicationException, SecurityViolationException,
ConfigurationException, ObjectNotFoundException {
var object = ObjectTypeUtil.asObjectTypeIfPossible(value);
if (object == null) {
traceNotApplicable(ctx, "Not an object");

// "Parsing" the incoming value
String objectOid;
switch (matching) {
case OBJECT -> {
var object = ObjectTypeUtil.asObjectTypeIfPossible(value);
if (object == null) {
traceNotApplicable(ctx, "Not an object");
return false;
}
objectOid = object.getOid();
}
case DEPUTY_ASSIGNMENT -> {
var assignment = toAssignmentIfPossible(value);
if (assignment == null) {
traceNotApplicable(ctx, "Not an assignment");
return false;
}
var targetRef = assignment.getTargetRef();
if (targetRef == null) {
traceNotApplicable(ctx, "Assignment without targetRef");
return false;
}
if (!relationMatches(targetRef, ctx)) {
return false;
}
objectOid = targetRef.getOid();
}
case DEPUTY_REFERENCE -> {
if (!(value instanceof PrismReferenceValue prv)) {
traceNotApplicable(ctx, "Not a reference value");
return false;
}
if (!relationMatches(prv.asReferencable(), ctx)) {
return false;
}
objectOid = prv.getOid();
}
default -> throw new AssertionError(matching);
}
if (objectOid == null) {
traceNotApplicable(ctx, "No OID in object");
return false;
}

// Comparing OIDs (relations were already matched)
String principalOid = ctx.getPrincipalOid();
if (principalOid == null) {
traceNotApplicable(ctx, "no principal OID");
return false;
} else {
String objectOid = object.getOid();
if (principalOid.equals(objectOid)) {
traceApplicable(ctx, "match on principal OID (%s)", objectOid);
return true;
Expand All @@ -54,6 +116,28 @@ public boolean matches(@NotNull PrismValue value, @NotNull MatchingContext ctx)
}
}

@SuppressWarnings("BooleanMethodIsAlwaysInverted")
private boolean relationMatches(@NotNull Referencable referencable, @NotNull MatchingContext ctx) {
QName objectRelation = referencable.getRelation();
if (relationRegistry.isDelegation(objectRelation)) {
return true;
} else {
traceNotApplicable(ctx, "Relation is not a deputy: %s", objectRelation);
return false;
}
}

private AssignmentType toAssignmentIfPossible(PrismValue value) {
if (!(value instanceof PrismContainerValue<?> pcv)) {
return null;
}
var clazz = pcv.getCompileTimeClass();
if (clazz == null || !AssignmentType.class.isAssignableFrom(clazz)) {
return null;
}
return (AssignmentType) pcv.asContainerable();
}

@Override
public boolean toFilter(@NotNull FilteringContext ctx) {
if (!ObjectType.class.isAssignableFrom(ctx.getRestrictedType())) {
Expand Down Expand Up @@ -82,4 +166,8 @@ void addDebugDumpContent(StringBuilder sb, int indent) {
public String toString() {
return "SelfClause{}";
}

enum Matching {
OBJECT, DEPUTY_ASSIGNMENT, DEPUTY_REFERENCE
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

import com.evolveum.midpoint.prism.*;
import com.evolveum.midpoint.prism.path.ItemPath;

import com.google.common.base.Preconditions;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
Expand Down Expand Up @@ -183,23 +184,22 @@ public static ValueSelector of(SelectorClause... clauses) {
}

for (SpecialObjectSpecificationType special : new HashSet<>(sBean.getSpecial())) {
if (special == SpecialObjectSpecificationType.SELF) {
clauses.add(new SelfClause());

if (filter != null
|| orgRef != null
|| orgRelation != null
|| roleRelation != null
|| (bean instanceof OwnedObjectSelectorType oBean && oBean.getTenant() != null)
|| !archetypeRefList.isEmpty()) {
throw new ConfigurationException(String.format(
"Both filter/org/role/archetype/tenant and special clause specified in %s",
ConfigErrorReporter.describe(bean)));
}

} else {
throw new ConfigurationException(
"Unsupported special clause: " + special + " in " + ConfigErrorReporter.describe(sBean));
clauses.add(
switch (special) {
case SELF -> SelfClause.object();
case SELF_DEPUTY_ASSIGNMENT -> SelfClause.deputyAssignment();
case SELF_DEPUTY_REF -> SelfClause.deputyReference();
});

if (filter != null
|| orgRef != null
|| orgRelation != null
|| roleRelation != null
|| (bean instanceof OwnedObjectSelectorType oBean && oBean.getTenant() != null)
|| !archetypeRefList.isEmpty()) {
throw new ConfigurationException(String.format(
"Both filter/org/role/archetype/tenant and special clause specified in %s",
ConfigErrorReporter.describe(bean)));
}
}
}
Expand Down Expand Up @@ -295,17 +295,6 @@ public static ValueSelector forType(@NotNull QName typeName) {
return effectiveTypeClause;
}

/** Returns complex type definition for the object, derived from [effective] type clause. */
@NotNull ComplexTypeDefinition getComplexTypeDefinitionRequired() throws ConfigurationException {
TypeClause typeClause = getEffectiveTypeClause();
var typeDef = typeClause.getTypeDefinitionRequired();
if (typeDef instanceof ComplexTypeDefinition ctd) {
return ctd;
} else {
throw new ConfigurationException("Type clause for " + this + " does not correspond to a complex type definition");
}
}

public @NotNull List<SelectorClause> getClauses() {
return clauses;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8640,6 +8640,32 @@
</xsd:appinfo>
</xsd:annotation>
</xsd:enumeration>
<xsd:enumeration value="selfDeputyAssignment">
<xsd:annotation>
<xsd:appinfo>
<xsd:documentation>
"Deputy" assignment that points to the subject.
May be replaced with something more general in the future.
</xsd:documentation>
<jaxb:typesafeEnumMember name="SELF_DEPUTY_ASSIGNMENT"/>
<a:since>4.8</a:since>
<a:experimental>true</a:experimental>
</xsd:appinfo>
</xsd:annotation>
</xsd:enumeration>
<xsd:enumeration value="selfDeputyRef">
<xsd:annotation>
<xsd:appinfo>
<xsd:documentation>
"Deputy" reference that points to the subject.
May be replaced with something more general in the future.
</xsd:documentation>
<jaxb:typesafeEnumMember name="SELF_DEPUTY_REF"/>
<a:since>4.8</a:since>
<a:experimental>true</a:experimental>
</xsd:appinfo>
</xsd:annotation>
</xsd:enumeration>
</xsd:restriction>
</xsd:simpleType>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -650,15 +650,15 @@ public void test999BulkActionsDefaults() throws CommonException, IOException {
runNegativeBulkActionTestLoggedIn(
FILE_SCRIPTING_GENERATE_VALUE,
ConfigurationItemOrigin.rest(),
"Access to action 'generate-value' ('generateValue')",
"Access to action 'search'",
"expression profile 'empty', actions profile 'empty'");

when("*** testing for privileged user");
login(USER_ADMINISTRATOR_USERNAME);
runNegativeBulkActionTestLoggedIn(
FILE_SCRIPTING_GENERATE_VALUE,
ConfigurationItemOrigin.rest(),
"Access to action 'generate-value' ('generateValue')",
"Access to action 'search'",
"expression profile 'empty', actions profile 'empty'");
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -721,7 +721,9 @@ public void test365AssignToJackDryAndRaw() throws Exception {
try {
evaluateExpression(expression, task, result);
fail("unexpected success");
} catch (UnsupportedOperationException e) {
} catch (UnsupportedOperationException | SystemException e) {
// Old repo throws UnsupportedOperationException, new repo throws SystemException
// (not a problem, for now)
displayExpectedException(e);
assertThat(e).hasMessageContaining("previewChanges is not supported in raw mode");
}
Expand Down

0 comments on commit 30da7b2

Please sign in to comment.