Search in sources :

Example 1 with LogEntry

use of org.nuxeo.ecm.platform.audit.api.LogEntry in project nuxeo-drive-server by nuxeo.

the class AuditChangeFinder method getUpperBound.

/**
 * Return the last available log id in the audit log table (primary key) to be used as the upper bound of the event
 * log id range clause in the change query.
 */
@Override
@SuppressWarnings("unchecked")
public long getUpperBound() {
    AuditReader auditService = Framework.getService(AuditReader.class);
    String auditQuery = "from LogEntry log order by log.id desc";
    if (log.isDebugEnabled()) {
        log.debug("Querying audit log for greatest id: " + auditQuery);
    }
    List<LogEntry> entries = (List<LogEntry>) auditService.nativeQuery(auditQuery, 1, 1);
    if (entries.isEmpty()) {
        if (log.isDebugEnabled()) {
            log.debug("Found no audit log entries, returning -1");
        }
        return -1;
    }
    return entries.get(0).getId();
}
Also used : ArrayList(java.util.ArrayList) List(java.util.List) AuditReader(org.nuxeo.ecm.platform.audit.api.AuditReader) LogEntry(org.nuxeo.ecm.platform.audit.api.LogEntry)

Example 2 with LogEntry

use of org.nuxeo.ecm.platform.audit.api.LogEntry in project nuxeo-drive-server by nuxeo.

the class AuditChangeFinder method getFileSystemChanges.

protected List<FileSystemItemChange> getFileSystemChanges(CoreSession session, Set<IdRef> lastActiveRootRefs, SynchronizationRoots activeRoots, Set<String> collectionSyncRootMemberIds, long lowerBound, long upperBound, boolean integerBounds, int limit) throws TooManyChangesException {
    String principalName = session.getPrincipal().getName();
    List<FileSystemItemChange> changes = new ArrayList<FileSystemItemChange>();
    // Note: lastActiveRootRefs is not used: we could remove it from the
    // public API
    // and from the client as well but it might be useful to optimize future
    // alternative implementations FileSystemChangeFinder component so it
    // might
    // be better to leave it part of the public API as currently.
    // Find changes from the log under active roots or events that are
    // linked to the un-registration or deletion of formerly synchronized
    // roots
    List<LogEntry> entries = queryAuditEntries(session, activeRoots, collectionSyncRootMemberIds, lowerBound, upperBound, integerBounds, limit);
    // query with the actual active roots.
    for (LogEntry entry : entries) {
        if (NuxeoDriveEvents.EVENT_CATEGORY.equals(entry.getCategory())) {
            if (log.isDebugEnabled()) {
                log.debug(String.format("Detected sync root change for user '%s' in audit log:" + " invalidating the root cache and refetching the changes.", principalName));
            }
            NuxeoDriveManager driveManager = Framework.getService(NuxeoDriveManager.class);
            driveManager.invalidateSynchronizationRootsCache(principalName);
            driveManager.invalidateCollectionSyncRootMemberCache(principalName);
            Map<String, SynchronizationRoots> synchronizationRoots = driveManager.getSynchronizationRoots(session.getPrincipal());
            SynchronizationRoots updatedActiveRoots = synchronizationRoots.get(session.getRepositoryName());
            Set<String> updatedCollectionSyncRootMemberIds = driveManager.getCollectionSyncRootMemberIds(session.getPrincipal()).get(session.getRepositoryName());
            entries = queryAuditEntries(session, updatedActiveRoots, updatedCollectionSyncRootMemberIds, lowerBound, upperBound, integerBounds, limit);
            break;
        }
    }
    if (entries.size() >= limit) {
        throw new TooManyChangesException("Too many changes found in the audit logs.");
    }
    for (LogEntry entry : entries) {
        if (log.isDebugEnabled()) {
            log.debug(String.format("Handling log entry %s", entry));
        }
        FileSystemItemChange change = null;
        DocumentRef docRef = new IdRef(entry.getDocUUID());
        ExtendedInfo fsIdInfo = entry.getExtendedInfos().get("fileSystemItemId");
        if (fsIdInfo != null) {
            // been updated, we just know the FileSystemItem id and name.
            if (log.isDebugEnabled()) {
                log.debug(String.format("Found extended info in audit log entry: document has been deleted, moved," + " is an unregistered synchronization root or its security has been updated," + " we just know the FileSystemItem id and name."));
            }
            boolean isChangeSet = false;
            // current user still has access to the document.
            if (!"deleted".equals(entry.getEventId()) && session.exists(docRef)) {
                change = getFileSystemItemChange(session, docRef, entry, fsIdInfo.getValue(String.class));
                if (change != null) {
                    if (NuxeoDriveEvents.MOVED_EVENT.equals(entry.getEventId())) {
                        // virtual event.
                        if (log.isDebugEnabled()) {
                            log.debug(String.format("Document %s (%s) has been moved to another synchronzation root, not adding entry to the change summary.", entry.getDocPath(), docRef));
                        }
                        continue;
                    }
                    isChangeSet = true;
                }
            }
            if (!isChangeSet) {
                // FileSystemItem id and name to the FileSystemItemChange entry.
                if (log.isDebugEnabled()) {
                    log.debug(String.format("Document %s (%s) doesn't exist or is not adaptable as a FileSystemItem, only providing the FileSystemItem id and name to the FileSystemItemChange entry.", entry.getDocPath(), docRef));
                }
                String fsId = fsIdInfo.getValue(String.class);
                String eventId;
                if (NuxeoDriveEvents.MOVED_EVENT.equals(entry.getEventId())) {
                    // Move to a non synchronization root
                    eventId = NuxeoDriveEvents.DELETED_EVENT;
                } else {
                    // Deletion, unregistration or security update
                    eventId = entry.getEventId();
                }
                change = new FileSystemItemChangeImpl(eventId, entry.getEventDate().getTime(), entry.getRepositoryId(), entry.getDocUUID(), fsId, null);
            }
            if (log.isDebugEnabled()) {
                log.debug(String.format("Adding FileSystemItemChange entry to the change summary: %s", change));
            }
            changes.add(change);
        } else {
            // unregistered synchronization root nor a security update denying access to the current user.
            if (log.isDebugEnabled()) {
                log.debug(String.format("No extended info found in audit log entry %s (%s): this is not a deleted document, a moved document," + " an unregistered synchronization root nor a security update denying access to the current user.", entry.getDocPath(), docRef));
            }
            if (!session.exists(docRef)) {
                if (log.isDebugEnabled()) {
                    log.debug(String.format("Document %s (%s) doesn't exist, not adding entry to the change summary.", entry.getDocPath(), docRef));
                }
                // try to propagate this event.
                continue;
            }
            // Let's try to adapt the document as a FileSystemItem to
            // provide it to the FileSystemItemChange entry.
            change = getFileSystemItemChange(session, docRef, entry, null);
            if (change == null) {
                // Non-adaptable documents are ignored
                if (log.isDebugEnabled()) {
                    log.debug(String.format("Document %s (%s) is not adaptable as a FileSystemItem, not adding any entry to the change summary.", entry.getDocPath(), docRef));
                }
            } else {
                if (log.isDebugEnabled()) {
                    log.debug(String.format("Adding FileSystemItemChange entry to the change summary: %s", change));
                }
                changes.add(change);
            }
        }
    }
    return changes;
}
Also used : DocumentRef(org.nuxeo.ecm.core.api.DocumentRef) ArrayList(java.util.ArrayList) SynchronizationRoots(org.nuxeo.drive.service.SynchronizationRoots) IdRef(org.nuxeo.ecm.core.api.IdRef) ExtendedInfo(org.nuxeo.ecm.platform.audit.api.ExtendedInfo) FileSystemItemChange(org.nuxeo.drive.service.FileSystemItemChange) TooManyChangesException(org.nuxeo.drive.service.TooManyChangesException) LogEntry(org.nuxeo.ecm.platform.audit.api.LogEntry) NuxeoDriveManager(org.nuxeo.drive.service.NuxeoDriveManager)

Example 3 with LogEntry

use of org.nuxeo.ecm.platform.audit.api.LogEntry in project nuxeo-drive-server by nuxeo.

the class NuxeoDriveFileSystemDeletionListener method fireVirtualEventLogEntries.

protected void fireVirtualEventLogEntries(DocumentModel doc, String eventName, Principal principal, String impactedUserName, CoreSession session) {
    if (Framework.getService(AuditLogger.class) == null) {
        // The log is not deployed (probably in unittest)
        return;
    }
    List<LogEntry> entries = new ArrayList<>();
    // XXX: shall we use the server local for the event date or UTC?
    Date currentDate = Calendar.getInstance(NuxeoDriveManagerImpl.UTC).getTime();
    FileSystemItem fsItem = getFileSystemItem(doc, eventName);
    if (fsItem == null) {
        // roots in order to make Drive add / remove them if needed
        if (NuxeoDriveEvents.SECURITY_UPDATED_EVENT.equals(eventName)) {
            for (DocumentModel childSyncRoot : getChildSyncRoots(doc, session)) {
                FileSystemItem childSyncRootFSItem = getFileSystemItem(childSyncRoot, eventName);
                if (childSyncRootFSItem != null) {
                    entries.add(computeLogEntry(eventName, currentDate, childSyncRoot.getId(), childSyncRoot.getPathAsString(), principal.getName(), childSyncRoot.getType(), childSyncRoot.getRepositoryName(), childSyncRoot.getCurrentLifeCycleState(), impactedUserName, childSyncRootFSItem));
                }
            }
        }
    } else {
        entries.add(computeLogEntry(eventName, currentDate, doc.getId(), doc.getPathAsString(), principal.getName(), doc.getType(), doc.getRepositoryName(), doc.getCurrentLifeCycleState(), impactedUserName, fsItem));
    }
    if (!entries.isEmpty()) {
        EventContext eventContext = new EventContextImpl(entries.toArray());
        Event event = eventContext.newEvent(NuxeoDriveEvents.VIRTUAL_EVENT_CREATED);
        Framework.getService(EventProducer.class).fireEvent(event);
    }
}
Also used : DocumentEventContext(org.nuxeo.ecm.core.event.impl.DocumentEventContext) EventContext(org.nuxeo.ecm.core.event.EventContext) AuditLogger(org.nuxeo.ecm.platform.audit.api.AuditLogger) FileSystemItem(org.nuxeo.drive.adapter.FileSystemItem) EventContextImpl(org.nuxeo.ecm.core.event.impl.EventContextImpl) ArrayList(java.util.ArrayList) EventProducer(org.nuxeo.ecm.core.event.EventProducer) Event(org.nuxeo.ecm.core.event.Event) LogEntry(org.nuxeo.ecm.platform.audit.api.LogEntry) Date(java.util.Date) DocumentModel(org.nuxeo.ecm.core.api.DocumentModel)

Example 4 with LogEntry

use of org.nuxeo.ecm.platform.audit.api.LogEntry in project nuxeo-drive-server by nuxeo.

the class NuxeoDriveFileSystemDeletionListener method computeLogEntry.

protected LogEntry computeLogEntry(String eventName, Date eventDate, String docId, String docPath, String principal, String docType, String repositoryName, String currentLifeCycleState, String impactedUserName, FileSystemItem fsItem) {
    AuditLogger logger = Framework.getService(AuditLogger.class);
    LogEntry entry = logger.newLogEntry();
    entry.setEventId(eventName);
    entry.setEventDate(eventDate);
    entry.setCategory(NuxeoDriveEvents.EVENT_CATEGORY);
    entry.setDocUUID(docId);
    entry.setDocPath(docPath);
    entry.setPrincipalName(principal);
    entry.setDocType(docType);
    entry.setRepositoryId(repositoryName);
    entry.setDocLifeCycle(currentLifeCycleState);
    Map<String, ExtendedInfo> extendedInfos = new HashMap<String, ExtendedInfo>();
    if (impactedUserName != null) {
        extendedInfos.put("impactedUserName", logger.newExtendedInfo(impactedUserName));
    }
    // We do not serialize the whole object as it's too big to fit in a
    // StringInfo column
    extendedInfos.put("fileSystemItemId", logger.newExtendedInfo(fsItem.getId()));
    extendedInfos.put("fileSystemItemName", logger.newExtendedInfo(fsItem.getName()));
    entry.setExtendedInfos(extendedInfos);
    return entry;
}
Also used : AuditLogger(org.nuxeo.ecm.platform.audit.api.AuditLogger) HashMap(java.util.HashMap) ExtendedInfo(org.nuxeo.ecm.platform.audit.api.ExtendedInfo) LogEntry(org.nuxeo.ecm.platform.audit.api.LogEntry)

Example 5 with LogEntry

use of org.nuxeo.ecm.platform.audit.api.LogEntry in project nuxeo-drive-server by nuxeo.

the class ESAuditChangeFinder method queryAuditEntries.

@Override
protected List<LogEntry> queryAuditEntries(CoreSession session, SynchronizationRoots activeRoots, Set<String> collectionSyncRootMemberIds, long lowerBound, long upperBound, boolean integerBounds, int limit) {
    List<LogEntry> entries = queryESAuditEntries(session, activeRoots, collectionSyncRootMemberIds, lowerBound, upperBound, integerBounds, limit);
    // Post filter the output to remove (un)registration that are unrelated
    // to the current user.
    // TODO move this to the ES query
    List<LogEntry> postFilteredEntries = new ArrayList<>();
    String principalName = session.getPrincipal().getName();
    for (LogEntry entry : entries) {
        ExtendedInfo impactedUserInfo = entry.getExtendedInfos().get("impactedUserName");
        if (impactedUserInfo != null && !principalName.equals(impactedUserInfo.getValue(String.class))) {
            // ignore event that only impact other users
            continue;
        }
        if (log.isDebugEnabled()) {
            if (log.isDebugEnabled()) {
                log.debug(String.format("Change detected: %s", entry));
            }
        }
        postFilteredEntries.add(entry);
    }
    return postFilteredEntries;
}
Also used : ArrayList(java.util.ArrayList) ExtendedInfo(org.nuxeo.ecm.platform.audit.api.ExtendedInfo) LogEntry(org.nuxeo.ecm.platform.audit.api.LogEntry)

Aggregations

LogEntry (org.nuxeo.ecm.platform.audit.api.LogEntry)10 ArrayList (java.util.ArrayList)9 ExtendedInfo (org.nuxeo.ecm.platform.audit.api.ExtendedInfo)4 HashMap (java.util.HashMap)3 List (java.util.List)3 AuditLogger (org.nuxeo.ecm.platform.audit.api.AuditLogger)3 AuditReader (org.nuxeo.ecm.platform.audit.api.AuditReader)3 ObjectMapper (com.fasterxml.jackson.databind.ObjectMapper)2 IOException (java.io.IOException)2 Date (java.util.Date)2 SearchRequest (org.elasticsearch.action.search.SearchRequest)2 SearchResponse (org.elasticsearch.action.search.SearchResponse)2 SearchHit (org.elasticsearch.search.SearchHit)2 SearchSourceBuilder (org.elasticsearch.search.builder.SearchSourceBuilder)2 Event (org.nuxeo.ecm.core.event.Event)2 EventContext (org.nuxeo.ecm.core.event.EventContext)2 LogEntryImpl (org.nuxeo.ecm.platform.audit.impl.LogEntryImpl)2 BoolQueryBuilder (org.elasticsearch.index.query.BoolQueryBuilder)1 QueryBuilder (org.elasticsearch.index.query.QueryBuilder)1 RangeQueryBuilder (org.elasticsearch.index.query.RangeQueryBuilder)1