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
KaterynaHonchar committed Sep 4, 2018
2 parents 9a52207 + 30bbc56 commit 6c8aaf0
Show file tree
Hide file tree
Showing 43 changed files with 891 additions and 262 deletions.
Expand Up @@ -290,7 +290,7 @@ public void populateItem(Item<ICellPopulator<ContainerValueWrapper<ObjectPolicyC

ContainerWrapper<LifecycleStateModelType> lifecycleState = rowModel.getObject().findContainerWrapper(new ItemPath(rowModel.getObject().getPath(), ObjectPolicyConfigurationType.F_LIFECYCLE_STATE_MODEL));

if(lifecycleState.getValues().get(0).getContainerValue().getValue().getState()==null ||
if (lifecycleState == null || lifecycleState.getValues().get(0).getContainerValue().getValue().getState()==null ||
lifecycleState.getValues().get(0).getContainerValue().getValue().getState().isEmpty()) {
item.add(new Label(componentId, createStringResource("ObjectPolicyConfigurationTabPanel.lifecycleState.value.no")));
} else {
Expand Down
Expand Up @@ -22,6 +22,7 @@
import java.util.List;
import java.util.Map;

import com.evolveum.midpoint.prism.util.CloneUtil;
import org.apache.commons.lang.StringUtils;

import com.evolveum.midpoint.xml.ns._public.common.common_3.AuditingConfigurationType;
Expand Down Expand Up @@ -135,7 +136,7 @@ public LoggingConfigurationType getNewObject() {
configuration.setRootLoggerLevel(getRootLevel());

for (AppenderConfiguration item : getAppenders()) {
configuration.getAppender().add(item.getConfig());
configuration.getAppender().add(CloneUtil.clone(item.getConfig()));
}

for (LoggerConfiguration item : getLoggers()) {
Expand Down
Expand Up @@ -294,16 +294,16 @@ public <O extends ObjectType> ObjectSecurityConstraints compileSecurityConstrain
}

@Override
public <T extends ObjectType, O extends ObjectType> ObjectFilter preProcessObjectFilter(String operationUrl, AuthorizationPhaseType phase,
public <T extends ObjectType, O extends ObjectType> ObjectFilter preProcessObjectFilter(String[] operationUrls, AuthorizationPhaseType phase,
Class<T> objectType, PrismObject<O> object, ObjectFilter origFilter, String limitAuthorizationAction, Task task, OperationResult result) throws SchemaException, ObjectNotFoundException, ExpressionEvaluationException, CommunicationException, ConfigurationException, SecurityViolationException {
return securityEnforcer.preProcessObjectFilter(operationUrl, phase, objectType, object, origFilter, limitAuthorizationAction, task, result);
return securityEnforcer.preProcessObjectFilter(operationUrls, phase, objectType, object, origFilter, limitAuthorizationAction, task, result);
}

@Override
public <T extends ObjectType, O extends ObjectType> boolean canSearch(String operationUrl,
public <T extends ObjectType, O extends ObjectType> boolean canSearch(String[] operationUrls,
AuthorizationPhaseType phase, Class<T> objectType, PrismObject<O> object, boolean includeSpecial, ObjectFilter filter, Task task, OperationResult result)
throws SchemaException, ObjectNotFoundException, ExpressionEvaluationException, CommunicationException, ConfigurationException, SecurityViolationException {
return securityEnforcer.canSearch(operationUrl, phase, objectType, object, includeSpecial, filter, task, result);
return securityEnforcer.canSearch(operationUrls, phase, objectType, object, includeSpecial, filter, task, result);
}

@Override
Expand Down
Expand Up @@ -463,6 +463,7 @@ public abstract class SchemaConstants {
public static final QName C_EVENT = new QName(NS_C, "event");
public static final QName C_EVENT_HANDLER = new QName(NS_C, "eventHandler"); // TODO: no such element in common-3 - is it OK?
public static final QName C_TEXT_FORMATTER = new QName(NS_C, "textFormatter");
public static final QName C_NOTIFICATION_FUNCTIONS = new QName(NS_C, "notificationFunctions");

public static final QName C_TRANSPORT_NAME = new QName(NS_C, "transportName");
public static final QName C_FROM = new QName(NS_C, "from");
Expand Down
Expand Up @@ -8471,8 +8471,22 @@
<xsd:element name="expression" type="tns:ExpressionType" minOccurs="0" maxOccurs="1"/>
<xsd:element name="target" type="tns:VariableBindingDefinitionType" minOccurs="0" maxOccurs="1"/>
<xsd:element name="condition" type="tns:ExpressionType" minOccurs="0" maxOccurs="1"/>
<xsd:element name="inputFilter" type="tns:ValueFilterType" minOccurs="0"/>
<xsd:element name="outputFilter" type="tns:ValueFilterType" minOccurs="0"/>
<xsd:element name="inputFilter" type="tns:ValueFilterType" minOccurs="0">
<xsd:annotation>
<xsd:appinfo>
<a:deprecated>true</a:deprecated>
<a:plannedRemoval>4.0</a:plannedRemoval>
</xsd:appinfo>
</xsd:annotation>
</xsd:element>
<xsd:element name="outputFilter" type="tns:ValueFilterType" minOccurs="0">
<xsd:annotation>
<xsd:appinfo>
<a:deprecated>true</a:deprecated>
<a:plannedRemoval>4.0</a:plannedRemoval>
</xsd:appinfo>
</xsd:annotation>
</xsd:element>
<xsd:element name="range" minOccurs="0" type="tns:ValueSetSpecificationType">
<xsd:annotation>
<xsd:documentation>
Expand Down Expand Up @@ -8660,6 +8674,7 @@
</xsd:documentation>
<xsd:appinfo>
<a:deprecated>true</a:deprecated>
<a:plannedRemoval>4.0</a:plannedRemoval>
</xsd:appinfo>
</xsd:annotation>
<xsd:sequence>
Expand Down Expand Up @@ -9208,6 +9223,17 @@
</xsd:appinfo>
</xsd:annotation>
</xsd:element>
<xsd:element name="condition" type="tns:ExpressionType" minOccurs="0">
<xsd:annotation>
<xsd:documentation>
Condition driving whether this expression is evaluated at all (for given inputs).
</xsd:documentation>
<xsd:appinfo>
<a:experimental>true</a:experimental>
<a:since>3.9</a:since>
</xsd:appinfo>
</xsd:annotation>
</xsd:element>
</xsd:sequence>
</xsd:complexType>

Expand Down
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2010-2017 Evolveum
* Copyright (c) 2010-2018 Evolveum
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -23,6 +23,8 @@
public enum ModelAuthorizationAction implements DisplayableValue<String> {

READ("read", "Read", "READ_HELP"),
GET("get", "Get", "GET_HELP"),
SEARCH("search", "Search", "SEARCH_HELP"),
ADD("add", "Add", "ADD_HELP"),
MODIFY("modify", "Modify", "MODIFY_HELP"),
DELETE("delete", "Delete", "DELETE_HELP"),
Expand Down Expand Up @@ -85,6 +87,13 @@ public enum ModelAuthorizationAction implements DisplayableValue<String> {

RAW_OPERATION("rawOperation", "Raw operation", "RAW_OPERATION_HELP"),
PARTIAL_EXECUTION("partialExecution", "Partial execution", "PARTIAL_EXECUTION_HELP");

public static final String[] AUTZ_ACTIONS_URLS_SEARCH = new String[] { READ.getUrl(), SEARCH.getUrl() };
public static final String[] AUTZ_ACTIONS_URLS_GET = new String[] { READ.getUrl(), GET.getUrl() };
public static final String[] AUTZ_ACTIONS_URLS_ADD = new String[] { ADD.getUrl() };
public static final String[] AUTZ_ACTIONS_URLS_MODIFY = new String[] { MODIFY.getUrl() };
public static final String[] AUTZ_ACTIONS_URLS_ASSIGN = new String[] { ASSIGN.getUrl() };
public static final String[] AUTZ_ACTIONS_URLS_ATTORNEY = new String[] { ATTORNEY.getUrl() };

private String url;
private String label;
Expand Down
Expand Up @@ -15,35 +15,20 @@
*/
package com.evolveum.midpoint.model.common.expression.evaluator;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.*;
import java.util.Map.Entry;

import javax.xml.namespace.QName;

import com.evolveum.midpoint.common.LocalizationService;
import com.evolveum.midpoint.prism.Item;
import com.evolveum.midpoint.prism.ItemDefinition;
import com.evolveum.midpoint.prism.PrismPropertyValue;
import com.evolveum.midpoint.prism.PrismValue;
import com.evolveum.midpoint.prism.*;
import com.evolveum.midpoint.prism.delta.DeltaSetTriple;
import com.evolveum.midpoint.prism.delta.ItemDelta;
import com.evolveum.midpoint.prism.delta.PlusMinusZero;
import com.evolveum.midpoint.prism.delta.PrismValueDeltaSetTriple;
import com.evolveum.midpoint.prism.path.ItemPath;
import com.evolveum.midpoint.prism.polystring.PolyString;
import com.evolveum.midpoint.repo.common.expression.ExpressionEvaluationContext;
import com.evolveum.midpoint.repo.common.expression.ExpressionEvaluator;
import com.evolveum.midpoint.repo.common.expression.ExpressionSyntaxException;
import com.evolveum.midpoint.repo.common.expression.ExpressionVariables;
import com.evolveum.midpoint.repo.common.expression.ItemDeltaItem;
import com.evolveum.midpoint.repo.common.expression.ObjectDeltaObject;
import com.evolveum.midpoint.repo.common.expression.Source;
import com.evolveum.midpoint.repo.common.expression.SourceTriple;
import com.evolveum.midpoint.repo.common.expression.*;
import com.evolveum.midpoint.schema.constants.ExpressionConstants;
import com.evolveum.midpoint.schema.result.OperationResult;
import com.evolveum.midpoint.schema.util.ExceptionUtil;
Expand Down Expand Up @@ -350,6 +335,14 @@ private PrismValueDeltaSetTriple<V> evaluateRelativeExpression(final List<Source

final PrismValueDeltaSetTriple<V> outputTriple = new PrismValueDeltaSetTriple<>();

Expression<PrismPropertyValue<Boolean>, PrismPropertyDefinition<Boolean>> conditionExpression;
if (expressionEvaluatorType.getCondition() != null) {
conditionExpression = ExpressionUtil.createCondition(expressionEvaluatorType.getCondition(),
evaluationContext.getExpressionFactory(), "condition in " + contextDescription, task, result);
} else {
conditionExpression = null;
}

Processor<Collection<? extends PrismValue>> processor = pvalues -> {
if (includeNulls != null && !includeNulls && MiscUtil.isAllNull(pvalues)) {
// The case that all the sources are null. There is no point executing the expression.
Expand Down Expand Up @@ -426,8 +419,22 @@ private PrismValueDeltaSetTriple<V> evaluateRelativeExpression(final List<Source

List<V> scriptResults;
try {
scriptResults = transformSingleValue(scriptVariables, valueDestination, useNew, evaluationContext,
contextDescription, task, result);
boolean conditionResult;
if (conditionExpression != null) {
ExpressionEvaluationContext ctx = new ExpressionEvaluationContext(null, scriptVariables,
"condition in " + contextDescription, task, result);
PrismValueDeltaSetTriple<PrismPropertyValue<Boolean>> triple = conditionExpression.evaluate(ctx);
conditionResult = ExpressionUtil.computeConditionResult(triple.getNonNegativeValues());
} else {
conditionResult = true;
}
if (conditionResult) {
scriptResults = transformSingleValue(scriptVariables, valueDestination, useNew, evaluationContext,
contextDescription, task, result);
} else {
LOGGER.trace("Skipping value transformation because condition evaluated to false in {}", contextDescription);
scriptResults = Collections.emptyList();
}
} catch (ExpressionEvaluationException e) {
throw new TunnelException(
localizationService.translate(
Expand Down
Expand Up @@ -815,7 +815,7 @@ private XMLGregorianCalendar parseTimeSource(VariableBindingDefinitionType sourc
throw new SchemaException("Empty source path in "+getMappingContextDescription());
}

Object sourceObject = ExpressionUtil.resolvePath(path, variables, sourceContext, objectResolver, "reference time definition in "+getMappingContextDescription(), task, result);
Object sourceObject = ExpressionUtil.resolvePath(path, variables, false, sourceContext, objectResolver, "reference time definition in "+getMappingContextDescription(), task, result);
if (sourceObject == null) {
return null;
}
Expand Down Expand Up @@ -871,7 +871,7 @@ private <IV extends PrismValue, ID extends ItemDefinition> Source<IV,ID> parseSo
name = ItemPath.getName(path.last());
}
ItemPath resolvePath = path;
Object sourceObject = ExpressionUtil.resolvePath(path, variables, sourceContext, objectResolver, "source definition in "+getMappingContextDescription(), task, result);
Object sourceObject = ExpressionUtil.resolvePath(path, variables, true, sourceContext, objectResolver, "source definition in "+getMappingContextDescription(), task, result);
Item<IV,ID> itemOld = null;
ItemDelta<IV,ID> delta = null;
Item<IV,ID> itemNew = null;
Expand Down
Expand Up @@ -206,7 +206,7 @@ private <T> T resolvePath(String path, ExpressionVariables variables, final Stri
ItemPath itemPath = toItemPath(path);

// WHEN
Object resolved = ExpressionUtil.resolvePath(itemPath, variables, null, null, TEST_NAME, null, result);
Object resolved = ExpressionUtil.resolvePath(itemPath, variables, false, null, null, TEST_NAME, null, result);

// THEN
System.out.println("Resolved:");
Expand Down
Expand Up @@ -790,16 +790,23 @@ public <T extends ObjectType> SearchResultList<PrismObject<T>> searchObjects(Cla
QNameUtil.setTemporarilyTolerateUndeclaredPrefixes(true);
}
switch (searchProvider) {
case EMULATED: list = emulatedSearchProvider.searchObjects(type, query, options, result); break;
case REPOSITORY: list = cacheRepositoryService.searchObjects(type, query, options, result); break;
case PROVISIONING: list = provisioning.searchObjects(type, query, options, task, result); break;
case EMULATED:
list = emulatedSearchProvider.searchObjects(type, query, options, result);
break;
case REPOSITORY:
list = cacheRepositoryService.searchObjects(type, query, options, result);
break;
case PROVISIONING:
list = provisioning.searchObjects(type, query, options, task, result);
break;
case TASK_MANAGER:
list = taskManager.searchObjects(type, query, options, result);
if (workflowManager != null && TaskType.class.isAssignableFrom(type) && !GetOperationOptions.isRaw(rootOptions) && !GetOperationOptions.isNoFetch(rootOptions)) {
workflowManager.augmentTaskObjectList(list, options, task, result);
}
break;
default: throw new AssertionError("Unexpected search provider: " + searchProvider);
default:
throw new AssertionError("Unexpected search provider: " + searchProvider);
}
result.computeStatus();
result.cleanupResult();
Expand All @@ -816,6 +823,10 @@ public <T extends ObjectType> SearchResultList<PrismObject<T>> searchObjects(Cla
if (list == null) {
list = new SearchResultList<>(new ArrayList<PrismObject<T>>());
}

if (LOGGER.isTraceEnabled()) {
LOGGER.trace("Basic search returned {} results (before hooks, security, etc.)", list.size());
}

for (PrismObject<T> object : list) {
if (hookRegistry != null) {
Expand All @@ -842,6 +853,10 @@ public <T extends ObjectType> SearchResultList<PrismObject<T>> searchObjects(Cla
} finally {
exitModelMethod();
}

if (LOGGER.isTraceEnabled()) {
LOGGER.trace("Final search returned {} results (after hooks, security and all other processing)", list.size());
}

return list;
}
Expand Down Expand Up @@ -1051,13 +1066,17 @@ protected boolean isFilterNone(ObjectQuery query, OperationResult result) {
}

protected void logQuery(ObjectQuery query) {
if (!LOGGER.isTraceEnabled()) {
return;
}
if (query != null){
if (query.getPaging() == null) {
LOGGER.trace("Searching objects with null paging (query in TRACE).");
LOGGER.trace("Searching objects with null paging. Query:\n{}", query.debugDump(1));
} else {
LOGGER.trace("Searching objects from {} to {} ordered {} by {} (query in TRACE).",
LOGGER.trace("Searching objects from {} to {} ordered {} by {}. Query:\n{}",
query.getPaging().getOffset(), query.getPaging().getMaxSize(),
query.getPaging().getDirection(), query.getPaging().getOrderBy());
query.getPaging().getDirection(), query.getPaging().getOrderBy(),
query.debugDump(1));
}
}
}
Expand Down Expand Up @@ -1086,6 +1105,7 @@ public <T extends ObjectType> SearchResultMetadata searchObjectsIterative(Class<

query = preProcessQuerySecurity(type, query, task, result);
if (isFilterNone(query, result)) {
LOGGER.trace("Skipping search because filter is NONE");
return null;
}

Expand Down Expand Up @@ -1165,6 +1185,7 @@ public <T extends ObjectType> Integer countObjects(Class<T> type, ObjectQuery qu

query = preProcessQuerySecurity(type, query, task, result);
if (isFilterNone(query, result)) {
LOGGER.trace("Skipping count because filter is NONE");
return 0;
}

Expand All @@ -1180,9 +1201,15 @@ public <T extends ObjectType> Integer countObjects(Class<T> type, ObjectQuery qu
objectManager = ObjectTypes.ObjectManager.REPOSITORY;
}
switch (objectManager) {
case PROVISIONING: count = provisioning.countObjects(type, query, options, task, parentResult); break;
case REPOSITORY: count = cacheRepositoryService.countObjects(type, query, options, parentResult); break;
case TASK_MANAGER: count = taskManager.countObjects(type, query, parentResult); break;
case PROVISIONING:
count = provisioning.countObjects(type, query, options, task, parentResult);
break;
case REPOSITORY:
count = cacheRepositoryService.countObjects(type, query, options, parentResult);
break;
case TASK_MANAGER:
count = taskManager.countObjects(type, query, parentResult);
break;
default: throw new AssertionError("Unexpected objectManager: " + objectManager);
}
} catch (ConfigurationException | SecurityViolationException | SchemaException | ObjectNotFoundException | CommunicationException | ExpressionEvaluationException | RuntimeException | Error e) {
Expand Down Expand Up @@ -1761,13 +1788,14 @@ private <O extends ObjectType> ObjectQuery preProcessQuerySecurity(Class<O> obje
if (origQuery != null) {
origFilter = origQuery.getFilter();
}
ObjectFilter secFilter = securityEnforcer.preProcessObjectFilter(ModelAuthorizationAction.READ.getUrl(), null, objectType, null, origFilter, null, task, result);
ObjectFilter secFilter = securityEnforcer.preProcessObjectFilter(ModelAuthorizationAction.AUTZ_ACTIONS_URLS_SEARCH, null, objectType, null, origFilter, null, task, result);
return updateObjectQuery(origQuery, secFilter);
}

// we expect that objectType is a direct parent of containerType
private <C extends Containerable, O extends ObjectType> ObjectQuery preProcessSubobjectQuerySecurity(Class<C> containerType, Class<O> objectType, ObjectQuery origQuery, Task task, OperationResult result) throws SchemaException, ObjectNotFoundException, ExpressionEvaluationException, CommunicationException, ConfigurationException, SecurityViolationException {
ObjectFilter secParentFilter = securityEnforcer.preProcessObjectFilter(ModelAuthorizationAction.READ.getUrl(), null, objectType, null, null, null, task, result);
// Search containers is an operation on one object. Therefore even if it works with a search filter, it requires GET authorizations
ObjectFilter secParentFilter = securityEnforcer.preProcessObjectFilter(ModelAuthorizationAction.AUTZ_ACTIONS_URLS_GET, null, objectType, null, null, null, task, result);
if (secParentFilter == null || secParentFilter instanceof AllFilter) {
return origQuery; // no need to update the query
}
Expand Down

0 comments on commit 6c8aaf0

Please sign in to comment.