netra / backend /app /api /v1 /auth.py
093xpku
Clean project layout deployment
9bc686b
Raw
History Blame Contribute Delete
3.51 kB
from fastapi import APIRouter, Depends, HTTPException, status, Request
from fastapi.security import OAuth2PasswordRequestForm
from sqlalchemy.orm import Session
from datetime import timedelta
from jose import jwt, JWTError
from app.core.database import get_db
from app.core import security
from app.core.config import settings
from app.crud import crud
from app.schemas import schemas
from app.models import models
router = APIRouter()
@router.post("/login", response_model=schemas.Token)
def login(
request: Request,
form_data: OAuth2PasswordRequestForm = Depends(),
db: Session = Depends(get_db)
):
user = crud.get_user_by_email(db, email=form_data.username)
if not user or not crud.verify_password(form_data.password, user.hashed_password):
# Log failed login attempt
crud.create_audit_log(
db=db,
user_id=None,
action="Failed Login Attempt",
ip_address=request.client.host if request.client else None,
user_agent=request.headers.get("user-agent"),
details=f"Attempted email: {form_data.username}"
)
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail="Incorrect email or password",
)
if not user.is_active:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail="Inactive user account"
)
access_token_expires = timedelta(minutes=settings.ACCESS_TOKEN_EXPIRE_MINUTES)
access_token = security.create_access_token(
user.email, role=user.role.name, expires_delta=access_token_expires
)
refresh_token = security.create_refresh_token(
user.email, role=user.role.name
)
# Audit log login
crud.create_audit_log(
db=db,
user_id=user.id,
action="User Login",
ip_address=request.client.host if request.client else None,
user_agent=request.headers.get("user-agent"),
details=f"Successful login for user email {user.email}"
)
return {
"access_token": access_token,
"refresh_token": refresh_token,
"token_type": "bearer"
}
@router.post("/refresh", response_model=schemas.Token)
def refresh_token(
refresh_token: str,
db: Session = Depends(get_db)
):
credentials_exception = HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Could not validate refresh token",
)
try:
payload = jwt.decode(
refresh_token, settings.JWT_SECRET_KEY, algorithms=[settings.JWT_ALGORITHM]
)
email: str = payload.get("sub")
token_type: str = payload.get("type")
if email is None or token_type != "refresh":
raise credentials_exception
except JWTError:
raise credentials_exception
user = crud.get_user_by_email(db, email=email)
if user is None or not user.is_active:
raise credentials_exception
access_token = security.create_access_token(
user.email, role=user.role.name
)
new_refresh_token = security.create_refresh_token(
user.email, role=user.role.name
)
return {
"access_token": access_token,
"refresh_token": new_refresh_token,
"token_type": "bearer"
}
@router.get("/me", response_model=schemas.UserOut)
def read_users_me(
current_user: models.User = Depends(security.get_current_user)
):
return current_user