use of com.evolveum.midpoint.repo.common.expression.ConfigurableValuePolicySupplier in project midpoint by Evolveum.
the class FocalMappingSetEvaluation method createFocusMapping.
private <V extends PrismValue, D extends ItemDefinition<?>, AH extends AssignmentHolderType, T extends AssignmentHolderType> MappingImpl<V, D> createFocusMapping(LensContext<AH> context, FocalMappingEvaluationRequest<?, ?> request, ObjectDeltaObject<AH> focusOdo, @NotNull PrismObject<T> targetContext, Integer iteration, String iterationToken, PrismObject<SystemConfigurationType> configuration, XMLGregorianCalendar now, String contextDesc, Task task, OperationResult result) throws SchemaException, ExpressionEvaluationException, ObjectNotFoundException, CommunicationException, ConfigurationException, SecurityViolationException {
MappingType mappingBean = request.getMapping();
MappingKindType mappingKind = request.getMappingKind();
ObjectType originObject = request.getOriginObject();
Source<V, D> defaultSource = request.constructDefaultSource(focusOdo);
AssignmentPathVariables assignmentPathVariables = request.getAssignmentPathVariables();
if (!MappingImpl.isApplicableToChannel(mappingBean, context.getChannel())) {
LOGGER.trace("Mapping {} not applicable to channel {}, skipping.", mappingBean, context.getChannel());
return null;
}
ConfigurableValuePolicySupplier valuePolicySupplier = new ConfigurableValuePolicySupplier() {
private ItemDefinition<?> outputDefinition;
@Override
public void setOutputDefinition(ItemDefinition<?> outputDefinition) {
this.outputDefinition = outputDefinition;
}
@Override
public ValuePolicyType get(OperationResult result) {
// TODO need to switch to ObjectValuePolicyEvaluator
if (outputDefinition.getItemName().equals(PasswordType.F_VALUE)) {
return beans.credentialsProcessor.determinePasswordPolicy(context.getFocusContext());
}
if (mappingBean.getExpression() != null) {
List<JAXBElement<?>> evaluators = mappingBean.getExpression().getExpressionEvaluator();
if (evaluators != null) {
for (JAXBElement jaxbEvaluator : evaluators) {
Object object = jaxbEvaluator.getValue();
if (object instanceof GenerateExpressionEvaluatorType && ((GenerateExpressionEvaluatorType) object).getValuePolicyRef() != null) {
ObjectReferenceType ref = ((GenerateExpressionEvaluatorType) object).getValuePolicyRef();
try {
ValuePolicyType valuePolicyType = beans.mappingFactory.getObjectResolver().resolve(ref, ValuePolicyType.class, null, "resolving value policy for generate attribute " + outputDefinition.getItemName() + " value", task, result);
if (valuePolicyType != null) {
return valuePolicyType;
}
} catch (CommonException ex) {
throw new SystemException(ex.getMessage(), ex);
}
}
}
}
}
return null;
}
};
VariablesMap variables = new VariablesMap();
variables.put(ExpressionConstants.VAR_FOCUS, focusOdo, focusOdo.getDefinition());
variables.put(ExpressionConstants.VAR_USER, focusOdo, focusOdo.getDefinition());
variables.registerAlias(ExpressionConstants.VAR_USER, ExpressionConstants.VAR_FOCUS);
variables.put(ExpressionConstants.VAR_ITERATION, iteration, Integer.class);
variables.put(ExpressionConstants.VAR_ITERATION_TOKEN, iterationToken, String.class);
variables.put(ExpressionConstants.VAR_CONFIGURATION, configuration, SystemConfigurationType.class);
variables.put(ExpressionConstants.VAR_OPERATION, context.getFocusContext().getOperation().getValue(), String.class);
variables.put(ExpressionConstants.VAR_SOURCE, originObject, ObjectType.class);
PrismContext prismContext = beans.prismContext;
TypedValue<PrismObject<T>> defaultTargetContext = new TypedValue<>(targetContext);
Collection<V> targetValues = ExpressionUtil.computeTargetValues(mappingBean.getTarget(), defaultTargetContext, variables, beans.mappingFactory.getObjectResolver(), contextDesc, prismContext, task, result);
MappingSpecificationType specification = new MappingSpecificationType(prismContext).mappingName(mappingBean.getName()).definitionObjectRef(ObjectTypeUtil.createObjectRef(originObject, prismContext)).assignmentId(createAssignmentId(assignmentPathVariables));
MappingBuilder<V, D> mappingBuilder = beans.mappingFactory.<V, D>createMappingBuilder(mappingBean, contextDesc).sourceContext(focusOdo).defaultSource(defaultSource).targetContext(targetContext.getDefinition()).variablesFrom(variables).variablesFrom(LensUtil.getAssignmentPathVariablesMap(assignmentPathVariables, prismContext)).originalTargetValues(targetValues).mappingKind(mappingKind).originType(OriginType.USER_POLICY).originObject(originObject).valuePolicySupplier(valuePolicySupplier).rootNode(focusOdo).mappingPreExpression(// Used to populate autoassign assignments
request.getMappingPreExpression()).mappingSpecification(specification).now(now);
MappingImpl<V, D> mapping = mappingBuilder.build();
ItemPath itemPath = mapping.getOutputPath();
if (itemPath == null) {
// no output element, i.e. this is a "validation mapping"
return mapping;
}
Item<V, D> existingTargetItem = targetContext.findItem(itemPath);
if (existingTargetItem != null && !existingTargetItem.isEmpty() && mapping.getStrength() == MappingStrengthType.WEAK) {
LOGGER.trace("Mapping {} is weak and target already has a value {}, skipping.", mapping, existingTargetItem);
return null;
}
return mapping;
}
use of com.evolveum.midpoint.repo.common.expression.ConfigurableValuePolicySupplier 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);
}
Aggregations