skyplatform-iam 1.0.5__py3-none-any.whl → 1.2.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.
@@ -5,6 +5,8 @@ import copy
5
5
  from enum import Enum
6
6
  from fastapi import HTTPException, status
7
7
 
8
+ from .config import decode_jwt_token
9
+
8
10
 
9
11
  class CredentialTypeEnum(str, Enum):
10
12
  """凭证类型枚举,与后端API保持一致"""
@@ -17,7 +19,7 @@ class CredentialTypeEnum(str, Enum):
17
19
  class ConnectAgenterraIam(object):
18
20
  _instance = None
19
21
  _initialized = False
20
-
22
+
21
23
  def __new__(cls, config=None, logger_name="skyplatform_iam", log_level=logging.INFO):
22
24
  """
23
25
  单例模式实现
@@ -26,11 +28,11 @@ class ConnectAgenterraIam(object):
26
28
  if cls._instance is None:
27
29
  cls._instance = super(ConnectAgenterraIam, cls).__new__(cls)
28
30
  return cls._instance
29
-
31
+
30
32
  def __init__(self, config=None, logger_name="skyplatform_iam", log_level=logging.INFO):
31
33
  """
32
34
  初始化AgenterraIAM连接器
33
-
35
+
34
36
  参数:
35
37
  - config: AuthConfig配置对象,如果为None则从环境变量读取
36
38
  - logger_name: 日志记录器名称
@@ -39,7 +41,7 @@ class ConnectAgenterraIam(object):
39
41
  # 防止重复初始化
40
42
  if self._initialized:
41
43
  return
42
-
44
+
43
45
  # 配置日志记录器
44
46
  self.logger = logging.getLogger(logger_name)
45
47
  if not self.logger.handlers:
@@ -50,16 +52,17 @@ class ConnectAgenterraIam(object):
50
52
  handler.setFormatter(formatter)
51
53
  self.logger.addHandler(handler)
52
54
  self.logger.setLevel(log_level)
53
-
55
+
54
56
  # 必须传入config参数,不再支持从环境变量读取
55
57
  if config is None:
56
58
  raise ValueError("必须传入AuthConfig配置对象,不再支持从环境变量读取配置")
57
-
59
+
58
60
  self.agenterra_iam_host = config.agenterra_iam_host
59
61
  self.server_name = config.server_name
60
62
  self.access_key = config.access_key
63
+ self.machine_token = config.machine_token
61
64
  self.logger.info("使用传入的AuthConfig配置")
62
-
65
+
63
66
  # 验证必要的配置
64
67
  if not self.agenterra_iam_host:
65
68
  self.logger.warning("AGENTERRA_IAM_HOST 配置未设置")
@@ -67,9 +70,10 @@ class ConnectAgenterraIam(object):
67
70
  self.logger.warning("AGENTERRA_SERVER_NAME 配置未设置")
68
71
  if not self.access_key:
69
72
  self.logger.warning("AGENTERRA_ACCESS_KEY 配置未设置")
70
-
71
- self.logger.info(f"初始化AgenterraIAM连接器 - Host: {self.agenterra_iam_host}, Server: {self._mask_sensitive(self.server_name)}")
72
-
73
+
74
+ self.logger.info(
75
+ f"初始化AgenterraIAM连接器 - Host: {self.agenterra_iam_host}, Server: {self._mask_sensitive(self.server_name)}")
76
+
73
77
  self.headers = {
74
78
  "Content-Type": "application/json",
75
79
  "SERVER-AK": self.server_name,
@@ -77,77 +81,31 @@ class ConnectAgenterraIam(object):
77
81
  }
78
82
  self.body = {
79
83
  "server_name": self.server_name,
80
- "access_key": self.access_key
84
+ "access_key": self.access_key,
85
+ "machine_token": self.machine_token
81
86
  }
82
-
87
+
83
88
  # 标记为已初始化
84
89
  self._initialized = True
85
90
 
86
- @classmethod
87
- def get_instance(cls):
88
- """
89
- 获取已初始化的ConnectAgenterraIam单例实例
90
-
91
- 如果实例尚未初始化,会抛出异常提示用户先进行配置
92
- 这个方法通常在用户已经通过setup_auth()进行配置后使用
93
-
94
- 返回:
95
- - ConnectAgenterraIam: 已初始化的单例实例
96
-
97
- 异常:
98
- - RuntimeError: 当实例未初始化时抛出
99
- """
100
- if cls._instance is None or not cls._initialized:
101
- raise RuntimeError(
102
- "ConnectAgenterraIam实例尚未初始化。请先使用以下方式之一进行配置:\n"
103
- "1. 使用setup_auth()进行一键配置\n"
104
- "2. 手动创建ConnectAgenterraIam实例:ConnectAgenterraIam(config=your_config)"
105
- )
106
- return cls._instance
107
-
108
- @classmethod
109
- def get_instance_lazy(cls):
110
- """
111
- 获取已初始化的单例实例(延迟模式)
112
-
113
- 此方法支持延迟初始化,当实例未初始化时返回 None 而不是抛出异常。
114
- 适用于在模块导入时需要获取实例但可能尚未初始化的场景。
115
-
116
- 返回:
117
- - ConnectAgenterraIam: 已初始化的单例实例,如果未初始化则返回 None
118
- """
119
- if cls._instance is None or not cls._initialized:
120
- return None
121
- return cls._instance
122
-
123
- @classmethod
124
- def is_initialized(cls):
125
- """
126
- 检查单例实例是否已初始化
127
-
128
- 返回:
129
- - bool: 如果实例已初始化返回 True,否则返回 False
130
- """
131
- return cls._instance is not None and cls._initialized
132
-
133
91
  def reload_config(self, config):
134
92
  """
135
93
  重新加载配置
136
94
  用于在运行时更新配置
137
-
95
+
138
96
  参数:
139
97
  - config: AuthConfig配置对象
140
98
  """
141
99
  if config is None:
142
100
  raise ValueError("必须传入AuthConfig配置对象")
143
-
101
+
144
102
  self.logger.info("重新加载配置")
145
-
103
+
146
104
  # 更新配置
147
105
  self.agenterra_iam_host = config.agenterra_iam_host
148
106
  self.server_name = config.server_name
149
107
  self.access_key = config.access_key
150
-
108
+
151
109
  # 验证必要的配置
152
110
  if not self.agenterra_iam_host:
153
111
  self.logger.warning("AGENTERRA_IAM_HOST 配置未设置")
@@ -155,7 +113,7 @@ class ConnectAgenterraIam(object):
155
113
  self.logger.warning("AGENTERRA_SERVER_NAME 配置未设置")
156
114
  if not self.access_key:
157
115
  self.logger.warning("AGENTERRA_ACCESS_KEY 配置未设置")
158
-
116
+
159
117
  # 更新headers和body
160
118
  self.headers = {
161
119
  "Content-Type": "application/json",
@@ -164,63 +122,65 @@ class ConnectAgenterraIam(object):
164
122
  }
165
123
  self.body = {
166
124
  "server_name": self.server_name,
167
- "access_key": self.access_key
125
+ "access_key": self.access_key,
126
+ "machine_token": self.machine_token,
168
127
  }
169
-
170
- self.logger.info(f"配置重新加载完成 - Host: {self.agenterra_iam_host}, Server: {self._mask_sensitive(self.server_name)}")
128
+
129
+ self.logger.info(
130
+ f"配置重新加载完成 - Host: {self.agenterra_iam_host}, Server: {self._mask_sensitive(self.server_name)}")
171
131
 
172
132
  def _mask_sensitive(self, value, mask_char="*", show_chars=4):
173
133
  """
174
134
  脱敏处理敏感信息
175
-
135
+
176
136
  参数:
177
137
  - value: 要脱敏的值
178
138
  - mask_char: 脱敏字符
179
139
  - show_chars: 显示的字符数量
180
-
140
+
181
141
  返回: 脱敏后的字符串
182
142
  """
183
143
  if not value or not isinstance(value, str):
184
144
  return str(value) if value else "None"
185
-
145
+
186
146
  if len(value) <= show_chars:
187
147
  return mask_char * len(value)
188
-
148
+
189
149
  return value[:show_chars] + mask_char * (len(value) - show_chars)
190
150
 
191
151
  def _sanitize_log_data(self, data):
192
152
  """
193
153
  清理日志数据,脱敏敏感信息
194
-
154
+
195
155
  参数:
196
156
  - data: 要清理的数据(字典或其他类型)
197
-
157
+
198
158
  返回: 清理后的数据
199
159
  """
200
160
  if not isinstance(data, dict):
201
161
  return data
202
-
162
+
203
163
  # 需要脱敏的字段列表
204
164
  sensitive_fields = [
205
- 'password', 'access_key', 'token', 'refresh_token',
165
+ 'password', 'access_key', 'token', 'refresh_token',
206
166
  'SERVER-SK', 'new_password', 'server_sk'
207
167
  ]
208
-
168
+
209
169
  sanitized = copy.deepcopy(data)
210
-
170
+
211
171
  for key, value in sanitized.items():
212
172
  if key.lower() in [field.lower() for field in sensitive_fields]:
213
173
  sanitized[key] = self._mask_sensitive(str(value))
214
174
  elif isinstance(value, dict):
215
175
  sanitized[key] = self._sanitize_log_data(value)
216
-
176
+
217
177
  return sanitized
218
178
 
219
179
  def _log_request(self, method_name, url, headers, body):
220
180
  """记录请求信息"""
221
181
  sanitized_headers = self._sanitize_log_data(headers)
222
182
  sanitized_body = self._sanitize_log_data(body)
223
-
183
+
224
184
  self.logger.info(f"[{method_name}] 发送请求 - URL: {url}")
225
185
  self.logger.info(f"[{method_name}] 请求头: {sanitized_headers}")
226
186
  self.logger.info(f"[{method_name}] 请求体: {sanitized_body}")
@@ -236,7 +196,7 @@ class ConnectAgenterraIam(object):
236
196
  self.logger.info(f"[{method_name}] 响应状态码: {response.status_code}")
237
197
  self.logger.info(f"[{method_name}] 响应内容解析失败: {str(e)}")
238
198
 
239
- def register(self, cred_type=None, cred_value=None, password=None, nickname=None, avatar_url=None,
199
+ def register(self, cred_type=None, cred_value=None, password=None, nickname=None, avatar_url=None,
240
200
  username=None, phone=None):
241
201
  """
242
202
  注册用户时,同步至iam
@@ -259,8 +219,9 @@ class ConnectAgenterraIam(object):
259
219
  - 失败: 返回False
260
220
  """
261
221
  method_name = "register"
262
- self.logger.info(f"[{method_name}] 开始用户注册 - cred_type: {cred_type}, cred_value: {self._mask_sensitive(str(cred_value))}")
263
-
222
+ self.logger.info(
223
+ f"[{method_name}] 开始用户注册 - cred_type: {cred_type}, cred_value: {self._mask_sensitive(str(cred_value))}")
224
+
264
225
  try:
265
226
  # 参数映射:支持旧的调用方式
266
227
  if cred_type is None and cred_value is None:
@@ -296,10 +257,10 @@ class ConnectAgenterraIam(object):
296
257
 
297
258
  uri = "/api/v2/service/register"
298
259
  url = self.agenterra_iam_host + uri
299
-
260
+
300
261
  # 记录请求信息
301
262
  self._log_request(method_name, url, self.headers, body)
302
-
263
+
303
264
  response = requests.post(
304
265
  url=url,
305
266
  headers=self.headers,
@@ -319,7 +280,7 @@ class ConnectAgenterraIam(object):
319
280
  self.logger.warning(f"[{method_name}] 用户注册失败 - 响应: {result}")
320
281
  else:
321
282
  self.logger.warning(f"[{method_name}] 用户注册失败 - 状态码: {response.status_code}")
322
-
283
+
323
284
  return False
324
285
  except Exception as e:
325
286
  self.logger.error(f"[{method_name}] 注册请求异常: {str(e)}")
@@ -327,7 +288,7 @@ class ConnectAgenterraIam(object):
327
288
  return False
328
289
 
329
290
  def login_with_password(self, cred_type=None, cred_value=None, password=None, ip_address=None, user_agent=None,
330
- username=None):
291
+ username=None):
331
292
  """
332
293
  账号密码登陆时,同步至iam,由iam签发token
333
294
 
@@ -343,8 +304,9 @@ class ConnectAgenterraIam(object):
343
304
  - password: 用户密码
344
305
  """
345
306
  method_name = "login_with_password"
346
- self.logger.info(f"[{method_name}] 开始密码登录 - cred_type: {cred_type}, cred_value: {self._mask_sensitive(str(cred_value))}")
347
-
307
+ self.logger.info(
308
+ f"[{method_name}] 开始密码登录 - cred_type: {cred_type}, cred_value: {self._mask_sensitive(str(cred_value))}")
309
+
348
310
  try:
349
311
  # 参数映射:支持旧的调用方式
350
312
  if cred_type is None and cred_value is None:
@@ -375,10 +337,10 @@ class ConnectAgenterraIam(object):
375
337
 
376
338
  uri = "/api/v2/service/login"
377
339
  url = self.agenterra_iam_host + uri
378
-
340
+
379
341
  # 记录请求信息
380
342
  self._log_request(method_name, url, self.headers, body)
381
-
343
+
382
344
  response = requests.post(
383
345
  url=url,
384
346
  headers=self.headers,
@@ -391,10 +353,15 @@ class ConnectAgenterraIam(object):
391
353
 
392
354
  if response.status_code == 200:
393
355
  self.logger.info(f"[{method_name}] 密码登录成功")
356
+ data = response.json()["data"]
357
+ access_token = data["access_token"]
358
+ payload = decode_jwt_token(access_token)
359
+ self.machine_token = payload["machine_access_token"]
360
+
394
361
  return response
395
362
  else:
396
363
  self.logger.warning(f"[{method_name}] 密码登录失败 - 状态码: {response.status_code}")
397
-
364
+
398
365
  return False
399
366
  except Exception as e:
400
367
  self.logger.error(f"[{method_name}] 密码登录请求异常: {str(e)}")
@@ -402,7 +369,7 @@ class ConnectAgenterraIam(object):
402
369
  return False
403
370
 
404
371
  def login_without_password(self, cred_type=None, cred_value=None, ip_address=None, user_agent=None,
405
- username=None):
372
+ username=None):
406
373
  """
407
374
  短信验证码登陆时,机机接口请求token
408
375
 
@@ -418,8 +385,9 @@ class ConnectAgenterraIam(object):
418
385
  返回: response对象或False
419
386
  """
420
387
  method_name = "login_without_password"
421
- self.logger.info(f"[{method_name}] 开始免密登录 - cred_type: {cred_type}, cred_value: {self._mask_sensitive(str(cred_value))}")
422
-
388
+ self.logger.info(
389
+ f"[{method_name}] 开始免密登录 - cred_type: {cred_type}, cred_value: {self._mask_sensitive(str(cred_value))}")
390
+
423
391
  try:
424
392
  # 参数映射:支持旧的调用方式
425
393
  if cred_type is None and cred_value is None:
@@ -449,10 +417,10 @@ class ConnectAgenterraIam(object):
449
417
 
450
418
  uri = "/api/v2/service/login_without_password"
451
419
  url = self.agenterra_iam_host + uri
452
-
420
+
453
421
  # 记录请求信息
454
422
  self._log_request(method_name, url, self.headers, body)
455
-
423
+
456
424
  response = requests.post(
457
425
  url=url,
458
426
  headers=self.headers,
@@ -468,7 +436,7 @@ class ConnectAgenterraIam(object):
468
436
  return response
469
437
  else:
470
438
  self.logger.warning(f"[{method_name}] 免密登录失败 - 状态码: {response.status_code}")
471
-
439
+
472
440
  return False
473
441
  except Exception as e:
474
442
  self.logger.error(f"[{method_name}] 免密登录请求异常: {str(e)}")
@@ -483,7 +451,7 @@ class ConnectAgenterraIam(object):
483
451
  """
484
452
  method_name = "logout"
485
453
  self.logger.info(f"[{method_name}] 开始用户登出 - token: {self._mask_sensitive(token)}")
486
-
454
+
487
455
  try:
488
456
  body = {
489
457
  "server_name": self.server_name,
@@ -492,13 +460,16 @@ class ConnectAgenterraIam(object):
492
460
  }
493
461
  uri = "/api/v2/service/logout"
494
462
  url = self.agenterra_iam_host + uri
495
-
463
+
496
464
  # 记录请求信息
497
465
  self._log_request(method_name, url, self.headers, body)
498
466
 
467
+ headers = self.headers.copy()
468
+ headers['MACHINE-TOKEN'] = self.machine_token
469
+
499
470
  response = requests.post(
500
471
  url=url,
501
- headers=self.headers,
472
+ headers=headers,
502
473
  json=body,
503
474
  verify=False
504
475
  )
@@ -511,14 +482,14 @@ class ConnectAgenterraIam(object):
511
482
  return True
512
483
  else:
513
484
  self.logger.warning(f"[{method_name}] 用户登出失败 - 状态码: {response.status_code}")
514
-
485
+
515
486
  return False
516
487
  except Exception as e:
517
488
  self.logger.error(f"[{method_name}] 登出请求异常: {str(e)}")
518
489
  self.logger.error(f"[{method_name}] 异常堆栈: {traceback.format_exc()}")
519
490
  return False
520
491
 
521
- def verify_token(self, token, api, method, server_ak="", server_sk=""):
492
+ def verify_token(self, token, api, method, server_ak="", server_sk="", machine_token=""):
522
493
  """
523
494
  请求iam进行鉴权
524
495
  server_name: 服务名称
@@ -531,12 +502,14 @@ class ConnectAgenterraIam(object):
531
502
  - token无效或其他错误: 返回None
532
503
  """
533
504
  method_name = "verify_token"
534
- self.logger.info(f"[{method_name}] 开始token验证 - api: {api}, method: {method}, token: {self._mask_sensitive(token)}")
535
-
505
+ self.logger.info(
506
+ f"[{method_name}] 开始token验证 - api: {api}, method: {method}, token: {self._mask_sensitive(token)}")
507
+
536
508
  try:
537
509
  body = {
538
510
  "server_name": self.server_name,
539
511
  "access_key": self.access_key,
512
+ "machine_token": machine_token if machine_token else self.machine_token,
540
513
  "token": token,
541
514
  "api": api,
542
515
  "method": method,
@@ -544,16 +517,16 @@ class ConnectAgenterraIam(object):
544
517
  "server_sk": server_sk,
545
518
  }
546
519
  uri = "/api/v2/service/verify"
547
-
520
+
548
521
  # 检查agenterra_iam_host是否为None
549
522
  if self.agenterra_iam_host is None:
550
523
  raise ValueError("AGENTERRA_IAM_HOST 配置未设置或为空,请确保传入正确的AuthConfig对象")
551
-
524
+
552
525
  url = self.agenterra_iam_host + uri
553
-
526
+
554
527
  # 记录请求信息
555
528
  self._log_request(method_name, url, self.headers, body)
556
-
529
+
557
530
  response = requests.post(
558
531
  url=url,
559
532
  headers=self.headers,
@@ -577,7 +550,8 @@ class ConnectAgenterraIam(object):
577
550
  "microservice": result.get("microservice"),
578
551
  "is_whitelist": result.get("is_whitelist", False)
579
552
  }
580
- self.logger.info(f"[{method_name}] token验证成功,用户有权限 - user_id: {user_info.get('user_id')}")
553
+ self.logger.info(
554
+ f"[{method_name}] token验证成功,用户有权限 - user_id: {user_info.get('user_id')}")
581
555
  return user_info
582
556
  else:
583
557
  # token有效但无权限,抛出403异常
@@ -587,7 +561,8 @@ class ConnectAgenterraIam(object):
587
561
  detail=result.get("message", "用户无权限访问此API")
588
562
  )
589
563
  else:
590
- self.logger.warning(f"[{method_name}] token验证失败 - success: {result.get('success')}, valid: {result.get('valid')}")
564
+ self.logger.warning(
565
+ f"[{method_name}] token验证失败 - success: {result.get('success')}, valid: {result.get('valid')}")
591
566
 
592
567
  elif response.status_code == 403:
593
568
  result = response.json()
@@ -623,11 +598,11 @@ class ConnectAgenterraIam(object):
623
598
  """
624
599
  method_name = "reset_password"
625
600
  self.logger.info(f"[{method_name}] 开始重置密码 - user_id: {user_id}")
626
-
601
+
627
602
  # 记录旧参数格式的使用
628
603
  if username or password:
629
604
  self.logger.debug(f"[{method_name}] 检测到旧参数格式 - username: {username}")
630
-
605
+
631
606
  try:
632
607
  # 参数映射:支持旧的调用方式
633
608
  if user_id is None and new_password is None:
@@ -641,31 +616,32 @@ class ConnectAgenterraIam(object):
641
616
  body = {
642
617
  "server_name": self.server_name,
643
618
  "access_key": self.access_key,
619
+ "machine_token": self.machine_token,
644
620
  "user_id": user_id,
645
621
  "new_password": new_password
646
622
  }
647
623
  uri = "/api/v2/service/reset_password"
648
624
  url = self.agenterra_iam_host + uri
649
-
625
+
650
626
  # 记录请求信息
651
627
  self._log_request(method_name, url, self.headers, body)
652
-
628
+
653
629
  response = requests.post(
654
630
  url=url,
655
631
  headers=self.headers,
656
632
  json=body,
657
633
  verify=False
658
634
  )
659
-
635
+
660
636
  # 记录响应信息
661
637
  self._log_response(method_name, response)
662
-
638
+
663
639
  if response.status_code == 200:
664
640
  self.logger.info(f"[{method_name}] 密码重置成功")
665
641
  return True
666
642
  else:
667
643
  self.logger.warning(f"[{method_name}] 密码重置失败 - 状态码: {response.status_code}")
668
-
644
+
669
645
  return False
670
646
  except Exception as e:
671
647
  self.logger.error(f"[{method_name}] 重置密码请求异常: {str(e)}")
@@ -683,19 +659,20 @@ class ConnectAgenterraIam(object):
683
659
  """
684
660
  method_name = "refresh_token"
685
661
  self.logger.info(f"[{method_name}] 开始刷新令牌 - refresh_token: {self._mask_sensitive(refresh_token)}")
686
-
662
+
687
663
  try:
688
664
  body = {
689
665
  "server_name": self.server_name,
690
666
  "access_key": self.access_key,
667
+ "machine_token": self.machine_token,
691
668
  "refresh_token": refresh_token
692
669
  }
693
670
  uri = "/api/v2/service/refresh_token"
694
671
  url = self.agenterra_iam_host + uri
695
-
672
+
696
673
  # 记录请求信息
697
674
  self._log_request(method_name, url, self.headers, body)
698
-
675
+
699
676
  response = requests.post(
700
677
  url=url,
701
678
  headers=self.headers,
@@ -711,7 +688,7 @@ class ConnectAgenterraIam(object):
711
688
  return response
712
689
  else:
713
690
  self.logger.warning(f"[{method_name}] 令牌刷新失败 - 状态码: {response.status_code}")
714
-
691
+
715
692
  return False
716
693
  except Exception as e:
717
694
  self.logger.error(f"[{method_name}] 刷新令牌请求异常: {str(e)}")
@@ -730,20 +707,21 @@ class ConnectAgenterraIam(object):
730
707
  """
731
708
  method_name = "assign_role_to_user"
732
709
  self.logger.info(f"[{method_name}] 开始角色分配 - user_id: {user_id}, role_id: {role_id}")
733
-
710
+
734
711
  try:
735
712
  body = {
736
713
  "server_name": self.server_name,
737
714
  "access_key": self.access_key,
715
+ "machine_token": self.machine_token,
738
716
  "user_id": user_id,
739
717
  "role_id": role_id
740
718
  }
741
719
  uri = "/api/v2/service/assign_role"
742
720
  url = self.agenterra_iam_host + uri
743
-
721
+
744
722
  # 记录请求信息
745
723
  self._log_request(method_name, url, self.headers, body)
746
-
724
+
747
725
  response = requests.post(
748
726
  url=url,
749
727
  headers=self.headers,
@@ -759,7 +737,7 @@ class ConnectAgenterraIam(object):
759
737
  return True
760
738
  else:
761
739
  self.logger.warning(f"[{method_name}] 角色分配失败 - 状态码: {response.status_code}")
762
-
740
+
763
741
  return False
764
742
  except Exception as e:
765
743
  self.logger.error(f"[{method_name}] 角色分配请求异常: {str(e)}")
@@ -772,19 +750,20 @@ class ConnectAgenterraIam(object):
772
750
  """
773
751
  method_name = "get_userinfo_by_token"
774
752
  self.logger.info(f"[{method_name}] 开始获取用户信息 - token: {self._mask_sensitive(token)}")
775
-
753
+
776
754
  try:
777
755
  body = {
778
756
  "server_name": self.server_name,
779
757
  "access_key": self.access_key,
758
+ "machine_token": self.machine_token,
780
759
  "token": token,
781
760
  }
782
761
  uri = "/api/v2/service/token"
783
762
  url = self.agenterra_iam_host + uri
784
-
763
+
785
764
  # 记录请求信息
786
765
  self._log_request(method_name, url, self.headers, body)
787
-
766
+
788
767
  response = requests.post(
789
768
  url=url,
790
769
  headers=self.headers,
@@ -800,7 +779,7 @@ class ConnectAgenterraIam(object):
800
779
  return response
801
780
  else:
802
781
  self.logger.warning(f"[{method_name}] 获取用户信息失败 - 状态码: {response.status_code}")
803
-
782
+
804
783
  return False
805
784
  except Exception as e:
806
785
  self.logger.error(f"[{method_name}] 获取用户信息请求异常: {str(e)}")
@@ -810,7 +789,7 @@ class ConnectAgenterraIam(object):
810
789
  def add_custom_config(self, user_id, config_name, config_value=None):
811
790
  """
812
791
  机机接口:添加用户自定义配置
813
-
792
+
814
793
  为指定用户添加或更新自定义属性配置。
815
794
 
816
795
  参数:
@@ -818,17 +797,18 @@ class ConnectAgenterraIam(object):
818
797
  - config_name: 配置项名称
819
798
  - config_value: 配置项值(可选)
820
799
 
821
- 返回:
800
+ 返回:
822
801
  - 成功: 返回响应对象
823
802
  - 失败: 返回False
824
803
  """
825
804
  method_name = "add_custom_config"
826
805
  self.logger.info(f"[{method_name}] 开始添加用户自定义配置 - user_id: {user_id}, config_name: {config_name}")
827
-
806
+
828
807
  try:
829
808
  body = {
830
809
  "server_name": self.server_name,
831
810
  "access_key": self.access_key,
811
+ "machine_token": self.machine_token,
832
812
  "user_id": user_id,
833
813
  "config_name": config_name
834
814
  }
@@ -839,10 +819,10 @@ class ConnectAgenterraIam(object):
839
819
 
840
820
  uri = "/api/v2/service/add_custom_config"
841
821
  url = self.agenterra_iam_host + uri
842
-
822
+
843
823
  # 记录请求信息
844
824
  self._log_request(method_name, url, self.headers, body)
845
-
825
+
846
826
  response = requests.post(
847
827
  url=url,
848
828
  headers=self.headers,
@@ -858,7 +838,7 @@ class ConnectAgenterraIam(object):
858
838
  return response
859
839
  else:
860
840
  self.logger.warning(f"[{method_name}] 添加用户自定义配置失败 - 状态码: {response.status_code}")
861
-
841
+
862
842
  return False
863
843
  except Exception as e:
864
844
  self.logger.error(f"[{method_name}] 添加用户自定义配置请求异常: {str(e)}")
@@ -868,32 +848,33 @@ class ConnectAgenterraIam(object):
868
848
  def get_custom_configs(self, user_id):
869
849
  """
870
850
  机机接口:获取用户自定义配置
871
-
851
+
872
852
  获取指定用户的所有自定义属性配置。
873
853
 
874
854
  参数:
875
855
  - user_id: 用户ID
876
856
 
877
- 返回:
857
+ 返回:
878
858
  - 成功: 返回响应对象
879
859
  - 失败: 返回False
880
860
  """
881
861
  method_name = "get_custom_configs"
882
862
  self.logger.info(f"[{method_name}] 开始获取用户自定义配置 - user_id: {user_id}")
883
-
863
+
884
864
  try:
885
865
  body = {
886
866
  "server_name": self.server_name,
887
867
  "access_key": self.access_key,
868
+ "machine_token": self.machine_token,
888
869
  "user_id": user_id
889
870
  }
890
871
 
891
872
  uri = "/api/v2/service/get_custom_configs"
892
873
  url = self.agenterra_iam_host + uri
893
-
874
+
894
875
  # 记录请求信息
895
876
  self._log_request(method_name, url, self.headers, body)
896
-
877
+
897
878
  response = requests.post(
898
879
  url=url,
899
880
  headers=self.headers,
@@ -909,7 +890,7 @@ class ConnectAgenterraIam(object):
909
890
  return response
910
891
  else:
911
892
  self.logger.warning(f"[{method_name}] 获取用户自定义配置失败 - 状态码: {response.status_code}")
912
-
893
+
913
894
  return False
914
895
  except Exception as e:
915
896
  self.logger.error(f"[{method_name}] 获取用户自定义配置请求异常: {str(e)}")
@@ -919,34 +900,35 @@ class ConnectAgenterraIam(object):
919
900
  def delete_custom_config(self, user_id, config_name):
920
901
  """
921
902
  机机接口:删除用户自定义配置
922
-
903
+
923
904
  删除指定用户的指定自定义属性配置。
924
905
 
925
906
  参数:
926
907
  - user_id: 用户ID
927
908
  - config_name: 配置项名称
928
909
 
929
- 返回:
910
+ 返回:
930
911
  - 成功: 返回响应对象
931
912
  - 失败: 返回False
932
913
  """
933
914
  method_name = "delete_custom_config"
934
915
  self.logger.info(f"[{method_name}] 开始删除用户自定义配置 - user_id: {user_id}, config_name: {config_name}")
935
-
916
+
936
917
  try:
937
918
  body = {
938
919
  "server_name": self.server_name,
939
920
  "access_key": self.access_key,
921
+ "machine_token": self.machine_token,
940
922
  "user_id": user_id,
941
923
  "config_name": config_name
942
924
  }
943
925
 
944
926
  uri = "/api/v2/service/delete_custom_config"
945
927
  url = self.agenterra_iam_host + uri
946
-
928
+
947
929
  # 记录请求信息
948
930
  self._log_request(method_name, url, self.headers, body)
949
-
931
+
950
932
  response = requests.post(
951
933
  url=url,
952
934
  headers=self.headers,
@@ -962,7 +944,7 @@ class ConnectAgenterraIam(object):
962
944
  return response
963
945
  else:
964
946
  self.logger.warning(f"[{method_name}] 删除用户自定义配置失败 - 状态码: {response.status_code}")
965
-
947
+
966
948
  return False
967
949
  except Exception as e:
968
950
  self.logger.error(f"[{method_name}] 删除用户自定义配置请求异常: {str(e)}")
@@ -972,7 +954,7 @@ class ConnectAgenterraIam(object):
972
954
  def merge_credential(self, target_user_id, cred_type, cred_value, merge_reason=None):
973
955
  """
974
956
  机机接口:凭证合并
975
-
957
+
976
958
  为第三方服务提供凭证合并功能,处理用户绑定新凭证时的账号合并场景。
977
959
  例如用户先用账号密码注册,后续又绑定手机号时的账号合并需求。
978
960
 
@@ -982,13 +964,14 @@ class ConnectAgenterraIam(object):
982
964
  - cred_value: 要绑定的凭证值
983
965
  - merge_reason: 合并原因(可选)
984
966
 
985
- 返回:
967
+ 返回:
986
968
  - 成功: 返回响应对象
987
969
  - 失败: 返回False
988
970
  """
989
971
  method_name = "merge_credential"
990
- self.logger.info(f"[{method_name}] 开始凭证合并 - target_user_id: {target_user_id}, cred_type: {cred_type}, cred_value: {self._mask_sensitive(cred_value)}")
991
-
972
+ self.logger.info(
973
+ f"[{method_name}] 开始凭证合并 - target_user_id: {target_user_id}, cred_type: {cred_type}, cred_value: {self._mask_sensitive(cred_value)}")
974
+
992
975
  try:
993
976
  # 验证凭证类型
994
977
  if isinstance(cred_type, str):
@@ -997,6 +980,7 @@ class ConnectAgenterraIam(object):
997
980
  body = {
998
981
  "server_name": self.server_name,
999
982
  "access_key": self.access_key,
983
+ "machine_token": self.machine_token,
1000
984
  "target_user_id": target_user_id,
1001
985
  "cred_type": cred_type.value,
1002
986
  "cred_value": cred_value
@@ -1009,10 +993,10 @@ class ConnectAgenterraIam(object):
1009
993
 
1010
994
  uri = "/api/v2/service/merge_credential"
1011
995
  url = self.agenterra_iam_host + uri
1012
-
996
+
1013
997
  # 记录请求信息
1014
998
  self._log_request(method_name, url, self.headers, body)
1015
-
999
+
1016
1000
  response = requests.post(
1017
1001
  url=url,
1018
1002
  headers=self.headers,
@@ -1028,7 +1012,7 @@ class ConnectAgenterraIam(object):
1028
1012
  return response
1029
1013
  else:
1030
1014
  self.logger.warning(f"[{method_name}] 凭证合并失败 - 状态码: {response.status_code}")
1031
-
1015
+
1032
1016
  return False
1033
1017
  except Exception as e:
1034
1018
  self.logger.error(f"[{method_name}] 凭证合并请求异常: {str(e)}")
@@ -1038,20 +1022,21 @@ class ConnectAgenterraIam(object):
1038
1022
  def get_user_by_credential(self, cred_type, cred_value):
1039
1023
  """
1040
1024
  机机接口:通过凭证获取用户信息
1041
-
1025
+
1042
1026
  为第三方服务提供通过用户名或手机号等认证凭据获取用户信息的功能。
1043
1027
 
1044
1028
  参数:
1045
1029
  - cred_type: 凭证类型 (CredentialTypeEnum: username, email, phone, wechat_openid)
1046
1030
  - cred_value: 凭证值
1047
1031
 
1048
- 返回:
1032
+ 返回:
1049
1033
  - 成功: 返回响应对象
1050
1034
  - 失败: 返回False
1051
1035
  """
1052
1036
  method_name = "get_user_by_credential"
1053
- self.logger.info(f"[{method_name}] 开始获取用户信息 - cred_type: {cred_type}, cred_value: {self._mask_sensitive(cred_value)}")
1054
-
1037
+ self.logger.info(
1038
+ f"[{method_name}] 开始获取用户信息 - cred_type: {cred_type}, cred_value: {self._mask_sensitive(cred_value)}")
1039
+
1055
1040
  try:
1056
1041
  # 验证凭证类型
1057
1042
  if isinstance(cred_type, str):
@@ -1060,16 +1045,17 @@ class ConnectAgenterraIam(object):
1060
1045
  body = {
1061
1046
  "server_name": self.server_name,
1062
1047
  "access_key": self.access_key,
1048
+ "machine_token": self.machine_token,
1063
1049
  "cred_type": cred_type.value,
1064
1050
  "cred_value": cred_value
1065
1051
  }
1066
1052
 
1067
1053
  uri = "/api/v2/service/get_user_by_credential"
1068
1054
  url = self.agenterra_iam_host + uri
1069
-
1055
+
1070
1056
  # 记录请求信息
1071
1057
  self._log_request(method_name, url, self.headers, body)
1072
-
1058
+
1073
1059
  response = requests.post(
1074
1060
  url=url,
1075
1061
  headers=self.headers,
@@ -1085,7 +1071,7 @@ class ConnectAgenterraIam(object):
1085
1071
  return response
1086
1072
  else:
1087
1073
  self.logger.warning(f"[{method_name}] 获取用户信息失败 - 状态码: {response.status_code}")
1088
-
1074
+
1089
1075
  return False
1090
1076
  except Exception as e:
1091
1077
  self.logger.error(f"[{method_name}] 获取用户信息请求异常: {str(e)}")