use of com.evolveum.midpoint.security.api.SecurityContextManager in project midpoint by Evolveum.
the class TransformationalAsyncUpdateMessageListener method onMessage.
@Override
public void onMessage(AsyncUpdateMessageType message, AcknowledgementSink acknowledgementSink) {
int messageNumber = messagesSeen.getAndIncrement();
LOGGER.trace("Got message number {}: {}", messageNumber, message);
SecurityContextManager securityContextManager = connectorInstance.getSecurityContextManager();
Authentication oldAuthentication = securityContextManager.getAuthentication();
try {
securityContextManager.setupPreAuthenticatedSecurityContext(authentication);
Task task = connectorInstance.getTaskManager().createTaskInstance(OP_ON_MESSAGE_PREPARATION);
task.setChannel(CHANNEL_ASYNC_UPDATE_URI);
if (authentication != null && authentication.getPrincipal() instanceof MidPointPrincipal) {
task.setOwner(((MidPointPrincipal) authentication.getPrincipal()).getFocus().asPrismObject().clone());
}
Tracer tracer = connectorInstance.getTracer();
OperationResult result = task.getResult();
OperationResultBuilder resultBuilder = OperationResult.createFor(OP_ON_MESSAGE);
try {
ActivityTracingDefinitionType tracing = connectorInstance.getConfiguration().getProcessTracingConfiguration();
if (tracing != null) {
int interval = defaultIfNull(tracing.getInterval(), 1);
boolean matches = interval > 0 && messageNumber % interval == 0;
if (matches) {
task.setTracingProfile(tracing.getTracingProfile());
if (tracing.getTracingPoint().isEmpty()) {
task.addTracingRequest(TracingRootType.ASYNCHRONOUS_MESSAGE_PROCESSING);
} else {
tracing.getTracingPoint().forEach(task::addTracingRequest);
}
}
}
if (task.getTracingRequestedFor().contains(TracingRootType.ASYNCHRONOUS_MESSAGE_PROCESSING)) {
TracingProfileType profile = task.getTracingProfile() != null ? task.getTracingProfile() : tracer.getDefaultProfile();
resultBuilder.tracingProfile(tracer.compileProfile(profile, task.getResult()));
}
// replace task result with the newly-built one
result = resultBuilder.build();
task.setResult(result);
VariablesMap variables = new VariablesMap();
variables.put(VAR_MESSAGE, message, AsyncUpdateMessageType.class);
List<UcfChangeType> changeBeans;
try {
ExpressionType transformExpression = connectorInstance.getTransformExpression();
if (transformExpression != null) {
changeBeans = connectorInstance.getUcfExpressionEvaluator().evaluate(transformExpression, variables, SchemaConstantsGenerated.C_UCF_CHANGE, "computing UCF change from async update", task, result);
} else {
changeBeans = unwrapMessage(message);
}
} catch (RuntimeException | SchemaException | ObjectNotFoundException | SecurityViolationException | CommunicationException | ConfigurationException | ExpressionEvaluationException e) {
throw new SystemException("Couldn't evaluate message transformation expression: " + e.getMessage(), e);
}
if (changeBeans.isEmpty()) {
acknowledgementSink.acknowledge(true, result);
} else {
AcknowledgementSink aggregatedSink = createAggregatingAcknowledgeSink(acknowledgementSink, changeBeans.size());
for (UcfChangeType changeBean : changeBeans) {
// For this to work reliably, we have to run in a single thread. But that's ok.
// If we receive messages in multiple threads, there is no message ordering.
int changeSequentialNumber = changesProduced.incrementAndGet();
// intentionally in this order - to process changes even after failure
// (if listener wants to fail fast, it can throw an exception)
UcfAsyncUpdateChange change = createChange(changeBean, result, changeSequentialNumber, aggregatedSink);
changeListener.onChange(change, task, result);
}
}
} catch (Exception e) {
LoggingUtils.logUnexpectedException(LOGGER, "Got exception while processing asynchronous message in {}", e, task);
result.recordFatalError(e.getMessage(), e);
int changeSequentialNumber = changesProduced.incrementAndGet();
UcfAsyncUpdateChange change = new UcfAsyncUpdateChange(changeSequentialNumber, UcfErrorState.error(e), acknowledgementSink);
changeListener.onChange(change, task, result);
} finally {
result.computeStatusIfUnknown();
// (Otherwise it captures only the pre-processing activities.)
if (result.isTraced()) {
tracer.storeTrace(task, result, null);
}
}
} finally {
securityContextManager.setupPreAuthenticatedSecurityContext(oldAuthentication);
}
}
use of com.evolveum.midpoint.security.api.SecurityContextManager in project midpoint by Evolveum.
the class AuditServiceProxy method completeRecord.
/**
* Complete the record with data that can be computed or discovered from the
* environment
*/
private void completeRecord(AuditEventRecord record, Task task, OperationResult result) {
LightweightIdentifier id = null;
if (record.getEventIdentifier() == null) {
id = lightweightIdentifierGenerator.generate();
record.setEventIdentifier(id.toString());
}
if (record.getTimestamp() == null) {
if (id == null) {
record.setTimestamp(System.currentTimeMillis());
} else {
// To be consistent with the ID
record.setTimestamp(id.getTimestamp());
}
}
if (record.getTaskIdentifier() == null && task != null) {
record.setTaskIdentifier(task.getTaskIdentifier());
}
if (record.getTaskOid() == null && task != null) {
if (task instanceof RunningTask) {
record.setTaskOid(((RunningTask) task).getRootTaskOid());
} else {
record.setTaskOid(task.getOid());
}
}
if (record.getChannel() == null && task != null) {
record.setChannel(task.getChannel());
}
if (record.getInitiatorRef() == null && task != null) {
PrismObject<? extends FocusType> taskOwner = task.getOwner(result);
record.setInitiator(taskOwner);
}
if (record.getNodeIdentifier() == null && taskManager != null) {
record.setNodeIdentifier(taskManager.getNodeId());
}
HttpConnectionInformation connInfo = SecurityUtil.getCurrentConnectionInformation();
if (connInfo == null && securityContextManager != null) {
connInfo = securityContextManager.getStoredConnectionInformation();
}
if (connInfo != null) {
if (record.getSessionIdentifier() == null) {
record.setSessionIdentifier(connInfo.getSessionId());
}
if (record.getRemoteHostAddress() == null) {
record.setRemoteHostAddress(connInfo.getRemoteHostAddress());
}
if (record.getHostIdentifier() == null) {
record.setHostIdentifier(connInfo.getLocalHostName());
}
}
if (record.getSessionIdentifier() == null && task != null) {
record.setSessionIdentifier(task.getTaskIdentifier());
}
for (ObjectDeltaOperation<? extends ObjectType> objectDeltaOperation : record.getDeltas()) {
ObjectDelta<? extends ObjectType> delta = objectDeltaOperation.getObjectDelta();
// currently this does not work as expected (retrieves all default items)
Collection<SelectorOptions<GetOperationOptions>> nameOnlyOptions = schemaService.getOperationOptionsBuilder().item(ObjectType.F_NAME).retrieve().build();
ObjectDeltaSchemaLevelUtil.NameResolver nameResolver = (objectClass, oid) -> {
if (record.getNonExistingReferencedObjects().contains(oid)) {
// save a useless getObject call plus associated warning (MID-5378)
return null;
}
if (repositoryService == null) {
LOGGER.warn("No repository, no OID resolution (for {})", oid);
return null;
}
LOGGER.warn("Unresolved object reference in delta being audited (for {}: {}) -- this might indicate " + "a performance problem, as these references are normally resolved using repository cache", objectClass.getSimpleName(), oid);
PrismObject<? extends ObjectType> object = repositoryService.getObject(objectClass, oid, nameOnlyOptions, new OperationResult(AuditServiceProxy.class.getName() + ".completeRecord.resolveName"));
return object.getName();
};
resolveNames(delta, nameResolver, prismContext);
}
}
use of com.evolveum.midpoint.security.api.SecurityContextManager in project midpoint by Evolveum.
the class AsyncWebProcessManagerImpl method submit.
@Override
public void submit(@NotNull String processId, @NotNull Callable callable) {
AsyncWebProcess process = getProcess(processId);
if (process == null) {
throw new IllegalStateException("Process with id '" + processId + "' doesn't exist");
}
Callable<?> securityAware = callable;
if (!(callable instanceof SecurityContextAwareCallable)) {
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
SecurityContextManager secManager = application.getSecurityContextManager();
securityAware = new SecurityContextAwareCallable(secManager, auth) {
@Override
public Object callWithContextPrepared() throws Exception {
return callable.call();
}
};
}
Future<?> future = executor.submit(securityAware);
process.setFuture(future);
}
use of com.evolveum.midpoint.security.api.SecurityContextManager in project midpoint by Evolveum.
the class ProgressAwareChangesExecutorImpl method executeChangesAsync.
private void executeChangesAsync(ProgressPanel progressPanel, Collection<ObjectDelta<? extends ObjectType>> deltas, boolean previewOnly, ModelExecuteOptions options, Task task, OperationResult result) {
MidPointApplication application = MidPointApplication.get();
final ModelInteractionService modelInteraction = application.getModelInteractionService();
final ModelService model = application.getModel();
final SecurityContextManager secManager = application.getSecurityContextManager();
final Authentication auth = SecurityContextHolder.getContext().getAuthentication();
final HttpConnectionInformation connInfo = SecurityUtil.getCurrentConnectionInformation();
AsyncWebProcessModel<ProgressReporter> reporterModel = progressPanel.getReporterModel();
Callable<Void> execution = new SecurityContextAwareCallable<>(secManager, auth, connInfo) {
@Override
public Void callWithContextPrepared() {
ProgressReporter reporter = reporterModel.getProcessData();
try {
LOGGER.debug("Execution start");
reporter.recordExecutionStart();
if (previewOnly) {
ModelContext previewResult = modelInteraction.previewChanges(deltas, options, task, Collections.singleton(reporter), result);
reporter.setPreviewResult(previewResult);
} else if (deltas != null && deltas.size() > 0) {
Collection<ObjectDeltaOperation<? extends ObjectType>> executedDeltas = model.executeChanges(deltas, options, task, Collections.singleton(reporter), result);
reporter.setObjectDeltaOperation(executedDeltas);
}
} catch (CommonException | RuntimeException e) {
LoggingUtils.logUnexpectedException(LOGGER, "Error executing changes", e);
if (!result.isFatalError()) {
// just to be sure the exception is recorded into the result
result.recordFatalError(e.getMessage(), e);
}
} finally {
LOGGER.debug("Execution finish {}", result);
}
reporter.recordExecutionStop();
// signals that the operation has finished
reporter.setAsyncOperationResult(result);
return null;
}
};
// to disable showing not-final results (why does it work? and why is the result shown otherwise?)
result.setInProgress();
AsyncWebProcessManager manager = application.getAsyncWebProcessManager();
manager.submit(reporterModel.getId(), execution);
}
use of com.evolveum.midpoint.security.api.SecurityContextManager in project midpoint by Evolveum.
the class AsyncWebProcessManagerImpl method submit.
@Override
public void submit(@NotNull String processId, Runnable runnable) {
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
SecurityContextManager secManager = application.getSecurityContextManager();
submit(processId, new SecurityContextAwareCallable(secManager, auth) {
@Override
public Object callWithContextPrepared() {
runnable.run();
return null;
}
});
}
Aggregations