Skip to content

Commit

Permalink
Merge branch 'master' of https://github.com/Evolveum/midpoint
Browse files Browse the repository at this point in the history
  • Loading branch information
Kateryna Honchar committed Jun 12, 2023
2 parents c9587bd + eac6bfb commit c69e96a
Show file tree
Hide file tree
Showing 17 changed files with 236 additions and 267 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@

import com.evolveum.midpoint.prism.Objectable;

import com.evolveum.midpoint.prism.query.FilterCreationUtil;
import com.evolveum.midpoint.prism.query.ObjectFilter;

import com.google.common.base.Preconditions;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
Expand Down Expand Up @@ -71,12 +74,6 @@ private ValueSelector(
return new ValueSelector(null, null, List.of(), null);
}

/** Type name must be qualified. */
public static @NotNull ValueSelector emptyWithType(@NotNull QName typeName) {
TypeClause typeClause = TypeClause.ofQualified(typeName);
return new ValueSelector(typeClause, null, List.of(typeClause), null);
}

public static ValueSelector of(@NotNull TypeClause typeClause, @NotNull ParentClause parentClause) {
return new ValueSelector(
typeClause,
Expand Down Expand Up @@ -131,8 +128,7 @@ public static ValueSelector of(SelectorClause... clauses) {
clauses.add(FilterClause.of(qTypeName, filter));
}

if (bean instanceof SubjectedObjectSelectorType) {
SubjectedObjectSelectorType sBean = (SubjectedObjectSelectorType) bean;
if (bean instanceof SubjectedObjectSelectorType sBean) {

var orgRelation = sBean.getOrgRelation();
if (orgRelation != null) {
Expand Down Expand Up @@ -164,8 +160,7 @@ public static ValueSelector of(SelectorClause... clauses) {
}
}

if (bean instanceof OwnedObjectSelectorType) {
OwnedObjectSelectorType oBean = (OwnedObjectSelectorType) bean;
if (bean instanceof OwnedObjectSelectorType oBean) {

var owner = oBean.getOwner();
if (owner != null) {
Expand Down Expand Up @@ -252,10 +247,6 @@ public static ValueSelector forType(@NotNull QName typeName) {
null);
}

public @Nullable TypeClause getTypeClause() {
return typeClause;
}

public @Nullable QName getTypeName() {
return typeClause != null ? typeClause.getTypeName() : null;
}
Expand All @@ -282,6 +273,16 @@ public boolean matches(@NotNull PrismValue value, @NotNull ClauseMatchingContext
return true;
}

public ObjectFilter computeFilter(@NotNull ClauseFilteringContext ctx)
throws SchemaException, ExpressionEvaluationException, CommunicationException, SecurityViolationException,
ConfigurationException, ObjectNotFoundException {
if (applyFilters(ctx)) {
return ctx.getFilterCollector().getFilter();
} else {
return FilterCreationUtil.createNone();
}
}

public boolean applyFilters(@NotNull ClauseFilteringContext ctx)
throws SchemaException, ExpressionEvaluationException, CommunicationException, SecurityViolationException,
ConfigurationException, ObjectNotFoundException {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1167,6 +1167,13 @@ public static <C extends Containerable> Collection<PrismObject<? extends ObjectT
.map(c -> c.asPrismContainerValue()));
}

/** Returns containerables that are not rooted in a {@link PrismObject}. */
public static @NotNull <C extends Containerable> List<C> getDetachedContainerables(@NotNull Collection<C> containerables) {
return containerables.stream()
.filter(c -> !c.asPrismContainerValue().getRootValue().isObjectable())
.collect(Collectors.toList());
}

/**
* As {@link #getRootsForContainerables(Collection)} but for {@link ObjectReferenceType} values.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -748,6 +748,9 @@ public <T extends Containerable> SearchResultList<T> searchContainers(
schemaTransformer.applySchemasAndSecurityToContainerValues(list, parsedOptions, task, result);
}
return list;
} catch (Throwable e) {
result.recordException(e);
throw e;
} finally {
result.close();
result.cleanup();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
import com.evolveum.midpoint.schema.util.ObjectTypeUtil;
import com.evolveum.midpoint.security.enforcer.api.*;
import com.evolveum.midpoint.task.api.Task;
import com.evolveum.midpoint.util.MiscUtil;
import com.evolveum.midpoint.util.exception.*;
import com.evolveum.midpoint.util.logging.Trace;
import com.evolveum.midpoint.util.logging.TraceManager;
Expand All @@ -71,7 +72,6 @@ public class SchemaTransformer {
@Autowired @Qualifier("cacheRepositoryService") private RepositoryService repositoryService;
@Autowired private SecurityEnforcer securityEnforcer;
@Autowired private ArchetypeManager archetypeManager;
@Autowired private PrismContext prismContext;

@Autowired private DataAccessProcessor dataAccessProcessor;
@Autowired private DefinitionAccessProcessor definitionAccessProcessor;
Expand Down Expand Up @@ -180,8 +180,15 @@ <C extends Containerable> void applySchemasAndSecurityToContainerValues(

applySchemasAndSecurityToMutableObjects(roots, parsedOptions, task, result);

// We have to check that no value was disconnected in the process of applying the constraints.
ObjectTypeUtil.getRootsForContainerables(values);
// We have to check that no value got detached in the process of applying the constraints.
var detached = ObjectTypeUtil.getDetachedContainerables(values);
if (!detached.isEmpty()) {
throw new SecurityViolationException( // TODO do better diagnostics
"%d containerable(s) returned by a search are not allowed by #get authorization: %s"
.formatted(
detached.size(),
MiscUtil.getDiagInfo(detached, 10, 200)));
}
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ public class CorrelationServiceImpl implements CorrelationService {
.correlate(correlationContext, result);
return createCompleteResult(correlationResult, rootCorrelatorContext);
} catch (Throwable t) {
result.recordFatalError(t);
result.recordException(t);
throw t;
} finally {
result.close();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,10 @@
import java.lang.reflect.Modifier;
import java.util.*;
import java.util.Objects;
import java.util.stream.Collectors;

import com.evolveum.midpoint.model.common.LinkManager;
import com.evolveum.midpoint.prism.schema.SchemaRegistry;
import com.evolveum.midpoint.repo.api.RepositoryService;
import com.evolveum.midpoint.repo.common.expression.ExpressionFactory;
import com.evolveum.midpoint.repo.common.query.LinkedSelectorToFilterTranslator;
import com.evolveum.midpoint.schema.result.OperationResult;
import com.evolveum.midpoint.task.api.Task;
Expand Down Expand Up @@ -59,7 +57,6 @@ public class LinkedObjectsFunctions {
@Autowired private RelationRegistry relationRegistry;
@Autowired private MidpointFunctionsImpl midpointFunctions;
@Autowired private LinkManager linkManager;
@Autowired private ExpressionFactory expressionFactory;
@Autowired
@Qualifier("cacheRepositoryService")
private RepositoryService repositoryService;
Expand Down Expand Up @@ -108,13 +105,17 @@ <T extends AssignmentHolderType> List<T> findLinkedSources(String linkType) thro
return List.of();
}
PrismReferenceValue focusReference = focusObjectReference.asReferenceValue();
LinkedSelectorToFilterTranslator translator = new LinkedSelectorToFilterTranslator(definition.getSelector(), focusReference,
"finding linked sources for " + focusContext, prismContext, expressionFactory,
currentTask, currentResult);
ObjectQuery query = prismContext.queryFactory().createQuery(translator.createFilter());
LinkedSelectorToFilterTranslator translator = new LinkedSelectorToFilterTranslator(
definition.getSelector(),
focusReference,
"finding linked sources for " + focusContext,
LOGGER,
currentTask);
ObjectQuery query = prismContext.queryFactory().createQuery(translator.createFilter(currentResult));

//noinspection unchecked
return (List<T>) midpointFunctions.searchObjects(translator.getNarrowedTargetType(), query, null);
return (List<T>) midpointFunctions.searchObjects(
translator.getNarrowedTargetType(), query, null);
}

// Should be used after assignment evaluation!
Expand Down Expand Up @@ -142,7 +143,7 @@ <T extends AssignmentHolderType> List<T> findLinkedTargets(Class<T> type, String
Set<PrismReferenceValue> membership = getMembership();
List<PrismReferenceValue> assignedWithMemberRelation = membership.stream()
.filter(ref -> relationRegistry.isMember(ref.getRelation()) && objectTypeMatches(ref, type))
.collect(Collectors.toList());
.toList();
// TODO deduplicate w.r.t. member/manager
// TODO optimize matching
List<T> objects = new ArrayList<>(assignedWithMemberRelation.size());
Expand Down Expand Up @@ -178,7 +179,7 @@ <T extends AssignmentHolderType> List<T> findLinkedTargets(String linkTypeName)
Set<PrismReferenceValue> membership = getMembership();
List<PrismReferenceValue> assignedWithMatchingRelation = membership.stream()
.filter(ref -> relationMatches(ref, definition.getSelector()) && objectTypeMatches(ref, expectedClasses))
.collect(Collectors.toList());
.toList();
// TODO deduplicate w.r.t. member/manager
// TODO optimize matching
List<T> objects = new ArrayList<>(assignedWithMatchingRelation.size());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,10 +113,12 @@ private List<LinkedObjectSelectorType> resolveLinkTypes(List<LinkSourceObjectSel
throws SchemaException, ConfigurationException {
List<LinkedObjectSelectorType> resolvedSelectors = new ArrayList<>();
for (LinkSourceObjectSelectorType selector : selectors) {
if (selector.getLinkType() != null) {
LinkedObjectSelectorType resolvedSelector = resolveSourceSelector(selector.getLinkType());
LinkSourceObjectSelectorType mergedSelector = mergeSelectors(selector, resolvedSelector);
resolvedSelectors.add(mergedSelector);
String linkType = selector.getLinkType();
if (linkType != null) {
resolvedSelectors.add(
mergeSelectors(
selector,
resolveSourceSelector(linkType)));
} else {
resolvedSelectors.add(selector);
}
Expand Down Expand Up @@ -155,29 +157,32 @@ private ObjectQuery createQuery() throws CommunicationException, ObjectNotFoundE
queryFactory.createOrOptimized(convertedSelectors));
}

private ObjectFilter createFilter(LinkedObjectSelectorType sourceSelector) throws CommunicationException,
private ObjectFilter createFilter(@NotNull LinkedObjectSelectorType sourceSelector) throws CommunicationException,
ObjectNotFoundException, SchemaException, SecurityViolationException, ConfigurationException,
ExpressionEvaluationException {
SelectorToFilterTranslator translator = new SelectorToFilterTranslator(sourceSelector, AssignmentHolderType.class,
"link source selector in rule script executor", beans.prismContext, beans.expressionFactory,
actx.task, result);
ObjectFilter selectorFilter = translator.createFilter();
SelectorToFilterTranslator translator =
new SelectorToFilterTranslator(
sourceSelector, AssignmentHolderType.class,
"link source selector in rule script executor", LOGGER, actx.task);
Class<? extends ObjectType> narrowedSourceType = translator.getNarrowedTargetType();
ObjectFilter allSourcesFilter = beans.prismContext.queryFor(narrowedSourceType)
.item(AssignmentHolderType.F_ROLE_MEMBERSHIP_REF).ref(createExpectedReferenceValues(sourceSelector))
.buildFilter();

narrowedSourceTypes.add(narrowedSourceType);
return ObjectQueryUtil.simplify(queryFactory.createAnd(allSourcesFilter, selectorFilter));
return ObjectQueryUtil.simplify(
queryFactory.createAndOptimized(
translator.createFilter(result),
beans.prismContext.queryFor(narrowedSourceType)
.item(AssignmentHolderType.F_ROLE_MEMBERSHIP_REF)
.ref(createExpectedReferenceValues(sourceSelector))
.buildFilter()));
}

@NotNull
private List<PrismReferenceValue> createExpectedReferenceValues(LinkedObjectSelectorType sourceSelector) {
List<PrismReferenceValue> values = new ArrayList<>(sourceSelector.getRelation().size());
if (sourceSelector.getRelation().isEmpty()) {
List<QName> relations = sourceSelector.getRelation();
List<PrismReferenceValue> values = new ArrayList<>(relations.size());
if (relations.isEmpty()) {
values.add(new ObjectReferenceType().oid(focusOid).asReferenceValue());
} else {
for (QName relation : sourceSelector.getRelation()) {
for (QName relation : relations) {
values.add(new ObjectReferenceType().oid(focusOid).relation(relation).asReferenceValue());
}
}
Expand All @@ -196,7 +201,7 @@ private List<PrismReferenceValue> searchForSourceReferences(CompleteQuery<?> com
List<PrismReferenceValue> references = new ArrayList<>();
beans.repositoryService.searchObjectsIterative(completeQuery.getType(), completeQuery.getQuery(),
(object, parentResult) ->
references.add(ObjectTypeUtil.createObjectRef(object, beans.prismContext).asReferenceValue()),
references.add(ObjectTypeUtil.createObjectRef(object).asReferenceValue()),
completeQuery.getOptions(), false, result);
return references;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,11 +87,12 @@ private LinkTargetObjectSelectorType resolveLinkType(LinkTargetObjectSelectorTyp
return selector;
} else {
LinkTargetObjectSelectorType mergedSelector = new LinkTargetObjectSelectorType();
PrismContainerValue<?> mergedPcv = mergedSelector.asPrismContainerValue();
LinkedObjectSelectorType linkSelector = resolveLinkTypeInternal(linkTypeName);
if (linkSelector != null) {
((PrismContainerValue<?>) mergedSelector.asPrismContainerValue()).mergeContent(linkSelector.asPrismContainerValue(), emptyList());
mergedPcv.mergeContent(linkSelector.asPrismContainerValue(), List.of());
}
((PrismContainerValue<?>) mergedSelector.asPrismContainerValue()).mergeContent(selector.asPrismContainerValue(), emptyList());
mergedPcv.mergeContent(selector.asPrismContainerValue(), List.of());
mergedSelector.setLinkType(null);
return mergedSelector;
}
Expand Down Expand Up @@ -123,8 +124,9 @@ private List<PrismObject<? extends ObjectType>> getTargetsInternal(LinkTargetObj
Set<PrismReferenceValue> links = new HashSet<>(getLinksInChangeSituation(selector));
LOGGER.trace("Links matching change situation: {}", links);

if (!selector.getRelation().isEmpty()) {
applyRelationFilter(links, selector.getRelation());
List<QName> relations = selector.getRelation();
if (!relations.isEmpty()) {
applyRelationFilter(links, relations);
LOGGER.trace("Links matching also relation(s): {}", links);
}

Expand All @@ -138,9 +140,10 @@ private List<PrismObject<? extends ObjectType>> getTargetsInternal(LinkTargetObj
LOGGER.trace("Links matching also policy constraints: {}", links);
}

if (selector.getType() != null) {
QName typeName = selector.getType();
if (typeName != null) {
// This is just to avoid resolving objects with non-matching type
applyObjectType(links, selector.getType());
applyObjectType(links, typeName);
LOGGER.trace("Links matching also object type: {}", links);
}

Expand All @@ -151,7 +154,8 @@ private List<PrismObject<? extends ObjectType>> getTargetsInternal(LinkTargetObj
return matchingObjects;
}

private List<PrismObject<? extends ObjectType>> getMatchingObjects(Collection<PrismObject<? extends ObjectType>> objects,
private List<PrismObject<? extends ObjectType>> getMatchingObjects(
Collection<PrismObject<? extends ObjectType>> objects,
ObjectSelectorType selector) {
List<PrismObject<? extends ObjectType>> matching = new ArrayList<>();
for (PrismObject<? extends ObjectType> object : objects) {
Expand All @@ -160,7 +164,8 @@ private List<PrismObject<? extends ObjectType>> getMatchingObjects(Collection<Pr
matching.add(object);
}
} catch (CommonException e) {
LoggingUtils.logUnexpectedException(LOGGER, "Couldn't match link target {} for {} when filtering link targets", e,
LoggingUtils.logUnexpectedException(
LOGGER, "Couldn't match link target {} for {} when filtering link targets", e,
object, actx.focusContext.getObjectAny());
}
}
Expand Down Expand Up @@ -230,24 +235,15 @@ private void applyRelationFilter(Set<PrismReferenceValue> links, List<QName> rel

@NotNull
private Set<PrismReferenceValue> getLinksInChangeSituation(LinkTargetObjectSelectorType selector) {
switch (defaultIfNull(selector.getChangeSituation(), LinkChangeSituationType.ALWAYS)) {
case ALWAYS:
return SetUtils.union(getLinkedOld(), getLinkedNew());
case ADDED:
return SetUtils.difference(getLinkedNew(), getLinkedOld());
case REMOVED:
return SetUtils.difference(getLinkedOld(), getLinkedNew());
case UNCHANGED:
return SetUtils.intersection(getLinkedOld(), getLinkedNew());
case CHANGED:
return SetUtils.disjunction(getLinkedOld(), getLinkedNew());
case IN_NEW:
return getLinkedNew();
case IN_OLD:
return getLinkedOld();
default:
throw new AssertionError(selector.getChangeSituation());
}
return switch (defaultIfNull(selector.getChangeSituation(), LinkChangeSituationType.ALWAYS)) {
case ALWAYS -> SetUtils.union(getLinkedOld(), getLinkedNew());
case ADDED -> SetUtils.difference(getLinkedNew(), getLinkedOld());
case REMOVED -> SetUtils.difference(getLinkedOld(), getLinkedNew());
case UNCHANGED -> SetUtils.intersection(getLinkedOld(), getLinkedNew());
case CHANGED -> SetUtils.disjunction(getLinkedOld(), getLinkedNew());
case IN_NEW -> getLinkedNew();
case IN_OLD -> getLinkedOld();
};
}

private Set<PrismReferenceValue> getLinkedOld() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -496,7 +496,7 @@ boolean isNotDryRunLikeMode() {
return !isDryRun() && !task.areShadowChangesSimulated();
}

boolean isFullMode() {
public boolean isFullMode() {
return executionMode == ExecutionModeType.FULL
&& task.isExecutionFullyPersistent();
}
Expand Down

0 comments on commit c69e96a

Please sign in to comment.