use of com.evolveum.midpoint.prism.util.ItemDeltaItem in project midpoint by Evolveum.
the class PathExpressionEvaluation method getInitialResolveContextFromVariable.
private ResolutionContext getInitialResolveContextFromVariable() throws ExpressionEvaluationException {
String variableName = ItemPath.toVariableName(pathToResolve.first()).getLocalPart();
pathToResolve = pathToResolve.rest();
TypedValue variableValueAndDefinition = evaluator.findInSourcesAndVariables(context, variableName);
if (variableValueAndDefinition == null) {
throw new ExpressionEvaluationException("No variable with name " + variableName + " in " + context.getContextDescription());
}
Object variableValue = variableValueAndDefinition.getValue();
if (variableValue == null) {
return null;
} else if (variableValue instanceof Item || variableValue instanceof ItemDeltaItem<?, ?>) {
return IdiResolutionContext.fromAnyObject(variableValue);
} else if (variableValue instanceof PrismValue) {
return new ValueResolutionContext((PrismValue) variableValue, context.getContextDescription());
} else if (variableValueAndDefinition.getTypeClass().isAssignableFrom(variableValue.getClass())) {
return ValueResolutionContext.fromRealValue(variableValue, context.getContextDescription(), evaluator.getPrismContext());
} else {
throw new ExpressionEvaluationException("Unexpected variable value " + variableValue + " (" + variableValue.getClass() + ")");
}
}
use of com.evolveum.midpoint.prism.util.ItemDeltaItem in project midpoint by Evolveum.
the class ModelInteractionServiceImpl method determineDeputyValidity.
private boolean determineDeputyValidity(PrismObject<UserType> potentialDeputy, List<ObjectReferenceType> assignees, @Nullable AbstractWorkItemType workItem, QName privilegeLimitationItemName, Task task, OperationResult result) {
AssignmentEvaluator.Builder<UserType> builder = new AssignmentEvaluator.Builder<UserType>().referenceResolver(referenceResolver).focusOdo(new ObjectDeltaObject<>(potentialDeputy, null, potentialDeputy, potentialDeputy.getDefinition())).channel(null).modelBeans(modelBeans).objectResolver(objectResolver).systemObjectCache(systemObjectCache).relationRegistry(relationRegistry).prismContext(prismContext).mappingFactory(mappingFactory).mappingEvaluator(mappingEvaluator).contextLoader(contextLoader).activationComputer(activationComputer).now(clock.currentTimeXMLGregorianCalendar()).loginMode(true).lensContext(new LensContextPlaceholder<>(potentialDeputy));
AssignmentEvaluator<UserType> assignmentEvaluator = builder.build();
for (AssignmentType assignmentType : potentialDeputy.asObjectable().getAssignment()) {
if (!DeputyUtils.isDelegationAssignment(assignmentType, relationRegistry)) {
continue;
}
try {
ItemDeltaItem<PrismContainerValue<AssignmentType>, PrismContainerDefinition<AssignmentType>> assignmentIdi = new ItemDeltaItem<>(LensUtil.createAssignmentSingleValueContainer(assignmentType));
// TODO some special mode for verification of the validity - we don't need complete calculation here!
EvaluatedAssignment<UserType> assignment = assignmentEvaluator.evaluate(assignmentIdi, PlusMinusZero.ZERO, false, potentialDeputy.asObjectable(), potentialDeputy.toString(), AssignmentOrigin.createInObject(), task, result);
if (!assignment.isValid()) {
continue;
}
for (EvaluatedAssignmentTarget target : assignment.getRoles().getNonNegativeValues()) {
// MID-6403
if (target.getTarget().getOid() != null && DeputyUtils.isDelegationPath(target.getAssignmentPath(), relationRegistry) && ObjectTypeUtil.containsOid(assignees, target.getTarget().getOid())) {
List<OtherPrivilegesLimitationType> limitations = DeputyUtils.extractLimitations(target.getAssignmentPath());
if (workItem != null && DeputyUtils.limitationsAllow(limitations, privilegeLimitationItemName, workItem) || workItem == null && SchemaDeputyUtil.limitationsAllow(limitations, privilegeLimitationItemName)) {
return true;
}
}
}
} catch (CommonException e) {
LoggingUtils.logUnexpectedException(LOGGER, "Couldn't verify 'deputy' relation between {} and {} for work item {}; assignment: {}", e, potentialDeputy, assignees, workItem, assignmentType);
}
}
return false;
}
use of com.evolveum.midpoint.prism.util.ItemDeltaItem in project midpoint by Evolveum.
the class ProjectionCredentialsProcessor method processProjectionPasswordMapping.
private <F extends FocusType> void processProjectionPasswordMapping(LensContext<F> context, final LensProjectionContext projCtx, final SecurityPolicyType securityPolicy, XMLGregorianCalendar now, Task task, OperationResult result) throws ExpressionEvaluationException, ObjectNotFoundException, SchemaException, CommunicationException, ConfigurationException, SecurityViolationException {
LensFocusContext<F> focusContext = context.getFocusContext();
PrismObject<F> focusNew = focusContext.getObjectNew();
if (focusNew == null) {
// This must be a focus delete or something similar. No point in proceeding
LOGGER.trace("focusNew is null, skipping credentials processing");
return;
}
PrismObjectDefinition<ShadowType> accountDefinition = prismContext.getSchemaRegistry().findObjectDefinitionByCompileTimeClass(ShadowType.class);
PrismPropertyDefinition<ProtectedStringType> projPasswordPropertyDefinition = accountDefinition.findPropertyDefinition(SchemaConstants.PATH_PASSWORD_VALUE);
ResourceShadowDiscriminator rsd = projCtx.getResourceShadowDiscriminator();
ResourceObjectDefinition objectDefinition = projCtx.getStructuralObjectDefinition();
if (objectDefinition == null) {
LOGGER.trace("No ResourceObjectTypeDefinition, therefore also no password outbound definition," + " skipping credentials processing for projection {}", rsd);
return;
}
List<MappingType> outboundMappingBeans = objectDefinition.getPasswordOutbound();
if (outboundMappingBeans.isEmpty()) {
LOGGER.trace("No outbound password mapping for {}, skipping credentials processing", rsd);
return;
}
ObjectDeltaObject<F> objectDeltaObject = focusContext.getObjectDeltaObjectAbsolute();
// HACK
if (!projCtx.isDoReconciliation() && !projCtx.isAdd() && !isActivated(outboundMappingBeans, objectDeltaObject.getObjectDelta())) {
LOGGER.trace("Outbound password mappings not activated for type {}, skipping credentials processing", rsd);
return;
}
ObjectDelta<ShadowType> projDelta = projCtx.getCurrentDelta();
PropertyDelta<ProtectedStringType> projPasswordDelta;
if (projDelta != null && projDelta.getChangeType() == MODIFY) {
projPasswordDelta = projDelta.findPropertyDelta(SchemaConstants.PATH_PASSWORD_VALUE);
} else {
projPasswordDelta = null;
}
checkExistingDeltaSanity(projCtx, projPasswordDelta);
boolean evaluateWeak = getEvaluateWeak(projCtx);
// TODO wave
ItemDeltaItem<PrismPropertyValue<ProtectedStringType>, PrismPropertyDefinition<ProtectedStringType>> focusPasswordIdi = objectDeltaObject.findIdi(SchemaConstants.PATH_PASSWORD_VALUE);
ConfigurableValuePolicySupplier valuePolicySupplier = (result1) -> SecurityUtil.getPasswordPolicy(securityPolicy);
MappingInitializer<PrismPropertyValue<ProtectedStringType>, PrismPropertyDefinition<ProtectedStringType>> initializer = (builder) -> {
builder.mappingKind(MappingKindType.OUTBOUND).implicitSourcePath(SchemaConstants.PATH_PASSWORD_VALUE).implicitTargetPath(SchemaConstants.PATH_PASSWORD_VALUE);
builder.defaultTargetDefinition(projPasswordPropertyDefinition);
builder.defaultSource(new Source<>(focusPasswordIdi, ExpressionConstants.VAR_INPUT_QNAME));
builder.valuePolicySupplier(valuePolicySupplier);
return builder;
};
MappingOutputProcessor<PrismPropertyValue<ProtectedStringType>> processor = (mappingOutputPath, outputStruct) -> {
PrismValueDeltaSetTriple<PrismPropertyValue<ProtectedStringType>> outputTriple = outputStruct.getOutputTriple();
if (outputTriple == null) {
LOGGER.trace("Credentials 'password' expression resulted in null output triple, skipping credentials processing for {}", rsd);
return false;
}
boolean projectionIsNew = projDelta != null && (projDelta.getChangeType() == ChangeType.ADD || projCtx.getSynchronizationPolicyDecision() == SynchronizationPolicyDecision.ADD);
Collection<PrismPropertyValue<ProtectedStringType>> newValues;
if (projectionIsNew) {
newValues = outputTriple.getNonNegativeValues();
} else {
newValues = outputTriple.getPlusSet();
}
if (!canGetCleartext(newValues)) {
ObjectDelta<ShadowType> projectionPrimaryDelta = projCtx.getPrimaryDelta();
if (projectionPrimaryDelta != null) {
PropertyDelta<ProtectedStringType> passwordPrimaryDelta = projectionPrimaryDelta.findPropertyDelta(SchemaConstants.PATH_PASSWORD_VALUE);
if (passwordPrimaryDelta != null) {
// We have only hashed value coming from the mapping. There are not very useful
// for provisioning. But we have primary projection delta - and that is very likely
// to be better.
// Skip all password mappings in this case. Primary delta trumps everything.
// No weak, normal or even strong mapping can change that.
// We need to disregard even strong mapping in this case. If we would heed the strong
// mapping then account initialization won't be possible.
LOGGER.trace("We have primary password delta in projection, skipping credentials processing");
return false;
}
}
}
Collection<PrismPropertyValue<ProtectedStringType>> minusSet = outputTriple.getMinusSet();
if (!minusSet.isEmpty()) {
if (!canGetCleartext(minusSet)) {
// We have hashed values in minus set. That is not great, we won't be able to get
// cleartext from that if we need it (e.g. for runAs in provisioning).
// Therefore try to get old value from focus password delta. If that matches with
// hashed value then we have the cleartext.
ProtectedStringType oldProjectionPassword = minusSet.iterator().next().getRealValue();
PropertyDelta<ProtectedStringType> focusPasswordDelta = (PropertyDelta<ProtectedStringType>) focusPasswordIdi.getDelta();
Collection<PrismPropertyValue<ProtectedStringType>> focusPasswordDeltaOldValues = focusPasswordDelta.getEstimatedOldValues();
if (focusPasswordDeltaOldValues != null && !focusPasswordDeltaOldValues.isEmpty()) {
ProtectedStringType oldFocusPassword = requireNonNull(focusPasswordDeltaOldValues.iterator().next().getRealValue());
try {
if (oldFocusPassword.canGetCleartext() && protector.compareCleartext(oldFocusPassword, oldProjectionPassword)) {
outputTriple.clearMinusSet();
outputTriple.addToMinusSet(prismContext.itemFactory().createPropertyValue(oldFocusPassword));
}
} catch (EncryptionException e) {
throw new SystemException(e.getMessage(), e);
}
}
}
}
return true;
};
String projCtxDesc = projCtx.toHumanReadableString();
PrismObject<ShadowType> shadowNew = projCtx.getObjectNew();
MappingInitializer<PrismPropertyValue<ProtectedStringType>, PrismPropertyDefinition<ProtectedStringType>> internalInitializer = builder -> {
builder.addVariableDefinitions(ModelImplUtils.getDefaultVariablesMap(context, projCtx, true));
builder.mappingKind(MappingKindType.OUTBOUND);
builder.originType(OriginType.OUTBOUND);
builder.implicitTargetPath(SchemaConstants.PATH_PASSWORD_VALUE);
builder.originObject(projCtx.getResource());
initializer.initialize(builder);
return builder;
};
MappingEvaluatorParams<PrismPropertyValue<ProtectedStringType>, PrismPropertyDefinition<ProtectedStringType>, ShadowType, F> params = new MappingEvaluatorParams<>();
params.setMappingTypes(outboundMappingBeans);
params.setMappingDesc("password mapping" + " in projection " + projCtxDesc);
params.setNow(now);
params.setInitializer(internalInitializer);
params.setProcessor(processor);
params.setTargetLoader(new ProjectionMappingLoader<>(projCtx, contextLoader));
params.setAPrioriTargetObject(shadowNew);
params.setAPrioriTargetDelta(LensUtil.findAPrioriDelta(context, projCtx));
params.setTargetContext(projCtx);
params.setDefaultTargetItemPath(SchemaConstants.PATH_PASSWORD_VALUE);
if (context.getFocusContext() != null) {
params.setSourceContext(context.getFocusContext().getObjectDeltaObjectAbsolute());
}
params.setEvaluateCurrent(MappingTimeEval.CURRENT);
params.setEvaluateWeak(evaluateWeak);
params.setContext(context);
params.setHasFullTargetObject(projCtx.hasFullShadow());
projectionMappingSetEvaluator.evaluateMappingsToTriples(params, task, result);
}
use of com.evolveum.midpoint.prism.util.ItemDeltaItem in project midpoint by Evolveum.
the class MappingParser method parseSource.
private <IV extends PrismValue, ID extends ItemDefinition<?>> Source<IV, ID> parseSource(VariableBindingDefinitionType sourceDefinition, OperationResult result) throws SchemaException, ObjectNotFoundException, ExpressionEvaluationException, CommunicationException, ConfigurationException, SecurityViolationException {
ItemPath path = getSourcePath(sourceDefinition);
@NotNull QName sourceQName = sourceDefinition.getName() != null ? sourceDefinition.getName() : ItemPath.toName(path.last());
String variableName = sourceQName.getLocalPart();
TypedValue<?> typedSourceObject = ExpressionUtil.resolvePathGetTypedValue(path, m.variables, true, m.getTypedSourceContext(), m.beans.objectResolver, m.beans.prismContext, "source definition in " + m.getMappingContextDescription(), m.getTask(), result);
Object sourceObject = typedSourceObject != null ? typedSourceObject.getValue() : null;
Item<IV, ID> itemOld = null;
ItemDelta<IV, ID> delta = null;
Item<IV, ID> itemNew = null;
ItemPath resolvePath = path;
ItemPath residualPath = null;
Collection<? extends ItemDelta<?, ?>> subItemDeltas = null;
if (sourceObject != null) {
if (sourceObject instanceof ItemDeltaItem<?, ?>) {
// noinspection unchecked
itemOld = ((ItemDeltaItem<IV, ID>) sourceObject).getItemOld();
// noinspection unchecked
delta = ((ItemDeltaItem<IV, ID>) sourceObject).getDelta();
// noinspection unchecked
itemNew = ((ItemDeltaItem<IV, ID>) sourceObject).getItemNew();
// noinspection unchecked
residualPath = ((ItemDeltaItem<IV, ID>) sourceObject).getResidualPath();
// noinspection unchecked
resolvePath = ((ItemDeltaItem<IV, ID>) sourceObject).getResolvePath();
// noinspection unchecked
subItemDeltas = ((ItemDeltaItem<IV, ID>) sourceObject).getSubItemDeltas();
} else if (sourceObject instanceof Item<?, ?>) {
// noinspection unchecked
itemOld = (Item<IV, ID>) sourceObject;
// noinspection unchecked
itemNew = (Item<IV, ID>) sourceObject;
} else {
throw new IllegalStateException("Unknown resolve result " + sourceObject);
}
}
ID sourceItemDefinition = typedSourceObject != null ? typedSourceObject.getDefinition() : null;
// apply domain
ValueSetDefinitionType domainSetType = sourceDefinition.getSet();
if (domainSetType != null) {
ValueSetDefinition<IV, ID> setDef = new ValueSetDefinition<>(domainSetType, sourceItemDefinition, m.valueMetadataDefinition, m.expressionProfile, variableName, null, "domain of " + variableName, "domain of " + variableName + " in " + m.getMappingContextDescription(), m.getTask(), result);
setDef.init(m.beans.expressionFactory);
setDef.setAdditionalVariables(m.variables);
try {
if (itemOld != null) {
// noinspection unchecked
itemOld = itemOld.clone();
itemOld.filterValues(setDef::containsTunnel);
itemOld.filterYields(setDef::containsYieldTunnel);
}
if (itemNew != null) {
// noinspection unchecked
itemNew = itemNew.clone();
itemNew.filterValues(setDef::containsTunnel);
itemNew.filterYields(setDef::containsYieldTunnel);
}
if (delta != null) {
delta = delta.clone();
delta.filterValues(setDef::containsTunnel);
delta.filterYields(setDef::containsYieldTunnel);
}
} catch (TunnelException te) {
unwrapTunnelException(te);
}
}
Source<IV, ID> source = new Source<>(itemOld, delta, itemNew, sourceQName, sourceItemDefinition);
source.setResidualPath(residualPath);
source.setResolvePath(resolvePath);
source.setSubItemDeltas(subItemDeltas);
return source;
}
use of com.evolveum.midpoint.prism.util.ItemDeltaItem in project midpoint by Evolveum.
the class ExpressionUtil method resolveDefinitionPath.
public static <ID extends ItemDefinition> ID resolveDefinitionPath(@NotNull ItemPath path, VariablesMap variables, PrismContainerDefinition<?> defaultContext, String shortDesc) throws SchemaException {
while (!path.isEmpty() && !path.startsWithName() && !path.startsWithVariable()) {
path = path.rest();
}
Object root = defaultContext;
ItemPath relativePath = path;
Object first = path.first();
if (ItemPath.isVariable(first)) {
relativePath = path.rest();
String varName = ItemPath.toVariableName(first).getLocalPart();
if (variables.containsKey(varName)) {
TypedValue typeVarValue = variables.get(varName);
Object varValue = typeVarValue.getValue();
if (varValue instanceof ItemDeltaItem<?, ?>) {
root = ((ItemDeltaItem<?, ?>) varValue).getDefinition();
} else if (varValue instanceof Item<?, ?>) {
root = ((Item<?, ?>) varValue).getDefinition();
} else if (varValue instanceof Objectable) {
root = ((Objectable) varValue).asPrismObject().getDefinition();
} else if (varValue instanceof ItemDefinition) {
root = varValue;
} else {
throw new IllegalStateException("Unexpected content of variable " + varName + ": " + varValue + " (" + varValue.getClass() + ")");
}
if (root == null) {
throw new IllegalStateException("Null definition in content of variable '" + varName + "': " + varValue);
}
} else {
throw new SchemaException("No variable with name '" + varName + "' in " + shortDesc);
}
}
if (root == null) {
return null;
}
if (relativePath.isEmpty()) {
return (ID) root;
}
if (root instanceof PrismObjectDefinition<?>) {
return ((PrismObjectDefinition<?>) root).findItemDefinition(relativePath);
} else if (root instanceof PrismContainerDefinition<?>) {
return ((PrismContainerDefinition<?>) root).findItemDefinition(relativePath);
} else if (root instanceof ItemDefinition) {
// Except for container (which is handled above)
throw new SchemaException("Cannot apply path " + relativePath + " to " + root + " in " + shortDesc);
} else {
throw new IllegalArgumentException("Unexpected root " + root + " in " + shortDesc);
}
}
Aggregations