-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
7 changed files
with
96 additions
and
17 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,8 +1,10 @@ | ||
from fastapi import APIRouter | ||
from .handlers import user | ||
from .handlers import user, todo | ||
from ..auth.jwt import auth_router | ||
|
||
router = APIRouter() | ||
|
||
router.include_router(user.user_router, prefix='/users', tags=['users']) | ||
router.include_router(auth_router, prefix='/auth', tags=['auth']) | ||
router.include_router(todo.todo_router, prefix='/todo', tags=['todo']) | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,20 +1,59 @@ | ||
from fastapi import APIRouter, Depends, HTTPException, status | ||
from datetime import datetime | ||
|
||
from fastapi import APIRouter, Depends, HTTPException, status, Body | ||
from fastapi.security import OAuth2PasswordRequestForm | ||
from typing import Any | ||
|
||
from jose import jwt | ||
from pydantic import ValidationError | ||
|
||
from ..deps.user_deps import get_current_user | ||
from ...core.config import settings | ||
from ...models.user_model import User | ||
from ...services.user_services import UserService | ||
from ...core.security import create_refresh_token, create_access_token | ||
from ...schemas.auth_schema import TokenSchema, TokenPayload | ||
from ...schemas.user_schema import UserOut | ||
|
||
auth_router = APIRouter() | ||
|
||
|
||
@auth_router.post('/login') | ||
@auth_router.post('/login', summary="Create access and refresh token", response_model=TokenSchema) | ||
async def login(form_data: OAuth2PasswordRequestForm = Depends()) -> Any: | ||
user = await UserService.authenticate(email=form_data.username, password=form_data.password) | ||
if not user: | ||
raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail="incorrect email or password") | ||
|
||
# create a access and refresh token | ||
return { | ||
"access_token" : create_access_token(user.user_id), | ||
"refresh_token" : create_refresh_token(user.user_id) | ||
"access_token": create_access_token(user.user_id), | ||
"refresh_token": create_refresh_token(user.user_id) | ||
} | ||
|
||
|
||
@auth_router.post('/test-token', summary="test if the access token is vaild", response_model=UserOut) | ||
async def tset_token(user: User = Depends(get_current_user)): | ||
return user | ||
|
||
|
||
@auth_router.post('/refresh', summary="refresh token", response_model=TokenSchema) | ||
async def refresh_token(refresh_token:str = Body(...)): | ||
try: | ||
payload = jwt.decode(refresh_token, settings.JWT_REFRESH_SECRET_KEY, algorithms=[settings.ALGORITHM]) | ||
token_data = TokenPayload(**payload) | ||
if datetime.fromtimestamp(token_data.exp) < datetime.now(): | ||
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Token expired", | ||
headers={"WWW-Authenticate": "Bearer"}) | ||
except(jwt.JWTError, ValidationError): | ||
raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail="Could not validate credentials", | ||
headers={"WWW-Authenticate": "Bearer"}) | ||
|
||
user = await UserService.get_user_by_id(token_data.sub) | ||
|
||
if not user: | ||
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Could not find user") | ||
|
||
return { | ||
"access_token":create_access_token(user.user_id), | ||
"refresh_token": create_refresh_token(user.user_id) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,15 +1,33 @@ | ||
from fastapi.security import OAuth2PasswordBearer | ||
from fastapi import Depends | ||
from fastapi import Depends, HTTPException, status | ||
from ...core.config import settings | ||
from ...models.user_model import User | ||
from ...services.user_services import UserService | ||
from jose import jwt | ||
from datetime import datetime | ||
from pydantic import ValidationError | ||
from ...schemas.auth_schema import TokenPayload | ||
|
||
reuseble_oauth = OAuth2PasswordBearer( | ||
tokenUrl=f"{settings.API_V1_STR1}/auth/login", | ||
tokenUrl=f"{settings.API_V1_STR}/auth/login", | ||
scheme_name="JWT" | ||
) | ||
|
||
async def get_current_user(token:str = Depends(reuseble_oauth))->User: | ||
|
||
async def get_current_user(token: str = Depends(reuseble_oauth)) -> User: | ||
try: | ||
payload = jwt.decode(token, settings.JWT_SECRET_KEY, algorithms=[settings.ALGORITHM]) | ||
finally: | ||
pass | ||
token_data = TokenPayload(**payload) | ||
if datetime.fromtimestamp(token_data.exp) < datetime.now(): | ||
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Token expired", | ||
headers={"WWW-Authenticate": "Bearer"}) | ||
except(jwt.JWTError, ValidationError): | ||
raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail="Could not validate credentials", | ||
headers={"WWW-Authenticate": "Bearer"}) | ||
|
||
user = await UserService.get_user_by_id(token_data.sub) | ||
|
||
if not user: | ||
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Could not find user") | ||
|
||
return user |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,12 @@ | ||
from uuid import UUID | ||
|
||
from pydantic import BaseModel | ||
|
||
class TokenSchema(BaseModel): | ||
acces_token : str | ||
access_token : str | ||
refresh_token : str | ||
|
||
|
||
class TokenPayload(BaseModel): | ||
sub : UUID = None | ||
exp : int |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters