Search in sources :

Example 6 with AuditEventRecord

use of com.evolveum.midpoint.audit.api.AuditEventRecord in project midpoint by Evolveum.

the class AuditedLogoutHandler method auditEvent.

private void auditEvent(HttpServletRequest request, Authentication authentication) {
    MidPointPrincipal principal = SecurityUtils.getPrincipalUser(authentication);
    PrismObject<UserType> user = principal != null ? principal.getUser().asPrismObject() : null;
    Task task = taskManager.createTaskInstance();
    task.setOwner(user);
    task.setChannel(SchemaConstants.CHANNEL_GUI_USER_URI);
    AuditEventRecord record = new AuditEventRecord(AuditEventType.TERMINATE_SESSION, AuditEventStage.REQUEST);
    record.setInitiator(user);
    record.setParameter(WebComponentUtil.getName(user));
    record.setChannel(SchemaConstants.CHANNEL_GUI_USER_URI);
    record.setTimestamp(System.currentTimeMillis());
    record.setOutcome(OperationResultStatus.SUCCESS);
    // probably not needed, as audit service would take care of it; but it doesn't hurt so let's keep it here
    record.setHostIdentifier(request.getLocalName());
    record.setRemoteHostAddress(request.getLocalAddr());
    record.setNodeIdentifier(taskManager.getNodeId());
    record.setSessionIdentifier(request.getRequestedSessionId());
    auditService.audit(record, task);
}
Also used : Task(com.evolveum.midpoint.task.api.Task) UserType(com.evolveum.midpoint.xml.ns._public.common.common_3.UserType) AuditEventRecord(com.evolveum.midpoint.audit.api.AuditEventRecord) MidPointPrincipal(com.evolveum.midpoint.security.api.MidPointPrincipal)

Example 7 with AuditEventRecord

use of com.evolveum.midpoint.audit.api.AuditEventRecord in project midpoint by Evolveum.

the class AbstractModelWebService method auditLogin.

protected void auditLogin(Task task) {
    AuditEventRecord record = new AuditEventRecord(AuditEventType.CREATE_SESSION, AuditEventStage.REQUEST);
    record.setInitiatorAndLoginParameter(task.getOwner());
    record.setChannel(SchemaConstants.CHANNEL_WEB_SERVICE_URI);
    record.setTimestamp(System.currentTimeMillis());
    record.setOutcome(OperationResultStatus.SUCCESS);
    auditService.audit(record, task);
}
Also used : AuditEventRecord(com.evolveum.midpoint.audit.api.AuditEventRecord)

Example 8 with AuditEventRecord

use of com.evolveum.midpoint.audit.api.AuditEventRecord in project midpoint by Evolveum.

the class WfTaskController method onTaskEvent.

//endregion
//region Processing work item (task) events
// workItem contains taskRef, assignee, candidates resolved (if possible)
// workItem can be freely modified (e.g. by overriding result, etc.)
@SuppressWarnings("unchecked")
public void onTaskEvent(WorkItemType workItem, TaskEvent taskEvent, OperationResult result) throws WorkflowException, SchemaException {
    final TaskType shadowTaskType = WfContextUtil.getTask(workItem);
    if (shadowTaskType == null) {
        LOGGER.warn("No task in workItem " + workItem + ", audit and notifications couldn't be performed.");
        return;
    }
    final Task shadowTask = taskManager.createTaskInstance(shadowTaskType.asPrismObject(), result);
    final WfTask wfTask = recreateWfTask(shadowTask);
    // auditing & notifications & event
    if (taskEvent instanceof TaskCreatedEvent) {
        AuditEventRecord auditEventRecord = getChangeProcessor(taskEvent).prepareWorkItemCreatedAuditRecord(workItem, taskEvent, wfTask, result);
        auditService.audit(auditEventRecord, wfTask.getTask());
        try {
            notifyWorkItemCreated(workItem.getOriginalAssigneeRef(), workItem, wfTask, result);
            if (workItem.getAssigneeRef() != null) {
                WorkItemAllocationChangeOperationInfo operationInfo = new WorkItemAllocationChangeOperationInfo(null, Collections.emptyList(), workItem.getAssigneeRef());
                notifyWorkItemAllocationChangeNewActors(workItem, operationInfo, null, wfTask.getTask(), result);
            }
        } catch (SchemaException e) {
            LoggingUtils.logUnexpectedException(LOGGER, "Couldn't send notification about work item create event", e);
        }
    } else if (taskEvent instanceof TaskDeletedEvent) {
        // this might be cancellation because of:
        //  (1) user completion of this task
        //  (2) timed completion of this task
        //  (3) user completion of another task
        //  (4) timed completion of another task
        //  (5) process stop/deletion
        //
        // Actually, when the source is (4) timed completion of another task, it is quite probable that this task
        // would be closed for the same reason. For a user it would be misleading if we would simply view this task
        // as 'cancelled', while, in fact, it is e.g. approved/rejected because of a timed action.
        WorkItemOperationKindType operationKind = BooleanUtils.isTrue(ActivitiUtil.getVariable(taskEvent.getVariables(), CommonProcessVariableNames.VARIABLE_WORK_ITEM_WAS_COMPLETED, Boolean.class, prismContext)) ? WorkItemOperationKindType.COMPLETE : WorkItemOperationKindType.CANCEL;
        WorkItemEventCauseInformationType cause = ActivitiUtil.getVariable(taskEvent.getVariables(), CommonProcessVariableNames.VARIABLE_CAUSE, WorkItemEventCauseInformationType.class, prismContext);
        boolean genuinelyCompleted = operationKind == WorkItemOperationKindType.COMPLETE;
        MidPointPrincipal user;
        try {
            user = SecurityUtil.getPrincipal();
        } catch (SecurityViolationException e) {
            throw new SystemException("Couldn't determine current user: " + e.getMessage(), e);
        }
        // partial fallback
        ObjectReferenceType userRef = user != null ? user.toObjectReference() : workItem.getPerformerRef();
        if (!genuinelyCompleted) {
            TaskType task = wfTask.getTask().getTaskPrismObject().asObjectable();
            int foundTimedActions = 0;
            for (TriggerType trigger : task.getTrigger()) {
                if (!WfTimedActionTriggerHandler.HANDLER_URI.equals(trigger.getHandlerUri())) {
                    continue;
                }
                String workItemId = ObjectTypeUtil.getExtensionItemRealValue(trigger.getExtension(), SchemaConstants.MODEL_EXTENSION_WORK_ITEM_ID);
                if (!taskEvent.getTaskId().equals(workItemId)) {
                    continue;
                }
                Duration timeBeforeAction = ObjectTypeUtil.getExtensionItemRealValue(trigger.getExtension(), SchemaConstants.MODEL_EXTENSION_TIME_BEFORE_ACTION);
                if (timeBeforeAction != null) {
                    continue;
                }
                WorkItemActionsType actions = ObjectTypeUtil.getExtensionItemRealValue(trigger.getExtension(), SchemaConstants.MODEL_EXTENSION_WORK_ITEM_ACTIONS);
                if (actions == null || actions.getComplete() == null) {
                    continue;
                }
                long diff = XmlTypeConverter.toMillis(trigger.getTimestamp()) - clock.currentTimeMillis();
                if (diff >= COMPLETION_TRIGGER_EQUALITY_THRESHOLD) {
                    continue;
                }
                CompleteWorkItemActionType completeAction = actions.getComplete();
                operationKind = WorkItemOperationKindType.COMPLETE;
                cause = new WorkItemEventCauseInformationType();
                cause.setType(WorkItemEventCauseTypeType.TIMED_ACTION);
                cause.setName(completeAction.getName());
                cause.setDisplayName(completeAction.getDisplayName());
                foundTimedActions++;
                WorkItemResultType workItemOutput = new WorkItemResultType();
                workItemOutput.setOutcome(completeAction.getOutcome() != null ? completeAction.getOutcome() : SchemaConstants.MODEL_APPROVAL_OUTCOME_REJECT);
                workItem.setOutput(workItemOutput);
            }
            if (foundTimedActions > 1) {
                LOGGER.warn("Multiple 'work item complete' timed actions ({}) for {}: {}", foundTimedActions, ObjectTypeUtil.toShortString(task), task.getTrigger());
            }
        }
        // We don't pass userRef (initiator) to the audit method. It does need the whole object (not only the reference),
        // so it fetches it directly from the security enforcer (logged-in user). This could change in the future.
        AuditEventRecord auditEventRecord = getChangeProcessor(taskEvent).prepareWorkItemDeletedAuditRecord(workItem, cause, taskEvent, wfTask, result);
        auditService.audit(auditEventRecord, wfTask.getTask());
        try {
            WorkItemAllocationChangeOperationInfo operationInfo = new WorkItemAllocationChangeOperationInfo(operationKind, workItem.getAssigneeRef(), null);
            WorkItemOperationSourceInfo sourceInfo = new WorkItemOperationSourceInfo(userRef, cause, null);
            if (workItem.getAssigneeRef().isEmpty()) {
                notifyWorkItemDeleted(null, workItem, operationInfo, sourceInfo, wfTask, result);
            } else {
                for (ObjectReferenceType assignee : workItem.getAssigneeRef()) {
                    notifyWorkItemDeleted(assignee, workItem, operationInfo, sourceInfo, wfTask, result);
                }
            }
            notifyWorkItemAllocationChangeCurrentActors(workItem, operationInfo, sourceInfo, null, wfTask.getTask(), result);
        } catch (SchemaException e) {
            LoggingUtils.logUnexpectedException(LOGGER, "Couldn't audit work item complete event", e);
        }
        AbstractWorkItemOutputType output = workItem.getOutput();
        if (genuinelyCompleted || output != null) {
            WorkItemCompletionEventType event = new WorkItemCompletionEventType();
            ActivitiUtil.fillInWorkItemEvent(event, user, taskEvent.getTaskId(), taskEvent.getVariables(), prismContext);
            event.setCause(cause);
            event.setOutput(output);
            ObjectDeltaType additionalDelta = output instanceof WorkItemResultType && ((WorkItemResultType) output).getAdditionalDeltas() != null ? ((WorkItemResultType) output).getAdditionalDeltas().getFocusPrimaryDelta() : null;
            MidpointUtil.recordEventInTask(event, additionalDelta, wfTask.getTask().getOid(), result);
        }
        MidpointUtil.removeTriggersForWorkItem(wfTask.getTask(), taskEvent.getTaskId(), result);
    }
}
Also used : PcpWfTask(com.evolveum.midpoint.wf.impl.processors.primary.PcpWfTask) Task(com.evolveum.midpoint.task.api.Task) MidPointPrincipal(com.evolveum.midpoint.security.api.MidPointPrincipal) Duration(javax.xml.datatype.Duration) PcpWfTask(com.evolveum.midpoint.wf.impl.processors.primary.PcpWfTask) ObjectDeltaType(com.evolveum.prism.xml.ns._public.types_3.ObjectDeltaType) AuditEventRecord(com.evolveum.midpoint.audit.api.AuditEventRecord)

Example 9 with AuditEventRecord

use of com.evolveum.midpoint.audit.api.AuditEventRecord in project midpoint by Evolveum.

the class TestEscalation method test220Reject.

@Test
public void test220Reject() throws Exception {
    final String TEST_NAME = "test220Reject";
    TestUtil.displayTestTile(this, TEST_NAME);
    login(userAdministrator);
    Task task = createTask(TEST_NAME);
    OperationResult result = task.getResult();
    dummyAuditService.clear();
    dummyTransport.clearMessages();
    // WHEN
    clock.resetOverride();
    // at 5D there's a deadline with auto-rejection
    clock.overrideDuration("P5DT20M");
    waitForTaskNextRun(TASK_TRIGGER_SCANNER_OID, true, 20000, true);
    // THEN
    SearchResultList<WorkItemType> workItems = getWorkItems(task, result);
    displayWorkItems("Work items after deadline", workItems);
    assertEquals("Wrong # of work items", 0, workItems.size());
    PrismObject<TaskType> wfTask = getTask(approvalTaskOid);
    display("workflow task", wfTask);
    assertEquals("Wrong # of triggers", 0, wfTask.asObjectable().getTrigger().size());
    Map<String, WorkItemCompletionEventType> eventMap = new HashMap<>();
    for (CaseEventType event : wfTask.asObjectable().getWorkflowContext().getEvent()) {
        if (event instanceof WorkItemCompletionEventType) {
            WorkItemCompletionEventType c = (WorkItemCompletionEventType) event;
            eventMap.put(c.getExternalWorkItemId(), c);
            assertNotNull("No result in " + c, c.getOutput());
            assertEquals("Wrong outcome in " + c, WorkItemOutcomeType.REJECT, ApprovalUtils.fromUri(c.getOutput().getOutcome()));
            assertNotNull("No cause in " + c, c.getCause());
            assertEquals("Wrong cause type in " + c, WorkItemEventCauseTypeType.TIMED_ACTION, c.getCause().getType());
            assertEquals("Wrong cause name in " + c, "auto-reject", c.getCause().getName());
            assertEquals("Wrong cause display name in " + c, "Automatic rejection at deadline", c.getCause().getDisplayName());
        }
    }
    assertEquals("Wrong # of completion events", 2, eventMap.size());
    displayCollection("audit records", dummyAuditService.getRecords());
    List<AuditEventRecord> workItemAuditRecords = dummyAuditService.getRecordsOfType(AuditEventType.WORK_ITEM);
    assertEquals("Wrong # of work item audit records", 2, workItemAuditRecords.size());
    for (AuditEventRecord r : workItemAuditRecords) {
        assertEquals("Wrong causeType in " + r, Collections.singleton("timedAction"), r.getPropertyValues(WorkflowConstants.AUDIT_CAUSE_TYPE));
        assertEquals("Wrong causeName in " + r, Collections.singleton("auto-reject"), r.getPropertyValues(WorkflowConstants.AUDIT_CAUSE_NAME));
        assertEquals("Wrong causeDisplayName in " + r, Collections.singleton("Automatic rejection at deadline"), r.getPropertyValues(WorkflowConstants.AUDIT_CAUSE_DISPLAY_NAME));
        assertEquals("Wrong result in " + r, "Rejected", r.getResult());
    }
    displayCollection("notifications - process", dummyTransport.getMessages("dummy:simpleWorkflowNotifier-Processes"));
    List<Message> notifications = dummyTransport.getMessages("dummy:simpleWorkflowNotifier-WorkItems");
    displayCollection("notifications - work items", notifications);
    for (Message notification : notifications) {
        assertContains(notification, "Reason: Automatic rejection at deadline (timed action)");
        assertContains(notification, "Result: REJECTED");
    }
}
Also used : Task(com.evolveum.midpoint.task.api.Task) Message(com.evolveum.midpoint.notifications.api.transports.Message) HashMap(java.util.HashMap) OperationResult(com.evolveum.midpoint.schema.result.OperationResult) AuditEventRecord(com.evolveum.midpoint.audit.api.AuditEventRecord) Test(org.testng.annotations.Test)

Example 10 with AuditEventRecord

use of com.evolveum.midpoint.audit.api.AuditEventRecord in project midpoint by Evolveum.

the class BaseAuditHelper method prepareProcessInstanceAuditRecord.

public AuditEventRecord prepareProcessInstanceAuditRecord(WfTask wfTask, AuditEventStage stage, OperationResult result) {
    WfContextType wfc = wfTask.getTask().getWorkflowContext();
    AuditEventRecord record = new AuditEventRecord();
    record.setEventType(WORKFLOW_PROCESS_INSTANCE);
    record.setEventStage(stage);
    record.setInitiator(wfTask.getRequesterIfExists(result));
    ObjectReferenceType objectRef = resolveIfNeeded(wfc.getObjectRef(), result);
    record.setTarget(objectRef.asReferenceValue());
    record.setOutcome(OperationResultStatus.SUCCESS);
    record.addReferenceValueIgnoreNull(WorkflowConstants.AUDIT_OBJECT, objectRef);
    record.addReferenceValueIgnoreNull(WorkflowConstants.AUDIT_TARGET, resolveIfNeeded(wfc.getTargetRef(), result));
    if (stage == EXECUTION) {
        String stageInfo = wfTask.getCompleteStageInfo();
        record.setParameter(stageInfo);
        String answer = wfTask.getAnswerNice();
        record.setResult(answer);
        record.setMessage(stageInfo != null ? stageInfo + " : " + answer : answer);
        record.addPropertyValueIgnoreNull(WorkflowConstants.AUDIT_STAGE_NUMBER, wfc.getStageNumber());
        record.addPropertyValueIgnoreNull(WorkflowConstants.AUDIT_STAGE_COUNT, WfContextUtil.getStageCount(wfc));
        record.addPropertyValueIgnoreNull(WorkflowConstants.AUDIT_STAGE_NAME, WfContextUtil.getStageName(wfc));
        record.addPropertyValueIgnoreNull(WorkflowConstants.AUDIT_STAGE_DISPLAY_NAME, WfContextUtil.getStageDisplayName(wfc));
    }
    record.addPropertyValue(WorkflowConstants.AUDIT_PROCESS_INSTANCE_ID, wfc.getProcessInstanceId());
    OperationBusinessContextType businessContext = WfContextUtil.getBusinessContext(wfc);
    String requesterComment = businessContext != null ? businessContext.getComment() : null;
    if (requesterComment != null) {
        record.addPropertyValue(WorkflowConstants.AUDIT_REQUESTER_COMMENT, requesterComment);
    }
    return record;
}
Also used : AuditEventRecord(com.evolveum.midpoint.audit.api.AuditEventRecord)

Aggregations

AuditEventRecord (com.evolveum.midpoint.audit.api.AuditEventRecord)83 OperationResult (com.evolveum.midpoint.schema.result.OperationResult)28 Task (com.evolveum.midpoint.task.api.Task)18 Test (org.testng.annotations.Test)18 ObjectDeltaOperation (com.evolveum.midpoint.schema.ObjectDeltaOperation)11 SchemaException (com.evolveum.midpoint.util.exception.SchemaException)9 ObjectDelta (com.evolveum.midpoint.prism.delta.ObjectDelta)8 PrismObject (com.evolveum.midpoint.prism.PrismObject)7 ObjectType (com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectType)6 ArrayList (java.util.ArrayList)6 MidPointPrincipal (com.evolveum.midpoint.security.api.MidPointPrincipal)5 NullTaskImpl (com.evolveum.midpoint.task.api.test.NullTaskImpl)5 PolyString (com.evolveum.midpoint.prism.polystring.PolyString)4 MAuditEventRecord (com.evolveum.midpoint.repo.sql.audit.beans.MAuditEventRecord)4 AuditResultHandler (com.evolveum.midpoint.audit.api.AuditResultHandler)3 MidpointAuthentication (com.evolveum.midpoint.authentication.api.config.MidpointAuthentication)3 Message (com.evolveum.midpoint.notifications.api.transports.Message)3 QAuditEventRecord (com.evolveum.midpoint.repo.sql.audit.querymodel.QAuditEventRecord)3 ObjectNotFoundException (com.evolveum.midpoint.util.exception.ObjectNotFoundException)3 AuditEventRecordType (com.evolveum.midpoint.xml.ns._public.common.audit_3.AuditEventRecordType)3