"""Auth router.""" from datetime import timedelta from typing import List from fastapi import APIRouter, Depends, HTTPException from fastapi.security import OAuth2PasswordRequestForm from pydantic import BaseModel from sqlalchemy.orm import Session from app.core.config import get_db, settings from app.models import models from app.models.role_permission import Permission, Role, RolePermission from app.schemas import schemas from app.api.deps import Token, verify_password, create_access_token, get_current_user router = APIRouter(prefix="/auth", tags=["Auth"]) @router.post("/token", response_model=Token) async def login(form_data: OAuth2PasswordRequestForm = Depends(), db: Session = Depends(get_db)): user = db.query(models.User).filter(models.User.username == form_data.username).first() if not user or not verify_password(form_data.password, user.hashed_password or ""): raise HTTPException(status_code=401, detail="Incorrect username or password", headers={"WWW-Authenticate": "Bearer"}) if not user.is_active: raise HTTPException(status_code=400, detail="Inactive user") access_token = create_access_token( data={"sub": str(user.id)}, expires_delta=timedelta(minutes=settings.ACCESS_TOKEN_EXPIRE_MINUTES) ) return {"access_token": access_token, "token_type": "bearer"} @router.get("/me", response_model=schemas.UserResponse) async def get_me(current_user: models.User = Depends(get_current_user)): return current_user class PermissionIntrospectionResponse(BaseModel): username: str role_name: str | None is_admin: bool permissions: List[str] @router.get("/me/permissions", response_model=PermissionIntrospectionResponse) async def get_my_permissions( current_user: models.User = Depends(get_current_user), db: Session = Depends(get_db), ): """Return the current user's effective permissions for CLI help introspection.""" perms: List[str] = [] role_name: str | None = None if current_user.is_admin: # Admin gets all permissions all_perms = db.query(Permission).order_by(Permission.name).all() perms = [p.name for p in all_perms] role_name = "admin" elif current_user.role_id: role = db.query(Role).filter(Role.id == current_user.role_id).first() if role: role_name = role.name perm_ids = db.query(RolePermission.permission_id).filter( RolePermission.role_id == role.id ).all() if perm_ids: pid_list = [p[0] for p in perm_ids] matched = db.query(Permission).filter(Permission.id.in_(pid_list)).order_by(Permission.name).all() perms = [p.name for p in matched] return PermissionIntrospectionResponse( username=current_user.username, role_name=role_name, is_admin=current_user.is_admin, permissions=perms, )