init commit
This commit is contained in:
@@ -0,0 +1,4 @@
|
||||
__all__: list[str] = []
|
||||
|
||||
# Initialize all routes
|
||||
from .routes import *
|
||||
@@ -0,0 +1,68 @@
|
||||
from typing import Annotated
|
||||
|
||||
from fastapi import Depends
|
||||
from fastapi import HTTPException
|
||||
from fastapi import Request
|
||||
from fastapi.security import HTTPAuthorizationCredentials
|
||||
from fastapi.security import HTTPBearer
|
||||
import jwt
|
||||
|
||||
from app.core.config import config
|
||||
from app.models.user import User
|
||||
|
||||
from .utils import decode_jwt
|
||||
|
||||
|
||||
class BearerAuth(HTTPBearer):
|
||||
def __init__(self, auto_error: bool = True):
|
||||
super().__init__(auto_error=auto_error)
|
||||
|
||||
async def __call__(self, request: Request):
|
||||
credentials: HTTPAuthorizationCredentials = await super().__call__(
|
||||
request
|
||||
)
|
||||
|
||||
if credentials:
|
||||
if not credentials.scheme == 'Bearer':
|
||||
raise HTTPException(
|
||||
status_code=403, detail='Invalid authentication scheme.'
|
||||
)
|
||||
if not self.verify_jwt(credentials.credentials):
|
||||
raise HTTPException(
|
||||
status_code=403, detail='Invalid token or expired token.'
|
||||
)
|
||||
return credentials.credentials
|
||||
else:
|
||||
raise HTTPException(
|
||||
status_code=403, detail='Invalid authorization code.'
|
||||
)
|
||||
|
||||
def verify_jwt(self, token: str) -> bool:
|
||||
payload = decode_jwt(token)
|
||||
is_valid = bool(payload)
|
||||
|
||||
return is_valid
|
||||
|
||||
|
||||
oauth2_scheme = BearerAuth()
|
||||
|
||||
|
||||
async def get_current_user(token: Annotated[str, Depends(oauth2_scheme)]):
|
||||
try:
|
||||
payload = jwt.decode(
|
||||
token, config.JWT_SECRET_KEY, algorithms=['HS256']
|
||||
)
|
||||
user = await User.get_or_create_user(
|
||||
User(
|
||||
id=payload['user_id'],
|
||||
username=payload['username'],
|
||||
events=[],
|
||||
items=[],
|
||||
transactions=[],
|
||||
)
|
||||
)
|
||||
return user
|
||||
except jwt.ExpiredSignatureError:
|
||||
return {'error': 'Token is expired'}
|
||||
except jwt.InvalidTokenError:
|
||||
return {'error': 'Invalid token'}
|
||||
@@ -0,0 +1,7 @@
|
||||
import fastapi
|
||||
|
||||
credentials_exception = fastapi.HTTPException(
|
||||
status_code=fastapi.status.HTTP_401_UNAUTHORIZED,
|
||||
detail='Could not validate credentials',
|
||||
headers={'WWW-Authenticate': 'Bearer'},
|
||||
)
|
||||
@@ -0,0 +1,3 @@
|
||||
import fastapi
|
||||
|
||||
auth_router = fastapi.APIRouter()
|
||||
@@ -0,0 +1,60 @@
|
||||
from datetime import timedelta
|
||||
|
||||
import fastapi
|
||||
|
||||
from app.api.auth.routers import auth_router
|
||||
import app.core.security.tokens
|
||||
from app.models.base import BasicResponse
|
||||
from app.models.telegram import TelegramInputData
|
||||
from app.models.tokens import Token
|
||||
from app.models.user import User
|
||||
|
||||
|
||||
@auth_router.post(
|
||||
'/token',
|
||||
responses={
|
||||
fastapi.status.HTTP_401_UNAUTHORIZED: {
|
||||
'description': 'Unauthorized',
|
||||
'model': BasicResponse,
|
||||
},
|
||||
},
|
||||
)
|
||||
async def authenticate(init_data: TelegramInputData) -> Token:
|
||||
# if not config.DEBUG:
|
||||
# fields = init_data.model_dump()
|
||||
# sorted_fields = sorted(fields.items())
|
||||
# formatted = [f'{key}={value}' for key, value in sorted_fields]
|
||||
# data_check_string = '\n'.join(formatted)
|
||||
|
||||
# secret_key = hmac.new(
|
||||
# config.TOKEN_TELEGRAM_API.encode(), b'WebAppData', sha256
|
||||
# ).digest()
|
||||
|
||||
# if (
|
||||
# hmac.new(
|
||||
# data_check_string.encode(), secret_key, sha256
|
||||
# ).hexdigest()
|
||||
# != init_data.hash
|
||||
# ):
|
||||
# print(hmac.new(
|
||||
# data_check_string.encode(), secret_key, sha256
|
||||
# ).hexdigest())
|
||||
# print(init_data.hash)
|
||||
# raise HTTPException(status_code=403, detail='Unauthorized')
|
||||
|
||||
user = await User.get_or_create_user(
|
||||
User(id=init_data.user.id, username=init_data.user.username)
|
||||
)
|
||||
|
||||
return Token(
|
||||
access_token=app.core.security.tokens.generate_token(
|
||||
{'user_id': user.id, 'username': user.username},
|
||||
expires_delta=timedelta(days=7),
|
||||
),
|
||||
token_type='bearer',
|
||||
)
|
||||
|
||||
|
||||
@auth_router.get('/ping')
|
||||
def ping() -> str:
|
||||
return 'pong'
|
||||
@@ -0,0 +1,14 @@
|
||||
import jwt
|
||||
|
||||
from app.core.config import config
|
||||
|
||||
|
||||
def decode_jwt(token: str) -> dict:
|
||||
try:
|
||||
decoded_token = jwt.decode(
|
||||
token, config.JWT_SECRET_KEY, algorithms=['HS256']
|
||||
)
|
||||
return decoded_token
|
||||
|
||||
except (jwt.InvalidTokenError, jwt.ExpiredSignatureError):
|
||||
return {}
|
||||
Reference in New Issue
Block a user