mirror of
https://github.com/tiennm99/DocsGPT.git
synced 2026-10-13 10:15:21 +00:00
feat(audit): split actor from subject on auth events
auth_events.user_id was overloaded and meant something different per call site: admin mutations filed the row under the target user and hid the acting admin in metadata->>'by', team events filed it under the actor, and quota events switched between the two depending on scope. The practical consequence was that "show me everything admin X did" had no answer. Adds actor_id (never NULL) and target_id (NULL when the event is not about a user) alongside the existing column, which keeps its meaning as the per-user feed key so nothing historical is rewritten. The backfill recovers the actor from metadata for rows that predate the columns. Also adds the indexes the cross-user admin feed needs. The only index was (user_id, created_at DESC), so the global feed -- which orders by created_at with no user predicate -- fell back to a sequential scan plus a sort on every page. The feed gains actor, multi-event, until and free-text search filters, plus a distinct-event catalogue so the UI can offer what the instance recorded instead of asking operators to type a name from memory.
This commit is contained in:
1 parent
f5b02ed374
commit
cb5343397f
11 files changed
+483
-15
No files matched your search
@@ -20,7 +20,10 @@ from sqlalchemy import Connection
|
||||
|
||||
from docsgpt.api.oidc.denylist import deny_user
|
||||
from docsgpt.core.settings import settings
|
||||
from docsgpt.storage.db.repositories.auth_events import AuthEventsRepository
|
||||
from docsgpt.storage.db.repositories.auth_events import (
|
||||
SYSTEM_ACTOR_SCIM,
|
||||
AuthEventsRepository,
|
||||
)
|
||||
from docsgpt.storage.db.repositories.users import UsersRepository
|
||||
from docsgpt.storage.db.session import db_readonly, db_session
|
||||
|
||||
@@ -201,7 +204,13 @@ def _audit(conn: Connection, user_id: str, event: str) -> None:
|
||||
"""Best-effort audit insert in a savepoint; failure never fails the request."""
|
||||
try:
|
||||
with conn.begin_nested():
|
||||
AuthEventsRepository(conn).insert(user_id, event, metadata={"via": "scim"})
|
||||
AuthEventsRepository(conn).insert(
|
||||
user_id,
|
||||
event,
|
||||
metadata={"via": "scim"},
|
||||
actor_id=SYSTEM_ACTOR_SCIM,
|
||||
target_id=user_id,
|
||||
)
|
||||
except Exception:
|
||||
logger.error("SCIM audit insert failed for user %s event %s", user_id, event, exc_info=True)
|
||||
|
||||
|
||||
Reference in new issue
Block a user