This commit is contained in:
Iliyan Angelov
2025-12-09 17:07:38 +02:00
parent e43a95eafb
commit 9de9d9701e
14 changed files with 270 additions and 91 deletions

View File

@@ -21,7 +21,7 @@ router = APIRouter(prefix='/accountant/security', tags=['accountant-security'])
async def verify_step_up(
request: Request,
step_up_data: dict,
current_user: User = Depends(authorize_roles('admin', 'accountant')),
current_user: User = Depends(authorize_roles('accountant')),
db: Session = Depends(get_db)
):
"""Verify step-up authentication (MFA token or password re-entry)."""
@@ -36,7 +36,9 @@ async def verify_step_up(
# Try to get from header or cookie
session_token = request.headers.get('X-Session-Token') or request.cookies.get('session_token')
# If still no session token, try to find the most recent active session for this user
# If still no session token, try to find the most recent active session for this user.
# If none exists (e.g., password-only admin without MFA), create a fresh session so
# password-based step-up can proceed without forcing a full re-login.
if not session_token:
active_session = db.query(AccountantSession).filter(
AccountantSession.user_id == current_user.id,
@@ -47,7 +49,13 @@ async def verify_step_up(
if active_session:
session_token = active_session.session_token
else:
raise HTTPException(status_code=400, detail='No active session found. Please log in again.')
new_session = accountant_security_service.create_session(
db=db,
user_id=current_user.id,
ip_address=request.client.host if request.client else None,
user_agent=request.headers.get('User-Agent')
)
session_token = new_session.session_token
# Verify MFA if token provided
if mfa_token:
@@ -107,7 +115,7 @@ async def verify_step_up(
@router.get('/sessions')
async def get_active_sessions(
current_user: User = Depends(authorize_roles('admin', 'accountant')),
current_user: User = Depends(authorize_roles('accountant')),
db: Session = Depends(get_db)
):
"""Get active sessions for current user."""
@@ -143,7 +151,7 @@ async def get_active_sessions(
@router.post('/sessions/{session_id}/revoke')
async def revoke_session(
session_id: int,
current_user: User = Depends(authorize_roles('admin', 'accountant')),
current_user: User = Depends(authorize_roles('accountant')),
db: Session = Depends(get_db)
):
"""Revoke a specific session."""
@@ -172,7 +180,7 @@ async def revoke_session(
@router.post('/sessions/revoke-all')
async def revoke_all_sessions(
current_user: User = Depends(authorize_roles('admin', 'accountant')),
current_user: User = Depends(authorize_roles('accountant')),
db: Session = Depends(get_db)
):
"""Revoke all active sessions for current user."""
@@ -196,7 +204,7 @@ async def get_activity_logs(
limit: int = Query(50, ge=1, le=100),
risk_level: Optional[str] = Query(None),
is_unusual: Optional[bool] = Query(None),
current_user: User = Depends(authorize_roles('admin', 'accountant')),
current_user: User = Depends(authorize_roles('accountant')),
db: Session = Depends(get_db)
):
"""Get activity logs for current user or all users (admin only)."""