skyplatform-iam 1.0.5__py3-none-any.whl → 1.1.0__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.
@@ -11,12 +11,10 @@ import jwt
11
11
 
12
12
  from .config import AuthConfig
13
13
  from .connect_agenterra_iam import ConnectAgenterraIam
14
- from .global_manager import get_global_manager
15
14
  from .exceptions import (
16
15
  AuthenticationError,
17
16
  AuthorizationError,
18
- ConfigurationError,
19
- IAMServiceError
17
+ ConfigurationError
20
18
  )
21
19
 
22
20
  logger = logging.getLogger(__name__)
@@ -26,72 +24,40 @@ class AuthMiddleware(BaseHTTPMiddleware):
26
24
  """
27
25
  认证中间件
28
26
  自动拦截请求进行Token验证和权限检查
29
- 支持全局实例共享和延迟初始化
30
27
  """
31
28
 
32
29
  def __init__(
33
30
  self,
34
31
  app,
35
- config: Optional[AuthConfig] = None,
36
- skip_validation: Optional[Callable[[Request], bool]] = None,
37
- use_global_manager: bool = True
32
+ config: AuthConfig,
33
+ skip_validation: Optional[Callable[[Request], bool]] = None
38
34
  ):
39
35
  """
40
36
  初始化认证中间件
41
37
 
42
38
  Args:
43
39
  app: FastAPI应用实例
44
- config: 认证配置,如果为None且use_global_manager=True,则从全局管理器获取
40
+ config: 认证配置
45
41
  skip_validation: 自定义跳过验证的函数
46
- use_global_manager: 是否使用全局管理器(推荐)
47
42
  """
48
43
  super().__init__(app)
49
- self.use_global_manager = use_global_manager
44
+ self.config = config
45
+ self.iam_client = ConnectAgenterraIam(config=config)
50
46
  self.skip_validation = skip_validation
51
-
52
- if use_global_manager:
53
- # 使用全局管理器(延迟初始化)
54
- self.config = None
55
- self.iam_client = None
56
- logger.info("AuthMiddleware使用全局管理器模式")
57
- else:
58
- # 传统模式(向后兼容)
59
- if config is None:
60
- raise ConfigurationError("在非全局管理器模式下,config参数不能为None")
61
- self.config = config
62
- self.iam_client = ConnectAgenterraIam(config=config)
63
-
64
- # 验证配置
65
- try:
66
- self.config.validate_config()
67
- except ValueError as e:
68
- raise ConfigurationError(str(e))
69
- logger.info("AuthMiddleware使用传统模式")
70
-
71
- def _get_config_and_client(self):
72
- """获取配置和客户端实例"""
73
- if self.use_global_manager:
74
- try:
75
- manager = get_global_manager()
76
- if not manager.is_initialized():
77
- raise IAMServiceError("SkyPlatform IAM SDK未初始化,请先调用init_skyplatform_iam()")
78
- return manager.get_config(), manager.get_client()
79
- except Exception as e:
80
- logger.error(f"从全局管理器获取配置和客户端失败: {str(e)}")
81
- raise IAMServiceError(f"获取IAM配置失败: {str(e)}")
82
- else:
83
- return self.config, self.iam_client
47
+
48
+ # 验证配置
49
+ try:
50
+ self.config.validate_config()
51
+ except ValueError as e:
52
+ raise ConfigurationError(str(e))
84
53
 
85
54
  def is_path_whitelisted(self, path: str) -> bool:
86
55
  """
87
56
  检查路径是否在本地白名单中
88
57
  """
89
- try:
90
- config, _ = self._get_config_and_client()
91
- return config.is_path_whitelisted(path)
92
- except Exception as e:
93
- logger.error(f"检查白名单路径失败: {str(e)}")
58
+ if not self.config:
94
59
  return False
60
+ return self.config.is_path_whitelisted(path)
95
61
 
96
62
  async def dispatch(self, request: Request, call_next: Callable) -> Response:
97
63
  """
@@ -173,31 +139,23 @@ class AuthMiddleware(BaseHTTPMiddleware):
173
139
  """
174
140
  从请求中提取Token
175
141
  """
176
- try:
177
- config, _ = self._get_config_and_client()
178
-
179
- # 从Authorization头提取
180
- auth_header = request.headers.get(config.token_header)
181
- if auth_header and auth_header.startswith(config.token_prefix):
182
- return auth_header[len(config.token_prefix):].strip()
142
+ # 从Authorization头提取
143
+ auth_header = request.headers.get(self.config.token_header)
144
+ if auth_header and auth_header.startswith(self.config.token_prefix):
145
+ return auth_header[len(self.config.token_prefix):].strip()
183
146
 
184
- # 从查询参数提取(备选方案)
185
- token = request.query_params.get("token")
186
- if token:
187
- return token
147
+ # 从查询参数提取(备选方案)
148
+ token = request.query_params.get("token")
149
+ if token:
150
+ return token
188
151
 
189
- return None
190
- except Exception as e:
191
- logger.error(f"提取Token失败: {str(e)}")
192
- return None
152
+ return None
193
153
 
194
154
  async def _verify_token_and_permission(self, request: Request, token: Optional[str]) -> Optional[Dict[str, Any]]:
195
155
  """
196
156
  验证Token和权限
197
157
  """
198
158
  try:
199
- config, iam_client = self._get_config_and_client()
200
-
201
159
  # 获取请求信息
202
160
  api_path = request.url.path
203
161
  method = request.method
@@ -207,7 +165,7 @@ class AuthMiddleware(BaseHTTPMiddleware):
207
165
  server_sk = request.headers.get("SERVER-SK", "")
208
166
 
209
167
  # 调用IAM验证接口(即使token为空也要调用,因为可能是白名单接口)
210
- user_info = iam_client.verify_token(
168
+ user_info = self.iam_client.verify_token(
211
169
  token=token or "", # 如果token为None,传递空字符串
212
170
  api=api_path,
213
171
  method=method,
@@ -222,12 +180,8 @@ class AuthMiddleware(BaseHTTPMiddleware):
222
180
  raise
223
181
  except Exception as e:
224
182
  logger.error(f"Token验证异常: {str(e)}")
225
- try:
226
- config, _ = self._get_config_and_client()
227
- if config.enable_debug:
228
- logger.exception("详细异常信息:")
229
- except:
230
- pass
183
+ if self.config.enable_debug:
184
+ logger.exception("详细异常信息:")
231
185
  return None
232
186
 
233
187
  def _create_error_response(
@@ -433,93 +387,32 @@ auth_service = None
433
387
 
434
388
  def setup_auth_middleware(auth_config: AuthConfig) -> None:
435
389
  """
436
- 设置认证中间件配置(向后兼容)
390
+ 设置认证中间件配置
437
391
 
438
392
  Args:
439
393
  auth_config: 认证配置实例,包含白名单路径等配置
440
-
441
- Deprecated:
442
- 请使用 init_skyplatform_iam() 替代
443
394
  """
444
395
  global auth_service
445
396
  auth_service = AuthService(auth_config)
446
- logger.warning("setup_auth_middleware()已废弃,请使用init_skyplatform_iam()替代")
447
397
  logger.info(f"认证中间件已配置,白名单路径数量: {len(auth_config.get_whitelist_paths())}")
448
398
 
449
399
 
450
- def create_auth_middleware(
451
- app,
452
- config: Optional[AuthConfig] = None,
453
- use_global_manager: bool = True
454
- ) -> AuthMiddleware:
455
- """
456
- 创建认证中间件实例
457
-
458
- Args:
459
- app: FastAPI应用实例
460
- config: 认证配置,如果为None且use_global_manager=True,则从全局管理器获取
461
- use_global_manager: 是否使用全局管理器(推荐)
462
-
463
- Returns:
464
- AuthMiddleware: 认证中间件实例
465
-
466
- Example:
467
- # 使用全局管理器(推荐)
468
- middleware = create_auth_middleware(app)
469
-
470
- # 传统模式(向后兼容)
471
- middleware = create_auth_middleware(app, config, use_global_manager=False)
472
- """
473
- return AuthMiddleware(app, config, use_global_manager=use_global_manager)
474
-
475
-
476
400
  # 便捷的依赖函数
477
401
  async def get_current_user(request: Request) -> Dict:
478
- """
479
- 获取当前用户的依赖函数
480
- 优先使用全局管理器,向后兼容传统模式
481
- """
482
- try:
483
- # 尝试使用全局管理器
484
- manager = get_global_manager()
485
- if manager.is_initialized():
486
- user_info = await manager.get_current_user_info(request)
487
- if user_info is None:
488
- raise HTTPException(
489
- status_code=status.HTTP_401_UNAUTHORIZED,
490
- detail="需要登录认证",
491
- headers={"WWW-Authenticate": "Bearer"},
492
- )
493
- return user_info
494
- except IAMServiceError:
495
- pass # 全局管理器未初始化,尝试传统模式
496
-
497
- # 传统模式(向后兼容)
402
+ """获取当前用户的依赖函数"""
498
403
  if auth_service is None:
499
404
  raise HTTPException(
500
405
  status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
501
- detail="认证服务未初始化,请先调用init_skyplatform_iam()或setup_auth_middleware()函数进行配置"
406
+ detail="认证服务未初始化,请先调用setup_auth_middleware函数进行配置"
502
407
  )
503
408
  return await auth_service.require_auth(request)
504
409
 
505
410
 
506
411
  async def get_optional_user(request: Request) -> Optional[Dict]:
507
- """
508
- 获取可选当前用户的依赖函数
509
- 优先使用全局管理器,向后兼容传统模式
510
- """
511
- try:
512
- # 尝试使用全局管理器
513
- manager = get_global_manager()
514
- if manager.is_initialized():
515
- return await manager.get_current_user_info(request)
516
- except IAMServiceError:
517
- pass # 全局管理器未初始化,尝试传统模式
518
-
519
- # 传统模式(向后兼容)
412
+ """获取可选当前用户的依赖函数"""
520
413
  if auth_service is None:
521
414
  raise HTTPException(
522
415
  status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
523
- detail="认证服务未初始化,请先调用init_skyplatform_iam()或setup_auth_middleware()函数进行配置"
416
+ detail="认证服务未初始化,请先调用setup_auth_middleware函数进行配置"
524
417
  )
525
418
  return await auth_service.optional_auth(request)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: skyplatform-iam
3
- Version: 1.0.5
3
+ Version: 1.1.0
4
4
  Summary: SkyPlatform IAM认证SDK,提供FastAPI中间件和认证路由
5
5
  Project-URL: Homepage, https://github.com/xinmayoujiang12621/agenterra_iam
6
6
  Project-URL: Documentation, https://skyplatform-iam.readthedocs.io/
@@ -0,0 +1,8 @@
1
+ skyplatform_iam/__init__.py,sha256=JfCqvHdzjiwkEVhgzlB45pKKs0VkxKg8yrMMQ4NpWpY,4664
2
+ skyplatform_iam/config.py,sha256=s4tctVpguKZv4O1Fhf7_Fo7zELNX6KYviMjkE1WPbQM,3715
3
+ skyplatform_iam/connect_agenterra_iam.py,sha256=9SnZkYmZ1VewzIz6a3-uOdOLzHrhPyJPIofZHgImJCM,39785
4
+ skyplatform_iam/exceptions.py,sha256=Rt55QIzVK1F_kn6yzKQKKakD6PZDFdPLCGaCphKKms8,2166
5
+ skyplatform_iam/middleware.py,sha256=XNJxvjw3O55TW-ff_uORK-C9Wy4BTAfkcnNjy1SQkx0,15721
6
+ skyplatform_iam-1.1.0.dist-info/METADATA,sha256=K3G-22HfmCKyzHOK_zvrpGDzez_gpEvrqon7nsvG4wg,12658
7
+ skyplatform_iam-1.1.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
8
+ skyplatform_iam-1.1.0.dist-info/RECORD,,
skyplatform_iam/api.py DELETED
@@ -1,366 +0,0 @@
1
- """
2
- SkyPlatform IAM SDK 统一API模块
3
- 提供统一的初始化和全局访问接口
4
- """
5
- import logging
6
- from typing import Optional, Dict, Any
7
- from fastapi import FastAPI, Request
8
-
9
- from .config import AuthConfig
10
- from .global_manager import get_global_manager, GlobalIAMManager
11
- from .connect_agenterra_iam import ConnectAgenterraIam
12
- from .exceptions import IAMServiceError, ConfigurationError
13
-
14
- logger = logging.getLogger(__name__)
15
-
16
-
17
- def init_skyplatform_iam(
18
- app: FastAPI,
19
- config: Optional[AuthConfig] = None,
20
- **kwargs
21
- ) -> GlobalIAMManager:
22
- """
23
- 统一初始化SkyPlatform IAM SDK
24
- 一次配置,全局可用
25
-
26
- Args:
27
- app: FastAPI应用实例
28
- config: 认证配置,如果为None则从环境变量加载
29
- **kwargs: 额外配置参数
30
-
31
- Returns:
32
- GlobalIAMManager: 全局IAM管理器实例
33
-
34
- Raises:
35
- ConfigurationError: 配置错误
36
- IAMServiceError: IAM服务连接错误
37
-
38
- Example:
39
- # 方式1:直接配置
40
- config = AuthConfig(
41
- agenterra_iam_host="http://127.0.0.1:5001",
42
- server_name="Agenterra_shop",
43
- access_key="your_access_key"
44
- )
45
- init_skyplatform_iam(app, config)
46
-
47
- # 方式2:从环境变量加载
48
- init_skyplatform_iam(app)
49
- """
50
- logger.info("开始初始化SkyPlatform IAM SDK")
51
-
52
- try:
53
- # 获取全局管理器
54
- manager = get_global_manager()
55
-
56
- # 如果已经初始化,记录警告并返回
57
- if manager.is_initialized():
58
- logger.warning("SkyPlatform IAM SDK已经初始化,跳过重复初始化")
59
- return manager
60
-
61
- # 处理配置
62
- if config is None:
63
- logger.info("未提供配置,从环境变量加载")
64
- try:
65
- config = AuthConfig.from_env()
66
- except Exception as e:
67
- raise ConfigurationError(f"从环境变量加载配置失败: {str(e)}")
68
-
69
- # 应用额外配置参数
70
- if kwargs:
71
- logger.debug(f"应用额外配置参数: {kwargs}")
72
- config = config.copy_with_updates(**kwargs)
73
-
74
- # 初始化管理器
75
- manager.initialize(app, config)
76
-
77
- logger.info("SkyPlatform IAM SDK初始化完成")
78
- return manager
79
-
80
- except Exception as e:
81
- logger.error(f"SkyPlatform IAM SDK初始化失败: {str(e)}")
82
- raise
83
-
84
-
85
- class LazyIAMClient:
86
- """
87
- 懒加载的IAM客户端包装器
88
- 解决模块导入时的初始化顺序问题
89
- """
90
-
91
- def __init__(self):
92
- self._client = None
93
- self._initialized = False
94
-
95
- def _get_client(self) -> ConnectAgenterraIam:
96
- """获取实际的IAM客户端实例"""
97
- if not self._initialized:
98
- try:
99
- manager = get_global_manager()
100
- self._client = manager.get_client()
101
- self._initialized = True
102
- except Exception as e:
103
- # 提供更详细的错误信息和解决建议
104
- error_msg = (
105
- f"获取IAM客户端失败: {str(e)}\n\n"
106
- "解决方案:\n"
107
- "1. 确保在使用IAM客户端前调用 init_skyplatform_iam() 初始化SDK\n"
108
- "2. 避免在模块导入时直接调用 get_iam_client(),应在函数内部调用\n"
109
- "3. 检查初始化顺序,确保SDK在应用启动时正确初始化\n\n"
110
- "正确的使用方式:\n"
111
- "```python\n"
112
- "# 在main.py或应用启动时\n"
113
- "from skyplatform_iam import init_skyplatform_iam\n"
114
- "init_skyplatform_iam(app, config)\n\n"
115
- "# 在业务代码中\n"
116
- "def some_function():\n"
117
- " iam_client = get_iam_client() # 在函数内部调用\n"
118
- " return iam_client.login_with_password(...)\n"
119
- "```"
120
- )
121
- logger.error(error_msg)
122
- raise IAMServiceError(error_msg)
123
- return self._client
124
-
125
- def __getattr__(self, name):
126
- """代理所有属性访问到实际的IAM客户端"""
127
- client = self._get_client()
128
- return getattr(client, name)
129
-
130
- def __repr__(self):
131
- """提供有用的调试信息"""
132
- if self._initialized and self._client:
133
- return f"<LazyIAMClient: {repr(self._client)}>"
134
- else:
135
- return "<LazyIAMClient: 未初始化,将在首次使用时自动初始化>"
136
-
137
-
138
- def get_iam_client() -> ConnectAgenterraIam:
139
- """
140
- 获取全局IAM客户端实例
141
-
142
- Returns:
143
- ConnectAgenterraIam: IAM客户端实例
144
-
145
- Raises:
146
- IAMServiceError: 如果SDK未初始化
147
-
148
- Example:
149
- # 正确的使用方式 - 注意要加括号调用函数
150
- iam_client = get_iam_client() # 正确 ✓
151
- user_info = iam_client.get_user_by_id("user123")
152
-
153
- # 用于登录验证
154
- result = iam_client.login_with_password(
155
- username="test_user",
156
- password="password123"
157
- )
158
-
159
- # 常见错误 - 不要这样做
160
- # iam_client = get_iam_client # 错误 ✗ 缺少括号
161
- # 这会导致 'function' object has no attribute 'login_with_password' 错误
162
-
163
- Note:
164
- 确保在调用此函数前已经通过 init_skyplatform_iam() 初始化了SDK
165
-
166
- Warning:
167
- 避免在模块导入时直接调用此函数,应在函数内部调用以避免初始化顺序问题
168
- """
169
- try:
170
- manager = get_global_manager()
171
- return manager.get_client()
172
- except Exception as e:
173
- # 提供更详细的错误信息和解决建议
174
- error_msg = (
175
- f"获取IAM客户端失败: {str(e)}\n\n"
176
- "解决方案:\n"
177
- "1. 确保在使用IAM客户端前调用 init_skyplatform_iam() 初始化SDK\n"
178
- "2. 避免在模块导入时直接调用 get_iam_client(),应在函数内部调用\n"
179
- "3. 检查初始化顺序,确保SDK在应用启动时正确初始化\n\n"
180
- "正确的使用方式:\n"
181
- "```python\n"
182
- "# 在main.py或应用启动时\n"
183
- "from skyplatform_iam import init_skyplatform_iam\n"
184
- "init_skyplatform_iam(app, config)\n\n"
185
- "# 在业务代码中\n"
186
- "def some_function():\n"
187
- " iam_client = get_iam_client() # 在函数内部调用\n"
188
- " return iam_client.login_with_password(...)\n"
189
- "```\n\n"
190
- "如果需要在模块级别使用IAM客户端,请考虑使用 create_lazy_iam_client() 函数"
191
- )
192
- logger.error(error_msg)
193
- raise IAMServiceError(error_msg)
194
-
195
-
196
- def create_lazy_iam_client() -> LazyIAMClient:
197
- """
198
- 创建懒加载的IAM客户端实例
199
-
200
- 这个函数专门用于解决模块导入时的初始化顺序问题。
201
- 返回的客户端会在首次使用时才进行实际的初始化。
202
-
203
- Returns:
204
- LazyIAMClient: 懒加载的IAM客户端包装器
205
-
206
- Example:
207
- # 在模块级别安全使用(推荐用于解决导入顺序问题)
208
- iam_client = create_lazy_iam_client()
209
-
210
- # 在函数中使用时才会真正初始化
211
- def login_user(username, password):
212
- return iam_client.login_with_password(username, password)
213
-
214
- # 也可以在类中使用
215
- class AuthService:
216
- def __init__(self):
217
- self.iam_client = create_lazy_iam_client()
218
-
219
- def authenticate(self, username, password):
220
- return self.iam_client.login_with_password(username, password)
221
- """
222
- return LazyIAMClient()
223
-
224
-
225
- async def get_current_user_info(request: Request) -> Optional[Dict[str, Any]]:
226
- """
227
- 便捷方法:获取当前用户信息
228
-
229
- Args:
230
- request: FastAPI请求对象
231
-
232
- Returns:
233
- Optional[Dict]: 用户信息字典,如果未登录则返回None
234
-
235
- Raises:
236
- IAMServiceError: 如果SDK未初始化
237
-
238
- Example:
239
- @app.get("/profile")
240
- async def get_profile(request: Request):
241
- user = await get_current_user_info(request)
242
- if not user:
243
- raise HTTPException(401, "未登录")
244
- return {"user": user}
245
- """
246
- try:
247
- manager = get_global_manager()
248
- return await manager.get_current_user_info(request)
249
- except Exception as e:
250
- logger.error(f"获取当前用户信息失败: {str(e)}")
251
- if isinstance(e, IAMServiceError):
252
- raise
253
- return None
254
-
255
-
256
- async def verify_permission(
257
- user_id: str,
258
- permission: str,
259
- resource: Optional[str] = None
260
- ) -> bool:
261
- """
262
- 便捷方法:验证用户权限
263
-
264
- Args:
265
- user_id: 用户ID
266
- permission: 权限标识
267
- resource: 资源标识(可选)
268
-
269
- Returns:
270
- bool: 是否有权限
271
-
272
- Raises:
273
- IAMServiceError: 如果SDK未初始化
274
-
275
- Example:
276
- has_permission = await verify_permission("user123", "read", "document")
277
- if not has_permission:
278
- raise HTTPException(403, "权限不足")
279
- """
280
- try:
281
- manager = get_global_manager()
282
- return await manager.verify_permission(user_id, permission, resource)
283
- except Exception as e:
284
- logger.error(f"权限验证失败: {str(e)}")
285
- if isinstance(e, IAMServiceError):
286
- raise
287
- return False
288
-
289
-
290
- def get_config() -> AuthConfig:
291
- """
292
- 获取当前配置
293
-
294
- Returns:
295
- AuthConfig: 当前认证配置
296
-
297
- Raises:
298
- IAMServiceError: 如果SDK未初始化
299
-
300
- Example:
301
- config = get_config()
302
- print(f"当前服务名: {config.server_name}")
303
- """
304
- try:
305
- manager = get_global_manager()
306
- return manager.get_config()
307
- except Exception as e:
308
- logger.error(f"获取配置失败: {str(e)}")
309
- raise
310
-
311
-
312
- def get_sdk_status() -> Dict[str, Any]:
313
- """
314
- 获取SDK状态信息
315
-
316
- Returns:
317
- Dict: SDK状态信息
318
-
319
- Example:
320
- status = get_sdk_status()
321
- print(f"SDK初始化状态: {status['initialized']}")
322
- """
323
- try:
324
- manager = get_global_manager()
325
- return manager.get_status()
326
- except Exception as e:
327
- logger.error(f"获取SDK状态失败: {str(e)}")
328
- return {
329
- "initialized": False,
330
- "error": str(e)
331
- }
332
-
333
-
334
- def reset_sdk() -> None:
335
- """
336
- 重置SDK状态(主要用于测试)
337
-
338
- Warning:
339
- 此方法会清除所有SDK状态,仅在测试环境中使用
340
- """
341
- logger.warning("重置SDK状态")
342
- try:
343
- manager = get_global_manager()
344
- manager.reset()
345
- logger.info("SDK状态已重置")
346
- except Exception as e:
347
- logger.error(f"重置SDK状态失败: {str(e)}")
348
-
349
-
350
- # 向后兼容的别名
351
- def setup_auth(app: FastAPI, config: Optional[AuthConfig] = None) -> GlobalIAMManager:
352
- """
353
- 向后兼容的初始化函数
354
-
355
- Args:
356
- app: FastAPI应用实例
357
- config: 认证配置
358
-
359
- Returns:
360
- GlobalIAMManager: 全局IAM管理器实例
361
-
362
- Deprecated:
363
- 请使用 init_skyplatform_iam() 替代
364
- """
365
- logger.warning("setup_auth()已废弃,请使用init_skyplatform_iam()替代")
366
- return init_skyplatform_iam(app, config)