This commit is contained in:
Iliyan Angelov
2025-12-01 01:08:39 +02:00
parent 0fa2adeb19
commit 1a103a769f
234 changed files with 5513 additions and 283 deletions

View File

@@ -0,0 +1,92 @@
"""
User session management routes.
"""
from fastapi import APIRouter, Depends, HTTPException
from sqlalchemy.orm import Session
from ...shared.config.database import get_db
from ...shared.config.logging_config import get_logger
from ...security.middleware.auth import get_current_user
from ...auth.models.user import User
from ...auth.services.session_service import session_service
from ...shared.utils.response_helpers import success_response
logger = get_logger(__name__)
router = APIRouter(prefix='/sessions', tags=['sessions'])
@router.get('/')
async def get_my_sessions(
current_user: User = Depends(get_current_user),
db: Session = Depends(get_db)
):
"""Get current user's active sessions."""
try:
sessions = session_service.get_user_sessions(
db=db,
user_id=current_user.id,
active_only=True
)
return success_response(data={
'sessions': [{
'id': s.id,
'ip_address': s.ip_address,
'user_agent': s.user_agent,
'device_info': s.device_info,
'last_activity': s.last_activity.isoformat() if s.last_activity else None,
'created_at': s.created_at.isoformat() if s.created_at else None,
'expires_at': s.expires_at.isoformat() if s.expires_at else None
} for s in sessions]
})
except Exception as e:
logger.error(f'Error getting sessions: {str(e)}', exc_info=True)
raise HTTPException(status_code=500, detail=str(e))
@router.delete('/{session_id}')
async def revoke_session(
session_id: int,
current_user: User = Depends(get_current_user),
db: Session = Depends(get_db)
):
"""Revoke a specific session."""
try:
# Verify session belongs to user
from ...auth.models.user_session import UserSession
session = db.query(UserSession).filter(
UserSession.id == session_id,
UserSession.user_id == current_user.id
).first()
if not session:
raise HTTPException(status_code=404, detail='Session not found')
success = session_service.revoke_session(db=db, session_token=session.session_token)
if not success:
raise HTTPException(status_code=404, detail='Session not found')
return success_response(message='Session revoked successfully')
except HTTPException:
raise
except Exception as e:
logger.error(f'Error revoking session: {str(e)}', exc_info=True)
raise HTTPException(status_code=500, detail=str(e))
@router.post('/revoke-all')
async def revoke_all_sessions(
current_user: User = Depends(get_current_user),
db: Session = Depends(get_db)
):
"""Revoke all sessions for current user."""
try:
count = session_service.revoke_all_user_sessions(
db=db,
user_id=current_user.id
)
return success_response(
data={'revoked_count': count},
message=f'Revoked {count} session(s)'
)
except Exception as e:
logger.error(f'Error revoking all sessions: {str(e)}', exc_info=True)
raise HTTPException(status_code=500, detail=str(e))