invenio-audit-logs 1.0.0.dev0__py2.py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- invenio_audit_logs/__init__.py +18 -0
- invenio_audit_logs/alembic/1743073617_create_audit_logs_branch.py +27 -0
- invenio_audit_logs/alembic/1743073720_create_audit_logs_table.py +57 -0
- invenio_audit_logs/config.py +42 -0
- invenio_audit_logs/ext.py +47 -0
- invenio_audit_logs/proxies.py +16 -0
- invenio_audit_logs/records/__init__.py +12 -0
- invenio_audit_logs/records/api.py +51 -0
- invenio_audit_logs/records/models.py +27 -0
- invenio_audit_logs/records/templates/__init__.py +10 -0
- invenio_audit_logs/records/templates/os-v1/__init__.py +8 -0
- invenio_audit_logs/records/templates/os-v1/datastream-auditlog-v1.0.0.json +73 -0
- invenio_audit_logs/records/templates/os-v2/__init__.py +8 -0
- invenio_audit_logs/records/templates/os-v2/datastream-auditlog-v1.0.0.json +73 -0
- invenio_audit_logs/resources/__init__.py +17 -0
- invenio_audit_logs/resources/config.py +57 -0
- invenio_audit_logs/resources/resource.py +68 -0
- invenio_audit_logs/services/__init__.py +18 -0
- invenio_audit_logs/services/config.py +109 -0
- invenio_audit_logs/services/generators.py +24 -0
- invenio_audit_logs/services/permissions.py +24 -0
- invenio_audit_logs/services/results.py +113 -0
- invenio_audit_logs/services/schema.py +140 -0
- invenio_audit_logs/services/service.py +88 -0
- invenio_audit_logs/services/uow.py +31 -0
- invenio_audit_logs/views.py +18 -0
- invenio_audit_logs-1.0.0.dev0.dist-info/METADATA +78 -0
- invenio_audit_logs-1.0.0.dev0.dist-info/RECORD +33 -0
- invenio_audit_logs-1.0.0.dev0.dist-info/WHEEL +6 -0
- invenio_audit_logs-1.0.0.dev0.dist-info/entry_points.txt +18 -0
- invenio_audit_logs-1.0.0.dev0.dist-info/licenses/AUTHORS.rst +13 -0
- invenio_audit_logs-1.0.0.dev0.dist-info/licenses/LICENSE +21 -0
- invenio_audit_logs-1.0.0.dev0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
#
|
|
3
|
+
# This file is part of Invenio.
|
|
4
|
+
# Copyright (C) 2025 CERN.
|
|
5
|
+
#
|
|
6
|
+
# Invenio-Audit-Logs is free software; you can redistribute it and/or modify
|
|
7
|
+
# it under the terms of the MIT License; see LICENSE file for more details.
|
|
8
|
+
|
|
9
|
+
"""Module providing audit logging features for Invenio.."""
|
|
10
|
+
|
|
11
|
+
from .ext import InvenioAuditLogs
|
|
12
|
+
|
|
13
|
+
__version__ = "1.0.0.dev0"
|
|
14
|
+
|
|
15
|
+
__all__ = (
|
|
16
|
+
"__version__",
|
|
17
|
+
"InvenioAuditLogs",
|
|
18
|
+
)
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
#
|
|
2
|
+
# This file is part of Invenio.
|
|
3
|
+
# Copyright (C) 2016-2018 CERN.
|
|
4
|
+
#
|
|
5
|
+
# Invenio-Audit-Logs is free software; you can redistribute it and/or modify it
|
|
6
|
+
# under the terms of the MIT License; see LICENSE file for more details.
|
|
7
|
+
|
|
8
|
+
"""Create Audit logs branch."""
|
|
9
|
+
|
|
10
|
+
import sqlalchemy as sa
|
|
11
|
+
from alembic import op
|
|
12
|
+
|
|
13
|
+
# revision identifiers, used by Alembic.
|
|
14
|
+
revision = "1743073617"
|
|
15
|
+
down_revision = None
|
|
16
|
+
branch_labels = ("invenio_audit_logs",)
|
|
17
|
+
depends_on = "dbdbc1b19cf2"
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def upgrade():
|
|
21
|
+
"""Upgrade database."""
|
|
22
|
+
pass
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def downgrade():
|
|
26
|
+
"""Downgrade database."""
|
|
27
|
+
pass
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
#
|
|
2
|
+
# This file is part of Invenio.
|
|
3
|
+
# Copyright (C) 2016-2018 CERN.
|
|
4
|
+
#
|
|
5
|
+
# Invenio-Audit-Logs is free software; you can redistribute it and/or modify it
|
|
6
|
+
# under the terms of the MIT License; see LICENSE file for more details.
|
|
7
|
+
|
|
8
|
+
"""Create Audit Logs table."""
|
|
9
|
+
|
|
10
|
+
import sqlalchemy as sa
|
|
11
|
+
import sqlalchemy_utils
|
|
12
|
+
from alembic import op
|
|
13
|
+
from sqlalchemy.dialects import mysql, postgresql
|
|
14
|
+
|
|
15
|
+
# revision identifiers, used by Alembic.
|
|
16
|
+
revision = "1743073720"
|
|
17
|
+
down_revision = "1743073617"
|
|
18
|
+
branch_labels = ()
|
|
19
|
+
depends_on = None
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def upgrade():
|
|
23
|
+
"""Upgrade database."""
|
|
24
|
+
op.create_table(
|
|
25
|
+
"audit_logs_metadata",
|
|
26
|
+
sa.Column("id", sqlalchemy_utils.types.uuid.UUIDType(), nullable=False),
|
|
27
|
+
sa.Column(
|
|
28
|
+
"created",
|
|
29
|
+
sa.DateTime().with_variant(mysql.DATETIME(fsp=6), "mysql"),
|
|
30
|
+
nullable=False,
|
|
31
|
+
),
|
|
32
|
+
sa.Column(
|
|
33
|
+
"updated",
|
|
34
|
+
sa.DateTime().with_variant(mysql.DATETIME(fsp=6), "mysql"),
|
|
35
|
+
nullable=False,
|
|
36
|
+
),
|
|
37
|
+
sa.Column("action", sa.String(length=255), nullable=False),
|
|
38
|
+
sa.Column("resource_type", sa.String(length=255), nullable=False),
|
|
39
|
+
sa.Column("user_id", sa.String(length=255), nullable=False),
|
|
40
|
+
sa.Column(
|
|
41
|
+
"json",
|
|
42
|
+
sa.JSON()
|
|
43
|
+
.with_variant(sqlalchemy_utils.types.json.JSONType(), "mysql")
|
|
44
|
+
.with_variant(
|
|
45
|
+
postgresql.JSONB(none_as_null=True, astext_type=sa.Text()), "postgresql"
|
|
46
|
+
)
|
|
47
|
+
.with_variant(sqlalchemy_utils.types.json.JSONType(), "sqlite"),
|
|
48
|
+
nullable=True,
|
|
49
|
+
),
|
|
50
|
+
sa.Column("version_id", sa.Integer(), nullable=False),
|
|
51
|
+
sa.PrimaryKeyConstraint("id", name=op.f("pk_audit_logs_metadata")),
|
|
52
|
+
)
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def downgrade():
|
|
56
|
+
"""Downgrade database."""
|
|
57
|
+
op.drop_table("audit_logs_metadata")
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
#
|
|
3
|
+
# Copyright (C) 2025 CERN.
|
|
4
|
+
#
|
|
5
|
+
# Invenio-Audit-Logs is free software; you can redistribute it and/or modify
|
|
6
|
+
# it under the terms of the MIT License; see LICENSE file for more details.
|
|
7
|
+
|
|
8
|
+
"""Configuration for invenio-audit-logs."""
|
|
9
|
+
|
|
10
|
+
from invenio_records_resources.services.records.facets import TermsFacet
|
|
11
|
+
|
|
12
|
+
AUDIT_LOGS_SEARCH = {
|
|
13
|
+
"facets": ["resource"],
|
|
14
|
+
"sort": [
|
|
15
|
+
"bestmatch",
|
|
16
|
+
"newest",
|
|
17
|
+
"oldest",
|
|
18
|
+
],
|
|
19
|
+
# query_parser_cls
|
|
20
|
+
}
|
|
21
|
+
"""Search configuration for audit logs."""
|
|
22
|
+
|
|
23
|
+
AUDIT_LOGS_FACETS = {
|
|
24
|
+
"resource": dict(
|
|
25
|
+
facet=TermsFacet(
|
|
26
|
+
field="resource_type",
|
|
27
|
+
label="Resource",
|
|
28
|
+
value_labels={
|
|
29
|
+
"record": "Record",
|
|
30
|
+
"community": "Community",
|
|
31
|
+
}, # Add user later
|
|
32
|
+
),
|
|
33
|
+
ui=dict(field="resource_type"),
|
|
34
|
+
),
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
AUDIT_LOGS_SORT_OPTIONS = {
|
|
38
|
+
"bestmatch": dict(title="Best match", fields=["_score"]),
|
|
39
|
+
"newest": dict(title="Newest", fields=["-@timestamp"]),
|
|
40
|
+
"oldest": dict(title="Oldest", fields=["@timestamp"]),
|
|
41
|
+
}
|
|
42
|
+
"""Sort options for audit logs."""
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
#
|
|
3
|
+
# Copyright (C) 2025 CERN.
|
|
4
|
+
#
|
|
5
|
+
# Invenio-Audit-Logs is free software; you can redistribute it and/or modify
|
|
6
|
+
# it under the terms of the MIT License; see LICENSE file for more details.
|
|
7
|
+
|
|
8
|
+
"""Module providing audit logging features for Invenio.."""
|
|
9
|
+
|
|
10
|
+
from . import config
|
|
11
|
+
from .resources import AuditLogResource, AuditLogResourceConfig
|
|
12
|
+
from .services import AuditLogService, AuditLogServiceConfig
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class InvenioAuditLogs(object):
|
|
16
|
+
"""Invenio-Audit-Logs extension."""
|
|
17
|
+
|
|
18
|
+
def __init__(self, app=None):
|
|
19
|
+
"""Extension initialization."""
|
|
20
|
+
if app:
|
|
21
|
+
self.init_app(app)
|
|
22
|
+
|
|
23
|
+
def init_app(self, app):
|
|
24
|
+
"""Flask application initialization."""
|
|
25
|
+
self.init_config(app)
|
|
26
|
+
self.init_services(app)
|
|
27
|
+
self.init_resources(app)
|
|
28
|
+
app.extensions["invenio-audit-logs"] = self
|
|
29
|
+
|
|
30
|
+
def init_config(self, app):
|
|
31
|
+
"""Initialize configuration."""
|
|
32
|
+
for k in dir(config):
|
|
33
|
+
if k.startswith("AUDIT_LOGS_"):
|
|
34
|
+
app.config.setdefault(k, getattr(config, k))
|
|
35
|
+
|
|
36
|
+
def init_services(self, app):
|
|
37
|
+
"""Initialize services."""
|
|
38
|
+
self.audit_log_service = AuditLogService(
|
|
39
|
+
config=AuditLogServiceConfig.build(app),
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
def init_resources(self, app):
|
|
43
|
+
"""Init resources."""
|
|
44
|
+
self.audit_log_resource = AuditLogResource(
|
|
45
|
+
service=self.audit_log_service,
|
|
46
|
+
config=AuditLogResourceConfig.build(app),
|
|
47
|
+
)
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
#
|
|
3
|
+
# Copyright (C) 2025 CERN.
|
|
4
|
+
#
|
|
5
|
+
# Invenio-Jobs is free software; you can redistribute it and/or modify it
|
|
6
|
+
# under the terms of the MIT License; see LICENSE file for more details.
|
|
7
|
+
|
|
8
|
+
"""Proxies."""
|
|
9
|
+
|
|
10
|
+
from flask import current_app
|
|
11
|
+
from werkzeug.local import LocalProxy
|
|
12
|
+
|
|
13
|
+
current_audit_logs_service = LocalProxy(
|
|
14
|
+
lambda: current_app.extensions["invenio-audit-logs"].audit_log_service
|
|
15
|
+
)
|
|
16
|
+
"""Proxy to an instance of ``AuditLogs`` service."""
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
#
|
|
3
|
+
# Copyright (C) 2025 CERN.
|
|
4
|
+
#
|
|
5
|
+
# Invenio-Audit-Logs is free software; you can redistribute it and/or modify it
|
|
6
|
+
# under the terms of the MIT License; see LICENSE file for more details.
|
|
7
|
+
|
|
8
|
+
"""Audit Log data layer definitions."""
|
|
9
|
+
|
|
10
|
+
from .api import AuditLog
|
|
11
|
+
|
|
12
|
+
__all__ = ("AuditLog",)
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
#
|
|
3
|
+
# This file is part of Invenio.
|
|
4
|
+
# Copyright (C) 2025 CERN.
|
|
5
|
+
#
|
|
6
|
+
# Invenio-Audit-Logs is free software; you can redistribute it and/or modify it
|
|
7
|
+
# under the terms of the MIT License; see LICENSE file for more details.
|
|
8
|
+
|
|
9
|
+
"""API classes for audit log event."""
|
|
10
|
+
|
|
11
|
+
from datetime import datetime
|
|
12
|
+
from uuid import UUID
|
|
13
|
+
|
|
14
|
+
from invenio_records.dumpers import SearchDumper
|
|
15
|
+
from invenio_records.systemfields import DictField, ModelField
|
|
16
|
+
from invenio_records_resources.records.api import Record
|
|
17
|
+
from invenio_records_resources.records.systemfields import IndexField
|
|
18
|
+
|
|
19
|
+
from . import models
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class AuditLog(Record):
|
|
23
|
+
"""API class to represent a structured audit-log event."""
|
|
24
|
+
|
|
25
|
+
model_cls = models.AuditLog
|
|
26
|
+
"""The model class for the log."""
|
|
27
|
+
|
|
28
|
+
dumper = SearchDumper(
|
|
29
|
+
model_fields={
|
|
30
|
+
"id": ("id", UUID),
|
|
31
|
+
"created": ("@timestamp", datetime),
|
|
32
|
+
},
|
|
33
|
+
)
|
|
34
|
+
"""Search dumper with configured dump keys."""
|
|
35
|
+
|
|
36
|
+
index = IndexField("auditlog-audit-log-v1.0.0", search_alias="auditlog")
|
|
37
|
+
"""The search engine index to use."""
|
|
38
|
+
|
|
39
|
+
id = ModelField("id", dump_type=UUID)
|
|
40
|
+
|
|
41
|
+
created = ModelField("created", dump_type=datetime, dump_key="@timestamp")
|
|
42
|
+
|
|
43
|
+
action = ModelField("action", dump_type=str)
|
|
44
|
+
|
|
45
|
+
user_id = ModelField("user_id", dump=False, dump_type=str)
|
|
46
|
+
|
|
47
|
+
user = DictField("user")
|
|
48
|
+
|
|
49
|
+
resource_type = ModelField("resource_type", dump=False, dump_type=str)
|
|
50
|
+
|
|
51
|
+
resource = DictField("resource")
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
#
|
|
3
|
+
# Copyright (C) 2025 CERN.
|
|
4
|
+
#
|
|
5
|
+
# Invenio-Audit-Logs is free software; you can redistribute it and/or modify it
|
|
6
|
+
# under the terms of the MIT License; see LICENSE file for more details.
|
|
7
|
+
|
|
8
|
+
"""Base model classes for Audit Logs in Invenio."""
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
from invenio_db import db
|
|
12
|
+
from invenio_records.models import RecordMetadataBase
|
|
13
|
+
from sqlalchemy.types import String
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class AuditLog(db.Model, RecordMetadataBase):
|
|
17
|
+
"""Model class for Audit Log."""
|
|
18
|
+
|
|
19
|
+
__tablename__ = "audit_logs_metadata"
|
|
20
|
+
|
|
21
|
+
encoder = None
|
|
22
|
+
|
|
23
|
+
action = db.Column(String(255), nullable=False)
|
|
24
|
+
|
|
25
|
+
resource_type = db.Column(String(255), nullable=False)
|
|
26
|
+
|
|
27
|
+
user_id = db.Column(String(255), nullable=False)
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
#
|
|
3
|
+
# This file is part of Invenio.
|
|
4
|
+
# Copyright (C) 2025 CERN.
|
|
5
|
+
#
|
|
6
|
+
# Invenio-Audit-Logs is free software; you can redistribute it and/or modify it
|
|
7
|
+
# under the terms of the MIT License; see LICENSE file for more details.
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
"""Audit Logs datastream index templates."""
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
{
|
|
2
|
+
"index_patterns": ["__SEARCH_INDEX_PREFIX__auditlog*"],
|
|
3
|
+
"data_stream": {},
|
|
4
|
+
"template": {
|
|
5
|
+
"settings": {
|
|
6
|
+
"analysis": {
|
|
7
|
+
"filter": {
|
|
8
|
+
"email_domains": {
|
|
9
|
+
"type": "pattern_capture",
|
|
10
|
+
"preserve_original": false,
|
|
11
|
+
"patterns": [
|
|
12
|
+
"@(.+)"
|
|
13
|
+
]
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
"analyzer": {
|
|
17
|
+
"email": {
|
|
18
|
+
"tokenizer": "uax_url_email",
|
|
19
|
+
"filter": [
|
|
20
|
+
"email_domains",
|
|
21
|
+
"lowercase",
|
|
22
|
+
"unique"
|
|
23
|
+
]
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
"mappings": {
|
|
29
|
+
"dynamic": "strict",
|
|
30
|
+
"numeric_detection": false,
|
|
31
|
+
"properties": {
|
|
32
|
+
"id": { "type": "keyword" },
|
|
33
|
+
"uuid": { "type": "keyword" },
|
|
34
|
+
"version_id": { "type": "integer" },
|
|
35
|
+
"action": { "type": "keyword" },
|
|
36
|
+
"resource": {
|
|
37
|
+
"properties": {
|
|
38
|
+
"id": { "type": "keyword" },
|
|
39
|
+
"type": { "type": "keyword" }
|
|
40
|
+
}
|
|
41
|
+
},
|
|
42
|
+
"message": { "type": "text" },
|
|
43
|
+
"user": {
|
|
44
|
+
"properties": {
|
|
45
|
+
"id": { "type": "keyword" },
|
|
46
|
+
"name": { "type": "keyword" },
|
|
47
|
+
"email": {
|
|
48
|
+
"type": "text",
|
|
49
|
+
"analyzer": "email",
|
|
50
|
+
"fielddata": true,
|
|
51
|
+
"fields": {
|
|
52
|
+
"domain": {
|
|
53
|
+
"type": "text",
|
|
54
|
+
"analyzer": "email",
|
|
55
|
+
"fielddata": true
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
},
|
|
61
|
+
"metadata": {
|
|
62
|
+
"type": "object",
|
|
63
|
+
"dynamic": true
|
|
64
|
+
},
|
|
65
|
+
"updated": { "type": "date" }
|
|
66
|
+
}
|
|
67
|
+
},
|
|
68
|
+
"aliases": {
|
|
69
|
+
"__SEARCH_INDEX_PREFIX__auditlog": {},
|
|
70
|
+
"__SEARCH_INDEX_PREFIX__audit-log": {}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
{
|
|
2
|
+
"index_patterns": ["__SEARCH_INDEX_PREFIX__auditlog*"],
|
|
3
|
+
"data_stream": {},
|
|
4
|
+
"template": {
|
|
5
|
+
"settings": {
|
|
6
|
+
"analysis": {
|
|
7
|
+
"filter": {
|
|
8
|
+
"email_domains": {
|
|
9
|
+
"type": "pattern_capture",
|
|
10
|
+
"preserve_original": false,
|
|
11
|
+
"patterns": [
|
|
12
|
+
"@(.+)"
|
|
13
|
+
]
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
"analyzer": {
|
|
17
|
+
"email": {
|
|
18
|
+
"tokenizer": "uax_url_email",
|
|
19
|
+
"filter": [
|
|
20
|
+
"email_domains",
|
|
21
|
+
"lowercase",
|
|
22
|
+
"unique"
|
|
23
|
+
]
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
"mappings": {
|
|
29
|
+
"dynamic": "strict",
|
|
30
|
+
"numeric_detection": false,
|
|
31
|
+
"properties": {
|
|
32
|
+
"id": { "type": "keyword" },
|
|
33
|
+
"uuid": { "type": "keyword" },
|
|
34
|
+
"version_id": { "type": "integer" },
|
|
35
|
+
"action": { "type": "keyword" },
|
|
36
|
+
"resource": {
|
|
37
|
+
"properties": {
|
|
38
|
+
"id": { "type": "keyword" },
|
|
39
|
+
"type": { "type": "keyword" }
|
|
40
|
+
}
|
|
41
|
+
},
|
|
42
|
+
"message": { "type": "text" },
|
|
43
|
+
"user": {
|
|
44
|
+
"properties": {
|
|
45
|
+
"id": { "type": "keyword" },
|
|
46
|
+
"name": { "type": "keyword" },
|
|
47
|
+
"email": {
|
|
48
|
+
"type": "text",
|
|
49
|
+
"analyzer": "email",
|
|
50
|
+
"fielddata": true,
|
|
51
|
+
"fields": {
|
|
52
|
+
"domain": {
|
|
53
|
+
"type": "text",
|
|
54
|
+
"analyzer": "email",
|
|
55
|
+
"fielddata": true
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
},
|
|
61
|
+
"metadata": {
|
|
62
|
+
"type": "object",
|
|
63
|
+
"dynamic": true
|
|
64
|
+
},
|
|
65
|
+
"updated": { "type": "date" }
|
|
66
|
+
}
|
|
67
|
+
},
|
|
68
|
+
"aliases": {
|
|
69
|
+
"__SEARCH_INDEX_PREFIX__auditlog": {},
|
|
70
|
+
"__SEARCH_INDEX_PREFIX__audit-log": {}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
#
|
|
3
|
+
# Copyright (C) 2025 CERN.
|
|
4
|
+
#
|
|
5
|
+
# Invenio-Audit-Logs is free software; you can redistribute it and/or
|
|
6
|
+
# modify it under the terms of the MIT License; see LICENSE file for more
|
|
7
|
+
# details.
|
|
8
|
+
|
|
9
|
+
"""Resources module."""
|
|
10
|
+
|
|
11
|
+
from .config import AuditLogResourceConfig
|
|
12
|
+
from .resource import AuditLogResource
|
|
13
|
+
|
|
14
|
+
__all__ = (
|
|
15
|
+
"AuditLogResource",
|
|
16
|
+
"AuditLogResourceConfig",
|
|
17
|
+
)
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
#
|
|
3
|
+
# Copyright (C) 2025 CERN.
|
|
4
|
+
#
|
|
5
|
+
# Invenio-Audit-Logs is free software; you can redistribute it and/or
|
|
6
|
+
# modify it under the terms of the MIT License; see LICENSE file for more
|
|
7
|
+
# details.
|
|
8
|
+
|
|
9
|
+
"""Audit logs resource config."""
|
|
10
|
+
|
|
11
|
+
from invenio_records_resources.resources import (
|
|
12
|
+
RecordResourceConfig,
|
|
13
|
+
SearchRequestArgsSchema,
|
|
14
|
+
)
|
|
15
|
+
from invenio_records_resources.services.base.config import ConfiguratorMixin
|
|
16
|
+
from marshmallow import fields
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
#
|
|
20
|
+
# Request args
|
|
21
|
+
#
|
|
22
|
+
class AuditLogSearchRequestArgsSchema(SearchRequestArgsSchema):
|
|
23
|
+
"""Search parameters for audit-logs."""
|
|
24
|
+
|
|
25
|
+
id = fields.UUID()
|
|
26
|
+
resource_id = fields.String()
|
|
27
|
+
resource_type = fields.String()
|
|
28
|
+
user_id = fields.String()
|
|
29
|
+
action = fields.String()
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
#
|
|
33
|
+
# Resource config
|
|
34
|
+
#
|
|
35
|
+
class AuditLogResourceConfig(RecordResourceConfig, ConfiguratorMixin):
|
|
36
|
+
"""Audit-Logs resource configuration."""
|
|
37
|
+
|
|
38
|
+
blueprint_name = "audit_logs"
|
|
39
|
+
url_prefix = "/audit-logs"
|
|
40
|
+
|
|
41
|
+
routes = {
|
|
42
|
+
"list": "/",
|
|
43
|
+
"item": "/<id>",
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
request_view_args = {
|
|
47
|
+
"id": fields.UUID(),
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
request_search_args = AuditLogSearchRequestArgsSchema
|
|
51
|
+
|
|
52
|
+
response_handlers = {
|
|
53
|
+
"application/vnd.inveniordm.v1+json": RecordResourceConfig.response_handlers[
|
|
54
|
+
"application/json"
|
|
55
|
+
],
|
|
56
|
+
**RecordResourceConfig.response_handlers,
|
|
57
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
#
|
|
3
|
+
# Copyright (C) 2025 CERN.
|
|
4
|
+
#
|
|
5
|
+
# Invenio-Audit-Logs is free software; you can redistribute it and/or
|
|
6
|
+
# modify it under the terms of the MIT License; see LICENSE file for more
|
|
7
|
+
# details.
|
|
8
|
+
|
|
9
|
+
"""Logs resource."""
|
|
10
|
+
|
|
11
|
+
from flask import g
|
|
12
|
+
from flask_resources import resource_requestctx, response_handler, route
|
|
13
|
+
from invenio_records_resources.resources.records.resource import (
|
|
14
|
+
RecordResource,
|
|
15
|
+
request_extra_args,
|
|
16
|
+
request_search_args,
|
|
17
|
+
request_view_args,
|
|
18
|
+
)
|
|
19
|
+
from invenio_records_resources.resources.records.utils import search_preference
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
#
|
|
23
|
+
# Resource
|
|
24
|
+
#
|
|
25
|
+
class AuditLogResource(RecordResource):
|
|
26
|
+
"""Resource layer for audit-logs."""
|
|
27
|
+
|
|
28
|
+
def create_blueprint(self, **options):
|
|
29
|
+
"""Create the blueprint."""
|
|
30
|
+
options["url_prefix"] = ""
|
|
31
|
+
return super().create_blueprint(**options)
|
|
32
|
+
|
|
33
|
+
def create_url_rules(self):
|
|
34
|
+
"""Create the URL rules for the log resource."""
|
|
35
|
+
routes = self.config.routes
|
|
36
|
+
|
|
37
|
+
def p(route):
|
|
38
|
+
"""Prefix a route with the URL prefix."""
|
|
39
|
+
return f"{self.config.url_prefix}{route}"
|
|
40
|
+
|
|
41
|
+
return [
|
|
42
|
+
route("GET", p(routes["list"]), self.search),
|
|
43
|
+
route("GET", p(routes["item"]), self.read),
|
|
44
|
+
]
|
|
45
|
+
|
|
46
|
+
@request_extra_args
|
|
47
|
+
@request_search_args
|
|
48
|
+
@request_view_args
|
|
49
|
+
@response_handler(many=True)
|
|
50
|
+
def search(self):
|
|
51
|
+
"""Perform a search over the logs."""
|
|
52
|
+
hits = self.service.search(
|
|
53
|
+
identity=g.identity,
|
|
54
|
+
params=resource_requestctx.args,
|
|
55
|
+
search_preference=search_preference(),
|
|
56
|
+
)
|
|
57
|
+
return hits.to_dict(), 200
|
|
58
|
+
|
|
59
|
+
@request_extra_args
|
|
60
|
+
@request_view_args
|
|
61
|
+
@response_handler()
|
|
62
|
+
def read(self):
|
|
63
|
+
"""Read a specific log entry."""
|
|
64
|
+
item = self.service.read(
|
|
65
|
+
id_=resource_requestctx.view_args["id"],
|
|
66
|
+
identity=g.identity,
|
|
67
|
+
)
|
|
68
|
+
return item.to_dict(), 200
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
#
|
|
3
|
+
# Copyright (C) 2025 CERN.
|
|
4
|
+
#
|
|
5
|
+
# Invenio-Audit-Logs is free software; you can redistribute it and/or modify it
|
|
6
|
+
# under the terms of the MIT License; see LICENSE file for more details.
|
|
7
|
+
|
|
8
|
+
"""Audit Log Services."""
|
|
9
|
+
|
|
10
|
+
from .config import AuditLogServiceConfig
|
|
11
|
+
from .schema import AuditLogSchema
|
|
12
|
+
from .service import AuditLogService
|
|
13
|
+
|
|
14
|
+
__all__ = (
|
|
15
|
+
"AuditLogService",
|
|
16
|
+
"AuditLogSchema",
|
|
17
|
+
"AuditLogServiceConfig",
|
|
18
|
+
)
|