use of com.evolveum.midpoint.util.exception.CommunicationException in project midpoint by Evolveum.
the class CustomFunctions method execute.
/**
* This method is invoked by the scripts. It is supposed to be only public method exposed
* by this class.
*/
public <V extends PrismValue, D extends ItemDefinition> Object execute(String functionName, Map<String, Object> params) throws ExpressionEvaluationException {
Validate.notNull(functionName, "Function name must be specified");
ScriptExpressionEvaluationContext ctx = ScriptExpressionEvaluationContext.getThreadLocal();
Task task;
OperationResult result;
if (ctx != null) {
if (ctx.getTask() != null) {
task = ctx.getTask();
} else {
// We shouldn't use task of unknown provenience.
throw new IllegalStateException("No task in ScriptExpressionEvaluationContext for the current thread found");
}
if (ctx.getResult() != null) {
result = ctx.getResult();
} else {
// This situation should never occur anyway.
throw new IllegalStateException("No operation result in ScriptExpressionEvaluationContext for the current thread found");
}
} else {
// This situation should never occur anyway.
throw new IllegalStateException("No ScriptExpressionEvaluationContext for current thread found");
}
List<ExpressionType> functions = library.getFunction().stream().filter(expression -> functionName.equals(expression.getName())).collect(Collectors.toList());
LOGGER.trace("functions {}", functions);
ExpressionType expressionType = MiscUtil.extractSingletonRequired(functions, () -> new ExpressionEvaluationException(functions.size() + " functions named '" + functionName + "' present"), () -> new ExpressionEvaluationException("No function named '" + functionName + "' present"));
LOGGER.trace("function to execute {}", expressionType);
try {
VariablesMap variables = new VariablesMap();
if (MapUtils.isNotEmpty(params)) {
for (Map.Entry<String, Object> entry : params.entrySet()) {
variables.put(entry.getKey(), convertInput(entry, expressionType));
}
}
QName returnType = defaultIfNull(expressionType.getReturnType(), DOMUtil.XSD_STRING);
D outputDefinition = prepareOutputDefinition(returnType, expressionType.getReturnMultiplicity());
String shortDesc = "custom function execute";
Expression<V, D> expression = expressionFactory.makeExpression(expressionType, outputDefinition, expressionProfile, shortDesc, task, result);
ExpressionEvaluationContext context = new ExpressionEvaluationContext(null, variables, shortDesc, task);
PrismValueDeltaSetTriple<V> outputTriple = expression.evaluate(context, result);
LOGGER.trace("Result of the expression evaluation: {}", outputTriple);
if (outputTriple == null) {
return null;
}
Collection<V> nonNegativeValues = outputTriple.getNonNegativeValues();
if (nonNegativeValues.isEmpty()) {
return null;
}
if (outputDefinition.isMultiValue()) {
return PrismValueCollectionsUtil.getRealValuesOfCollection(nonNegativeValues);
}
if (nonNegativeValues.size() > 1) {
throw new ExpressionEvaluationException("Expression returned more than one value (" + nonNegativeValues.size() + ") in " + shortDesc);
}
return nonNegativeValues.iterator().next().getRealValue();
} catch (SchemaException | ExpressionEvaluationException | ObjectNotFoundException | CommunicationException | ConfigurationException | SecurityViolationException e) {
throw new ExpressionEvaluationException(e.getMessage(), e);
}
}
use of com.evolveum.midpoint.util.exception.CommunicationException in project midpoint by Evolveum.
the class ConnectorFactoryConnIdImpl method listConnectors.
/**
* Returns a list XML representation of the ICF connectors.
*/
@Override
public Set<ConnectorType> listConnectors(ConnectorHostType host, OperationResult parentResult) throws CommunicationException {
OperationResult result = parentResult.createSubresult(ConnectorFactory.OPERATION_LIST_CONNECTORS);
result.addContext(OperationResult.CONTEXT_IMPLEMENTATION_CLASS, ConnectorFactoryConnIdImpl.class);
result.addParam("host", host);
try {
if (host == null) {
Set<ConnectorType> connectors = listLocalConnectors();
result.recordSuccess();
return connectors;
} else {
// This is necessary as list of the remote connectors is cached locally.
// So if any remote connector is added then it will not be discovered unless we
// clear the cache. This may look like inefficiency but in fact the listConnectors() method is
// used only when discovering new connectors. Normal connector operation is using connector objects
// stored in repository.
connectorInfoManagerFactory.clearRemoteCache();
Set<ConnectorType> connectors = listRemoteConnectors(host);
result.recordSuccess();
return connectors;
}
} catch (Throwable icfException) {
Throwable ex = processConnIdException(icfException, "list connectors", result);
result.recordFatalError(ex.getMessage(), ex);
if (ex instanceof CommunicationException) {
throw (CommunicationException) ex;
} else if (ex instanceof RuntimeException) {
throw (RuntimeException) ex;
} else if (ex instanceof Error) {
throw (Error) ex;
} else {
throw new SystemException("Unexpected ICF exception: " + ex.getMessage(), ex);
}
}
}
use of com.evolveum.midpoint.util.exception.CommunicationException in project midpoint by Evolveum.
the class SecurityEnforcerImpl method isAuthorizedPhase.
private <O extends ObjectType, T extends ObjectType> AccessDecision isAuthorizedPhase(MidPointPrincipal midPointPrincipal, String operationUrl, AuthorizationPhaseType phase, AuthorizationParameters<O, T> params, OwnerResolver ownerResolver, Consumer<Authorization> applicableAutzConsumer, Task task, OperationResult result) throws SchemaException, ObjectNotFoundException, ExpressionEvaluationException, CommunicationException, ConfigurationException, SecurityViolationException {
if (AuthorizationConstants.AUTZ_NO_ACCESS_URL.equals(operationUrl)) {
return AccessDecision.DENY;
}
if (phase == null) {
throw new IllegalArgumentException("No phase");
}
AccessDecision decision = AccessDecision.DEFAULT;
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("AUTZ: evaluating authorization principal={}, op={}, phase={}, {}", getUsername(midPointPrincipal), operationUrl, phase, params.shortDump());
}
final AutzItemPaths allowedItems = new AutzItemPaths();
Collection<Authorization> authorities = getAuthorities(midPointPrincipal);
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(" {} not applicable for operation {}", autzHumanReadableDesc, operationUrl);
continue;
}
// phase
if (autz.getPhase() == null) {
LOGGER.trace(" {} is applicable for all phases (continuing evaluation)", autzHumanReadableDesc);
} else {
if (autz.getPhase() != phase) {
LOGGER.trace(" {} is not applicable for phases {} (breaking evaluation)", autzHumanReadableDesc, phase);
continue;
} else {
LOGGER.trace(" {} is applicable for phases {} (continuing evaluation)", autzHumanReadableDesc, phase);
}
}
// relation
if (!isApplicableRelation(autz, params.getRelation())) {
LOGGER.trace(" {} not applicable for relation {}", autzHumanReadableDesc, params.getRelation());
continue;
}
// orderConstraints
if (!isApplicableOrderConstraints(autz, params.getOrderConstraints())) {
if (LOGGER.isTraceEnabled()) {
LOGGER.trace(" {} not applicable for orderConstraints {}", autzHumanReadableDesc, SchemaDebugUtil.shortDumpOrderConstraintsList(params.getOrderConstraints()));
}
continue;
}
// object
if (isApplicableObject(autz, params.getOdo(), midPointPrincipal, ownerResolver, autzHumanReadableDesc, task, result)) {
LOGGER.trace(" {} applicable for object {} (continuing evaluation)", autzHumanReadableDesc, params.getAnyObject());
} else {
LOGGER.trace(" {} not applicable for object {}, none of the object specifications match (breaking evaluation)", autzHumanReadableDesc, params.getAnyObject());
continue;
}
// target
if (isApplicable(autz.getTarget(), params.getTarget(), midPointPrincipal, ownerResolver, "target", autzHumanReadableDesc, task, result)) {
LOGGER.trace(" {} applicable for target {} (continuing evaluation)", autzHumanReadableDesc, params.getAnyObject());
} else {
LOGGER.trace(" {} not applicable for target {}, none of the target specifications match (breaking evaluation)", autzHumanReadableDesc, params.getAnyObject());
continue;
}
if (applicableAutzConsumer != null) {
applicableAutzConsumer.accept(autz);
}
// authority is applicable to this situation. now we can process the decision.
AuthorizationDecisionType autzDecision = autz.getDecision();
if (autzDecision == null || autzDecision.equals(AuthorizationDecisionType.ALLOW)) {
allowedItems.collectItems(autz);
LOGGER.trace(" {}: ALLOW operation {} (but continue evaluation)", autzHumanReadableDesc, operationUrl);
decision = AccessDecision.ALLOW;
// Do NOT break here. Other authorization statements may still deny the operation
} else {
// item
if (isApplicableItem(autz, params.getOldObject(), params.getDelta())) {
LOGGER.trace(" {}: Deny authorization applicable for items (continuing evaluation)", autzHumanReadableDesc);
} else {
LOGGER.trace(" {} not applicable for items (breaking evaluation)", autzHumanReadableDesc);
continue;
}
LOGGER.trace(" {}: DENY operation {}", autzHumanReadableDesc, operationUrl);
decision = AccessDecision.DENY;
// Break right here. Deny cannot be overridden by allow. This decision cannot be changed.
break;
}
} else {
LOGGER.warn("Unknown authority type {} in user {}", authority.getClass(), getUsername(midPointPrincipal));
}
}
}
if (decision == AccessDecision.ALLOW) {
// Still check allowedItems. We may still deny the operation.
if (allowedItems.isAllItems()) {
// This means all items are allowed. No need to check anything
LOGGER.trace(" Empty list of allowed items, operation allowed");
} else {
// all items in the object and delta must be allowed
LOGGER.trace(" Checking for allowed items: {}", allowedItems);
ItemDecisionFunction itemDecisionFunction = (itemPath, removingContainer) -> decideAllowedItems(itemPath, allowedItems, phase, removingContainer);
AccessDecision itemsDecision = null;
if (params.hasDelta()) {
// Behave as if this is execution phase for delete delta authorizations. We do not want to avoid deleting objects just because there
// are automatic/operational items that were generated by midPoint. Otherwise we won't be really able to delete any object.
ItemDecisionFunction itemDecisionFunctionDelete = (itemPath, removingContainer) -> decideAllowedItems(itemPath, allowedItems, AuthorizationPhaseType.EXECUTION, removingContainer);
itemsDecision = determineDeltaDecision(params.getDelta(), params.getOldObject(), itemDecisionFunction, itemDecisionFunctionDelete);
} else if (params.hasObject()) {
itemsDecision = determineObjectDecision(params.getAnyObject(), itemDecisionFunction);
}
if (itemsDecision != AccessDecision.ALLOW) {
LOGGER.trace(" NOT ALLOWED operation because the item decision is {}", itemsDecision);
decision = AccessDecision.DEFAULT;
}
}
}
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("AUTZ result: principal={}, operation={}: {}", getUsername(midPointPrincipal), prettyActionUrl(operationUrl), decision);
}
return decision;
}
use of com.evolveum.midpoint.util.exception.CommunicationException in project midpoint by Evolveum.
the class ConnectorManager method discoverConnectors.
/**
* Lists local connectors and makes sure that appropriate ConnectorType
* objects for them exist in repository.
*
* It will never delete any repository object, even if the corresponding
* connector cannot be found. The connector may temporarily removed, may be
* present on a different node, manual upgrade may be needed etc.
*
* @return set of discovered connectors (new connectors found)
*/
// @SuppressWarnings("unchecked")
public Set<ConnectorType> discoverConnectors(ConnectorHostType hostType, OperationResult parentResult) throws CommunicationException {
OperationResult result = parentResult.createSubresult(ConnectorManager.class.getName() + ".discoverConnectors");
result.addParam("host", hostType);
// it
if (hostType != null && hostType.getOid() == null) {
throw new SystemException("Discovery attempt with non-persistent " + hostType);
}
Set<ConnectorType> discoveredConnectors = new HashSet<>();
for (ConnectorFactory connectorFactory : getConnectorFactories()) {
Set<ConnectorType> foundConnectors;
try {
foundConnectors = connectorFactory.listConnectors(hostType, result);
} catch (CommunicationException ex) {
result.recordFatalError("Discovery failed: " + ex.getMessage(), ex);
throw new CommunicationException("Discovery failed: " + ex.getMessage(), ex);
}
if (foundConnectors == null) {
LOGGER.trace("Connector factory {} discovered null connectors, skipping", connectorFactory);
continue;
}
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("Got {} connectors from {}: {}", foundConnectors.size(), hostType, foundConnectors);
}
for (ConnectorType foundConnector : foundConnectors) {
LOGGER.trace("Examining connector {}", foundConnector);
boolean inRepo = isInRepo(foundConnector, hostType, result);
if (inRepo) {
LOGGER.trace("Connector {} is in the repository, skipping", foundConnector);
} else {
if (notInRepoConsumer != null) {
notInRepoConsumer.accept(foundConnector);
}
if (addConnectorToRepo(foundConnector, result, hostType)) {
discoveredConnectors.add(foundConnector);
LOGGER.info("Discovered new connector {}", foundConnector);
}
}
}
}
result.recordSuccess();
return discoveredConnectors;
}
use of com.evolveum.midpoint.util.exception.CommunicationException in project midpoint by Evolveum.
the class ResourceObjectReferenceResolver method resolve.
/**
* Resolves a {@link ResourceObjectReferenceType}.
*
* @param useRawDefinition If true, object class definition is used (instead of object type definition).
* This is to avoid endless recursion when resolving the base context for object type.
*/
@Nullable
PrismObject<ShadowType> resolve(@NotNull ProvisioningContext ctx, @NotNull ResourceObjectReferenceType resourceObjectReference, boolean useRawDefinition, @NotNull String desc, @NotNull OperationResult result) throws ObjectNotFoundException, SchemaException, CommunicationException, ConfigurationException, SecurityViolationException, ExpressionEvaluationException {
ObjectReferenceType shadowRef = resourceObjectReference.getShadowRef();
if (shadowRef != null && shadowRef.getOid() != null) {
if (resourceObjectReference.getResolutionFrequency() == null || resourceObjectReference.getResolutionFrequency() == ResourceObjectReferenceResolutionFrequencyType.ONCE) {
PrismObject<ShadowType> shadow = repositoryService.getObject(ShadowType.class, shadowRef.getOid(), null, result);
shadowsFacade.applyDefinition(shadow, ctx.getTask(), result);
return shadow;
}
} else if (resourceObjectReference.getResolutionFrequency() == ResourceObjectReferenceResolutionFrequencyType.NEVER) {
throw new ObjectNotFoundException("No shadowRef OID in " + desc + " and resolution frequency set to NEVER");
}
argCheck(resourceObjectReference.getObjectClass() != null, "No object class name in object reference in %s", desc);
QName objectClassName = QNameUtil.qualifyIfNeeded(resourceObjectReference.getObjectClass(), MidPointConstants.NS_RI);
ProvisioningContext subCtx = useRawDefinition ? ctx.spawnForObjectClassWithRawDefinition(objectClassName) : ctx.spawnForObjectClass(objectClassName);
subCtx.assertDefinition();
ObjectQuery refQuery = prismContext.getQueryConverter().createObjectQuery(ShadowType.class, resourceObjectReference.getFilter());
// No variables. At least not now. We expect that mostly constants will be used here.
VariablesMap variables = new VariablesMap();
ObjectQuery evaluatedRefQuery = ExpressionUtil.evaluateQueryExpressions(refQuery, variables, MiscSchemaUtil.getExpressionProfile(), expressionFactory, prismContext, desc, ctx.getTask(), result);
ObjectFilter baseFilter = ObjectQueryUtil.createResourceAndObjectClassFilter(ctx.getResource().getOid(), objectClassName, prismContext);
ObjectFilter filter = prismContext.queryFactory().createAnd(baseFilter, evaluatedRefQuery.getFilter());
ObjectQuery query = prismContext.queryFactory().createQuery(filter);
// TODO: implement "repo" search strategies, don't forget to apply definitions
Holder<PrismObject<ShadowType>> shadowHolder = new Holder<>();
ResultHandler<ShadowType> handler = (shadow, objResult) -> {
if (shadowHolder.getValue() != null) {
throw new IllegalStateException("More than one search results for " + desc);
}
shadowHolder.setValue(shadow);
return true;
};
shadowsFacade.searchObjectsIterative(subCtx, query, null, handler, result);
return shadowHolder.getValue();
}
Aggregations