Files
sakhteman/core/utils/auth/__init__.py
T
2026-06-10 00:31:45 +03:30

79 lines
3.0 KiB
Python

import httpx
from fastapi import HTTPException, Depends, Security
from fastapi.security import SecurityScopes
from httpx import ConnectError
from jose import jwt
from starlette.requests import Request
from config import conf
from .model import UserModel, ValidateTokenInput
from .schema import oauth2
from ..app_context import use_user
from ...service.redis import redis_set, redis_get
def decode_token(token: str):
return jwt.decode(
token.split(' ').pop(), conf.auth.secret_key, algorithms=[conf.auth.algorithm])
async def validate_token(_input: ValidateTokenInput):
try:
_cache_key = _input.token.split('.')[-1]
_cache_auth = await redis_get(f'{conf.auth.cache_prefix_key}{_cache_key}', conf.database.get('auth_redis'))
if not _cache_auth:
client = httpx.AsyncClient()
headers = {'Content-Type': 'application/json', 'Authorization':'Bearer '+_input.token}
result = await client.request('GET', conf.auth.url, json=_input.dict(), headers=headers)
export = result.text
if 'application/json' in result.headers['content-type']:
export = result.json()
if result.status_code > 299:
raise HTTPException(status_code=result.status_code, detail=export)
if 'v2' in conf.auth.url:
export = export.get('data')
print(export)
await redis_set(f'{conf.auth.cache_prefix_key}{_cache_key}', export, conf.database.get('auth_redis'),
ex=conf.auth.cache_ttl)
return UserModel(**export)
else:
return UserModel(**_cache_auth)
except ConnectError as e:
raise HTTPException(status_code=400, detail=str(e))
except HTTPException as e:
raise e
except Exception as e:
raise HTTPException(status_code=400, detail=str(e))
async def get_current_user(security_scopes: SecurityScopes, token: str = Depends(oauth2)):
if security_scopes.scopes:
authenticate_value = f'Bearer scope="{security_scopes.scope_str}"'
else:
authenticate_value = f"Bearer"
credentials_exception = HTTPException(
status_code=401,
detail="Could not validate credentials",
headers={"WWW-Authenticate": authenticate_value},
)
user = await validate_token(ValidateTokenInput(token=token, scopes=security_scopes.scopes))
if user is None:
raise credentials_exception
user.scopes = security_scopes.scopes if isinstance(
security_scopes.scopes, list) else security_scopes.scopes
return user
async def get_current_active_user(request: Request,
current_user: UserModel = Security(get_current_user, scopes=["account"]), ):
if current_user.disabled:
raise HTTPException(status_code=400, detail="Inactive user")
request.state.user = UserModel(**current_user.mongo_dict())
use_user(UserModel(**current_user.mongo_dict()))
return current_user