feat(13-06): emit metadata-only audit rows on authoritative upload success
- Write cloud.file_uploaded audit row in same transaction as reconciliation - Audit payload is metadata-only: filename, size_bytes, connection_id, provider_item_id, parent_ref - No provider URLs, tokens, bytes, or document text in audit metadata (T-13-02) - Non-success paths (conflict, offline, reauth_required) bypass audit write (T-13-21) - Import get_client_ip from deps.utils and write_audit_log from services.audit
This commit is contained in:
@@ -45,6 +45,8 @@ from config import settings
|
|||||||
from db.models import User
|
from db.models import User
|
||||||
from deps.auth import get_regular_user
|
from deps.auth import get_regular_user
|
||||||
from deps.db import get_db
|
from deps.db import get_db
|
||||||
|
from deps.utils import get_client_ip
|
||||||
|
from services.audit import write_audit_log
|
||||||
from services.cloud_items import ConnectionNotFound
|
from services.cloud_items import ConnectionNotFound
|
||||||
from services.rate_limiting import account_limiter
|
from services.rate_limiting import account_limiter
|
||||||
from storage.cloud_base import (
|
from storage.cloud_base import (
|
||||||
@@ -683,6 +685,28 @@ async def upload_cloud_file(
|
|||||||
error_message="Folder contents changed by upload — re-listing required.",
|
error_message="Folder contents changed by upload — re-listing required.",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Write metadata-only audit row in the same transaction (Plan 06, Task 2: T-13-20).
|
||||||
|
# Only authoritative upload success reaches this path. Non-success outcomes
|
||||||
|
# (conflict, offline, reauth_required) are handled in separate branches below
|
||||||
|
# and never call write_audit_log — preserving T-13-21 (no false success events).
|
||||||
|
# The audit payload is metadata-only: no provider URLs, tokens, bytes, or
|
||||||
|
# document text are included (T-13-02).
|
||||||
|
await write_audit_log(
|
||||||
|
session,
|
||||||
|
event_type="cloud.file_uploaded",
|
||||||
|
user_id=current_user.id,
|
||||||
|
actor_id=current_user.id,
|
||||||
|
resource_id=None,
|
||||||
|
ip_address=get_client_ip(request),
|
||||||
|
metadata_={
|
||||||
|
"connection_id": str(connection_id),
|
||||||
|
"provider_item_id": provider_item_id,
|
||||||
|
"filename": resolved_name,
|
||||||
|
"size_bytes": resolved_size,
|
||||||
|
"parent_ref": resolved_parent_ref,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
await session.commit()
|
await session.commit()
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|||||||
Reference in New Issue
Block a user