|
| 1 | +from pydantic import BaseModel |
1 | 2 | from sqlalchemy.orm import Session |
2 | | -from fastapi import APIRouter, Depends |
| 3 | +from fastapi import APIRouter, Depends, HTTPException, status |
| 4 | + |
3 | 5 | from src.auth.utils.bcrypt_helper import generate_access_token |
4 | 6 | from src.auth.services.auth_service import ( |
5 | 7 | AuthService, |
6 | 8 | LoginInput, |
7 | 9 | RegisterInput, |
8 | 10 | VerifyInput |
9 | 11 | ) |
10 | | - |
| 12 | +from src.util.execptions import * |
11 | 13 | from src.db.sql_alchemy import Database |
12 | | -from src.util.response import global_response |
| 14 | +from src.util.response import global_response, GlobalResponse, ExceptionResponse |
13 | 15 |
|
14 | 16 | router = APIRouter(prefix="/auth") |
15 | 17 | database = Database() |
16 | 18 |
|
17 | 19 | auth = AuthService() |
18 | 20 |
|
| 21 | +# Create a module-level dependency |
| 22 | +get_db_dependency = Depends(database.get_db) |
| 23 | + |
| 24 | + |
| 25 | +class AuthOutput(BaseModel): |
| 26 | + access_token: str |
| 27 | + |
19 | 28 |
|
20 | 29 | @router.post( |
21 | 30 | "/register", |
| 31 | + response_model=GlobalResponse[AuthOutput, dict], |
22 | 32 | summary="User Registration", |
23 | 33 | description="Register a new user with email and password.", |
24 | | - deprecated=True |
| 34 | + deprecated=True, |
| 35 | + responses={ |
| 36 | + 409: { |
| 37 | + "model": ExceptionResponse, |
| 38 | + "description": "User or Email already exists" |
| 39 | + }, |
| 40 | + 400: { |
| 41 | + "model": ExceptionResponse, |
| 42 | + "description": "Bad request" |
| 43 | + }, |
| 44 | + } |
25 | 45 | ) |
26 | | -def register(input: RegisterInput, db: Session = Depends(database.get_db)): |
| 46 | +def register(input: RegisterInput, db: Session = get_db_dependency): |
27 | 47 | """ |
28 | 48 | Register a new user. |
29 | 49 |
|
30 | 50 | - **email**: User's email address |
31 | 51 | - **password**: User's password |
32 | 52 | """ |
33 | | - user = auth.register(input, db) |
34 | | - |
35 | | - payload = {"id": str(user.id)} |
36 | | - token = generate_access_token(data=payload) |
37 | | - return global_response( |
38 | | - { |
39 | | - "access_token": token, |
40 | | - } |
41 | | - ) |
| 53 | + try: |
| 54 | + user = auth.register(input, db) |
| 55 | + |
| 56 | + payload = {"id": str(user.id)} |
| 57 | + token = generate_access_token(data=payload) |
| 58 | + return global_response( |
| 59 | + { |
| 60 | + "access_token": token, |
| 61 | + } |
| 62 | + ) |
| 63 | + except AlreadyExistsError as e: |
| 64 | + raise HTTPException( |
| 65 | + status_code=status.HTTP_409_CONFLICT, detail=str(e)) |
| 66 | + except Exception as e: |
| 67 | + raise HTTPException( |
| 68 | + status_code=status.HTTP_400_BAD_REQUEST, detail=str(e)) |
42 | 69 |
|
43 | 70 |
|
44 | 71 | @router.post( |
45 | 72 | "/login", |
| 73 | + response_model=GlobalResponse[AuthOutput, dict], |
46 | 74 | summary="User Login", |
47 | 75 | description="Authenticate a user with email and password.", |
48 | 76 | deprecated=True, |
| 77 | + responses={ |
| 78 | + 404: { |
| 79 | + "model": ExceptionResponse, |
| 80 | + "description": "User not found" |
| 81 | + }, |
| 82 | + 401: { |
| 83 | + "model": ExceptionResponse, |
| 84 | + "description": "Incorrect password" |
| 85 | + }, |
| 86 | + 400: { |
| 87 | + "model": ExceptionResponse, |
| 88 | + "description": "Bad request" |
| 89 | + }, |
| 90 | + } |
49 | 91 | ) |
50 | | -def login(input: LoginInput, db: Session = Depends(database.get_db)): |
| 92 | +def login(input: LoginInput, db: Session = get_db_dependency): |
51 | 93 | """ |
52 | 94 | Login a user and return an access token. |
53 | 95 |
|
54 | 96 | - **email**: User's email address |
55 | 97 | - **password**: User's password |
56 | 98 | """ |
57 | | - user = auth.authenticate_user(input.email.lower(), input.password, db) |
58 | | - |
59 | | - payload = {"id": str(user.id)} |
60 | | - token = generate_access_token(data=payload) |
61 | | - return global_response( |
62 | | - { |
63 | | - "access_token": token, |
64 | | - } |
65 | | - ) |
| 99 | + try: |
| 100 | + user = auth.authenticate_user(input.email.lower(), input.password, db) |
| 101 | + |
| 102 | + payload = {"id": str(user.id)} |
| 103 | + token = generate_access_token(data=payload) |
| 104 | + return global_response( |
| 105 | + { |
| 106 | + "access_token": token, |
| 107 | + } |
| 108 | + ) |
| 109 | + except NotFoundError as e: |
| 110 | + raise HTTPException( |
| 111 | + status_code=status.HTTP_404_NOT_FOUND, detail=str(e)) |
| 112 | + except InvalidPasswordError: |
| 113 | + raise HTTPException( |
| 114 | + status_code=status.HTTP_401_UNAUTHORIZED, detail="Incorrect password") |
| 115 | + except Exception as e: |
| 116 | + raise HTTPException( |
| 117 | + status_code=status.HTTP_400_BAD_REQUEST, detail=str(e)) |
66 | 118 |
|
67 | 119 |
|
68 | 120 | @router.post( |
69 | 121 | "/verify", |
| 122 | + response_model=GlobalResponse[AuthOutput, dict], |
70 | 123 | summary="Verify a Signature", |
71 | 124 | description="Verify a signature according to SIWE spec", |
| 125 | + responses={ |
| 126 | + 400: { |
| 127 | + "model": ExceptionResponse, |
| 128 | + "description": "Bad request including invalid message or signature" |
| 129 | + }, |
| 130 | + } |
72 | 131 | ) |
73 | | -def verify(input: VerifyInput, db: Session = Depends(database.get_db)): |
| 132 | +def verify(input: VerifyInput, db: Session = get_db_dependency): |
74 | 133 | """ |
75 | 134 | Verify a signature according to SIWE spec and return an access token |
76 | 135 |
|
77 | 136 | - **message**: A SIWE message |
78 | 137 | - **signature**: User's signature for the message |
79 | 138 | """ |
80 | | - |
81 | | - user = auth.verify_signature( |
82 | | - input.message, input.signature, db) |
83 | | - |
84 | | - payload = {"id": str(user.id)} |
85 | | - token = generate_access_token(data=payload) |
86 | | - return global_response( |
87 | | - { |
88 | | - "access_token": token, |
89 | | - } |
90 | | - ) |
| 139 | + try: |
| 140 | + user = auth.verify_signature( |
| 141 | + input.message, input.signature, db) |
| 142 | + |
| 143 | + payload = {"id": str(user.id)} |
| 144 | + token = generate_access_token(data=payload) |
| 145 | + return global_response( |
| 146 | + { |
| 147 | + "access_token": token, |
| 148 | + } |
| 149 | + ) |
| 150 | + except InvalidMessageError as e: |
| 151 | + raise HTTPException( |
| 152 | + status_code=status.HTTP_400_BAD_REQUEST, detail=str(e)) |
| 153 | + except InvalidSignatureError as e: |
| 154 | + raise HTTPException( |
| 155 | + status_code=status.HTTP_400_BAD_REQUEST, detail=str(e)) |
| 156 | + except Exception as e: |
| 157 | + raise HTTPException( |
| 158 | + status_code=status.HTTP_400_BAD_REQUEST, detail=str(e)) |
0 commit comments