- app/api/deps.py: shared auth dependencies - app/api/routers/auth.py: login, me - app/api/routers/issues.py: CRUD, transition, assign, relations, tags, batch, search - app/api/routers/projects.py: CRUD, members, worklog summary - app/api/routers/users.py: CRUD, worklogs - app/api/routers/comments.py: CRUD - app/api/routers/webhooks.py: CRUD, logs, retry - app/api/routers/misc.py: API keys, activity, milestones, notifications, worklogs, export, dashboard - main.py: 1165 lines → 51 lines - Version bump to 0.2.0
33 lines
1.4 KiB
Python
33 lines
1.4 KiB
Python
"""Auth router."""
|
|
from datetime import timedelta
|
|
from fastapi import APIRouter, Depends, HTTPException
|
|
from fastapi.security import OAuth2PasswordRequestForm
|
|
from sqlalchemy.orm import Session
|
|
|
|
from app.core.config import get_db, settings
|
|
from app.models import models
|
|
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
|