credentials.go 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393
  1. // Copyright 2019 Yunion
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package identity
  15. import (
  16. "fmt"
  17. "time"
  18. "yunion.io/x/jsonutils"
  19. "yunion.io/x/pkg/util/printutils"
  20. api "yunion.io/x/onecloud/pkg/apis/identity"
  21. "yunion.io/x/onecloud/pkg/mcclient"
  22. modules "yunion.io/x/onecloud/pkg/mcclient/modules/identity"
  23. )
  24. func init() {
  25. type CredentialListOptions struct {
  26. Scope string `help:"scope" choices:"project|domain|system"`
  27. Type string `help:"credential type" choices:"totp|recovery_secret|aksk|enc_key|container_image"`
  28. User string `help:"filter by user"`
  29. UserDomain string `help:"the domain of user"`
  30. }
  31. R(&CredentialListOptions{}, "credential-list", "List all credentials", func(s *mcclient.ClientSession, args *CredentialListOptions) error {
  32. query := jsonutils.NewDict()
  33. if len(args.Type) > 0 {
  34. query.Add(jsonutils.NewString(args.Type), "type")
  35. }
  36. if len(args.Scope) > 0 {
  37. query.Add(jsonutils.NewString(args.Scope), "scope")
  38. }
  39. if len(args.User) > 0 {
  40. if len(args.UserDomain) > 0 {
  41. query.Add(jsonutils.NewString(args.UserDomain), "domain_id")
  42. }
  43. query.Add(jsonutils.NewString(args.User), "user_id")
  44. }
  45. results, err := modules.Credentials.List(s, query)
  46. if err != nil {
  47. return err
  48. }
  49. printList(results, nil)
  50. return nil
  51. })
  52. type CredentialTOTPOptions struct {
  53. USER string `help:"User"`
  54. UserDomain string `help:"domain of user"`
  55. }
  56. R(&CredentialTOTPOptions{}, "credential-create-totp", "Create totp credential", func(s *mcclient.ClientSession, args *CredentialTOTPOptions) error {
  57. uid, err := modules.UsersV3.FetchId(s, args.USER, args.UserDomain)
  58. if err != nil {
  59. return err
  60. }
  61. secret, err := modules.Credentials.CreateTotpSecret(s, uid)
  62. if err != nil {
  63. return err
  64. }
  65. fmt.Println("secret:", secret)
  66. return nil
  67. })
  68. R(&CredentialTOTPOptions{}, "credential-get-totp", "Get totp credential for user", func(s *mcclient.ClientSession, args *CredentialTOTPOptions) error {
  69. uid, err := modules.UsersV3.FetchId(s, args.USER, args.UserDomain)
  70. if err != nil {
  71. return err
  72. }
  73. secret, err := modules.Credentials.GetTotpSecret(s, uid)
  74. if err != nil {
  75. return err
  76. }
  77. fmt.Println("secret:", secret)
  78. return nil
  79. })
  80. R(&CredentialTOTPOptions{}, "credential-remove-totp", "Remove totp credential for user", func(s *mcclient.ClientSession, args *CredentialTOTPOptions) error {
  81. uid, err := modules.UsersV3.FetchId(s, args.USER, args.UserDomain)
  82. if err != nil {
  83. return err
  84. }
  85. err = modules.Credentials.RemoveTotpSecrets(s, uid)
  86. if err != nil {
  87. return err
  88. }
  89. fmt.Println("success")
  90. return nil
  91. })
  92. type CredentialCreateRecoverySecretsOptions struct {
  93. USER string `help:"User"`
  94. UserDomain string `help:"domain of user"`
  95. Question []string `help:"questions"`
  96. Answer []string `help:"answers"`
  97. }
  98. R(&CredentialCreateRecoverySecretsOptions{}, "credential-save-recovery-secrets", "save recovery secrets for user", func(s *mcclient.ClientSession, args *CredentialCreateRecoverySecretsOptions) error {
  99. uid, err := modules.UsersV3.FetchId(s, args.USER, args.UserDomain)
  100. if err != nil {
  101. return err
  102. }
  103. if len(args.Question) == 0 || len(args.Answer) == 0 {
  104. return fmt.Errorf("no recovery secrets provided")
  105. }
  106. if len(args.Question) != len(args.Answer) {
  107. return fmt.Errorf("number of questions and answers does not match")
  108. }
  109. secrets := make([]modules.SRecoverySecret, len(args.Question))
  110. for i := range args.Question {
  111. secrets[i] = modules.SRecoverySecret{
  112. Question: args.Question[i],
  113. Answer: args.Answer[i],
  114. }
  115. }
  116. err = modules.Credentials.SaveRecoverySecrets(s, uid, secrets)
  117. if err != nil {
  118. return err
  119. }
  120. fmt.Println("success")
  121. return nil
  122. })
  123. R(&CredentialTOTPOptions{}, "credential-get-recovery-secrets", "Get totp credential for user", func(s *mcclient.ClientSession, args *CredentialTOTPOptions) error {
  124. uid, err := modules.UsersV3.FetchId(s, args.USER, args.UserDomain)
  125. if err != nil {
  126. return err
  127. }
  128. secret, err := modules.Credentials.GetRecoverySecrets(s, uid)
  129. if err != nil {
  130. return err
  131. }
  132. fmt.Println("secret:", secret)
  133. return nil
  134. })
  135. R(&CredentialTOTPOptions{}, "credential-remove-recovery-secrets", "Remove totp credential for user", func(s *mcclient.ClientSession, args *CredentialTOTPOptions) error {
  136. uid, err := modules.UsersV3.FetchId(s, args.USER, args.UserDomain)
  137. if err != nil {
  138. return err
  139. }
  140. err = modules.Credentials.RemoveRecoverySecrets(s, uid)
  141. if err != nil {
  142. return err
  143. }
  144. fmt.Println("success")
  145. return nil
  146. })
  147. type CredentialAkSkOptions struct {
  148. User string `help:"User"`
  149. UserDomain string `help:"domain of user"`
  150. Project string `help:"Project"`
  151. ProjectDomain string `help:"domain of user"`
  152. }
  153. R(&CredentialAkSkOptions{}, "credential-create-aksk", "Create AccessKey/Secret credential", func(s *mcclient.ClientSession, args *CredentialAkSkOptions) error {
  154. var uid string
  155. var pid string
  156. var err error
  157. if len(args.User) > 0 {
  158. uid, err = modules.UsersV3.FetchId(s, args.User, args.UserDomain)
  159. if err != nil {
  160. return err
  161. }
  162. }
  163. if len(args.Project) > 0 {
  164. pid, err = modules.Projects.FetchId(s, args.Project, args.ProjectDomain)
  165. if err != nil {
  166. return err
  167. }
  168. }
  169. secret, err := modules.Credentials.CreateAccessKeySecret(s, uid, pid, time.Time{})
  170. if err != nil {
  171. return err
  172. }
  173. result := jsonutils.Marshal(secret)
  174. result.(*jsonutils.JSONDict).Add(jsonutils.NewString(secret.KeyId), "access_key")
  175. printObject(result)
  176. return nil
  177. })
  178. R(&CredentialAkSkOptions{}, "credential-get-aksk", "Get AccessKey/Secret credential for user and project", func(s *mcclient.ClientSession, args *CredentialAkSkOptions) error {
  179. var uid string
  180. var err error
  181. if len(args.User) > 0 {
  182. uid, err = modules.UsersV3.FetchId(s, args.User, args.UserDomain)
  183. if err != nil {
  184. return err
  185. }
  186. }
  187. var pid string
  188. if len(args.Project) > 0 {
  189. pid, err = modules.Projects.FetchId(s, args.Project, args.ProjectDomain)
  190. if err != nil {
  191. return err
  192. }
  193. }
  194. secrets, err := modules.Credentials.GetAccessKeySecrets(s, uid, pid)
  195. if err != nil {
  196. return err
  197. }
  198. result := printutils.ListResult{}
  199. result.Data = make([]jsonutils.JSONObject, len(secrets))
  200. for i := range secrets {
  201. result.Data[i] = jsonutils.Marshal(secrets[i])
  202. result.Data[i].(*jsonutils.JSONDict).Add(jsonutils.NewString(secrets[i].KeyId), "key_id")
  203. result.Data[i].(*jsonutils.JSONDict).Add(jsonutils.NewString(secrets[i].ProjectId), "project_id")
  204. result.Data[i].(*jsonutils.JSONDict).Add(jsonutils.NewTimeString(secrets[i].TimeStamp), "time_stamp")
  205. }
  206. printList(&result, nil)
  207. return nil
  208. })
  209. R(&CredentialAkSkOptions{}, "credential-remove-aksk", "Remove AccessKey/Secret credential for user and project", func(s *mcclient.ClientSession, args *CredentialAkSkOptions) error {
  210. uid, err := modules.UsersV3.FetchId(s, args.User, args.UserDomain)
  211. if err != nil {
  212. return err
  213. }
  214. var pid string
  215. if len(args.Project) > 0 {
  216. pid, err = modules.Projects.FetchId(s, args.Project, args.ProjectDomain)
  217. if err != nil {
  218. return err
  219. }
  220. }
  221. err = modules.Credentials.RemoveAccessKeySecrets(s, uid, pid)
  222. if err != nil {
  223. return err
  224. }
  225. fmt.Println("success")
  226. return nil
  227. })
  228. type OIDCCredentialOptions struct {
  229. User string `help:"User"`
  230. UserDomain string `help:"domain of user"`
  231. Project string `help:"Project"`
  232. ProjectDomain string `help:"domain of user"`
  233. }
  234. type OIDCCredentialCreateOptions struct {
  235. RedirectUri string `help:"redirect URL"`
  236. OIDCCredentialOptions
  237. }
  238. R(&OIDCCredentialCreateOptions{}, "credential-create-oidc", "Create OpenID Connection Credential", func(s *mcclient.ClientSession, args *OIDCCredentialCreateOptions) error {
  239. var uid string
  240. var pid string
  241. var err error
  242. if len(args.User) > 0 {
  243. uid, err = modules.UsersV3.FetchId(s, args.User, args.UserDomain)
  244. if err != nil {
  245. return err
  246. }
  247. }
  248. if len(args.Project) > 0 {
  249. pid, err = modules.Projects.FetchId(s, args.Project, args.ProjectDomain)
  250. if err != nil {
  251. return err
  252. }
  253. }
  254. secret, err := modules.Credentials.CreateOIDCSecret(s, uid, pid, args.RedirectUri)
  255. if err != nil {
  256. return err
  257. }
  258. printObject(jsonutils.Marshal(&secret))
  259. return nil
  260. })
  261. R(&OIDCCredentialOptions{}, "credential-get-oidc", "Get OpenID Connect credential for user and project", func(s *mcclient.ClientSession, args *OIDCCredentialOptions) error {
  262. var uid string
  263. var err error
  264. if len(args.User) > 0 {
  265. uid, err = modules.UsersV3.FetchId(s, args.User, args.UserDomain)
  266. if err != nil {
  267. return err
  268. }
  269. }
  270. var pid string
  271. if len(args.Project) > 0 {
  272. pid, err = modules.Projects.FetchId(s, args.Project, args.ProjectDomain)
  273. if err != nil {
  274. return err
  275. }
  276. }
  277. secrets, err := modules.Credentials.GetOIDCSecret(s, uid, pid)
  278. if err != nil {
  279. return err
  280. }
  281. result := printutils.ListResult{}
  282. result.Data = make([]jsonutils.JSONObject, len(secrets))
  283. for i := range secrets {
  284. result.Data[i] = jsonutils.Marshal(secrets[i])
  285. }
  286. printList(&result, nil)
  287. return nil
  288. })
  289. R(&OIDCCredentialOptions{}, "credential-remove-oidc", "Remove OpenID Connect credential for user and project", func(s *mcclient.ClientSession, args *OIDCCredentialOptions) error {
  290. uid, err := modules.UsersV3.FetchId(s, args.User, args.UserDomain)
  291. if err != nil {
  292. return err
  293. }
  294. var pid string
  295. if len(args.Project) > 0 {
  296. pid, err = modules.Projects.FetchId(s, args.Project, args.ProjectDomain)
  297. if err != nil {
  298. return err
  299. }
  300. }
  301. err = modules.Credentials.RemoveOIDCSecrets(s, uid, pid)
  302. if err != nil {
  303. return err
  304. }
  305. fmt.Println("success")
  306. return nil
  307. })
  308. type CredentialDeleteOptions struct {
  309. ID string `help:"ID of credentail"`
  310. }
  311. R(&CredentialDeleteOptions{}, "credential-delete", "Delete credential", func(s *mcclient.ClientSession, args *CredentialDeleteOptions) error {
  312. result, err := modules.Credentials.Delete(s, args.ID, nil)
  313. if err != nil {
  314. return err
  315. }
  316. printObject(result)
  317. return nil
  318. })
  319. type CredentialUpdateOptions struct {
  320. ID string `help:"ID of credentail"`
  321. Enable bool `help:"Enable credential"`
  322. Disable bool `help:"Disable credential"`
  323. Name string `help:"new name of credential"`
  324. Desc string `help:"new description of credential"`
  325. }
  326. R(&CredentialUpdateOptions{}, "credential-update", "Enable/disable credential", func(s *mcclient.ClientSession, args *CredentialUpdateOptions) error {
  327. params := jsonutils.NewDict()
  328. if args.Enable {
  329. params.Add(jsonutils.JSONTrue, "enabled")
  330. } else if args.Disable {
  331. params.Add(jsonutils.JSONFalse, "enabled")
  332. }
  333. if args.Name != "" {
  334. params.Add(jsonutils.NewString(args.Name), "name")
  335. }
  336. if args.Desc != "" {
  337. params.Add(jsonutils.NewString(args.Desc), "description")
  338. }
  339. result, err := modules.Credentials.Update(s, args.ID, params)
  340. if err != nil {
  341. return err
  342. }
  343. printObject(result)
  344. return nil
  345. })
  346. type CredentialContainerImageOptions struct {
  347. NAME string `help:"container image credential name"`
  348. USER string `help:"container image credential user"`
  349. PASSWORD string `help:"container image credential password"`
  350. Project string `help:"Project"`
  351. ProjectDomain string `help:"domain of user"`
  352. }
  353. R(&CredentialContainerImageOptions{}, "credential-create-container-image", "Create container image crendential", func(s *mcclient.ClientSession, args *CredentialContainerImageOptions) error {
  354. var pid string
  355. var err error
  356. if len(args.Project) > 0 {
  357. pid, err = modules.Projects.FetchId(s, args.Project, args.ProjectDomain)
  358. if err != nil {
  359. return err
  360. }
  361. }
  362. obj, err := modules.Credentials.CreateContainerImageSecret(s, pid, args.NAME, &api.CredentialContainerImageBlob{
  363. Username: args.USER,
  364. Password: args.PASSWORD,
  365. })
  366. if err != nil {
  367. return err
  368. }
  369. printObject(obj)
  370. return nil
  371. })
  372. }