core/auth/credentials.py

96 lines
3.5 KiB
Python
Raw Normal View History

2025-05-16 06:23:48 +00:00
from typing import Dict, List, Optional, Set, Any
2025-05-16 06:23:48 +00:00
from pydantic import BaseModel, Field
2023-10-26 21:07:35 +00:00
2023-01-10 08:15:28 +00:00
# from base.exceptions import Unauthorized
2025-05-16 06:23:48 +00:00
from settings import ADMIN_EMAILS as ADMIN_EMAILS_LIST
ADMIN_EMAILS = ADMIN_EMAILS_LIST.split(",")
class Permission(BaseModel):
2025-05-16 06:23:48 +00:00
"""Модель разрешения для RBAC"""
resource: str
operation: str
def __str__(self) -> str:
return f"{self.resource}:{self.operation}"
class AuthCredentials(BaseModel):
2025-05-16 06:23:48 +00:00
"""
Модель учетных данных авторизации.
Используется как часть механизма аутентификации Starlette.
"""
author_id: Optional[int] = Field(None, description="ID автора")
scopes: Dict[str, Set[str]] = Field(default_factory=dict, description="Разрешения пользователя")
logged_in: bool = Field(False, description="Флаг, указывающий, авторизован ли пользователь")
error_message: str = Field("", description="Сообщение об ошибке аутентификации")
email: Optional[str] = Field(None, description="Email пользователя")
2025-05-19 21:00:24 +00:00
token: Optional[str] = Field(None, description="JWT токен авторизации")
2025-05-16 06:23:48 +00:00
def get_permissions(self) -> List[str]:
"""
Возвращает список строковых представлений разрешений.
Например: ["posts:read", "posts:write", "comments:create"].
Returns:
List[str]: Список разрешений
"""
result = []
for resource, operations in self.scopes.items():
for operation in operations:
result.append(f"{resource}:{operation}")
return result
def has_permission(self, resource: str, operation: str) -> bool:
"""
Проверяет наличие определенного разрешения.
Args:
resource: Ресурс (например, "posts")
operation: Операция (например, "read")
Returns:
bool: True, если пользователь имеет указанное разрешение
"""
if not self.logged_in:
return False
return resource in self.scopes and operation in self.scopes[resource]
@property
2025-05-16 06:23:48 +00:00
def is_admin(self) -> bool:
"""
Проверяет, является ли пользователь администратором.
Returns:
bool: True, если email пользователя находится в списке ADMIN_EMAILS
"""
return self.email in ADMIN_EMAILS if self.email else False
def to_dict(self) -> Dict[str, Any]:
"""
Преобразует учетные данные в словарь
Returns:
Dict[str, Any]: Словарь с данными учетных данных
"""
return {
"author_id": self.author_id,
"logged_in": self.logged_in,
"is_admin": self.is_admin,
"permissions": self.get_permissions(),
}
async def permissions(self) -> List[Permission]:
2025-05-16 06:23:48 +00:00
if self.author_id is None:
2023-01-10 08:15:28 +00:00
# raise Unauthorized("Please login first")
2023-10-30 21:00:55 +00:00
return {"error": "Please login first"}
2022-12-01 08:12:48 +00:00
else:
# TODO: implement permissions logix
2025-05-16 06:23:48 +00:00
print(self.author_id)
2023-10-30 21:00:55 +00:00
return NotImplemented