/cmd/ttn-lw-cli/commands/users_access.go

https://github.com/TheThingsNetwork/lorawan-stack · Go · 216 lines · 183 code · 20 blank · 13 comment · 40 complexity · 7e00cfa3155947ae101c50df4de21d23 MD5 · raw file

  1. // Copyright © 2019 The Things Network Foundation, The Things Industries B.V.
  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 commands
  15. import (
  16. "os"
  17. "strings"
  18. "github.com/spf13/cobra"
  19. "go.thethings.network/lorawan-stack/v3/cmd/ttn-lw-cli/internal/api"
  20. "go.thethings.network/lorawan-stack/v3/cmd/ttn-lw-cli/internal/io"
  21. "go.thethings.network/lorawan-stack/v3/pkg/ttnpb"
  22. )
  23. var (
  24. userRights = &cobra.Command{
  25. Use: "rights [user-id]",
  26. Short: "List the rights to a user",
  27. RunE: func(cmd *cobra.Command, args []string) error {
  28. usrID := getUserID(cmd.Flags(), args)
  29. if usrID == nil {
  30. return errNoUserID
  31. }
  32. is, err := api.Dial(ctx, config.IdentityServerGRPCAddress)
  33. if err != nil {
  34. return err
  35. }
  36. res, err := ttnpb.NewUserAccessClient(is).ListRights(ctx, usrID)
  37. if err != nil {
  38. return err
  39. }
  40. return io.Write(os.Stdout, config.OutputFormat, res.Rights)
  41. },
  42. }
  43. userAPIKeys = &cobra.Command{
  44. Use: "api-keys",
  45. Aliases: []string{"api-key"},
  46. Short: "Manage user API keys",
  47. }
  48. userAPIKeysList = &cobra.Command{
  49. Use: "list [user-id]",
  50. Aliases: []string{"ls"},
  51. Short: "List user API keys",
  52. RunE: func(cmd *cobra.Command, args []string) error {
  53. usrID := getUserID(cmd.Flags(), args)
  54. if usrID == nil {
  55. return errNoUserID
  56. }
  57. is, err := api.Dial(ctx, config.IdentityServerGRPCAddress)
  58. if err != nil {
  59. return err
  60. }
  61. limit, page, opt, getTotal := withPagination(cmd.Flags())
  62. res, err := ttnpb.NewUserAccessClient(is).ListAPIKeys(ctx, &ttnpb.ListUserAPIKeysRequest{
  63. UserIdentifiers: *usrID, Limit: limit, Page: page,
  64. }, opt)
  65. if err != nil {
  66. return err
  67. }
  68. getTotal()
  69. return io.Write(os.Stdout, config.OutputFormat, res.APIKeys)
  70. },
  71. }
  72. userAPIKeysCreate = &cobra.Command{
  73. Use: "create [user-id]",
  74. Aliases: []string{"add", "generate", "register"},
  75. Short: "Create a user API key",
  76. RunE: func(cmd *cobra.Command, args []string) error {
  77. usrID := getUserID(cmd.Flags(), args)
  78. if usrID == nil {
  79. return errNoUserID
  80. }
  81. name, _ := cmd.Flags().GetString("name")
  82. rights := getRights(cmd.Flags())
  83. if len(rights) == 0 {
  84. return errNoAPIKeyRights
  85. }
  86. is, err := api.Dial(ctx, config.IdentityServerGRPCAddress)
  87. if err != nil {
  88. return err
  89. }
  90. res, err := ttnpb.NewUserAccessClient(is).CreateAPIKey(ctx, &ttnpb.CreateUserAPIKeyRequest{
  91. UserIdentifiers: *usrID,
  92. Name: name,
  93. Rights: rights,
  94. })
  95. if err != nil {
  96. return err
  97. }
  98. logger.Infof("API key ID: %s", res.ID)
  99. logger.Infof("API key value: %s", res.Key)
  100. logger.Warn("The API key value will never be shown again")
  101. logger.Warn("Make sure to copy it to a safe place")
  102. return io.Write(os.Stdout, config.OutputFormat, res)
  103. },
  104. }
  105. userAPIKeysUpdate = &cobra.Command{
  106. Use: "set [user-id] [api-key-id]",
  107. Aliases: []string{"update"},
  108. Short: "Set properties of a user API key",
  109. RunE: func(cmd *cobra.Command, args []string) error {
  110. usrID := getUserID(cmd.Flags(), firstArgs(1, args...))
  111. if usrID == nil {
  112. return errNoUserID
  113. }
  114. id := getAPIKeyID(cmd.Flags(), args, 1)
  115. if id == "" {
  116. return errNoAPIKeyID
  117. }
  118. name, _ := cmd.Flags().GetString("name")
  119. rights := getRights(cmd.Flags())
  120. if len(rights) == 0 {
  121. return errNoAPIKeyRights
  122. }
  123. is, err := api.Dial(ctx, config.IdentityServerGRPCAddress)
  124. if err != nil {
  125. return err
  126. }
  127. _, err = ttnpb.NewUserAccessClient(is).UpdateAPIKey(ctx, &ttnpb.UpdateUserAPIKeyRequest{
  128. UserIdentifiers: *usrID,
  129. APIKey: ttnpb.APIKey{
  130. ID: id,
  131. Name: name,
  132. Rights: rights,
  133. },
  134. })
  135. if err != nil {
  136. return err
  137. }
  138. return nil
  139. },
  140. }
  141. userAPIKeysDelete = &cobra.Command{
  142. Use: "delete [user-id] [api-key-id]",
  143. Aliases: []string{"del", "remove", "rm"},
  144. Short: "Delete a user API key",
  145. RunE: func(cmd *cobra.Command, args []string) error {
  146. usrID := getUserID(cmd.Flags(), firstArgs(1, args...))
  147. if usrID == nil {
  148. return errNoUserID
  149. }
  150. id := getAPIKeyID(cmd.Flags(), args, 1)
  151. if id == "" {
  152. return errNoAPIKeyID
  153. }
  154. is, err := api.Dial(ctx, config.IdentityServerGRPCAddress)
  155. if err != nil {
  156. return err
  157. }
  158. _, err = ttnpb.NewUserAccessClient(is).UpdateAPIKey(ctx, &ttnpb.UpdateUserAPIKeyRequest{
  159. UserIdentifiers: *usrID,
  160. APIKey: ttnpb.APIKey{
  161. ID: id,
  162. Rights: nil,
  163. },
  164. })
  165. if err != nil {
  166. return err
  167. }
  168. return nil
  169. },
  170. }
  171. )
  172. var userRightsFlags = rightsFlags(func(flag string) bool {
  173. for _, entity := range []string{"application", "client", "gateway", "organization", "user"} {
  174. if strings.HasPrefix(flag, "right-"+entity) {
  175. return true
  176. }
  177. }
  178. return false
  179. })
  180. func init() {
  181. userRights.Flags().AddFlagSet(userIDFlags())
  182. usersCommand.AddCommand(userRights)
  183. userAPIKeysList.Flags().AddFlagSet(paginationFlags())
  184. userAPIKeys.AddCommand(userAPIKeysList)
  185. userAPIKeysCreate.Flags().String("name", "", "")
  186. userAPIKeysCreate.Flags().AddFlagSet(userRightsFlags)
  187. userAPIKeys.AddCommand(userAPIKeysCreate)
  188. userAPIKeysUpdate.Flags().String("api-key-id", "", "")
  189. userAPIKeysUpdate.Flags().String("name", "", "")
  190. userAPIKeysUpdate.Flags().AddFlagSet(userRightsFlags)
  191. userAPIKeys.AddCommand(userAPIKeysUpdate)
  192. userAPIKeysDelete.Flags().String("api-key-id", "", "")
  193. userAPIKeys.AddCommand(userAPIKeysDelete)
  194. userAPIKeys.PersistentFlags().AddFlagSet(userIDFlags())
  195. usersCommand.AddCommand(userAPIKeys)
  196. }