tccli 3.0.1216.1__py2.py3-none-any.whl → 3.0.1217.1__py2.py3-none-any.whl

Sign up to get free protection for your applications and to get access to all the features.
Files changed (252) hide show
  1. tccli/__init__.py +1 -1
  2. tccli/argparser.py +1 -1
  3. tccli/command.py +2 -2
  4. tccli/credentials.py +25 -0
  5. tccli/main.py +6 -2
  6. tccli/plugins/sso/__init__.py +61 -0
  7. tccli/plugins/sso/configs.py +4 -0
  8. tccli/plugins/sso/configure.py +45 -0
  9. tccli/plugins/sso/login.py +144 -0
  10. tccli/plugins/sso/logout.py +21 -0
  11. tccli/plugins/sso/terminal.py +161 -0
  12. tccli/plugins/sso/texts.py +40 -0
  13. tccli/services/__init__.py +6 -0
  14. tccli/services/acp/v20220105/api.json +7 -7
  15. tccli/services/acp/v20220105/examples.json +2 -2
  16. tccli/services/aiart/v20221229/api.json +29 -29
  17. tccli/services/aiart/v20221229/examples.json +8 -8
  18. tccli/services/apigateway/v20180808/api.json +18 -17
  19. tccli/services/apigateway/v20180808/examples.json +12 -12
  20. tccli/services/apm/v20210622/api.json +98 -4
  21. tccli/services/asr/v20190614/api.json +18 -17
  22. tccli/services/asr/v20190614/examples.json +13 -13
  23. tccli/services/autoscaling/v20180419/api.json +371 -309
  24. tccli/services/autoscaling/v20180419/examples.json +17 -17
  25. tccli/services/batch/v20170312/api.json +7 -7
  26. tccli/services/bda/v20200324/api.json +39 -31
  27. tccli/services/bda/v20200324/examples.json +9 -9
  28. tccli/services/bh/__init__.py +4 -0
  29. tccli/services/bh/bh_client.py +3428 -0
  30. tccli/services/bh/v20230418/api.json +8180 -0
  31. tccli/services/bh/v20230418/examples.json +519 -0
  32. tccli/services/bi/v20220105/api.json +48 -0
  33. tccli/services/billing/v20180709/api.json +26 -24
  34. tccli/services/bsca/v20210811/api.json +1 -1
  35. tccli/services/btoe/v20210514/api.json +4 -4
  36. tccli/services/btoe/v20210514/examples.json +2 -2
  37. tccli/services/ca/v20230228/api.json +60 -0
  38. tccli/services/cam/v20190116/api.json +11 -11
  39. tccli/services/cat/v20180409/api.json +9 -0
  40. tccli/services/cbs/v20170312/api.json +200 -188
  41. tccli/services/cbs/v20170312/examples.json +4 -4
  42. tccli/services/ccc/v20200210/api.json +390 -323
  43. tccli/services/ccc/v20200210/examples.json +15 -15
  44. tccli/services/cdb/cdb_client.py +13 -13
  45. tccli/services/cdb/v20170320/api.json +295 -270
  46. tccli/services/cdb/v20170320/examples.json +38 -38
  47. tccli/services/cdc/v20201214/api.json +283 -270
  48. tccli/services/cdc/v20201214/examples.json +26 -26
  49. tccli/services/cds/v20180420/api.json +82 -76
  50. tccli/services/cds/v20180420/examples.json +1 -1
  51. tccli/services/cdwch/v20200915/api.json +1 -1
  52. tccli/services/cdwdoris/v20211228/api.json +42 -2
  53. tccli/services/cdz/v20221123/api.json +41 -5
  54. tccli/services/cfg/v20210820/api.json +31 -0
  55. tccli/services/cfs/v20190719/api.json +89 -1
  56. tccli/services/cfs/v20190719/examples.json +1 -1
  57. tccli/services/cfw/cfw_client.py +0 -53
  58. tccli/services/cfw/v20190904/api.json +1849 -1999
  59. tccli/services/cfw/v20190904/examples.json +157 -159
  60. tccli/services/ckafka/v20190819/api.json +104 -75
  61. tccli/services/clb/v20180317/api.json +48 -26
  62. tccli/services/clb/v20180317/examples.json +1 -1
  63. tccli/services/cloudapp/v20220530/api.json +5 -1
  64. tccli/services/cloudaudit/v20190319/api.json +58 -44
  65. tccli/services/cloudaudit/v20190319/examples.json +6 -6
  66. tccli/services/cloudstudio/v20230508/api.json +38 -37
  67. tccli/services/cloudstudio/v20230508/examples.json +4 -4
  68. tccli/services/cls/cls_client.py +216 -4
  69. tccli/services/cls/v20201016/api.json +536 -47
  70. tccli/services/cls/v20201016/examples.json +34 -2
  71. tccli/services/csip/v20221121/api.json +2562 -2382
  72. tccli/services/csip/v20221121/examples.json +108 -108
  73. tccli/services/cvm/v20170312/api.json +149 -112
  74. tccli/services/cvm/v20170312/examples.json +2 -2
  75. tccli/services/cwp/cwp_client.py +4 -110
  76. tccli/services/cwp/v20180228/api.json +6338 -6146
  77. tccli/services/cwp/v20180228/examples.json +342 -370
  78. tccli/services/cynosdb/v20190107/api.json +93 -81
  79. tccli/services/cynosdb/v20190107/examples.json +70 -70
  80. tccli/services/dasb/v20191018/api.json +796 -651
  81. tccli/services/dasb/v20191018/examples.json +101 -101
  82. tccli/services/dcdb/dcdb_client.py +114 -61
  83. tccli/services/dcdb/v20180411/api.json +141 -7
  84. tccli/services/dcdb/v20180411/examples.json +32 -0
  85. tccli/services/dlc/v20210125/api.json +21 -11
  86. tccli/services/dnspod/dnspod_client.py +417 -46
  87. tccli/services/dnspod/v20210323/api.json +751 -30
  88. tccli/services/dnspod/v20210323/examples.json +62 -0
  89. tccli/services/dts/v20211206/api.json +4 -4
  90. tccli/services/ecm/v20190719/api.json +2 -2
  91. tccli/services/emr/v20190103/api.json +339 -114
  92. tccli/services/emr/v20190103/examples.json +64 -82
  93. tccli/services/es/v20180416/api.json +29 -0
  94. tccli/services/es/v20180416/examples.json +1 -1
  95. tccli/services/ess/v20201111/api.json +49 -31
  96. tccli/services/ess/v20201111/examples.json +20 -8
  97. tccli/services/essbasic/v20210526/api.json +54 -49
  98. tccli/services/essbasic/v20210526/examples.json +36 -18
  99. tccli/services/facefusion/v20181201/api.json +47 -45
  100. tccli/services/facefusion/v20181201/examples.json +2 -2
  101. tccli/services/facefusion/v20220927/api.json +54 -48
  102. tccli/services/facefusion/v20220927/examples.json +5 -5
  103. tccli/services/faceid/v20180301/api.json +497 -496
  104. tccli/services/faceid/v20180301/examples.json +219 -101
  105. tccli/services/fmu/v20191213/api.json +59 -67
  106. tccli/services/fmu/v20191213/examples.json +22 -22
  107. tccli/services/ft/v20200304/api.json +53 -57
  108. tccli/services/ft/v20200304/examples.json +14 -14
  109. tccli/services/gme/v20180711/api.json +21 -11
  110. tccli/services/gme/v20180711/examples.json +1 -1
  111. tccli/services/hai/v20230812/api.json +116 -9
  112. tccli/services/hai/v20230812/examples.json +4 -4
  113. tccli/services/hunyuan/hunyuan_client.py +436 -12
  114. tccli/services/hunyuan/v20230901/api.json +1482 -118
  115. tccli/services/hunyuan/v20230901/examples.json +82 -18
  116. tccli/services/iai/v20180301/api.json +23 -19
  117. tccli/services/iai/v20180301/examples.json +2 -2
  118. tccli/services/iai/v20200303/api.json +530 -511
  119. tccli/services/iai/v20200303/examples.json +116 -86
  120. tccli/services/ig/__init__.py +4 -0
  121. tccli/services/ig/ig_client.py +195 -0
  122. tccli/services/ig/v20210518/api.json +83 -0
  123. tccli/services/ig/v20210518/examples.json +13 -0
  124. tccli/services/ioa/ioa_client.py +53 -0
  125. tccli/services/ioa/v20220601/api.json +662 -413
  126. tccli/services/ioa/v20220601/examples.json +24 -10
  127. tccli/services/iotexplorer/v20190423/api.json +33 -13
  128. tccli/services/iotexplorer/v20190423/examples.json +3 -3
  129. tccli/services/iotvideo/iotvideo_client.py +106 -0
  130. tccli/services/iotvideo/v20191126/api.json +256 -24
  131. tccli/services/iotvideo/v20191126/examples.json +19 -3
  132. tccli/services/iotvideo/v20201215/api.json +1 -1
  133. tccli/services/iotvideo/v20201215/examples.json +1 -1
  134. tccli/services/iotvideo/v20211125/api.json +1 -1
  135. tccli/services/iotvideo/v20211125/examples.json +2 -2
  136. tccli/services/iss/iss_client.py +69 -122
  137. tccli/services/iss/v20230517/api.json +10 -54
  138. tccli/services/iss/v20230517/examples.json +0 -14
  139. tccli/services/kms/v20190118/api.json +301 -268
  140. tccli/services/kms/v20190118/examples.json +45 -51
  141. tccli/services/lcic/lcic_client.py +159 -0
  142. tccli/services/lcic/v20220817/api.json +273 -1
  143. tccli/services/lcic/v20220817/examples.json +24 -0
  144. tccli/services/lighthouse/v20200324/api.json +56 -0
  145. tccli/services/live/live_client.py +159 -0
  146. tccli/services/live/v20180801/api.json +244 -0
  147. tccli/services/live/v20180801/examples.json +24 -0
  148. tccli/services/lke/v20231130/api.json +17 -17
  149. tccli/services/lke/v20231130/examples.json +19 -25
  150. tccli/services/mariadb/v20170312/api.json +7 -7
  151. tccli/services/market/v20191010/api.json +3 -3
  152. tccli/services/market/v20191010/examples.json +2 -2
  153. tccli/services/mmps/v20200710/api.json +47 -47
  154. tccli/services/mmps/v20200710/examples.json +3 -3
  155. tccli/services/mongodb/v20190725/api.json +4 -4
  156. tccli/services/monitor/v20180724/api.json +46 -19
  157. tccli/services/mps/v20190612/api.json +282 -5
  158. tccli/services/mps/v20190612/examples.json +25 -1
  159. tccli/services/mqtt/v20240516/api.json +2 -2
  160. tccli/services/mrs/v20200910/api.json +72 -34
  161. tccli/services/mrs/v20200910/examples.json +2 -2
  162. tccli/services/ms/v20180408/api.json +535 -506
  163. tccli/services/ms/v20180408/examples.json +25 -25
  164. tccli/services/oceanus/v20190422/api.json +130 -0
  165. tccli/services/ocr/ocr_client.py +232 -20
  166. tccli/services/ocr/v20181119/api.json +2265 -760
  167. tccli/services/ocr/v20181119/examples.json +200 -180
  168. tccli/services/omics/v20221128/api.json +614 -553
  169. tccli/services/omics/v20221128/examples.json +9 -9
  170. tccli/services/organization/v20210331/api.json +13 -4
  171. tccli/services/organization/v20210331/examples.json +2 -2
  172. tccli/services/partners/v20180321/api.json +244 -234
  173. tccli/services/partners/v20180321/examples.json +19 -19
  174. tccli/services/privatedns/privatedns_client.py +428 -4
  175. tccli/services/privatedns/v20201028/api.json +815 -11
  176. tccli/services/privatedns/v20201028/examples.json +64 -0
  177. tccli/services/pts/v20210728/api.json +18 -0
  178. tccli/services/pts/v20210728/examples.json +1 -1
  179. tccli/services/rce/rce_client.py +53 -0
  180. tccli/services/rce/v20201103/api.json +146 -0
  181. tccli/services/rce/v20201103/examples.json +8 -0
  182. tccli/services/redis/v20180412/api.json +42 -42
  183. tccli/services/redis/v20180412/examples.json +19 -19
  184. tccli/services/rum/v20210622/api.json +9 -0
  185. tccli/services/scf/v20180416/api.json +15 -15
  186. tccli/services/scf/v20180416/examples.json +1 -1
  187. tccli/services/smop/v20201203/api.json +46 -42
  188. tccli/services/smop/v20201203/examples.json +2 -2
  189. tccli/services/soe/v20180724/api.json +10 -10
  190. tccli/services/sqlserver/v20180328/api.json +21 -8
  191. tccli/services/sqlserver/v20180328/examples.json +5 -5
  192. tccli/services/ssl/v20191205/api.json +97 -4
  193. tccli/services/ssm/v20190923/api.json +292 -231
  194. tccli/services/ssm/v20190923/examples.json +42 -42
  195. tccli/services/tat/v20201028/api.json +97 -97
  196. tccli/services/tat/v20201028/examples.json +20 -26
  197. tccli/services/tchd/v20230306/api.json +5 -5
  198. tccli/services/tchd/v20230306/examples.json +3 -3
  199. tccli/services/tcr/v20190924/api.json +1 -1
  200. tccli/services/tcr/v20190924/examples.json +1 -1
  201. tccli/services/tcss/v20201101/api.json +1973 -1426
  202. tccli/services/tcss/v20201101/examples.json +346 -364
  203. tccli/services/tdmq/v20200217/api.json +539 -401
  204. tccli/services/tdmq/v20200217/examples.json +104 -104
  205. tccli/services/tds/v20220801/api.json +4 -4
  206. tccli/services/tem/v20210701/api.json +287 -271
  207. tccli/services/tem/v20210701/examples.json +59 -59
  208. tccli/services/teo/v20220901/api.json +37 -9
  209. tccli/services/teo/v20220901/examples.json +13 -7
  210. tccli/services/thpc/v20230321/api.json +5 -5
  211. tccli/services/tke/tke_client.py +217 -58
  212. tccli/services/tke/v20180525/api.json +36 -27
  213. tccli/services/tke/v20180525/examples.json +1 -1
  214. tccli/services/tke/v20220501/api.json +176 -0
  215. tccli/services/tke/v20220501/examples.json +24 -0
  216. tccli/services/tmt/v20180321/api.json +38 -8
  217. tccli/services/trp/v20210515/api.json +86 -74
  218. tccli/services/trp/v20210515/examples.json +65 -65
  219. tccli/services/trro/v20220325/api.json +72 -71
  220. tccli/services/trro/v20220325/examples.json +8 -8
  221. tccli/services/trtc/trtc_client.py +8 -61
  222. tccli/services/trtc/v20190722/api.json +72 -30
  223. tccli/services/trtc/v20190722/examples.json +3 -11
  224. tccli/services/tse/tse_client.py +110 -4
  225. tccli/services/tse/v20201207/api.json +122 -7
  226. tccli/services/tse/v20201207/examples.json +25 -9
  227. tccli/services/vclm/v20240523/api.json +225 -82
  228. tccli/services/vclm/v20240523/examples.json +13 -19
  229. tccli/services/vod/v20180717/api.json +431 -4
  230. tccli/services/vod/v20180717/examples.json +25 -5
  231. tccli/services/vod/v20240718/api.json +11 -11
  232. tccli/services/vod/v20240718/examples.json +4 -4
  233. tccli/services/vod/vod_client.py +53 -0
  234. tccli/services/vpc/v20170312/api.json +1090 -862
  235. tccli/services/vpc/v20170312/examples.json +74 -66
  236. tccli/services/vpc/vpc_client.py +61 -8
  237. tccli/services/waf/v20180125/api.json +2540 -2177
  238. tccli/services/waf/v20180125/examples.json +216 -284
  239. tccli/services/waf/waf_client.py +172 -119
  240. tccli/services/wav/v20210129/api.json +48 -48
  241. tccli/services/wav/v20210129/examples.json +4 -4
  242. tccli/services/wedata/v20210820/api.json +909 -25
  243. tccli/services/wedata/v20210820/examples.json +28 -4
  244. tccli/services/wedata/wedata_client.py +159 -0
  245. tccli/services/weilingwith/v20230427/api.json +6 -6
  246. tccli/services/weilingwith/v20230427/examples.json +3 -3
  247. tccli/sso.py +229 -0
  248. {tccli-3.0.1216.1.dist-info → tccli-3.0.1217.1.dist-info}/METADATA +2 -2
  249. {tccli-3.0.1216.1.dist-info → tccli-3.0.1217.1.dist-info}/RECORD +252 -235
  250. {tccli-3.0.1216.1.dist-info → tccli-3.0.1217.1.dist-info}/WHEEL +0 -0
  251. {tccli-3.0.1216.1.dist-info → tccli-3.0.1217.1.dist-info}/entry_points.txt +0 -0
  252. {tccli-3.0.1216.1.dist-info → tccli-3.0.1217.1.dist-info}/license_files/LICENSE +0 -0
tccli/__init__.py CHANGED
@@ -1 +1 @@
1
- __version__ = '3.0.1216.1'
1
+ __version__ = '3.0.1217.1'
tccli/argparser.py CHANGED
@@ -58,7 +58,7 @@ class BaseArgParser(argparse.ArgumentParser):
58
58
  def parse_known_args(self, args=None, namespace=None):
59
59
  parsed, remaining = super(BaseArgParser, self).parse_known_args(args, namespace)
60
60
  terminal_encoding = getattr(sys.stdin, 'encoding', 'utf-8')
61
- if terminal_encoding is None:
61
+ if terminal_encoding is None or terminal_encoding == 'cp65001':
62
62
  terminal_encoding = 'utf-8'
63
63
  for arg, value in vars(parsed).items():
64
64
  if isinstance(value, six.binary_type):
tccli/command.py CHANGED
@@ -7,7 +7,7 @@ import tccli.services as Services
7
7
  import tccli.options_define as Options_define
8
8
  from collections import OrderedDict
9
9
 
10
- from tccli import oauth
10
+ from tccli import credentials
11
11
  from tccli.utils import Utils
12
12
  from tccli.argument import CLIArgument, CustomArgument, ListArgument, BooleanArgument
13
13
  from tccli.exceptions import UnknownArgumentError
@@ -291,7 +291,7 @@ class ActionCommand(BaseCommand):
291
291
  action_parameters = self.cli_unfold_argument.build_action_parameters(parsed_args)
292
292
  else:
293
293
  action_parameters = self._build_action_parameters(parsed_args, self.argument_map)
294
- oauth.maybe_refresh_credential(parsed_globals.profile if parsed_globals.profile else "default")
294
+ credentials.maybe_refresh_credential(parsed_globals.profile if parsed_globals.profile else "default")
295
295
  return self._action_caller(action_parameters, vars(parsed_globals))
296
296
 
297
297
  def create_help_command(self):
tccli/credentials.py ADDED
@@ -0,0 +1,25 @@
1
+ import json
2
+ import os
3
+
4
+ from tccli import oauth, sso
5
+
6
+
7
+ def maybe_refresh_credential(profile):
8
+ try:
9
+ with open(cred_path_of_profile(profile), "r") as cred_file:
10
+ cred = json.load(cred_file)
11
+ except IOError:
12
+ # file not found, don't check
13
+ return
14
+
15
+ if cred.get("type", "") == "oauth":
16
+ oauth.maybe_refresh_credential(profile)
17
+ return
18
+
19
+ if cred.get("type", "") == "sso":
20
+ sso.maybe_refresh_credential(profile)
21
+ return
22
+
23
+
24
+ def cred_path_of_profile(profile):
25
+ return os.path.join(os.path.expanduser("~"), ".tccli", profile + ".credential")
tccli/main.py CHANGED
@@ -4,14 +4,18 @@ import _locale
4
4
  _locale._getdefaultlocale = (lambda *args: ['zh_CN', 'utf8'])
5
5
 
6
6
  import io
7
- import os
8
7
  import sys
9
8
  import six
10
- import signal
11
9
  from tccli.log import init
12
10
  from tencentcloud.common.exception.tencent_cloud_sdk_exception import TencentCloudSDKException
13
11
 
14
12
  try:
13
+ # cp65001 is utf-8 on windows platform
14
+ # python2 doesn't support cp65001 codec
15
+ if getattr(sys.stdin, 'encoding', 'utf-8') == "cp65001":
16
+ import codecs
17
+ codecs.register(lambda name: codecs.lookup('utf-8') if name == 'cp65001' else None)
18
+
15
19
  reload(sys) # Python 2.7
16
20
  sys.setdefaultencoding('utf8')
17
21
  except NameError:
@@ -0,0 +1,61 @@
1
+ # encoding: utf-8
2
+ from tccli.plugins.sso.login import login_command_entrypoint
3
+ from tccli.plugins.sso.logout import logout_command_entrypoint
4
+ from tccli.plugins.sso.configure import configure_command_entrypoint
5
+
6
+ service_name = "sso"
7
+ service_version = "2024-10-14"
8
+
9
+ _spec = {
10
+ "metadata": {
11
+ "serviceShortName": service_name,
12
+ "apiVersion": service_version,
13
+ "description": "sso related commands",
14
+ },
15
+ "actions": {
16
+ "configure": {
17
+ "name": "配置",
18
+ "document": "configure login url",
19
+ "input": "configureRequest",
20
+ "output": "configureResponse",
21
+ "action_caller": configure_command_entrypoint,
22
+ },
23
+ "login": {
24
+ "name": "登录",
25
+ "document": "login through sso",
26
+ "input": "loginRequest",
27
+ "output": "loginResponse",
28
+ "action_caller": login_command_entrypoint,
29
+ },
30
+ "logout": {
31
+ "name": "登出",
32
+ "document": "remove local credential file",
33
+ "input": "logoutRequest",
34
+ "output": "logoutResponse",
35
+ "action_caller": logout_command_entrypoint,
36
+ },
37
+ },
38
+ "objects": {
39
+ "loginRequest": {"members": []},
40
+ "loginResponse": {"members": []},
41
+ "logoutRequest": {"members": []},
42
+ "logoutResponse": {"members": []},
43
+ "configureRequest": {"members": [
44
+ {
45
+ "name": "url",
46
+ "member": "string",
47
+ "type": "string",
48
+ "required": True,
49
+ "document": "url for sso authentication",
50
+ },
51
+ ]},
52
+ "configureResponse": {"members": []},
53
+ },
54
+ "version": "1.0",
55
+ }
56
+
57
+
58
+ def register_service(specs):
59
+ specs[service_name] = {
60
+ service_version: _spec,
61
+ }
@@ -0,0 +1,4 @@
1
+ # encoding: utf-8
2
+ CLI_URL = "https://cli.cloud.tencent.com/sso"
3
+ SITE = "cn"
4
+ DEFAULT_LANG = "zh-CN"
@@ -0,0 +1,45 @@
1
+ # coding: utf-8
2
+ import json
3
+ try:
4
+ from urlparse import urlparse
5
+ except ImportError:
6
+ from urllib.parse import urlparse
7
+
8
+ from tccli import sso
9
+ from tccli.plugins.sso import texts, configs
10
+
11
+
12
+ def configure_command_entrypoint(args, parsed_globals):
13
+ language = parsed_globals.get("language")
14
+ if not language:
15
+ language = configs.DEFAULT_LANG
16
+ texts.set_lang(language)
17
+
18
+ profile = parsed_globals.get("profile", "default")
19
+ if not profile:
20
+ profile = "default"
21
+
22
+ cred_data = {}
23
+ try:
24
+ with open(sso.cred_path_of_profile(profile), "r") as cred_file:
25
+ cred_data = json.load(cred_file)
26
+ except IOError:
27
+ pass
28
+
29
+ if "sso" not in cred_data:
30
+ cred_data["sso"] = {}
31
+
32
+ auth_url = args.get("url")
33
+ if not auth_url.startswith("http://") and not auth_url.startswith("https://"):
34
+ auth_url = "https://" + auth_url
35
+
36
+ parsed_url = urlparse(auth_url)
37
+ if not (parsed_url.scheme in ("http", "https") and parsed_url.netloc):
38
+ print(texts.get("invalid_auth_url") % auth_url)
39
+ return
40
+
41
+ cred_data["sso"]["authUrl"] = auth_url
42
+ with open(sso.cred_path_of_profile(profile), "w") as cred_file:
43
+ json.dump(cred_data, cred_file, indent=4)
44
+
45
+ print(texts.get("configure_succeed") % auth_url)
@@ -0,0 +1,144 @@
1
+ # coding: utf-8
2
+ import json
3
+ import os.path
4
+ import random
5
+ import string
6
+ import sys
7
+ import time
8
+ import uuid
9
+ import webbrowser
10
+
11
+ from six.moves.urllib.parse import urlencode
12
+
13
+ from tccli import sso
14
+ from tccli.plugins.sso import texts, terminal, configs
15
+ from tccli.plugins.sso.texts import get as _
16
+
17
+
18
+ def print_message(msg):
19
+ print(msg)
20
+ sys.stdout.flush()
21
+
22
+
23
+ def login_command_entrypoint(args, parsed_globals):
24
+ language = parsed_globals.get("language")
25
+ if not language:
26
+ language = configs.DEFAULT_LANG
27
+ texts.set_lang(language)
28
+
29
+ profile = parsed_globals.get("profile", "default")
30
+ if not profile:
31
+ profile = "default"
32
+
33
+ login(profile, language)
34
+
35
+
36
+ def login(profile, language):
37
+ cred_path = sso.cred_path_of_profile(profile)
38
+ auth_url = ""
39
+ if os.path.exists(cred_path):
40
+ with open(cred_path, "r") as cred_file:
41
+ cred_data = json.load(cred_file)
42
+ auth_url = cred_data.get("sso", {}).get("authUrl", "")
43
+
44
+ if not auth_url:
45
+ profile_opt = ""
46
+ if profile != "default":
47
+ profile_opt = "--profile %s " % profile
48
+ print_message(_("auth_url_not_configured") % profile_opt)
49
+ return
50
+
51
+ characters = string.ascii_letters + string.digits
52
+ state = ''.join(random.choice(characters) for x in range(32))
53
+
54
+ token = _get_token(auth_url, state, language)
55
+
56
+ if token["State"] != state:
57
+ raise ValueError("invalid state %s" % token["state"])
58
+
59
+ print_message("")
60
+
61
+ login_token = token["Token"]
62
+ site = token["Site"]
63
+ accounts = sso.list_accounts_for_access_assignment(login_token, site)
64
+ if not accounts:
65
+ print_message(_("no_account"))
66
+ return
67
+
68
+ idx = terminal.select_from_items(
69
+ _("account_select_prompt"), ["%s:%s" % (x["Name"], x["Uin"]) for x in accounts], 10)
70
+ account = accounts[idx]
71
+ print_message("uin: %s" % account["Uin"])
72
+ print_message("username: %s" % account["Name"])
73
+
74
+ roles = sso.list_role_configurations_for_account(account["Uin"], login_token, site)
75
+ if not roles:
76
+ print_message(_("no_role"))
77
+ return
78
+
79
+ idx = terminal.select_from_items(
80
+ _("role_select_prompt"), [x["RoleConfigurationName"] for x in roles], 10)
81
+ role = roles[idx]
82
+ print_message("role: %s" % role["RoleConfigurationName"])
83
+
84
+ saml_resp = sso.gen_saml_response(
85
+ login_token, "RoleSAML", account["Uin"], "", role["RoleConfigurationId"], site)
86
+
87
+ token_info = sso.verify_login_skey(login_token, site)
88
+
89
+ role_arn = "qcs::cam::uin/%s:roleName/TencentCloudSSO-%s" % (account["Uin"], role["RoleConfigurationName"])
90
+ principal_arn = "qcs::cam::uin/%s:saml-provider/TencentReservedSSO-%s" % (account["Uin"], token_info["ZoneId"])
91
+ cred = sso.assume_role_with_saml(
92
+ saml_resp["SAMLResponse"], principal_arn, role_arn, "ses-%s" % uuid.uuid4(), 7200, site)
93
+
94
+ sso_info = {
95
+ "token": login_token,
96
+ "uin": account["Uin"],
97
+ "roleConfigurationId": role["RoleConfigurationId"],
98
+ "roleConfigurationName": role["RoleConfigurationName"],
99
+ "zoneId": token_info["ZoneId"],
100
+ "site": site,
101
+ "authUrl": auth_url,
102
+ "expiresAt": int(time.time()) + 3600 * 12,
103
+ }
104
+ sso.save_credential(cred, sso_info, profile)
105
+
106
+ print_message(_("login_success") % sso.cred_path_of_profile(profile))
107
+
108
+
109
+ def _get_token(auth_url, state, language):
110
+ cli_params = {
111
+ "lang": language,
112
+ "site": configs.SITE,
113
+ "state": state,
114
+ }
115
+ cli_query = urlencode(cli_params)
116
+ cli_url = configs.CLI_URL + "?" + cli_query
117
+ url_params = {
118
+ "loginType": "tccli",
119
+ "callback": cli_url,
120
+ "state": state,
121
+ }
122
+ url_query = urlencode(url_params)
123
+ auth_url = auth_url + "?" + url_query
124
+
125
+ print_message(_("try_login_with_url"))
126
+ print_message("")
127
+ print_message(auth_url)
128
+
129
+ webbrowser.open(auth_url)
130
+
131
+ while True:
132
+ time.sleep(1)
133
+
134
+ login_state = sso.check_login_state(state)
135
+ if "Error" in login_state:
136
+ raise ValueError(login_state["Error"])
137
+
138
+ if login_state["Status"] == "NotFound":
139
+ continue
140
+
141
+ if login_state["Status"] == "Finished":
142
+ return login_state["Token"]
143
+
144
+ raise ValueError("invalid resp: %s" % login_state)
@@ -0,0 +1,21 @@
1
+ # coding: utf-8
2
+ import os
3
+
4
+ from tccli import sso
5
+ from tccli.plugins.sso import texts, configs
6
+
7
+
8
+ def logout_command_entrypoint(args, parsed_globals):
9
+ language = parsed_globals.get("language")
10
+ if not language:
11
+ language = configs.DEFAULT_LANG
12
+ texts.set_lang(language)
13
+
14
+ profile = parsed_globals.get("profile", "default")
15
+ if not profile:
16
+ profile = "default"
17
+
18
+ cred_path = sso.cred_path_of_profile(profile)
19
+ if os.path.exists(cred_path):
20
+ os.remove(cred_path)
21
+ print(texts.get("logout_success") % cred_path)
@@ -0,0 +1,161 @@
1
+ # encoding: utf-8
2
+ import math
3
+ import sys
4
+ import os
5
+ from string import ascii_letters, digits, punctuation
6
+
7
+ _LEFT_ARROW = "LEFT_ARROW"
8
+ _RIGHT_ARROW = "RIGHT_ARROW"
9
+ _UP_ARROW = "UP_ARROW"
10
+ _DOWN_ARROW = "DOWN_ARROW"
11
+ _CTRL_C = "\x03"
12
+ _ENTER = "\r"
13
+ _BACKSPACE = "\x7f"
14
+ _EL = "\033[K"
15
+ _CPL = "\033[F"
16
+ _LIGHTBLUE = "\033[94m"
17
+ _LIGHTBLUE_END = "\033[0m"
18
+
19
+ _win = os.name == "nt"
20
+
21
+
22
+ class Printer(object):
23
+ def __init__(self):
24
+ self._n = 0
25
+
26
+ def print_lines(self, lines):
27
+ self.clear()
28
+ lines = [line + '\n' for line in lines]
29
+ sys.stdout.writelines(lines)
30
+ sys.stdout.flush()
31
+ self._n = len(lines)
32
+
33
+ def clear(self):
34
+ for _ in range(self._n):
35
+ self.move_up()
36
+ self.clear_cur_line()
37
+
38
+ @staticmethod
39
+ def clear_cur_line():
40
+ sys.stdout.write(_EL)
41
+
42
+ @staticmethod
43
+ def move_up():
44
+ sys.stdout.write(_CPL)
45
+
46
+
47
+ def _select_from_items_unix(prompt, items, page_size):
48
+ p = Printer()
49
+
50
+ selection = 0
51
+ search = ""
52
+
53
+ while True:
54
+ filtered_items = [item for item in items if search in item] if search else items
55
+
56
+ page_total = math.ceil(len(filtered_items) / float(page_size))
57
+ page_num = selection // page_size + 1
58
+ page_start = page_size * (page_num - 1)
59
+ page_items = list(filtered_items[page_start: page_start + page_size])
60
+
61
+ for i in range(len(page_items)):
62
+ selection_i = selection % page_size
63
+ selection_prompt = "* " if i == selection_i else " "
64
+ page_items[i] = selection_prompt + _LIGHTBLUE + page_items[i] + _LIGHTBLUE_END
65
+
66
+ page_lines = ["", "%s%s" % (prompt, search), ""] + page_items + ["", "page: %d/%d" % (page_num, page_total)]
67
+ p.print_lines(page_lines)
68
+
69
+ ch = _getch_wrap()
70
+
71
+ if ch == _CTRL_C:
72
+ raise KeyboardInterrupt()
73
+
74
+ if ch == _UP_ARROW:
75
+ selection = max(0, selection - 1)
76
+ elif ch == _DOWN_ARROW:
77
+ selection = min(len(filtered_items) - 1, selection + 1)
78
+ elif ch == _LEFT_ARROW:
79
+ if selection - page_size >= 0:
80
+ selection -= page_size
81
+ elif ch == _RIGHT_ARROW:
82
+ selection = min(len(filtered_items) - 1, selection + page_size)
83
+ elif ch == _BACKSPACE:
84
+ search = search[:len(search) - 1] if search else ""
85
+ selection = 0
86
+ elif ch == _ENTER:
87
+ idx = 0
88
+ matched = -1
89
+
90
+ for item in items:
91
+ if search in item:
92
+ matched += 1
93
+ if matched == selection:
94
+ p.print_lines([])
95
+ return idx
96
+ idx += 1
97
+
98
+ elif ch in (ascii_letters + digits + punctuation):
99
+ search += ch
100
+ selection = 0
101
+
102
+
103
+ def _select_from_items_win(prompt, items, page_size):
104
+ print("")
105
+ print("--------------------------------")
106
+ for i in range(len(items)):
107
+ print("%d. %s" % (i, items[i]))
108
+
109
+ print("--------------------------------")
110
+ sys.stdout.flush()
111
+
112
+ try:
113
+ input_func = raw_input
114
+ except NameError:
115
+ input_func = input
116
+
117
+ while True:
118
+ try:
119
+ sys.stdout.write(prompt)
120
+ idx = int(input_func())
121
+ if 0 <= idx < len(items):
122
+ return idx
123
+ except ValueError:
124
+ pass
125
+
126
+
127
+ select_from_items = _select_from_items_win if _win else _select_from_items_unix
128
+
129
+ if not _win:
130
+ def getch():
131
+ import sys
132
+ import tty
133
+ import termios
134
+ fd = sys.stdin.fileno()
135
+ old = termios.tcgetattr(fd)
136
+ try:
137
+ tty.setraw(fd)
138
+ return sys.stdin.read(1)
139
+ finally:
140
+ termios.tcsetattr(fd, termios.TCSADRAIN, old)
141
+
142
+
143
+ def _getch_wrap():
144
+ ch = getch()
145
+ if ch == "\x1b":
146
+ ch1 = getch()
147
+ if ch1 != "[":
148
+ raise KeyError(ch1)
149
+ ch2 = getch()
150
+ if ch2 == "A":
151
+ return _UP_ARROW
152
+ if ch2 == "B":
153
+ return _DOWN_ARROW
154
+ if ch2 == "C":
155
+ return _RIGHT_ARROW
156
+ if ch2 == "D":
157
+ return _LEFT_ARROW
158
+
159
+ raise KeyError(ch + ch1 + ch2)
160
+ else:
161
+ return ch
@@ -0,0 +1,40 @@
1
+ # encoding: utf-8
2
+ from tccli.plugins.sso import configs
3
+
4
+ _lang = configs.DEFAULT_LANG
5
+
6
+ texts = {
7
+ "zh-CN": {
8
+ "invalid_auth_url": "输入的 url 不合法: %s",
9
+ "auth_url_not_configured": "尚未配置 sso url, 使用 `tccli sso configure %s--url https://your-login-domain.com` 来进行配置",
10
+ "configure_succeed": "url 已配置为 '%s', 接下来可以使用 `tccli sso login` 进行登陆",
11
+ "try_login_with_url": "在浏览器中转到以下链接, 并根据提示完成登录:",
12
+ "account_select_prompt": "登录成功, 请选择您的用户: ",
13
+ "role_select_prompt": "请选择您的角色: ",
14
+ "login_success": "登录成功, 密钥凭证已被写入: %s",
15
+ "logout_success": "登出成功, 密钥凭证已被删除: %s",
16
+ "no_account": "未找到成员账号, 请确认是否同步过 CAM 角色",
17
+ "no_role": "当前成员账号不存在授权角色",
18
+ },
19
+ "en-US": {
20
+ "invalid_auth_url": "The entered url is invalid: %s",
21
+ "auth_url_not_configured": "sso url is not configured yet, use `tccli sso configure %s--url https://your-login-domain.com` to configure",
22
+ "configure_succeed": "The url has been configured as '%s', use `tccli sso login` to log in",
23
+ "try_login_with_url": "Go to the following link in your browser, and complete the sign-in prompts:",
24
+ "account_select_prompt": "Login succeed, choose your account: ",
25
+ "role_select_prompt": "choose your role: ",
26
+ "login_success": "Login succeed, credential has been written to %s",
27
+ "logout_success": "Logout succeed, credential has been removed: %s",
28
+ "no_account": "no account found, please confirm the account is synchronized",
29
+ "no_role": "no role found in current account",
30
+ }
31
+ }
32
+
33
+
34
+ def set_lang(lang):
35
+ global _lang
36
+ _lang = lang
37
+
38
+
39
+ def get(key):
40
+ return texts[_lang][key]
@@ -88,6 +88,9 @@ SERVICE_VERSIONS = {
88
88
  "bda": [
89
89
  "2020-03-24"
90
90
  ],
91
+ "bh": [
92
+ "2023-04-18"
93
+ ],
91
94
  "bi": [
92
95
  "2022-01-05"
93
96
  ],
@@ -398,6 +401,9 @@ SERVICE_VERSIONS = {
398
401
  "iecp": [
399
402
  "2021-09-14"
400
403
  ],
404
+ "ig": [
405
+ "2021-05-18"
406
+ ],
401
407
  "iir": [
402
408
  "2020-04-17"
403
409
  ],
@@ -519,7 +519,7 @@
519
519
  {
520
520
  "disabled": false,
521
521
  "document": "联系人信息",
522
- "example": "王某",
522
+ "example": "张三",
523
523
  "member": "string",
524
524
  "name": "ContactName",
525
525
  "required": false,
@@ -528,7 +528,7 @@
528
528
  {
529
529
  "disabled": false,
530
530
  "document": "联系电话",
531
- "example": "13800138000",
531
+ "example": "138XXXXXXXX",
532
532
  "member": "string",
533
533
  "name": "TelNumber",
534
534
  "required": false,
@@ -537,7 +537,7 @@
537
537
  {
538
538
  "disabled": false,
539
539
  "document": "公司邮箱",
540
- "example": "testApp@test.com",
540
+ "example": "user****@tencent.com",
541
541
  "member": "string",
542
542
  "name": "Email",
543
543
  "required": false,
@@ -546,7 +546,7 @@
546
546
  {
547
547
  "disabled": false,
548
548
  "document": "公司名称",
549
- "example": "App测试有限公司",
549
+ "example": "****科技有限公司",
550
550
  "member": "string",
551
551
  "name": "CorpName",
552
552
  "required": false,
@@ -564,7 +564,7 @@
564
564
  {
565
565
  "disabled": false,
566
566
  "document": "备注信息",
567
- "example": "备注信息",
567
+ "example": "Remark备注信息",
568
568
  "member": "string",
569
569
  "name": "Remark",
570
570
  "required": false,
@@ -618,7 +618,7 @@
618
618
  "example": "0",
619
619
  "member": "int64",
620
620
  "name": "Result",
621
- "required": true,
621
+ "output_required": true,
622
622
  "type": "int",
623
623
  "value_allowed_null": false
624
624
  },
@@ -628,7 +628,7 @@
628
628
  "example": "170143813*******360",
629
629
  "member": "string",
630
630
  "name": "TaskID",
631
- "required": true,
631
+ "output_required": true,
632
632
  "type": "string",
633
633
  "value_allowed_null": true
634
634
  },
@@ -3,7 +3,7 @@
3
3
  "CreateAppScanTask": [
4
4
  {
5
5
  "document": "",
6
- "input": "POST / HTTP/1.1\nHost: acp.tencentcloudapi.com\nContent-Type: application/json\nX-TC-Action: CreateAppScanTask\n<公共请求参数>\n\n{\n \"Remark\": \"备注信息啦\",\n \"Platform\": \"0\",\n \"TelNumber\": \"10086\",\n \"Source\": \"2\",\n \"SalesPerson\": \"张三\",\n \"ContactName\": \"老王\",\n \"TaskType\": \"2\",\n \"CorpName\": \"测试有限公司\",\n \"Email\": \"test@test.com\",\n \"IsAgreePrivacy\": \"1\"\n}",
6
+ "input": "POST / HTTP/1.1\nHost: acp.tencentcloudapi.com\nContent-Type: application/json\nX-TC-Action: CreateAppScanTask\n<公共请求参数>\n\n{\n \"Remark\": \"Remark备注信息\",\n \"Platform\": \"0\",\n \"TelNumber\": \"138XXXXXXXX\",\n \"Source\": \"2\",\n \"SalesPerson\": \"张三\",\n \"ContactName\": \"张三\",\n \"TaskType\": \"2\",\n \"CorpName\": \"****科技有限公司\",\n \"Email\": \"user****@tencent.com\",\n \"IsAgreePrivacy\": \"1\"\n}",
7
7
  "output": "{\n \"Response\": {\n \"RequestId\": \"6c296e5b-48ad-4cfb-a90d-8010c9951341\",\n \"Result\": 0,\n \"TaskID\": \"271***520\"\n }\n}",
8
8
  "title": "本地化任务"
9
9
  },
@@ -21,7 +21,7 @@
21
21
  },
22
22
  {
23
23
  "document": "",
24
- "input": "POST / HTTP/1.1\nHost: acp.tencentcloudapi.com\nContent-Type: application/json\nX-TC-Action: CreateAppScanTask\n<公共请求参数>\n\n{\n \"PrivacyTextName\": \"腾讯iOA隐私保护指引.txt\",\n \"AppDownloadUrl\": \"https://bm****OYpo8YKRrbnTofaB.apk\",\n \"Platform\": \"0\",\n \"TelNumber\": \"10086\",\n \"AppName\": \"ioa\",\n \"PrivacyTextUrl\": \"https://bm****jc7yrar9xIKPYyvpEgVA.txt\",\n \"AppPackage\": \"com.***.i**oa\",\n \"Source\": \"2\",\n \"SalesPerson\": \"张三\",\n \"ContactName\": \"老王\",\n \"TaskType\": \"1\",\n \"CorpName\": \"测试有限企业\",\n \"Email\": \"test@test.com\",\n \"IsAgreePrivacy\": \"1\"\n}",
24
+ "input": "POST / HTTP/1.1\nHost: acp.tencentcloudapi.com\nContent-Type: application/json\nX-TC-Action: CreateAppScanTask\n<公共请求参数>\n\n{\n \"PrivacyTextName\": \"腾讯iOA隐私保护指引.txt\",\n \"AppDownloadUrl\": \"https://bm****OYpo8YKRrbnTofaB.apk\",\n \"Platform\": \"0\",\n \"TelNumber\": \"138XXXXXXXX\",\n \"AppName\": \"ioa\",\n \"PrivacyTextUrl\": \"https://bm****jc7yrar9xIKPYyvpEgVA.txt\",\n \"AppPackage\": \"com.***.i**oa\",\n \"Source\": \"2\",\n \"SalesPerson\": \"张三\",\n \"ContactName\": \"张三\",\n \"TaskType\": \"1\",\n \"CorpName\": \"****科技有限公司\",\n \"Email\": \"user****@tencent.com\",\n \"IsAgreePrivacy\": \"1\"\n}",
25
25
  "output": "{\n \"Response\": {\n \"RequestId\": \"ab653763-5494-42db-b7d3-4afd9eb76410\",\n \"Result\": 0,\n \"TaskID\": \"271***344\"\n }\n}",
26
26
  "title": "App专家版隐私合规诊断示例"
27
27
  },