diff --git a/invenio_rdm_records/auditlog/actions.py b/invenio_rdm_records/auditlog/actions.py index e634cd4dd..17c62a881 100644 --- a/invenio_rdm_records/auditlog/actions.py +++ b/invenio_rdm_records/auditlog/actions.py @@ -18,7 +18,7 @@ Grant, ) -from .context import LogChangesContext, ResourceDataContext +from .context import FileContext, LogChangesContext, ResourceDataContext class ParentBaseAuditLog(BaseAuditLog): @@ -128,3 +128,32 @@ class RDMDraftAccessSettingsAuditLog(RDMRecordAccessSettingsAuditLog): message_template = _( "User {user_id} updated access settings of {resource_type} {resource_id} via draft." ) + + +class FileCreateAuditLog(BaseAuditLog): + """Audit log for file create.""" + + resource_type = "draft" + + context = BaseAuditLog.context + [ + FileContext(), + ] + + id = "file.create" + message_template = _( + "User {user_id} created file {file_key} of {resource_type} {resource_id}." + ) + + metadata_schema = { + **BaseAuditLog.metadata_schema, + "file_key": ma.fields.String(required=True), + } + + +class FileDeleteAuditLog(FileCreateAuditLog): + """Audit log for file delete.""" + + id = "file.delete" + message_template = _( + "User {user_id} deleted file {file_key} of {resource_type} {resource_id}." + ) diff --git a/invenio_rdm_records/auditlog/context.py b/invenio_rdm_records/auditlog/context.py index f80f44ea5..a3ce9e30c 100644 --- a/invenio_rdm_records/auditlog/context.py +++ b/invenio_rdm_records/auditlog/context.py @@ -38,3 +38,12 @@ def __call__(self, data, **kwargs): "type": "draft" if isinstance(resource, RDMDraft) else "record", } dict_set(data, "metadata.triggered_by", triggered_by) + + +class FileContext(object): + """Payload generator for setting file data.""" + + def __call__(self, data, **kwargs): + """Update data with file data.""" + file_key = kwargs.get("file_key", None) + dict_set(data, "metadata.file_key", file_key) diff --git a/invenio_rdm_records/services/files/service.py b/invenio_rdm_records/services/files/service.py index 80ff6f113..17b02a485 100644 --- a/invenio_rdm_records/services/files/service.py +++ b/invenio_rdm_records/services/files/service.py @@ -7,8 +7,14 @@ """File Service API.""" +from invenio_audit_logs.services.uow import AuditLogOp from invenio_records_resources.services import FileService +from invenio_records_resources.services.uow import unit_of_work +from invenio_rdm_records.auditlog.actions import ( + FileCreateAuditLog, + FileDeleteAuditLog, +) from invenio_rdm_records.services.errors import RecordDeletedException @@ -32,3 +38,23 @@ def _get_record(self, id_, identity, action, file_key=None): self._check_record_deleted_permissions(record, identity) return record + + @unit_of_work() + def commit_file(self, identity, id_, file_key, uow=None): + """Commit a file upload.""" + result = super().commit_file(identity, id_, file_key, uow=uow) + + uow.register( + AuditLogOp(FileCreateAuditLog.build(identity, id_, file_key=file_key)) + ) # Added here as audit logs can't be added to invenio-records-resources + return result + + @unit_of_work() + def delete_file(self, identity, id_, file_key, uow=None): + """Delete a file.""" + result = super().delete_file(identity, id_, file_key, uow=uow) + + uow.register( + AuditLogOp(FileDeleteAuditLog.build(identity, id_, file_key=file_key)) + ) # Added here as audit logs can't be added to invenio-records-resources + return result diff --git a/setup.cfg b/setup.cfg index 501c61ce3..f12a54438 100644 --- a/setup.cfg +++ b/setup.cfg @@ -154,6 +154,8 @@ invenio_audit_logs.actions = draft.secret_link_update = invenio_rdm_records.auditlog.actions:RDMDraftSecretLinkAuditLog record.access_settings_update = invenio_rdm_records.auditlog.actions:RDMRecordAccessSettingsAuditLog draft.access_settings_update = invenio_rdm_records.auditlog.actions:RDMDraftAccessSettingsAuditLog + file.create = invenio_rdm_records.auditlog.actions:FileCreateAuditLog + file.delete = invenio_rdm_records.auditlog.actions:FileDeleteAuditLog [build_sphinx] source-dir = docs/