# Copyright 2026 zhaoxi826 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. from typing import Annotated from fastapi import Depends, HTTPException from pretor.utils.access import Accessor, TokenData from pretor.core.database.table.user import UserAuthority from pretor.utils.ray_hook import ray_actor_hook async def get_authority(user_id: str) -> UserAuthority: """检索并获取特定的 authority 数据集合或实例对象。 根据提供的查询条件或上下文凭证,从数据库、缓存或第三方服务中读取对应的资源状态。 Args: user_id (str): 目标对象的唯一全局标识符 (UUID/ULID),用于在数据库表或缓存结构中精准匹配该 user 实例。 Returns: (UserAuthority): 经由当前业务模型加工处理后所输出的具体数据实例或领域模型对象。""" from pretor.utils.error import UserNotExistError postgres_database = ray_actor_hook("postgres_database").postgres_database try: user_authority = await postgres_database.get_user_authority.remote( user_id=user_id ) return user_authority except UserNotExistError: raise HTTPException(status_code=401, detail="用户不存在或已被删除,请重新登录") except Exception as e: # Check if it's a RayTaskError wrapping UserNotExistError if "UserNotExistError" in str(e): raise HTTPException( status_code=401, detail="用户不存在或已被删除,请重新登录" ) raise class RoleChecker: """RoleChecker 核心组件类。 这是一个领域数据模型或功能封装类,承载了 RoleChecker 相关的内聚属性定义与状态维护。它的存在隔离了局部的业务复杂性,并对外提供了类型安全的访问接口。""" def __init__(self, **kwargs): self.allowed_roles = kwargs.get( "allowed_roles", ) async def __call__( self, token_data: Annotated[TokenData, Depends(Accessor.get_current_user)] ): """执行与 call 相关的核心业务流转操作。 该方法封装了具体的算法策略或状态控制逻辑,确保操作能够在事务上下文中被原子且一致地执行。 Args: token_data (Annotated[TokenData, Depends(Accessor.get_current_user)]): 从客户端传递过来或由上游组件生成的核心业务数据体,通常需要进一步的清洗和结构化解析。 Returns: : 经由当前业务模型加工处理后所输出的具体数据实例或领域模型对象。""" user_authority = await get_authority(token_data.user_id) if user_authority < self.allowed_roles: raise HTTPException( status_code=403, detail={ "message": f"User {token_data.user_id} does not have allowed roles" }, ) return token_data