"""Authentication routes for SocialPhoto.""" import sqlite3 from typing import Annotated from fastapi import APIRouter, Depends, HTTPException, status from fastapi.security import HTTPAuthorizationCredentials, HTTPBearer from app.auth import create_access_token, hash_password, verify_password from app.db.database import get_db, row_to_dict from app.schemas import Token, UserLogin, UserRegister router = APIRouter(prefix="/auth", tags=["Authentication"]) security = HTTPBearer() @router.post("/register", response_model=Token, status_code=status.HTTP_201_CREATED) async def register( user_data: UserRegister, conn: sqlite3.Connection = Depends(get_db), ) -> Token: """Register a new user.""" cursor = conn.cursor() # Check if username exists cursor.execute("SELECT id FROM users WHERE username = ?", (user_data.username,)) if cursor.fetchone(): raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail="Username already registered", ) # Check if email exists cursor.execute("SELECT id FROM users WHERE email = ?", (user_data.email,)) if cursor.fetchone(): raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail="Email already registered", ) # Hash password and create user password_hash = hash_password(user_data.password) cursor.execute( "INSERT INTO users (username, email, password_hash) VALUES (?, ?, ?)", (user_data.username, user_data.email, password_hash), ) conn.commit() # Get the new user's ID cursor.execute("SELECT id FROM users WHERE username = ?", (user_data.username,)) user = row_to_dict(cursor.fetchone()) user_id = user["id"] # Create access token access_token = create_access_token(data={"sub": str(user_id)}) return Token(access_token=access_token) @router.post("/login", response_model=Token) async def login( user_data: UserLogin, conn: sqlite3.Connection = Depends(get_db), ) -> Token: """Login and get access token.""" cursor = conn.cursor() # Find user by username cursor.execute( "SELECT id, password_hash FROM users WHERE username = ?", (user_data.username,), ) row = cursor.fetchone() if not row or not verify_password(user_data.password, row["password_hash"]): raise HTTPException( status_code=status.HTTP_401_UNAUTHORIZED, detail="Incorrect username or password", ) user = row_to_dict(row) access_token = create_access_token(data={"sub": user["id"]}) return Token(access_token=access_token)