skyplatform-iam 1.0.1__py3-none-any.whl → 1.0.5__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,272 @@
1
+ """
2
+ SkyPlatform IAM SDK 全局管理器模块
3
+ 提供单例模式的全局状态管理,确保线程安全和统一配置
4
+ """
5
+ import threading
6
+ import logging
7
+ from typing import Optional, Dict, Any, TYPE_CHECKING
8
+ from fastapi import FastAPI, Request
9
+
10
+ from .config import AuthConfig
11
+ from .connect_agenterra_iam import ConnectAgenterraIam
12
+ from .exceptions import ConfigurationError, IAMServiceError
13
+
14
+ # 使用TYPE_CHECKING避免循环导入
15
+ if TYPE_CHECKING:
16
+ from .middleware import AuthMiddleware
17
+
18
+ logger = logging.getLogger(__name__)
19
+
20
+
21
+ class GlobalIAMManager:
22
+ """
23
+ 全局IAM管理器,使用单例模式
24
+ 负责管理全局的IAM配置、客户端实例和中间件
25
+ """
26
+
27
+ _instance: Optional['GlobalIAMManager'] = None
28
+ _lock = threading.Lock()
29
+
30
+ def __new__(cls) -> 'GlobalIAMManager':
31
+ """单例模式实现,确保线程安全"""
32
+ if cls._instance is None:
33
+ with cls._lock:
34
+ if cls._instance is None:
35
+ cls._instance = super().__new__(cls)
36
+ cls._instance._initialized = False
37
+ return cls._instance
38
+
39
+ def __init__(self):
40
+ """初始化全局管理器"""
41
+ if hasattr(self, '_initialized') and self._initialized:
42
+ return
43
+
44
+ self._config: Optional[AuthConfig] = None
45
+ self._iam_client: Optional[ConnectAgenterraIam] = None
46
+ self._middleware: Optional['AuthMiddleware'] = None
47
+ self._app: Optional[FastAPI] = None
48
+ self._initialized = False
49
+ self._init_lock = threading.Lock()
50
+
51
+ logger.debug("GlobalIAMManager实例已创建")
52
+
53
+ def initialize(self, app: FastAPI, config: Optional[AuthConfig] = None, **kwargs) -> None:
54
+ """
55
+ 初始化IAM管理器
56
+
57
+ Args:
58
+ app: FastAPI应用实例
59
+ config: 认证配置,如果为None则从环境变量加载
60
+ **kwargs: 额外配置参数
61
+
62
+ Raises:
63
+ ConfigurationError: 配置错误
64
+ IAMServiceError: IAM服务连接错误
65
+ """
66
+ with self._init_lock:
67
+ if self._initialized:
68
+ logger.warning("GlobalIAMManager已经初始化,跳过重复初始化")
69
+ return
70
+
71
+ try:
72
+ # 1. 处理配置
73
+ if config is None:
74
+ logger.info("未提供配置,尝试从环境变量加载")
75
+ config = AuthConfig.from_env()
76
+
77
+ # 验证配置
78
+ config.validate_config()
79
+ self._config = config
80
+
81
+ # 2. 创建IAM客户端
82
+ self._iam_client = ConnectAgenterraIam(config=config)
83
+ logger.info(f"IAM客户端已创建,连接到: {config.agenterra_iam_host}")
84
+
85
+ # 3. 创建中间件(不直接注册,由用户决定)
86
+ from .middleware import AuthMiddleware
87
+ self._middleware = AuthMiddleware(app=app, config=config, use_global_manager=False)
88
+ logger.info("认证中间件已创建")
89
+
90
+ # 4. 保存应用引用
91
+ self._app = app
92
+
93
+ # 5. 标记为已初始化
94
+ self._initialized = True
95
+
96
+ logger.info(f"GlobalIAMManager初始化完成 - 服务: {config.server_name}, "
97
+ f"白名单路径数量: {len(config.get_whitelist_paths())}")
98
+
99
+ except Exception as e:
100
+ logger.error(f"GlobalIAMManager初始化失败: {str(e)}")
101
+ # 清理部分初始化的状态
102
+ self._config = None
103
+ self._iam_client = None
104
+ self._middleware = None
105
+ self._app = None
106
+
107
+ if isinstance(e, (ConfigurationError, IAMServiceError)):
108
+ raise
109
+ else:
110
+ raise IAMServiceError(f"初始化失败: {str(e)}")
111
+
112
+ def get_client(self) -> ConnectAgenterraIam:
113
+ """
114
+ 获取IAM客户端实例
115
+
116
+ Returns:
117
+ ConnectAgenterraIam: IAM客户端实例
118
+
119
+ Raises:
120
+ IAMServiceError: 如果管理器未初始化
121
+ """
122
+ if not self._initialized or self._iam_client is None:
123
+ raise IAMServiceError(
124
+ "GlobalIAMManager未初始化,请先调用init_skyplatform_iam()函数进行初始化"
125
+ )
126
+ return self._iam_client
127
+
128
+ def get_config(self) -> AuthConfig:
129
+ """
130
+ 获取当前配置
131
+
132
+ Returns:
133
+ AuthConfig: 当前认证配置
134
+
135
+ Raises:
136
+ IAMServiceError: 如果管理器未初始化
137
+ """
138
+ if not self._initialized or self._config is None:
139
+ raise IAMServiceError(
140
+ "GlobalIAMManager未初始化,请先调用init_skyplatform_iam()函数进行初始化"
141
+ )
142
+ return self._config
143
+
144
+ def get_middleware(self) -> 'AuthMiddleware':
145
+ """
146
+ 获取中间件实例
147
+
148
+ Returns:
149
+ AuthMiddleware: 认证中间件实例
150
+
151
+ Raises:
152
+ IAMServiceError: 如果管理器未初始化
153
+ """
154
+ if not self._initialized or self._middleware is None:
155
+ raise IAMServiceError(
156
+ "GlobalIAMManager未初始化,请先调用init_skyplatform_iam()函数进行初始化"
157
+ )
158
+ return self._middleware
159
+
160
+ def is_initialized(self) -> bool:
161
+ """
162
+ 检查是否已初始化
163
+
164
+ Returns:
165
+ bool: 是否已初始化
166
+ """
167
+ return self._initialized
168
+
169
+ async def get_current_user_info(self, request: Request) -> Optional[Dict[str, Any]]:
170
+ """
171
+ 便捷方法:获取当前用户信息
172
+
173
+ Args:
174
+ request: FastAPI请求对象
175
+
176
+ Returns:
177
+ Optional[Dict]: 用户信息字典,如果未登录则返回None
178
+
179
+ Raises:
180
+ IAMServiceError: 如果管理器未初始化
181
+ """
182
+ if not self._initialized:
183
+ raise IAMServiceError(
184
+ "GlobalIAMManager未初始化,请先调用init_skyplatform_iam()函数进行初始化"
185
+ )
186
+
187
+ # 检查请求状态中是否已有用户信息(由中间件设置)
188
+ if hasattr(request.state, 'user') and request.state.user:
189
+ return request.state.user
190
+
191
+ # 如果中间件没有设置用户信息,尝试手动验证
192
+ try:
193
+ from .middleware import AuthService
194
+ auth_service = AuthService(self._config)
195
+ return await auth_service.get_current_user(request)
196
+ except Exception as e:
197
+ logger.error(f"获取用户信息失败: {str(e)}")
198
+ return None
199
+
200
+ async def verify_permission(
201
+ self,
202
+ user_id: str,
203
+ permission: str,
204
+ resource: Optional[str] = None
205
+ ) -> bool:
206
+ """
207
+ 便捷方法:验证用户权限
208
+
209
+ Args:
210
+ user_id: 用户ID
211
+ permission: 权限标识
212
+ resource: 资源标识(可选)
213
+
214
+ Returns:
215
+ bool: 是否有权限
216
+
217
+ Raises:
218
+ IAMServiceError: 如果管理器未初始化
219
+ """
220
+ client = self.get_client()
221
+ try:
222
+ # 这里可以根据实际的IAM客户端API进行权限验证
223
+ # 目前先返回True,具体实现需要根据ConnectAgenterraIam的API
224
+ logger.info(f"验证权限: user_id={user_id}, permission={permission}, resource={resource}")
225
+ return True
226
+ except Exception as e:
227
+ logger.error(f"权限验证失败: {str(e)}")
228
+ return False
229
+
230
+ def reset(self) -> None:
231
+ """
232
+ 重置管理器状态(主要用于测试)
233
+ """
234
+ with self._init_lock:
235
+ self._config = None
236
+ self._iam_client = None
237
+ self._middleware = None
238
+ self._app = None
239
+ self._initialized = False
240
+ logger.info("GlobalIAMManager状态已重置")
241
+
242
+ def get_status(self) -> Dict[str, Any]:
243
+ """
244
+ 获取管理器状态信息
245
+
246
+ Returns:
247
+ Dict: 状态信息
248
+ """
249
+ return {
250
+ "initialized": self._initialized,
251
+ "has_config": self._config is not None,
252
+ "has_client": self._iam_client is not None,
253
+ "has_middleware": self._middleware is not None,
254
+ "has_app": self._app is not None,
255
+ "server_name": self._config.server_name if self._config else None,
256
+ "iam_host": self._config.agenterra_iam_host if self._config else None,
257
+ "whitelist_paths_count": len(self._config.get_whitelist_paths()) if self._config else 0
258
+ }
259
+
260
+
261
+ # 全局管理器实例
262
+ _global_manager = GlobalIAMManager()
263
+
264
+
265
+ def get_global_manager() -> GlobalIAMManager:
266
+ """
267
+ 获取全局管理器实例
268
+
269
+ Returns:
270
+ GlobalIAMManager: 全局管理器实例
271
+ """
272
+ return _global_manager