use of com.evolveum.prism.xml.ns._public.query_3.SearchFilterType in project midpoint by Evolveum.
the class TestQueryConvertor method testGenericQuery.
@Test
public void testGenericQuery() throws Exception {
displayTestTitle("testGenericQuery");
SearchFilterType queryType = unmarshalFilter(FILTER_AND_GENERIC_FILE);
ObjectQuery query = toObjectQuery(GenericObjectType.class, queryType);
displayQuery(query);
// check parent filter
assertNotNull(query);
ObjectFilter filter = query.getFilter();
PrismAsserts.assertAndFilter(filter, 2);
// check first condition
ObjectFilter first = getFilterCondition(filter, 0);
PrismAsserts.assertEqualsFilter(first, GenericObjectType.F_NAME, PolyStringType.COMPLEX_TYPE, new ItemPath(GenericObjectType.F_NAME));
PrismAsserts.assertEqualsFilterValue((EqualFilter) first, createPolyString("generic object"));
// check second condition
ObjectFilter second = getFilterCondition(filter, 1);
PrismAsserts.assertEqualsFilter(second, intExtensionDefinition, DOMUtil.XSD_INT, new ItemPath(ObjectType.F_EXTENSION, new QName(NS_EXTENSION, "intType")));
PrismAsserts.assertEqualsFilterValue((EqualFilter) second, 123);
QueryType convertedQueryType = toQueryType(query);
assertNotNull("Re-serialized query is null ", convertedQueryType);
assertNotNull("Filter in re-serialized query must not be null.", convertedQueryType.getFilter());
displayQueryType(convertedQueryType);
}
use of com.evolveum.prism.xml.ns._public.query_3.SearchFilterType in project midpoint by Evolveum.
the class PrismReferenceValue method asReferencable.
public Referencable asReferencable() {
if (referencable != null) {
return referencable;
}
Itemable parent = getParent();
if (parent != null) {
QName xsdType = parent.getDefinition().getTypeName();
Class clazz = getPrismContext().getSchemaRegistry().getCompileTimeClass(xsdType);
if (clazz != null) {
try {
referencable = (Referencable) clazz.newInstance();
} catch (InstantiationException | IllegalAccessException e) {
throw new SystemException("Couldn't create jaxb object instance of '" + clazz + "': " + e.getMessage(), e);
}
}
referencable.setupReferenceValue(this);
}
// A hack, just to avoid crashes. TODO think about this!
return new Referencable() {
PrismReferenceValue referenceValue = PrismReferenceValue.this;
@Override
public PrismReferenceValue asReferenceValue() {
return referenceValue;
}
@Override
public void setupReferenceValue(PrismReferenceValue value) {
referenceValue = value;
}
@Override
public String getOid() {
return referenceValue.getOid();
}
@Override
public QName getType() {
return referenceValue.getTargetType();
}
@Override
public PolyStringType getTargetName() {
return PrismForJAXBUtil.getReferenceTargetName(referenceValue);
}
@Override
public QName getRelation() {
return referenceValue.getRelation();
}
@Override
public String getDescription() {
return referenceValue.getDescription();
}
@Override
public EvaluationTimeType getResolutionTime() {
return referenceValue.getResolutionTime();
}
@Override
public SearchFilterType getFilter() {
SearchFilterType filter = new SearchFilterType();
filter.setFilterClauseXNode(PrismForJAXBUtil.getReferenceFilterClauseXNode(referenceValue));
return filter;
}
};
}
use of com.evolveum.prism.xml.ns._public.query_3.SearchFilterType in project midpoint by Evolveum.
the class ModelClientUtil method parseSearchFilterType.
public static SearchFilterType parseSearchFilterType(String filterClauseAsXml) throws IOException, SAXException, JAXBException {
Element filterClauseAsElement = parseElement(filterClauseAsXml);
SearchFilterType searchFilterType = new SearchFilterType();
searchFilterType.setFilterClause(filterClauseAsElement);
return searchFilterType;
}
use of com.evolveum.prism.xml.ns._public.query_3.SearchFilterType in project midpoint by Evolveum.
the class AbstractSearchExpressionEvaluator method transformSingleValue.
@Override
protected List<V> transformSingleValue(ExpressionVariables variables, PlusMinusZero valueDestination, boolean useNew, ExpressionEvaluationContext context, String contextDescription, Task task, OperationResult result) throws ExpressionEvaluationException, ObjectNotFoundException, SchemaException {
// if (LOGGER.isTraceEnabled()) {
// LOGGER.trace("transformSingleValue in {}\nvariables:\n{}\nvalueDestination: {}\nuseNew: {}",
// new Object[]{contextDescription, variables.debugDump(1), valueDestination, useNew});
// }
QName targetTypeQName = getExpressionEvaluatorType().getTargetType();
if (targetTypeQName == null) {
targetTypeQName = getDefaultTargetType();
}
if (targetTypeQName != null && QNameUtil.isUnqualified(targetTypeQName)) {
targetTypeQName = getPrismContext().getSchemaRegistry().resolveUnqualifiedTypeName(targetTypeQName);
}
ObjectTypes targetType = ObjectTypes.getObjectTypeFromTypeQName(targetTypeQName);
if (targetType == null) {
throw new SchemaException("Unknown target type " + targetTypeQName + " in " + shortDebugDump());
}
Class<? extends ObjectType> targetTypeClass = targetType.getClassDefinition();
List<V> resultValues = null;
ObjectQuery query = null;
List<ItemDelta<V, D>> additionalAttributeDeltas = null;
PopulateType populateAssignmentType = getExpressionEvaluatorType().getPopulate();
if (populateAssignmentType != null) {
additionalAttributeDeltas = collectAdditionalAttributes(populateAssignmentType, outputDefinition, variables, context, contextDescription, task, result);
}
if (getExpressionEvaluatorType().getOid() != null) {
resultValues = new ArrayList<>(1);
resultValues.add(createPrismValue(getExpressionEvaluatorType().getOid(), targetTypeQName, additionalAttributeDeltas, context));
} else {
SearchFilterType filterType = getExpressionEvaluatorType().getFilter();
if (filterType == null) {
throw new SchemaException("No filter in " + shortDebugDump());
}
query = QueryJaxbConvertor.createObjectQuery(targetTypeClass, filterType, prismContext);
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("XML query converted to: {}", query.debugDump());
}
query = ExpressionUtil.evaluateQueryExpressions(query, variables, context.getExpressionFactory(), prismContext, context.getContextDescription(), task, result);
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("Expression in query evaluated to: {}", query.debugDump());
}
query = extendQuery(query, context);
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("Query after extension: {}", query.debugDump());
}
resultValues = executeSearchUsingCache(targetTypeClass, targetTypeQName, query, additionalAttributeDeltas, context, contextDescription, task, context.getResult());
if (resultValues.isEmpty()) {
ObjectReferenceType defaultTargetRef = getExpressionEvaluatorType().getDefaultTargetRef();
if (defaultTargetRef != null) {
resultValues.add(createPrismValue(defaultTargetRef.getOid(), targetTypeQName, additionalAttributeDeltas, context));
}
}
}
if (resultValues.isEmpty() && getExpressionEvaluatorType().isCreateOnDemand() == Boolean.TRUE && (valueDestination == PlusMinusZero.PLUS || valueDestination == PlusMinusZero.ZERO || useNew)) {
String createdObjectOid = createOnDemand(targetTypeClass, variables, context, context.getContextDescription(), task, context.getResult());
resultValues.add(createPrismValue(createdObjectOid, targetTypeQName, additionalAttributeDeltas, context));
}
LOGGER.trace("Search expression got {} results for query {}", resultValues == null ? "null" : resultValues.size(), query);
return (List<V>) resultValues;
}
use of com.evolveum.prism.xml.ns._public.query_3.SearchFilterType in project midpoint by Evolveum.
the class SecurityEnforcerImpl method preProcessObjectFilterInternal.
private <T extends ObjectType, O extends ObjectType> ObjectFilter preProcessObjectFilterInternal(MidPointPrincipal principal, String operationUrl, AuthorizationPhaseType phase, boolean includeNullPhase, Class<T> objectType, PrismObject<O> object, boolean includeSpecial, ObjectFilter origFilter, String desc) throws SchemaException {
Collection<Authorization> authorities = getAuthorities(principal);
ObjectFilter securityFilterAllow = null;
ObjectFilter securityFilterDeny = null;
QueryItemsSpec queryItemsSpec = new QueryItemsSpec();
// MID-3916
queryItemsSpec.addRequiredItems(origFilter);
if (LOGGER.isTraceEnabled()) {
LOGGER.trace(" Initial query items spec {}", queryItemsSpec.shortDump());
}
boolean hasAllowAll = false;
if (authorities != null) {
for (GrantedAuthority authority : authorities) {
if (authority instanceof Authorization) {
Authorization autz = (Authorization) authority;
String autzHumanReadableDesc = autz.getHumanReadableDesc();
LOGGER.trace("Evaluating {}", autzHumanReadableDesc);
// action
if (!autz.getAction().contains(operationUrl) && !autz.getAction().contains(AuthorizationConstants.AUTZ_ALL_URL)) {
LOGGER.trace(" Authorization not applicable for operation {}", operationUrl);
continue;
}
// phase
if (autz.getPhase() == phase || (includeNullPhase && autz.getPhase() == null)) {
LOGGER.trace(" Authorization is applicable for phases {} (continuing evaluation)", phase);
} else {
LOGGER.trace(" Authorization is not applicable for phase {}", phase);
continue;
}
// object or target
String objectTargetSpec;
ObjectFilter autzObjSecurityFilter = null;
List<OwnedObjectSelectorType> objectSpecTypes;
if (object == null) {
// object not present. Therefore we are looking for object here
objectSpecTypes = autz.getObject();
objectTargetSpec = "object";
} else {
// object present. Therefore we are looking for target
objectSpecTypes = autz.getTarget();
objectTargetSpec = "target";
// .. but we need to decide whether this authorization is applicable to the object
if (isApplicable(autz.getObject(), object, principal, null, "object", autzHumanReadableDesc)) {
LOGGER.trace(" Authorization is applicable for object {}", object);
} else {
LOGGER.trace(" Authorization is not applicable for object {}", object);
continue;
}
}
boolean applicable = true;
if (objectSpecTypes == null || objectSpecTypes.isEmpty()) {
LOGGER.trace(" No {} specification in authorization (authorization is universaly applicable)", objectTargetSpec);
autzObjSecurityFilter = AllFilter.createAll();
} else {
applicable = false;
for (OwnedObjectSelectorType objectSpecType : objectSpecTypes) {
ObjectFilter objSpecSecurityFilter = null;
TypeFilter objSpecTypeFilter = null;
SearchFilterType specFilterType = objectSpecType.getFilter();
ObjectReferenceType specOrgRef = objectSpecType.getOrgRef();
OrgRelationObjectSpecificationType specOrgRelation = objectSpecType.getOrgRelation();
RoleRelationObjectSpecificationType specRoleRelation = objectSpecType.getRoleRelation();
QName specTypeQName = objectSpecType.getType();
PrismObjectDefinition<T> objectDefinition = null;
// Type
if (specTypeQName != null) {
specTypeQName = prismContext.getSchemaRegistry().qualifyTypeName(specTypeQName);
PrismObjectDefinition<?> specObjectDef = prismContext.getSchemaRegistry().findObjectDefinitionByType(specTypeQName);
if (specObjectDef == null) {
throw new SchemaException("Unknown object type " + specTypeQName + " in " + autzHumanReadableDesc);
}
Class<?> specObjectClass = specObjectDef.getCompileTimeClass();
if (!objectType.isAssignableFrom(specObjectClass)) {
LOGGER.trace(" Authorization not applicable for object because of type mismatch, authorization {}, query {}", new Object[] { specObjectClass, objectType });
continue;
} else {
LOGGER.trace(" Authorization is applicable for object because of type match, authorization {}, query {}", new Object[] { specObjectClass, objectType });
// The spec type is a subclass of requested type. So it might be returned from the search.
// We need to use type filter.
objSpecTypeFilter = TypeFilter.createType(specTypeQName, null);
// and now we have a more specific object definition to use later in filter processing
objectDefinition = (PrismObjectDefinition<T>) specObjectDef;
}
}
// Owner
if (objectSpecType.getOwner() != null) {
if (objectDefinition == null) {
objectDefinition = prismContext.getSchemaRegistry().findObjectDefinitionByCompileTimeClass(objectType);
}
// TODO: MID-3899
if (AbstractRoleType.class.isAssignableFrom(objectType)) {
objSpecSecurityFilter = applyOwnerFilterOwnerRef(new ItemPath(AbstractRoleType.F_OWNER_REF), objSpecSecurityFilter, principal, objectDefinition);
} else if (TaskType.class.isAssignableFrom(objectType)) {
objSpecSecurityFilter = applyOwnerFilterOwnerRef(new ItemPath(TaskType.F_OWNER_REF), objSpecSecurityFilter, principal, objectDefinition);
} else {
LOGGER.trace(" Authorization not applicable for object because it has owner specification (this is not applicable for search)");
continue;
}
}
// // Delegator
// if (objectSpecType.getDelegator() != null) {
// if (objectDefinition == null) {
// objectDefinition = prismContext.getSchemaRegistry().findObjectDefinitionByCompileTimeClass(objectType);
// }
// // TODO: MID-3899
// if (UserType.class.isAssignableFrom(objectType)) { TODO
// objSpecSecurityFilter = applyOwnerFilterOwnerRef(new ItemPath(AbstractRoleType.F_OWNER_REF), objSpecSecurityFilter, principal, objectDefinition);
// } else if (TaskType.class.isAssignableFrom(objectType)) {
// objSpecSecurityFilter = applyOwnerFilterOwnerRef(new ItemPath(TaskType.F_OWNER_REF), objSpecSecurityFilter, principal, objectDefinition);
// } else {
// LOGGER.trace(" Authorization not applicable for object because it has owner specification (this is not applicable for search)");
// continue;
// }
// }
applicable = true;
// Special
List<SpecialObjectSpecificationType> specSpecial = objectSpecType.getSpecial();
if (specSpecial != null && !specSpecial.isEmpty()) {
if (!includeSpecial) {
LOGGER.trace(" Skipping authorization, because specials are present: {}", specSpecial);
applicable = false;
}
if (specFilterType != null || specOrgRef != null || specOrgRelation != null || specRoleRelation != null) {
throw new SchemaException("Both filter/org/role and special object specification specified in authorization");
}
ObjectFilter specialFilter = null;
for (SpecialObjectSpecificationType special : specSpecial) {
if (special == SpecialObjectSpecificationType.SELF) {
String principalOid = principal.getOid();
specialFilter = ObjectQueryUtil.filterOr(specialFilter, InOidFilter.createInOid(principalOid));
} else {
throw new SchemaException("Unsupported special object specification specified in authorization: " + special);
}
}
objSpecSecurityFilter = specTypeQName != null ? TypeFilter.createType(specTypeQName, specialFilter) : specialFilter;
} else {
LOGGER.trace(" specials empty: {}", specSpecial);
}
// Filter
if (specFilterType != null) {
if (objectDefinition == null) {
objectDefinition = prismContext.getSchemaRegistry().findObjectDefinitionByCompileTimeClass(objectType);
}
ObjectFilter specFilter = QueryJaxbConvertor.createObjectFilter(objectDefinition, specFilterType, prismContext);
if (specFilter != null) {
ObjectQueryUtil.assertNotRaw(specFilter, "Filter in authorization object has undefined items. Maybe a 'type' specification is missing in the authorization?");
ObjectQueryUtil.assertPropertyOnly(specFilter, "Filter in authorization object is not property-only filter");
}
LOGGER.trace(" applying property filter {}", specFilter);
objSpecSecurityFilter = ObjectQueryUtil.filterAnd(objSpecSecurityFilter, specFilter);
} else {
LOGGER.trace(" filter empty");
}
// Org
if (specOrgRef != null) {
ObjectFilter orgFilter = QueryBuilder.queryFor(ObjectType.class, prismContext).isChildOf(specOrgRef.getOid()).buildFilter();
objSpecSecurityFilter = ObjectQueryUtil.filterAnd(objSpecSecurityFilter, orgFilter);
LOGGER.trace(" applying org filter {}", orgFilter);
} else {
LOGGER.trace(" org empty");
}
// orgRelation
if (specOrgRelation != null) {
ObjectFilter objSpecOrgRelationFilter = null;
QName subjectRelation = specOrgRelation.getSubjectRelation();
for (ObjectReferenceType subjectParentOrgRef : principal.getUser().getParentOrgRef()) {
if (MiscSchemaUtil.compareRelation(subjectRelation, subjectParentOrgRef.getRelation())) {
S_FilterEntryOrEmpty q = QueryBuilder.queryFor(ObjectType.class, prismContext);
S_AtomicFilterExit q2;
if (specOrgRelation.getScope() == null || specOrgRelation.getScope() == OrgScopeType.ALL_DESCENDANTS) {
q2 = q.isChildOf(subjectParentOrgRef.getOid());
} else if (specOrgRelation.getScope() == OrgScopeType.DIRECT_DESCENDANTS) {
q2 = q.isDirectChildOf(subjectParentOrgRef.getOid());
} else if (specOrgRelation.getScope() == OrgScopeType.ALL_ANCESTORS) {
q2 = q.isParentOf(subjectParentOrgRef.getOid());
} else {
throw new UnsupportedOperationException("Unknown orgRelation scope " + specOrgRelation.getScope());
}
if (BooleanUtils.isTrue(specOrgRelation.isIncludeReferenceOrg())) {
q2 = q2.or().id(subjectParentOrgRef.getOid());
}
objSpecOrgRelationFilter = ObjectQueryUtil.filterOr(objSpecOrgRelationFilter, q2.buildFilter());
}
}
if (objSpecOrgRelationFilter == null) {
objSpecOrgRelationFilter = NoneFilter.createNone();
}
objSpecSecurityFilter = ObjectQueryUtil.filterAnd(objSpecSecurityFilter, objSpecOrgRelationFilter);
LOGGER.trace(" applying orgRelation filter {}", objSpecOrgRelationFilter);
} else {
LOGGER.trace(" orgRelation empty");
}
// roleRelation
if (specRoleRelation != null) {
ObjectFilter objSpecRoleRelationFilter = processRoleRelationFilter(principal, autz, specRoleRelation, queryItemsSpec, origFilter);
if (objSpecRoleRelationFilter == null) {
if (autz.maySkipOnSearch()) {
LOGGER.trace(" not applying roleRelation filter because it is not efficient and maySkipOnSearch is set", objSpecRoleRelationFilter);
applicable = false;
} else {
objSpecRoleRelationFilter = NoneFilter.createNone();
}
}
if (objSpecRoleRelationFilter != null) {
objSpecSecurityFilter = ObjectQueryUtil.filterAnd(objSpecSecurityFilter, objSpecRoleRelationFilter);
LOGGER.trace(" applying roleRelation filter {}", objSpecRoleRelationFilter);
}
} else {
LOGGER.trace(" roleRelation empty");
}
if (objSpecTypeFilter != null) {
objSpecTypeFilter.setFilter(objSpecSecurityFilter);
objSpecSecurityFilter = objSpecTypeFilter;
}
traceFilter("objSpecSecurityFilter", objectSpecType, objSpecSecurityFilter);
autzObjSecurityFilter = ObjectQueryUtil.filterOr(autzObjSecurityFilter, objSpecSecurityFilter);
}
}
traceFilter("autzObjSecurityFilter", autz, autzObjSecurityFilter);
if (applicable) {
autzObjSecurityFilter = ObjectQueryUtil.simplify(autzObjSecurityFilter);
// authority is applicable to this situation. now we can process the decision.
AuthorizationDecisionType decision = autz.getDecision();
if (decision == null || decision == AuthorizationDecisionType.ALLOW) {
// allow
if (ObjectQueryUtil.isAll(autzObjSecurityFilter)) {
// this is "allow all" authorization.
hasAllowAll = true;
} else {
securityFilterAllow = ObjectQueryUtil.filterOr(securityFilterAllow, autzObjSecurityFilter);
}
if (!ObjectQueryUtil.isNone(autzObjSecurityFilter)) {
queryItemsSpec.addAllowedItems(autz);
}
} else {
// deny
if (autz.getItem() != null && !autz.getItem().isEmpty()) {
// This is a tricky situation. We have deny authorization, but it only denies access to
// some items. Therefore we need to find the objects and then filter out the items.
// Therefore do not add this authorization into the filter.
} else {
if (ObjectQueryUtil.isAll(autzObjSecurityFilter)) {
// This is "deny all". We cannot have anything stronger than that.
// There is no point in continuing the evaluation.
LOGGER.trace("AUTZ {}: principal={}, operation={}: deny all", desc, new Object[] { getUsername(principal), operationUrl });
NoneFilter secFilter = NoneFilter.createNone();
traceFilter("secFilter", null, secFilter);
return secFilter;
}
securityFilterDeny = ObjectQueryUtil.filterOr(securityFilterDeny, autzObjSecurityFilter);
}
}
}
traceFilter("securityFilterAllow", autz, securityFilterAllow);
traceFilter("securityFilterDeny", autz, securityFilterDeny);
} else {
LOGGER.warn("Unknown authority type {} in user {}", authority.getClass(), getUsername(principal));
}
}
}
traceFilter("securityFilterAllow", null, securityFilterAllow);
traceFilter("securityFilterDeny", null, securityFilterDeny);
if (LOGGER.isTraceEnabled()) {
LOGGER.trace(" Final items: {}", queryItemsSpec.shortDump());
}
List<ItemPath> unsatisfiedItems = queryItemsSpec.evaluateUnsatisfierItems();
if (!unsatisfiedItems.isEmpty()) {
LOGGER.trace("AUTZ {}: principal={}, operation={}: deny because items {} are not allowed", desc, getUsername(principal), operationUrl, unsatisfiedItems);
NoneFilter secFilter = NoneFilter.createNone();
traceFilter("secFilter", null, secFilter);
return secFilter;
}
ObjectFilter origWithAllowFilter;
if (hasAllowAll) {
origWithAllowFilter = origFilter;
} else if (securityFilterAllow == null) {
// Nothing has been allowed. This means default deny.
LOGGER.trace("AUTZ {}: principal={}, operation={}: default deny", desc, getUsername(principal), operationUrl);
NoneFilter secFilter = NoneFilter.createNone();
traceFilter("secFilter", null, secFilter);
return secFilter;
} else {
origWithAllowFilter = ObjectQueryUtil.filterAnd(origFilter, securityFilterAllow);
}
if (securityFilterDeny == null) {
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("AUTZ {}: principal={}, operation={}: allow:\n{}", desc, getUsername(principal), operationUrl, origWithAllowFilter == null ? "null" : origWithAllowFilter.debugDump());
}
traceFilter("origWithAllowFilter", null, origWithAllowFilter);
return origWithAllowFilter;
} else {
ObjectFilter secFilter = ObjectQueryUtil.filterAnd(origWithAllowFilter, NotFilter.createNot(securityFilterDeny));
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("AUTZ {}: principal={}, operation={}: allow (with deny clauses):\n{}", desc, getUsername(principal), operationUrl, secFilter == null ? "null" : secFilter.debugDump());
}
traceFilter("secFilter", null, secFilter);
return secFilter;
}
}
Aggregations