Skip to content

Commit

Permalink
OwnedByRestriction, first checks that path matches the owned entity
Browse files Browse the repository at this point in the history
  • Loading branch information
virgo47 committed Jun 6, 2022
1 parent 795be54 commit fc968f5
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

import static java.util.Collections.emptySet;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.testng.AssertJUnit.*;

import static com.evolveum.midpoint.repo.api.RepoModifyOptions.createForceReindex;
Expand All @@ -30,6 +31,7 @@
import com.evolveum.midpoint.prism.polystring.PolyString;
import com.evolveum.midpoint.prism.query.ObjectQuery;
import com.evolveum.midpoint.prism.query.OrderDirection;
import com.evolveum.midpoint.repo.sqlbase.QueryException;
import com.evolveum.midpoint.schema.GetOperationOptions;
import com.evolveum.midpoint.schema.ResultHandler;
import com.evolveum.midpoint.schema.SearchResultList;
Expand Down Expand Up @@ -1194,7 +1196,7 @@ public void test922AssignmentsWithSpecifiedTargetName() throws SchemaException {
}

@Test
public void test923AssignmentsAndInducementsOwnedByRoles() throws SchemaException {
public void test923AssignmentsAndInducementsOwnedByAbstractRoles() throws SchemaException {
given("query for assignments or inducements owned by any abstract role");
ObjectQuery query = prismContext.queryFor(AssignmentType.class)
.ownedBy(AbstractRoleType.class)
Expand All @@ -1221,8 +1223,8 @@ public void test923AssignmentsAndInducementsOwnedByRoles() throws SchemaExceptio
}

@Test
public void test924AssignmentsAndInducementsOwnedByIncludingInnerFilter() throws SchemaException {
given("query for assignments or inducements owned by any user including inner filter");
public void test924AssignmentsAndInducementsOwnedByAbstractRolesIncludingInnerFilter() throws SchemaException {
given("query for assignments or inducements owned by any abstract role with specified name (inner filter)");
ObjectQuery query = prismContext.queryFor(AssignmentType.class)
.ownedBy(AbstractRoleType.class)
.block()
Expand All @@ -1240,7 +1242,31 @@ public void test924AssignmentsAndInducementsOwnedByIncludingInnerFilter() throws
repositoryService.searchContainers(AssignmentType.class, query, null, result);
result.recomputeStatus();

then("only assignments/inducements from roles matching the inner filter are returned");
then("only assignments/inducements matching the outer filter from roles matching the inner filter are returned");
assertThat(result.isSuccess()).isTrue();
assertThat(assignments).singleElement()
.matches(a -> a.getId().equals(1L)
&& a.getConstruction().getResourceRef().getOid().equals("10000000-0000-0000-0000-000000000004"));
}

@Test(enabled = false) // TODO
public void test925AssignmentsOwnedByRole() throws SchemaException {
given("query for assignments (using path) owned by the specified role");
ObjectQuery query = prismContext.queryFor(AssignmentType.class)
.ownedBy(AbstractRoleType.class, AbstractRoleType.F_ASSIGNMENT) // path for assignments only
.block()
// the inner condition path starts from AbstractRoleType
.item(F_NAME).eq("Judge") // only assignments from the Role "Judge"
.endBlock()
.build();
OperationResult result = new OperationResult("search");

when("executing container search");
SearchResultList<AssignmentType> assignments =
repositoryService.searchContainers(AssignmentType.class, query, null, result);
result.recomputeStatus();

then("only assignments from the specified role are returned (not inducements)");
assertThat(result.isSuccess()).isTrue();
assertThat(assignments).singleElement()
.matches(a -> a.getId().equals(1L)
Expand All @@ -1264,6 +1290,33 @@ public void test924AssignmentsAndInducementsOwnedByIncludingInnerFilter() throws
.containsExactlyInAnyOrder(11, 12);
*/

@Test
public void test929OwnedByComplainsAboutInvalidPath() {
expect("query fails when ownedBy path points to non-owning type");
OperationResult result = new OperationResult("search");
assertThatThrownBy(() -> repositoryService.searchContainers(AssignmentType.class,
prismContext.queryFor(AssignmentType.class)
.ownedBy(AbstractRoleType.class, AbstractRoleType.F_RISK_LEVEL) // risk level is not assignment
.block()
.endBlock()
.build(), null, result))
.isInstanceOf(SystemException.class)
.hasCauseInstanceOf(QueryException.class)
.hasMessage("Path for OwnedByFilter (riskLevel) points to a type 'String', expected type is 'AssignmentType'.");
assertThatOperationResult(result).isFatalError();

expect("query fails when ownedBy path points to non-owning type (collection version)");
assertThatThrownBy(() -> repositoryService.searchContainers(AssignmentType.class,
prismContext.queryFor(AssignmentType.class)
.ownedBy(AbstractRoleType.class, AbstractRoleType.F_LINK_REF) // multi-value ref, not assignment
.block()
.endBlock()
.build(), null, new OperationResult("search")))
.isInstanceOf(SystemException.class)
.hasCauseInstanceOf(QueryException.class)
.hasMessage("Path for OwnedByFilter (linkRef) is a reference, not a container of expected type 'AssignmentType'.");
}

/**
* See MID-5474 (just a quick attempt to replicate)
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
*/
package com.evolveum.midpoint.repo.sql.query.restriction;

import java.util.Objects;
import java.util.Set;
import javax.xml.namespace.QName;

Expand All @@ -18,6 +19,7 @@
import com.evolveum.midpoint.repo.sql.query.QueryDefinitionRegistry;
import com.evolveum.midpoint.repo.sql.query.definition.JpaDataNodeDefinition;
import com.evolveum.midpoint.repo.sql.query.definition.JpaEntityDefinition;
import com.evolveum.midpoint.repo.sql.query.definition.JpaReferenceDefinition;
import com.evolveum.midpoint.repo.sql.query.hqm.EntityReference;
import com.evolveum.midpoint.repo.sql.query.hqm.GenericProjectionElement;
import com.evolveum.midpoint.repo.sql.query.hqm.HibernateQuery;
Expand All @@ -30,18 +32,18 @@

public class OwnedByRestriction extends Restriction<OwnedByFilter> {

// TODO: Extend to cases, work items, etc...
public static final Set<Class<?>> SUPPORTED_OWNED_TYPES = Set.of(AssignmentType.class);

private final JpaEntityDefinition owningEntityDefinition;

public static OwnedByRestriction create(
InterpretationContext context, OwnedByFilter filter, JpaEntityDefinition baseEntityDefinition)
throws QueryException {
Class<?> ownedType = baseEntityDefinition.getJaxbClass();
Class<?> ownedType = Objects.requireNonNull(baseEntityDefinition.getJaxbClass());
if (!SUPPORTED_OWNED_TYPES.contains(ownedType)) {
throw new QueryException("OwnedBy filter is not supported for type '"
+ (ownedType != null ? ownedType.getSimpleName() : null)
+ "'; supported types are: " + SUPPORTED_OWNED_TYPES);
+ ownedType.getSimpleName() + "'; supported types are: " + SUPPORTED_OWNED_TYPES);
}

ItemPath path = filter.getPath();
Expand All @@ -59,6 +61,17 @@ public static OwnedByRestriction create(
throw new QueryException("Path for OwnedByFilter (" + path +
") doesn't point to a hibernate entity or property within " + owningEntityDefinition);
}
JpaDataNodeDefinition<?> pathTargetDefinition = Objects.requireNonNull(searchResult.getTargetDefinition());
if (pathTargetDefinition instanceof JpaReferenceDefinition<?>) {
throw new QueryException("Path for OwnedByFilter (" + path +
") is a reference, not a container of expected type '" + ownedType.getSimpleName() + "'.");
}
Class<?> targetType = pathTargetDefinition.getJaxbClass();
if (!ownedType.equals(targetType)) {
throw new QueryException("Path for OwnedByFilter (" + path + ") points to a type '"
+ (targetType != null ? targetType.getSimpleName() : "?")
+ "', expected type is '" + ownedType.getSimpleName() + "'.");
}
}
return new OwnedByRestriction(context, filter, baseEntityDefinition, owningEntityDefinition);
}
Expand Down

0 comments on commit fc968f5

Please sign in to comment.