Skip to content

Commit 1693f4e

Browse files
authored
Update auth.py
1 parent a62a661 commit 1693f4e

1 file changed

Lines changed: 29 additions & 70 deletions

File tree

‎app/routes/auth.py‎

Lines changed: 29 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,24 @@
1-
"""Auth routes: register, login, refresh, me."""
1+
"""Auth routes: register, login, refresh, me.
2+
3+
HTTP wiring only -- credentials, tokens and account state are decided
4+
in ``controllers.accounts``.
5+
"""
26

37
from __future__ import annotations
48

5-
import jwt as pyjwt
6-
from fastapi import APIRouter, Depends, HTTPException, Query, status
9+
from fastapi import APIRouter, Depends, Query, status
710
from fastapi.security import HTTPAuthorizationCredentials, HTTPBearer
8-
from sqlalchemy import select
911
from sqlalchemy.orm import Session
1012

11-
from ..infra.security import (
12-
create_access_token,
13-
create_refresh_token,
14-
decode_token,
15-
hash_password,
16-
verify_password,
17-
)
18-
from ..models import User, new_id
19-
from ..models.db import commit_now, get_db
13+
from ..controllers import accounts
14+
from ..models import User
15+
from ..models.db import get_db
2016
from ..validation.schemas import RefreshIn, RegisterIn, TokenPair, UserOut
2117

2218
router = APIRouter(prefix="/auth", tags=["auth"])
2319
_bearer = HTTPBearer(auto_error=False)
2420

2521

26-
def _user_for_token(db: Session, token: str | None) -> User:
27-
"""Shared bearer-token validation for header and query-param auth."""
28-
if not token:
29-
raise HTTPException(status.HTTP_401_UNAUTHORIZED, "missing bearer token")
30-
try:
31-
payload = decode_token(token, expected_type="access")
32-
except pyjwt.PyJWTError as exc:
33-
raise HTTPException(status.HTTP_401_UNAUTHORIZED, f"invalid token: {exc}") from exc
34-
user = db.get(User, payload["sub"])
35-
if user is None or not user.is_active:
36-
raise HTTPException(status.HTTP_401_UNAUTHORIZED, "unknown or inactive user")
37-
return user
38-
39-
4022
def authenticate_user(
4123
db: Session = Depends(get_db),
4224
credentials: HTTPAuthorizationCredentials | None = Depends(_bearer),
@@ -49,69 +31,46 @@ def authenticate_user(
4931
``access_token`` query parameter.
5032
"""
5133
header_token = credentials.credentials if credentials is not None else None
52-
return _user_for_token(db, header_token or access_token)
34+
return accounts.user_for_access_token(db, header_token or access_token)
35+
36+
37+
def require_admin(user: User = Depends(authenticate_user)) -> User:
38+
return accounts.require_admin(user)
5339

5440

5541
def _token_pair(user: User) -> TokenPair:
56-
return TokenPair(
57-
access_token=create_access_token(user.id),
58-
refresh_token=create_refresh_token(user.id),
42+
access, refresh_token = accounts.token_pair(user)
43+
return TokenPair(access_token=access, refresh_token=refresh_token)
44+
45+
46+
def _user_out(user: User) -> UserOut:
47+
return UserOut(
48+
id=user.id,
49+
email=user.email,
50+
is_active=user.is_active,
51+
is_admin=user.is_admin,
52+
created_at=user.created_at,
5953
)
6054

6155

6256
@router.post("/register", response_model=TokenPair, status_code=status.HTTP_201_CREATED)
6357
def register(body: RegisterIn, db: Session = Depends(get_db)) -> TokenPair:
64-
exists = db.scalar(select(User).where(User.email == body.email))
65-
if exists is not None:
66-
raise HTTPException(status.HTTP_409_CONFLICT, "email already registered")
67-
user = User(
68-
id=new_id("usr"),
69-
email=body.email,
70-
password_hash=hash_password(body.password),
71-
)
72-
db.add(user)
73-
db.flush()
74-
commit_now(db)
75-
return _token_pair(user)
58+
return _token_pair(accounts.register(db, body.email, body.password))
7659

7760

7861
@router.post("/login", response_model=TokenPair)
7962
def login(body: RegisterIn, db: Session = Depends(get_db)) -> TokenPair:
80-
user = db.scalar(select(User).where(User.email == body.email))
81-
if user is None or not verify_password(body.password, user.password_hash):
82-
raise HTTPException(status.HTTP_401_UNAUTHORIZED, "invalid email or password")
83-
if not user.is_active:
84-
raise HTTPException(status.HTTP_403_FORBIDDEN, "account disabled")
85-
return _token_pair(user)
63+
return _token_pair(accounts.login(db, body.email, body.password))
8664

8765

8866
@router.post("/refresh", response_model=TokenPair)
8967
def refresh(body: RefreshIn, db: Session = Depends(get_db)) -> TokenPair:
90-
try:
91-
payload = decode_token(body.refresh_token, expected_type="refresh")
92-
except pyjwt.PyJWTError as exc:
93-
raise HTTPException(status.HTTP_401_UNAUTHORIZED, f"invalid token: {exc}") from exc
94-
user = db.get(User, payload["sub"])
95-
if user is None or not user.is_active:
96-
raise HTTPException(status.HTTP_401_UNAUTHORIZED, "unknown or inactive user")
97-
return _token_pair(user)
68+
return _token_pair(accounts.user_for_refresh_token(db, body.refresh_token))
9869

9970

10071
@router.get("/me", response_model=UserOut)
10172
def me(user: User = Depends(authenticate_user)) -> UserOut:
102-
return UserOut(
103-
id=user.id,
104-
email=user.email,
105-
is_active=user.is_active,
106-
is_admin=user.is_admin,
107-
created_at=user.created_at,
108-
)
109-
110-
111-
def require_admin(user: User = Depends(authenticate_user)) -> User:
112-
if not user.is_admin:
113-
raise HTTPException(status.HTTP_403_FORBIDDEN, "admin required")
114-
return user
73+
return _user_out(user)
11574

11675

11776
@router.get("/admin-check")

0 commit comments

Comments
 (0)