128 lines
3.8 KiB
Python
128 lines
3.8 KiB
Python
|
from fastapi_pagination import add_pagination
|
||
|
from fastapi.responses import PlainTextResponse
|
||
|
from fastapi.exceptions import RequestValidationError, ValidationError
|
||
|
from datetime import timedelta
|
||
|
from fastapi import FastAPI, HTTPException, Depends, Request, status
|
||
|
from fastapi_jwt_auth import AuthJWT
|
||
|
from fastapi_jwt_auth.exceptions import AuthJWTException
|
||
|
from fastapi.responses import JSONResponse
|
||
|
from typing import List
|
||
|
from tortoise.contrib.pydantic import pydantic_model_creator
|
||
|
from fastapi import FastAPI, HTTPException
|
||
|
from tortoise import Tortoise
|
||
|
from database.exercices.models import Exercice
|
||
|
from fastapi.middleware.cors import CORSMiddleware
|
||
|
from tortoise.contrib.fastapi import register_tortoise
|
||
|
from pydantic import BaseModel
|
||
|
import apis.base
|
||
|
import config
|
||
|
from redis import Redis
|
||
|
from fastapi.encoders import jsonable_encoder
|
||
|
|
||
|
app = FastAPI(title="Tortoise ORM FastAPI example")
|
||
|
origins = [
|
||
|
"http://localhost:8000",
|
||
|
"https://localhost:8001",
|
||
|
"http://localhost",
|
||
|
"http://localhost:8080",
|
||
|
]
|
||
|
|
||
|
app.add_middleware(
|
||
|
CORSMiddleware,
|
||
|
allow_origins=['*'],
|
||
|
allow_credentials=True,
|
||
|
allow_methods=["*"],
|
||
|
allow_headers=["*"],
|
||
|
)
|
||
|
|
||
|
@app.exception_handler(RequestValidationError)
|
||
|
@app.exception_handler(ValidationError)
|
||
|
async def validation_exception_handler(request, exc: RequestValidationError):
|
||
|
errors = {}
|
||
|
for e in exc.errors():
|
||
|
errors[e['loc'][-1] + "_error"] = e['msg']
|
||
|
|
||
|
return JSONResponse(
|
||
|
status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
|
||
|
content=jsonable_encoder({"detail": errors}),
|
||
|
)
|
||
|
|
||
|
|
||
|
class Settings(BaseModel):
|
||
|
authjwt_secret_key: str = config.SECRET_KEY
|
||
|
authjwt_denylist_enabled: bool = True
|
||
|
authjwt_denylist_token_checks: set = {"access", "refresh"}
|
||
|
access_expires: int = timedelta(minutes=15 )
|
||
|
refresh_expires: int = timedelta(days=30)
|
||
|
|
||
|
# callback to get your configuration
|
||
|
|
||
|
settings = Settings()
|
||
|
@AuthJWT.load_config
|
||
|
def get_config():
|
||
|
return settings
|
||
|
|
||
|
|
||
|
# exception handler for authjwt
|
||
|
# in production, you can tweak performance using orjson response
|
||
|
@app.exception_handler(AuthJWTException)
|
||
|
def authjwt_exception_handler(request: Request, exc: AuthJWTException):
|
||
|
return JSONResponse(
|
||
|
status_code=exc.status_code,
|
||
|
content={"detail": exc.message}
|
||
|
)
|
||
|
|
||
|
|
||
|
redis_conn = Redis(host='localhost', port=6379, db=0, decode_responses=True)
|
||
|
|
||
|
|
||
|
@AuthJWT.token_in_denylist_loader
|
||
|
def check_if_token_in_denylist(decrypted_token):
|
||
|
jti = decrypted_token['jti']
|
||
|
entry = redis_conn.get(jti)
|
||
|
return entry and entry == 'true'
|
||
|
|
||
|
app.include_router(apis.base.api_router)
|
||
|
|
||
|
|
||
|
@app.delete('/access-revoke')
|
||
|
def access_revoke(Authorize: AuthJWT = Depends()):
|
||
|
Authorize.jwt_required()
|
||
|
|
||
|
# Store the tokens in redis with the value true for revoked.
|
||
|
# We can also set an expires time on these tokens in redis,
|
||
|
# so they will get automatically removed after they expired.
|
||
|
jti = Authorize.get_raw_jwt()['jti']
|
||
|
redis_conn.setex(jti, settings.access_expires, 'true')
|
||
|
return {"detail": "Access token has been revoke"}
|
||
|
|
||
|
|
||
|
@app.delete('/refresh-revoke')
|
||
|
def refresh_revoke(Authorize: AuthJWT = Depends()):
|
||
|
Authorize.jwt_refresh_token_required()
|
||
|
|
||
|
jti = Authorize.get_raw_jwt()['jti']
|
||
|
redis_conn.setex(jti, settings.refresh_expires, 'true')
|
||
|
return {"detail": "Refresh token has been revoke"}
|
||
|
add_pagination(app)
|
||
|
|
||
|
TORTOISE_ORM = {
|
||
|
"connections": {"default": "sqlite://database/db.sqlite3"},
|
||
|
"apps": {
|
||
|
"models": {
|
||
|
"models": ["database.exercices.models", 'database.auth.models', "database.room.models","aerich.models"],
|
||
|
"default_connection": "default",
|
||
|
},
|
||
|
},
|
||
|
}
|
||
|
|
||
|
|
||
|
register_tortoise(
|
||
|
app,
|
||
|
config=TORTOISE_ORM,
|
||
|
#db_url="sqlite://database/db.sqlite3",
|
||
|
modules={"models": ["database.exercices.models", 'database.auth.models']},
|
||
|
generate_schemas=True,
|
||
|
add_exception_handlers=True,
|
||
|
)
|