mirror of
https://github.com/complexcaresolutions/dak.c2s.git
synced 2026-03-17 20:43:41 +00:00
feat: add audit logging for login, logout, imports, and report generation
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
4a3648a018
commit
9650889d24
3 changed files with 59 additions and 3 deletions
|
|
@ -1,10 +1,11 @@
|
|||
"""Auth API router: login, register, refresh, logout, MFA, password change."""
|
||||
|
||||
from fastapi import APIRouter, Depends
|
||||
from fastapi import APIRouter, Depends, Request
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from app.core.dependencies import get_current_user
|
||||
from app.database import get_db
|
||||
from app.services.audit_service import log_action
|
||||
from app.models.user import User
|
||||
from app.schemas.auth import (
|
||||
ChangePasswordRequest,
|
||||
|
|
@ -36,10 +37,19 @@ router = APIRouter()
|
|||
|
||||
|
||||
@router.post("/login", response_model=TokenResponse)
|
||||
def login(data: LoginRequest, db: Session = Depends(get_db)):
|
||||
def login(data: LoginRequest, request: Request, db: Session = Depends(get_db)):
|
||||
"""Authenticate with email/password (+ optional MFA) and receive tokens."""
|
||||
user = authenticate_user(db, data.email, data.password, data.mfa_code)
|
||||
access, refresh = create_tokens(db, user)
|
||||
log_action(
|
||||
db,
|
||||
user_id=user.id,
|
||||
action="login",
|
||||
entity_type="user",
|
||||
entity_id=user.id,
|
||||
ip_address=request.client.host if request.client else None,
|
||||
user_agent=request.headers.get("user-agent"),
|
||||
)
|
||||
return TokenResponse(
|
||||
access_token=access,
|
||||
refresh_token=refresh,
|
||||
|
|
@ -79,11 +89,21 @@ def refresh(data: RefreshRequest, db: Session = Depends(get_db)):
|
|||
@router.post("/logout")
|
||||
def logout(
|
||||
data: RefreshRequest,
|
||||
request: Request,
|
||||
db: Session = Depends(get_db),
|
||||
current_user: User = Depends(get_current_user),
|
||||
):
|
||||
"""Revoke the supplied refresh token (logout)."""
|
||||
revoke_refresh_token(db, data.refresh_token)
|
||||
log_action(
|
||||
db,
|
||||
user_id=current_user.id,
|
||||
action="logout",
|
||||
entity_type="user",
|
||||
entity_id=current_user.id,
|
||||
ip_address=request.client.host if request.client else None,
|
||||
user_agent=request.headers.get("user-agent"),
|
||||
)
|
||||
return {"detail": "Logged out"}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ from app.database import get_db
|
|||
from app.models.audit import ImportLog
|
||||
from app.models.user import User
|
||||
from app.schemas.import_schemas import ImportPreview, ImportResult
|
||||
from app.services.audit_service import log_action
|
||||
from app.services.csv_parser import parse_csv
|
||||
from app.services.icd_service import import_icd_from_xlsx
|
||||
from app.services.import_service import confirm_import, preview_import
|
||||
|
|
@ -140,7 +141,20 @@ async def confirm_csv_import(
|
|||
detail=f"CSV parsing failed: {exc}",
|
||||
)
|
||||
|
||||
return confirm_import(db, parsed, file.filename, user.id)
|
||||
result = confirm_import(db, parsed, file.filename, user.id)
|
||||
log_action(
|
||||
db,
|
||||
user_id=user.id,
|
||||
action="csv_imported",
|
||||
entity_type="import",
|
||||
new_values={
|
||||
"filename": file.filename,
|
||||
"imported": result.imported,
|
||||
"skipped": result.skipped,
|
||||
"updated": result.updated,
|
||||
},
|
||||
)
|
||||
return result
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
|
|
@ -194,6 +208,18 @@ async def upload_icd_xlsx(
|
|||
db.add(log)
|
||||
db.commit()
|
||||
|
||||
log_action(
|
||||
db,
|
||||
user_id=user.id,
|
||||
action="icd_xlsx_imported",
|
||||
entity_type="import",
|
||||
new_values={
|
||||
"filename": file.filename,
|
||||
"updated": result["updated"],
|
||||
"errors": len(result["errors"]),
|
||||
},
|
||||
)
|
||||
|
||||
return ICDImportResponse(**result)
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ from app.schemas.report import (
|
|||
ReportListResponse,
|
||||
ReportMeta,
|
||||
)
|
||||
from app.services.audit_service import log_action
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
|
@ -144,6 +145,15 @@ def generate_report(
|
|||
db.commit()
|
||||
db.refresh(report)
|
||||
|
||||
log_action(
|
||||
db,
|
||||
user_id=user.id,
|
||||
action="report_generated",
|
||||
entity_type="report",
|
||||
entity_id=report.id,
|
||||
new_values={"jahr": jahr, "kw": kw, "filename": filename},
|
||||
)
|
||||
|
||||
return ReportMeta.model_validate(report)
|
||||
except ImportError as exc:
|
||||
raise HTTPException(501, f"Required service not yet available: {exc}")
|
||||
|
|
|
|||
Loading…
Reference in a new issue