Files
MoviePilot/app/db/oper/user.py
T

164 lines
5.3 KiB
Python

"""
用户数据访问。
认证依赖(get_current_user 等八个)已迁至 app/api/deps.py——那是 HTTP 层的关注点,
产出 403/400 而非数据。本模块只保留 UserOper。
这里不为那八个名字留惰性转发,否则会把
app.db.oper.user -> app.api.deps -> app.application.security 这条边永久焊进依赖图,
让数据访问模块在静态分析里牵着整个鉴权栈。仓外插件的旧 ``app.db.user_oper`` 路径由
runtime 兼容映射指向 SDK 薄门面;canonical 数据访问模块仍只依赖模型,不承担兼容职责。
"""
from typing import List, Optional
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy import select
from app.db.base import DbOper
from app.db.models.user import User
class UserOper(DbOper):
"""
用户管理
"""
def list(self) -> List[User]:
"""
获取用户列表
"""
return User.list(self._db)
def add(self, **kwargs):
"""
新增用户
"""
user = User(**kwargs)
self._stage_create(user)
def get_by_name(self, name: str) -> Optional[User]:
"""
根据用户名获取用户
"""
return User.get_by_name(self._db, name)
def get_by_id(self, user_id: int) -> Optional[User]:
"""按 ID 获取用户。"""
return User.get_by_id(self._db, user_id)
async def async_list(self) -> List[User]:
"""异步获取用户列表。"""
return await User.async_list(self._db)
async def async_create(self, payload: dict) -> Optional[User]:
"""异步创建用户。"""
user = User(**payload)
async def stage(session: AsyncSession) -> User:
"""在当前异步事务中暂存用户并分配主键。"""
session.add(user)
await session.flush()
return user
return await self._execute_async_write(stage)
async def async_update(self, user_id: int, payload: dict) -> Optional[User]:
"""异步更新用户。"""
user = await self.async_get_by_id(user_id)
if user:
async def stage(session: AsyncSession) -> User:
"""在当前事务中更新用户字段,必要时重新附加游离对象。"""
for key, value in payload.items():
setattr(user, key, value)
return await session.merge(user)
await self._execute_async_write(stage)
return user
async def async_delete(self, user_id: int) -> bool:
"""异步删除用户。"""
return bool(await self._execute_async_write(
lambda session: User.async_delete_by_id(session, user_id)
))
async def async_delete_by_name(self, name: str) -> bool:
"""在独立异步事务中按用户名删除用户。"""
return bool(await self._execute_async_write(
lambda session: User().async_delete_by_name(session, name)
))
async def async_update_otp_by_name(
self,
name: str,
otp: bool,
secret: str,
) -> bool:
"""异步更新用户 OTP 状态。"""
return bool(await self._execute_async_write(
lambda session: User.async_update_otp_by_name(
session, name, otp, secret
)
))
async def async_get_by_name(self, name: str) -> Optional[User]:
"""
异步根据用户名获取用户。
"""
async def query(session: AsyncSession) -> Optional[User]:
"""在调用方异步会话中执行用户名查询。"""
result = await session.execute(select(User).where(User.name == name))
return result.scalars().first()
return await self._execute_async_query(query)
async def async_get_by_id(self, user_id: int) -> Optional[User]:
"""
异步根据用户 ID 获取用户。
"""
async def query(session: AsyncSession) -> Optional[User]:
"""在调用方异步会话中执行用户 ID 查询。"""
result = await session.execute(select(User).where(User.id == user_id))
return result.scalars().first()
return await self._execute_async_query(query)
def get_permissions(self, name: str) -> dict:
"""
获取用户权限
"""
user = User.get_by_name(self._db, name)
if user:
return user.permissions or {}
return {}
def get_settings(self, name: str) -> Optional[dict]:
"""
获取用户个性化设置,返回None表示用户不存在
"""
user = User.get_by_name(self._db, name)
if user:
return user.settings or {}
return None
def get_setting(self, name: str, key: str) -> Optional[str]:
"""
获取用户个性化设置
"""
settings = self.get_settings(name)
if settings:
return settings.get(key)
return None
def get_name(self, **kwargs) -> Optional[str]:
"""
根据绑定账号获取用户名称
"""
users = self.list()
for user in users:
user_setting = user.settings
if user_setting:
for k, v in kwargs.items():
if user_setting.get(k) == str(v):
return user.name
return None