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
+2
View File
@@ -0,0 +1,2 @@
from .auth import *
from .property import *
+242
View File
@@ -0,0 +1,242 @@
import datetime
import uuid
from typing import Optional, Union, List, Literal
import pydantic
from fastapi import Body
from pydantic import Field, validator
from core.models.base import BaseModel, BaseCUAt
from core.utils.utils import is_mobile_number, is_email
class AuthModel(BaseModel):
username: str
password: str
class SessionModel(BaseModel):
id: Optional[uuid.UUID] = Field(alias='_id')
user_id: Optional[uuid.UUID]
access_token: Optional[str]
token: Optional[str]
refresh_token: Optional[str]
token_type: Optional[str]
agent: Optional[List[str]]
ip_info: Optional[dict]
class NotifyConfigModel(pydantic.BaseModel):
sms_info: Optional[bool]
sms_emergency: Optional[bool]
push: Optional[bool]
email: Optional[bool]
class UserOptions(pydantic.BaseModel):
active_password_login: Optional[bool]
last_password_changes: Optional[datetime.datetime]
active_otp: Optional[bool]
active_token: Optional[bool]
dark_mode: Optional[Literal['LIGHT', 'DARK', 'SYSTEM', 'DYNAMIC']]
time_format: Optional[str]
date_format: Optional[str]
date_type: Optional[str]
lang: Optional[str]
notify: Optional[NotifyConfigModel]
class VisualUserUpdate(pydantic.BaseModel):
storage: Optional[str]
class UserUpdateModel(BaseModel):
username: Optional[str]
email: Optional[str]
name: Optional[str]
first_name: Optional[str]
last_name: Optional[str]
unit: Optional[str]
personnel_code: Optional[str]
avatar: Optional[str]
desc: Optional[str]
gender: Optional[Literal[1, 2, 3]]
home_path: Optional[str]
force_password_change: Optional[bool]
disabled: Optional[bool]
class PasswordChangeModel(pydantic.BaseModel):
old_password: str
new_password: str = Field(min_length=6, max_length=28)
class UserModel(BaseModel, BaseCUAt):
id: Optional[Union[uuid.UUID, str]] = Field(alias='_id')
username: Optional[str]
mobile: Optional[str]
email: Optional[str]
name: Optional[Union[str,List[str]]]
first_name: Optional[str]
last_name: Optional[str]
is_su: Optional[bool]
unit: Optional[str]
units: Optional[List[str]]
personnel_code: Optional[str]
avatar: Optional[str]
desc: Optional[str]
gender: Optional[Literal[1, 2, 3]]
scopes: Optional[List[str]]
options: Optional[UserOptions]
home_path: Optional[str]
force_password_change: Optional[bool]
roles: Optional[List[uuid.UUID]]
_options: Optional[dict]
disabled: Optional[bool]
async def get_roles(self, exclude: [] = None, include: [] = None):
from auth.utils.mongo import use_auth_collection
projection = {}
if exclude:
projection = {
f: 0 for f in exclude
}
if include:
projection = {
f: 1 for f in include
}
cursor = use_auth_collection('roles').find(
{'_id': {'$in': [uuid.UUID(str(role)) for role in self.roles]}}, projection)
return [role async for role in cursor]
async def get_units(self):
roles = await self.get_roles(include=['units'])
units = []
for role in roles:
units.extend(role.get('units', []))
return units
def is_superuser(self) -> bool:
return self.is_su
@validator("mobile")
def mobile_validation(cls, v):
if not is_mobile_number(v):
raise ValueError('Mobile not valid')
return v
@validator("email")
def email_validation(cls, v):
if not is_email(v):
raise ValueError('Email not valid')
return v
class OAuth2PasswordRequestFormJson:
"""
This is a dependency class, use it like:
@app.post("/login")
def login(form_data: OAuth2PasswordRequestForm = Depends()):
data = form_data.parse()
print(data.username)
print(data.password)
for scope in data.scopes:
print(scope)
if data.client_id:
print(data.client_id)
if data.client_secret:
print(data.client_secret)
return data
It creates the following Form request parameters in your endpoint:
grant_type: the OAuth2 spec says it is required and MUST be the fixed string "password".
Nevertheless, this dependency class is permissive and allows not passing it. If you want to enforce it,
use instead the OAuth2PasswordRequestFormStrict dependency.
username: username string. The OAuth2 spec requires the exact field name "username".
password: password string. The OAuth2 spec requires the exact field name "password".
scope: Optional string. Several scopes (each one a string) separated by spaces. E.g.
"items:read items:write users:read profile openid"
client_id: optional string. OAuth2 recommends sending the client_id and client_secret (if any)
using HTTP Basic auth, as: client_id:client_secret
client_secret: optional string. OAuth2 recommends sending the client_id and client_secret (if any)
using HTTP Basic auth, as: client_id:client_secret
"""
def __init__(
self,
grant_type: str = Body(None, regex="password"),
username: str = Body(...),
password: str = Body(...),
scopes: Optional[List[str]] = Body(['default']),
client_id: Optional[str] = Body(None),
client_secret: Optional[str] = Body(None),
):
self.grant_type = grant_type
self.username = username
self.password = password
self.scopes = scopes
self.client_id = client_id
self.client_secret = client_secret
class OAuth2OptRequest:
def __init__(
self,
grant_type: str = Body(None, regex="password"),
allow_register: bool = Body(None),
mobile: str = Body(...),
token: Optional[int] = Body(None),
scopes: Optional[List[str]] = Body(['customer']),
step: Literal[1, 2] = Body(1),
client_id: Optional[str] = Body(None),
client_secret: Optional[str] = Body(None),
):
self.grant_type = grant_type
self.allow_register = allow_register
self.mobile = mobile
self.token = token
self.scopes = scopes
self.step = step
self.client_id = client_id
self.client_secret = client_secret
class Token(BaseModel):
access_token: str
token_type: str
class TokenData(BaseModel):
username: Optional[str] = None
scopes: List[str] = []
class UserInDB(UserModel):
password: Optional[str]
class CreateTokenModel(BaseModel):
id: Optional[Union[uuid.UUID, str]] = Field(alias='_id')
user_id: Optional[uuid.UUID]
mode: Optional[Literal['user_admin', 'customer']]
access_token: str
token: str
refresh_token: str
token_type: str = 'bearer'
class PasswordForgottenInput(pydantic.BaseModel):
password: str
mode: Optional[Literal['user_admin', 'customer']]
mobile: str
token: int
class UIdsInput(BaseModel):
u_ids: List[uuid.UUID]
+16
View File
@@ -0,0 +1,16 @@
from typing import Optional, Any
from uuid import UUID
from pydantic import Field
from core.models.base import BaseModel
class AuthPropertyModel(BaseModel):
id: Optional[UUID] = Field(alias='_id')
key: Optional[str]
user_id: Optional[UUID]
role_id: Optional[UUID]
value: Optional[Any]
meta: Optional[Any]
parent_id: Optional[UUID]
+22
View File
@@ -0,0 +1,22 @@
import uuid
from typing import Optional, Union, List
import pydantic
from pydantic import Field
from core.models.base import BaseModel, BaseCUAt
class ModuleModel(pydantic.BaseModel):
title: str
icon: str
description: Optional[str]
url: Optional[str]
class RoleModel(BaseModel, BaseCUAt):
id: Optional[Union[uuid.UUID, str]] = Field(alias='_id')
title: str
f_routes: Optional[List[str]]
units: Optional[List[uuid.UUID]]
modules: Optional[List[ModuleModel]]
+12
View File
@@ -0,0 +1,12 @@
import uuid
from typing import Optional, Union, List
from pydantic import Field
from core.models.base import BaseSoftDelete, BaseModel
class UnitModel(BaseModel, BaseSoftDelete):
id: Union[Optional[uuid.UUID], str] = Field(alias='_id')
title: str
parents: Optional[List[uuid.UUID]]