Skip to content

Commit

Permalink
feat: add 'scopes list' subcommand
Browse files Browse the repository at this point in the history
  • Loading branch information
Widcket committed Jan 28, 2021
1 parent d922922 commit 7e6138a
Show file tree
Hide file tree
Showing 2 changed files with 152 additions and 11 deletions.
107 changes: 105 additions & 2 deletions internal/cli/apis.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package cli

import (
"strings"

"github.com/auth0/auth0-cli/internal/ansi"
"github.com/auth0/auth0-cli/internal/prompt"
"github.com/spf13/cobra"
Expand All @@ -11,6 +13,7 @@ const (
apiID = "id"
apiName = "name"
apiIdentifier = "identifier"
apiScopes = "scopes"
)

func apisCmd(cli *cli) *cobra.Command {
Expand All @@ -26,6 +29,19 @@ func apisCmd(cli *cli) *cobra.Command {
cmd.AddCommand(createApiCmd(cli))
cmd.AddCommand(updateApiCmd(cli))
cmd.AddCommand(deleteApiCmd(cli))
cmd.AddCommand(scopesCmd(cli))

return cmd
}

func scopesCmd(cli *cli) *cobra.Command {
cmd := &cobra.Command{
Use: "scopes",
Short: "Manage resources for API scopes",
}

cmd.SetUsageTemplate(resourceUsageTemplate())
cmd.AddCommand(listScopesCmd(cli))

return cmd
}
Expand Down Expand Up @@ -111,6 +127,7 @@ func createApiCmd(cli *cli) *cobra.Command {
var flags struct {
Name string
Identifier string
Scopes string
}

cmd := &cobra.Command{
Expand Down Expand Up @@ -146,11 +163,23 @@ auth0 apis create --name myapi --identifier http://my-api
}
}

if shouldPrompt(cmd, apiScopes) {
input := prompt.TextInput(apiScopes, "Scopes:", "Space-separated list of scopes.", false)

if err := prompt.AskOne(input, &flags); err != nil {
return err
}
}

api := &management.ResourceServer{
Name: &flags.Name,
Identifier: &flags.Identifier,
}

if flags.Scopes != "" {
api.Scopes = getScopes(flags.Scopes)
}

err := ansi.Spinner("Creating API", func() error {
return cli.api.ResourceServer.Create(api)
})
Expand All @@ -166,15 +195,17 @@ auth0 apis create --name myapi --identifier http://my-api

cmd.Flags().StringVarP(&flags.Name, apiName, "n", "", "Name of the API.")
cmd.Flags().StringVarP(&flags.Identifier, apiIdentifier, "i", "", "Identifier of the API.")
cmd.Flags().StringVarP(&flags.Scopes, apiScopes, "s", "", "Space-separated list of scopes.")
mustRequireFlags(cmd, apiName, apiIdentifier)

return cmd
}

func updateApiCmd(cli *cli) *cobra.Command {
var flags struct {
ID string
Name string
ID string
Name string
Scopes string
}

cmd := &cobra.Command{
Expand Down Expand Up @@ -204,8 +235,20 @@ auth0 apis update --id id --name myapi
}
}

if shouldPrompt(cmd, apiScopes) {
input := prompt.TextInput(apiScopes, "Scopes:", "Space-separated list of scopes.", false)

if err := prompt.AskOne(input, &flags); err != nil {
return err
}
}

api := &management.ResourceServer{Name: &flags.Name}

if flags.Scopes != "" {
api.Scopes = getScopes(flags.Scopes)
}

err := ansi.Spinner("Updating API", func() error {
return cli.api.ResourceServer.Update(flags.ID, api)
})
Expand All @@ -221,6 +264,7 @@ auth0 apis update --id id --name myapi

cmd.Flags().StringVarP(&flags.ID, apiID, "i", "", "ID of the API.")
cmd.Flags().StringVarP(&flags.Name, apiName, "n", "", "Name of the API.")
cmd.Flags().StringVarP(&flags.Scopes, apiScopes, "s", "", "Space-separated list of scopes.")
mustRequireFlags(cmd, apiID, apiName)

return cmd
Expand Down Expand Up @@ -273,3 +317,62 @@ auth0 apis delete --id id

return cmd
}

func listScopesCmd(cli *cli) *cobra.Command {
var flags struct {
ID string
}

cmd := &cobra.Command{
Use: "list",
Short: "List the scopes of an API",
Long: `List the scopes of an API:
auth0 apis scopes list --id id
`,
PreRun: func(cmd *cobra.Command, args []string) {
prepareInteractivity(cmd)
},
RunE: func(cmd *cobra.Command, args []string) error {
if shouldPrompt(cmd, apiID) {
input := prompt.TextInput(apiID, "Id:", "Id of the API.", true)

if err := prompt.AskOne(input, &flags); err != nil {
return err
}
}

api := &management.ResourceServer{ID: &flags.ID}

err := ansi.Spinner("Loading scopes", func() error {
var err error
api, err = cli.api.ResourceServer.Read(flags.ID)
return err
})

if err != nil {
return err
}

cli.renderer.ScopesList(api.GetName(), api.Scopes)
return nil
},
}

cmd.Flags().StringVarP(&flags.ID, apiID, "i", "", "ID of the API.")
mustRequireFlags(cmd, apiID)

return cmd
}

func getScopes(scopes string) []*management.ResourceServerScope {
list := strings.Fields(scopes)
models := []*management.ResourceServerScope{}

for _, scope := range list {
value := scope
models = append(models, &management.ResourceServerScope{Value: &value})
}

return models
}
56 changes: 47 additions & 9 deletions internal/display/apis.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package display

import (
"fmt"

"github.com/auth0/auth0-cli/internal/ansi"
"github.com/auth0/auth0-cli/internal/auth0"
"gopkg.in/auth0.v5/management"
Expand All @@ -10,47 +12,83 @@ type apiView struct {
ID string
Name string
Identifier string
Scopes int
}

func (v *apiView) AsTableHeader() []string {
return []string{"ID", "Name", "Identifier"}
return []string{"ID", "Name", "Identifier", "Scopes"}
}

func (v *apiView) AsTableRow() []string {
return []string{ansi.Faint(v.ID), v.Name, v.Identifier}
return []string{ansi.Faint(v.ID), v.Name, v.Identifier, fmt.Sprint(v.Scopes)}
}

func (r *Renderer) ApiList(apis []*management.ResourceServer) {
r.Heading(ansi.Bold(r.Tenant), "APIs\n")

var res []View
results := []View{}

for _, api := range apis {
res = append(res, makeView(api))
results = append(results, makeApiView(api))
}

r.Results(res)
r.Results(results)
}

func (r *Renderer) ApiShow(api *management.ResourceServer) {
r.Heading(ansi.Bold(r.Tenant), "API\n")
r.Results([]View{makeView(api)})
r.Results([]View{makeApiView(api)})
}

func (r *Renderer) ApiCreate(api *management.ResourceServer) {
r.Heading(ansi.Bold(r.Tenant), "API created\n")
r.Results([]View{makeView(api)})
r.Results([]View{makeApiView(api)})
}

func (r *Renderer) ApiUpdate(api *management.ResourceServer) {
r.Heading(ansi.Bold(r.Tenant), "API updated\n")
r.Results([]View{makeView(api)})
r.Results([]View{makeApiView(api)})
}

func makeView(api *management.ResourceServer) *apiView {
func makeApiView(api *management.ResourceServer) *apiView {
scopes := len(api.Scopes)

return &apiView{
ID: auth0.StringValue(api.ID),
Name: auth0.StringValue(api.Name),
Identifier: auth0.StringValue(api.Identifier),
Scopes: auth0.IntValue(&scopes),
}
}

type scopeView struct {
Scope string
Description string
}

func (v *scopeView) AsTableHeader() []string {
return []string{"Scope", "Description"}
}

func (v *scopeView) AsTableRow() []string {
return []string{v.Scope, v.Description}
}

func (r *Renderer) ScopesList(api string, scopes []*management.ResourceServerScope) {
r.Heading(ansi.Bold(r.Tenant), fmt.Sprintf("Scopes of %s\n", ansi.Bold(api)))

results := []View{}

for _, scope := range scopes {
results = append(results, makeScopeView(scope))
}

r.Results(results)
}

func makeScopeView(scope *management.ResourceServerScope) *scopeView {
return &scopeView{
Scope: auth0.StringValue(scope.Value),
Description: auth0.StringValue(scope.Description),
}
}

0 comments on commit 7e6138a

Please sign in to comment.