Initial commit

This commit is contained in:
shahzeydyfah
2024-02-15 00:17:51 +03:30
commit 4b0396466d
111 changed files with 6296 additions and 0 deletions
+78
View File
@@ -0,0 +1,78 @@
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', }
result = await client.request('POST', 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')
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
+29
View File
@@ -0,0 +1,29 @@
import uuid
from typing import Optional, Union, List
import pydantic
from pydantic import Field
from core.models.base import BaseModel
class UserModel(BaseModel):
id: Optional[Union[uuid.UUID, str]] = Field(alias='_id')
username: Optional[str]
mobile: Optional[str]
name: Optional[str]
first_name: Optional[str]
last_name: Optional[str]
is_su: Optional[bool]
unit: Optional[str]
avatar: Optional[str]
desc: Optional[str]
scopes: Optional[List[str]]
home_path: Optional[str]
roles: Optional[List[uuid.UUID]]
disabled: Optional[bool]
class ValidateTokenInput(pydantic.BaseModel):
token: str
scopes: Optional[List[str]] = ['account']
+9
View File
@@ -0,0 +1,9 @@
from fastapi.security import OAuth2PasswordBearer
oauth2 = OAuth2PasswordBearer(
tokenUrl="token",
scopes={
"account": "Read information about the current user.",
"scm": "Scm Modules",
},
)