private void assertRecordSanity(String recordDesc, AuditEventRecord record) { assert record != null : "Null audit record ("+recordDesc+")"; assert !StringUtils.isEmpty(record.getEventIdentifier()) : "No event identifier in audit record ("+recordDesc+")"; assert !StringUtils.isEmpty(record.getTaskIdentifier()) : "No task identifier in audit record ("+recordDesc+")"; // TODO }
private String toDetails(AuditEventRecord record) { StringBuilder sb = new StringBuilder("Details of event "); sb.append(record.getEventIdentifier()).append(" stage ").append(record.getEventStage()).append("\n"); sb.append("Deltas:"); for (ObjectDeltaOperation<?> delta: record.getDeltas()) { sb.append("\n"); if (delta == null) { sb.append("null"); } else { sb.append(delta.debugDump(1)); } } // TODO: target? return sb.toString(); }
private <O extends ObjectType> PrismObject<O> getObjectFromLastEvent(PrismObject<O> object, List<AuditEventRecord> changeTrail, String eventIdentifier) { if (changeTrail.isEmpty()) { return object; } AuditEventRecord lastEvent = changeTrail.remove(changeTrail.size() - 1); if (!eventIdentifier.equals(lastEvent.getEventIdentifier())) { throw new IllegalStateException("Wrong last event identifier, expected " + eventIdentifier+" but was " + lastEvent.getEventIdentifier()); } Collection<ObjectDeltaOperation<? extends ObjectType>> lastEventDeltasOperations = lastEvent.getDeltas(); for (ObjectDeltaOperation<? extends ObjectType> lastEventDeltasOperation: lastEventDeltasOperations) { ObjectDelta<O> objectDelta = (ObjectDelta<O>) lastEventDeltasOperation.getObjectDelta(); if (!isApplicable(lastEventDeltasOperation, object, lastEvent)) { continue; } if (objectDelta.isAdd()) { // We are lucky. This is object add, so we have complete object there. No need to roll back // the operations. PrismObject<O> objectToAdd = objectDelta.getObjectToAdd(); if (LOGGER.isTraceEnabled()) { LOGGER.trace("Taking object from add delta in last event {}:\n{}", lastEvent.getEventIdentifier(), objectToAdd.debugDump(1)); } return objectToAdd; } } return null; }
private List<AuditEventRecord> getChangeTrail(String targetOid, String finalEventIdentifier) throws ObjectNotFoundException { AuditEventRecord finalEvent = findEvent(finalEventIdentifier); if (finalEvent == null) { throw new ObjectNotFoundException("Audit event ID "+finalEventIdentifier+" was not found"); } if (LOGGER.isTraceEnabled()) { LOGGER.trace("Final event:\n{}", finalEvent.debugDump(1)); } List<AuditEventRecord> changeTrail = getChangeTrail(targetOid, XmlTypeConverter.createXMLGregorianCalendar(finalEvent.getTimestamp())); // The search may have returned more events that we want to, e.g. if two // events happened in the same millisecond. Iterator<AuditEventRecord> iterator = changeTrail.iterator(); boolean foundFinalEvent = false; while (iterator.hasNext()) { AuditEventRecord event = iterator.next(); if (foundFinalEvent) { iterator.remove(); } else if (finalEventIdentifier.equals(event.getEventIdentifier())) { foundFinalEvent = true; } } return changeTrail; }
private String assertObjectAuditRecords(String oid, int expectedNumberOfRecords) throws SecurityViolationException, SchemaException, ObjectNotFoundException, ExpressionEvaluationException, CommunicationException, ConfigurationException { Task task = createTask("assertObjectAuditRecords"); OperationResult result = task.getResult(); List<AuditEventRecord> auditRecords = getObjectAuditRecords(oid, task, result); display("Object records", auditRecords); assertEquals("Wrong number of jack audit records", expectedNumberOfRecords, auditRecords.size()); return auditRecords.get(auditRecords.size() - 1).getEventIdentifier(); }
private <O extends ObjectType> boolean isApplicable(ObjectDeltaOperation<? extends ObjectType> lastEventDeltasOperation, PrismObject<O> object, AuditEventRecord lastEvent) { OperationResult executionResult = lastEventDeltasOperation.getExecutionResult(); ObjectDelta<O> objectDelta = (ObjectDelta<O>) lastEventDeltasOperation.getObjectDelta(); if (executionResult != null && executionResult.getStatus() == OperationResultStatus.FATAL_ERROR) { LOGGER.trace("Skipping delta {} in event {} because it is {}", objectDelta, lastEvent.getEventIdentifier(), executionResult.getStatus()); return false; } if (!object.getOid().equals(objectDelta.getOid())) { if (LOGGER.isTraceEnabled()) { LOGGER.trace("Skipping delta {} in event {} because OID does not match ({} vs {})", objectDelta, lastEvent.getEventIdentifier(), object.getOid(), objectDelta.getOid()); } return false; } return true; }
/** * Checks that the first record is login and the last is logout. */ public void assertLoginLogout(String expectedChannel) { AuditEventRecord firstRecord = records.get(0); assertEquals("Wrong type of first audit record: "+firstRecord.getEventType(), AuditEventType.CREATE_SESSION, firstRecord.getEventType()); assertEquals("Wrong outcome of first audit record: "+firstRecord.getOutcome(), OperationResultStatus.SUCCESS, firstRecord.getOutcome()); AuditEventRecord lastRecord = records.get(records.size()-1); assertEquals("Wrong type of last audit record: "+lastRecord.getEventType(), AuditEventType.TERMINATE_SESSION, lastRecord.getEventType()); assertEquals("Wrong outcome of last audit record: "+lastRecord.getOutcome(), OperationResultStatus.SUCCESS, lastRecord.getOutcome()); assertEquals("Audit session ID does not match", firstRecord.getSessionIdentifier(), lastRecord.getSessionIdentifier()); assertFalse("Same login and logout event IDs", firstRecord.getEventIdentifier().equals(lastRecord.getEventIdentifier())); if (expectedChannel != null) { assertEquals("Wrong channel in first audit record", expectedChannel, firstRecord.getChannel()); assertEquals("Wrong channel in last audit record", expectedChannel, lastRecord.getChannel()); } }
private <O extends ObjectType> PrismObject<O> rollBackTime(PrismObject<O> object, List<AuditEventRecord> changeTrail) throws SchemaException { for (AuditEventRecord event: changeTrail) { if (LOGGER.isTraceEnabled()) { LOGGER.trace("Applying event {} ({})", event.getEventIdentifier(), XmlTypeConverter.createXMLGregorianCalendar(event.getTimestamp())); LOGGER.trace("Object after application of event {} ({}):\n{}", event.getEventIdentifier(), XmlTypeConverter.createXMLGregorianCalendar(event.getTimestamp()), object.debugDump(1));
repo.setEventType(RAuditEventType.toRepo(record.getEventType())); repo.setSessionIdentifier(record.getSessionIdentifier()); repo.setEventIdentifier(record.getEventIdentifier()); repo.setHostIdentifier(record.getHostIdentifier()); repo.setRemoteHostAddress(record.getRemoteHostAddress());
private String toSummary(AuditEventRecord record) { return formatTimestamp(record.getTimestamp()) + " eid=" + record.getEventIdentifier() + ", et=" + record.getEventType() + ", es=" + record.getEventStage() + ", sid=" + record.getSessionIdentifier() + ", tid=" + record.getTaskIdentifier() + ", toid=" + record.getTaskOID() + ", hid=" + record.getHostIdentifier() + ", nid=" + record.getNodeIdentifier() + ", raddr=" + record.getRemoteHostAddress() + ", I=" + formatObject(record.getInitiator()) + ", T=" + formatReference(record.getTarget()) + ", TO=" + formatObject(record.getTargetOwner()) + ", D=" + formatDeltaSummary(record.getDeltas()) + ", ch=" + record.getChannel() + ", o=" + record.getOutcome() + ", p=" + record.getParameter() + ", m=" + record.getMessage(); }
if (record.getEventIdentifier() == null) { id = lightweightIdentifierGenerator.generate(); record.setEventIdentifier(id.toString());