Spaces:
Running
Running
Commit all 3 files seperately
Browse files- auth/responses.py +7 -0
- auth/route.py +20 -0
- auth/services.py +68 -0
auth/responses.py
ADDED
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from pydantic import BaseModel
|
2 |
+
|
3 |
+
class TokenResponse(BaseModel):
|
4 |
+
access_token: str
|
5 |
+
refresh_token: str
|
6 |
+
token_type: str = "Bearer"
|
7 |
+
expires_in: int
|
auth/route.py
ADDED
@@ -0,0 +1,20 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from fastapi import APIRouter, status, Depends, Header
|
2 |
+
from fastapi.security import OAuth2PasswordRequestForm
|
3 |
+
from sqlalchemy.orm import Session
|
4 |
+
from core.database import get_db
|
5 |
+
from auth.services import get_refresh_token, get_token
|
6 |
+
|
7 |
+
router = APIRouter(
|
8 |
+
prefix="/auth",
|
9 |
+
tags=["Authentication"],
|
10 |
+
responses={404: {"description": "Not found"}},
|
11 |
+
)
|
12 |
+
|
13 |
+
@router.get("/token", status_code=status.HTTP_200_OK)
|
14 |
+
async def authenticate_user(data: OAuth2PasswordRequestForm = Depends(), db: Session = Depends(get_db)):
|
15 |
+
return await get_token(data, db)
|
16 |
+
|
17 |
+
|
18 |
+
@router.post("/refresh", status_code=status.HTTP_200_OK)
|
19 |
+
async def refresh_token(refresh_token: str , db: Session = Depends(get_db)):
|
20 |
+
return await get_refresh_token(token=refresh_token, db=db)
|
auth/services.py
ADDED
@@ -0,0 +1,68 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from fastapi import HTTPException, Depends
|
2 |
+
from users.models import User
|
3 |
+
from core.security import verify_password
|
4 |
+
from core.security import create_access_token, create_refresh_token, get_token_payload
|
5 |
+
from core.config import get_settings
|
6 |
+
from auth.responses import TokenResponse
|
7 |
+
from datetime import timedelta
|
8 |
+
from sqlalchemy.orm import Session
|
9 |
+
from core.database import get_db
|
10 |
+
|
11 |
+
|
12 |
+
settings = get_settings()
|
13 |
+
|
14 |
+
async def get_token(data, db:Session):
|
15 |
+
user = db.query(User).filter(User.email == data.username).first()
|
16 |
+
if not user:
|
17 |
+
raise HTTPException(status_code=401,
|
18 |
+
detail="Invalid Login Credentials",
|
19 |
+
headers={"WWW-Authenticate": "Bearer"})
|
20 |
+
|
21 |
+
if not verify_password(data.password, user.password):
|
22 |
+
raise HTTPException(status_code=401,
|
23 |
+
detail="Invalid Login Credentials",
|
24 |
+
headers={"WWW-Authenticate": "Bearer"})
|
25 |
+
|
26 |
+
_verify_user_access(user=user)
|
27 |
+
|
28 |
+
return _get_user_token(user=user)
|
29 |
+
|
30 |
+
|
31 |
+
async def get_refresh_token(token: str, db):
|
32 |
+
paylod = get_token_payload(token)
|
33 |
+
user_id = paylod.get("id")
|
34 |
+
if not user_id:
|
35 |
+
raise HTTPException(status_code=400,
|
36 |
+
detail="Invalid Token",
|
37 |
+
headers={"WWW-Authenticate": "Bearer"}
|
38 |
+
)
|
39 |
+
user = db.query(User).filter(User.id == user_id).first()
|
40 |
+
if not user:
|
41 |
+
raise HTTPException(status_code=400,
|
42 |
+
detail="Invalid Token",
|
43 |
+
headers={"WWW-Authenticate": "Bearer"}
|
44 |
+
)
|
45 |
+
|
46 |
+
def _verify_user_access(user: User):
|
47 |
+
if not user.is_active:
|
48 |
+
raise HTTPException(status_code=400,
|
49 |
+
detail="User is inactive",
|
50 |
+
headers={"WWW-Authenticate": "Bearer"}
|
51 |
+
)
|
52 |
+
return True
|
53 |
+
|
54 |
+
async def _get_user_token(user:User, refresh_token: bool = False):
|
55 |
+
payload = {"id": user.id, "sub": user.email}
|
56 |
+
|
57 |
+
access_token_expiry = timedelta(minutes=settings.ACCESS_TOKEN_EXPIRE_MINUTES)
|
58 |
+
|
59 |
+
access_token = await create_access_token(data=payload, expiry=access_token_expiry)
|
60 |
+
if not refresh_token:
|
61 |
+
refresh_token = await create_refresh_token(data=payload)
|
62 |
+
|
63 |
+
return TokenResponse(
|
64 |
+
access_token=access_token,
|
65 |
+
refresh_token=refresh_token,
|
66 |
+
expires_in= access_token_expiry.seconds
|
67 |
+
)
|
68 |
+
|