Skip to content

Commit

Permalink
feat: clients create (#19)
Browse files Browse the repository at this point in the history
* feat: create client / app

* fix: show the created client

* fix: scope

* feat: reveal secret during create

* feat: secret format

* Update internal/cli/clients.go

Co-authored-by: Cyril David <[email protected]>

* fix wording

* fix: type case insensitive

Co-authored-by: Cyril David <[email protected]>
  • Loading branch information
jfatta and cyx authored Jan 25, 2021
1 parent ec6a8ef commit 0d36b7d
Show file tree
Hide file tree
Showing 3 changed files with 125 additions and 11 deletions.
9 changes: 9 additions & 0 deletions internal/cli/cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
"time"

"github.com/auth0/auth0-cli/internal/display"
"github.com/spf13/cobra"
"gopkg.in/auth0.v5/management"
)

Expand Down Expand Up @@ -205,3 +206,11 @@ func (c *cli) initContext() (err error) {

return nil
}

func mustRequireFlags(cmd *cobra.Command, flags ...string) {
for _, f := range flags {
if err := cmd.MarkFlagRequired(f); err != nil {
panic(err)
}
}
}
86 changes: 83 additions & 3 deletions internal/cli/clients.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
package cli

import (
"strings"

"github.com/auth0/auth0-cli/internal/ansi"
"github.com/spf13/cobra"
"gopkg.in/auth0.v5"
"gopkg.in/auth0.v5/management"
)

func clientsCmd(cli *cli) *cobra.Command {
Expand All @@ -11,12 +16,13 @@ func clientsCmd(cli *cli) *cobra.Command {
}

cmd.SetUsageTemplate(resourceUsageTemplate())
cmd.AddCommand(listClientsCmd(cli))
cmd.AddCommand(clientsListCmd(cli))
cmd.AddCommand(clientsCreateCmd(cli))

return cmd
}

func listClientsCmd(cli *cli) *cobra.Command {
func clientsListCmd(cli *cli) *cobra.Command {
cmd := &cobra.Command{
Use: "list",
Short: "Lists your existing clients",
Expand All @@ -26,7 +32,13 @@ Lists your existing clients. To create one try:
$ auth0 clients create
`,
RunE: func(cmd *cobra.Command, args []string) error {
list, err := cli.api.Client.List()
var list *management.ClientList
err := ansi.Spinner("Getting clients", func() error {
var err error
list, err = cli.api.Client.List()
return err
})

if err != nil {
return err
}
Expand All @@ -38,3 +50,71 @@ Lists your existing clients. To create one try:

return cmd
}

func clientsCreateCmd(cli *cli) *cobra.Command {
var flags struct {
name string
appType string
description string
reveal bool
}
cmd := &cobra.Command{
Use: "create",
Short: "Create a new client (also know as application)",
Long: `Creates a new client (or application):
auth0 clients create --name myapp --type [native|spa|regular|m2m]
- supported application type:
- native: mobile, desktop, CLI and smart device apps running natively.
- spa (single page application): a JavaScript front-end app that uses an API.
- regular: Traditional web app using redirects.
- m2m (machine to machine): CLIs, daemons or services running on your backend.
`,
RunE: func(cmd *cobra.Command, args []string) error {
// TODO(jfatta): depending on the app type, other client properties might be mandatory
// check: create app dashboard
c := &management.Client{
Name: &flags.name,
Description: &flags.description,
AppType: auth0.String(apiAppTypeFor(flags.appType)),
}

err := ansi.Spinner("Creating client", func() error {
return cli.api.Client.Create(c)
})

if err != nil {
return err
}

// note: c is populated with the rest of the client fields by the API during creation.
cli.renderer.ClientCreate(c, flags.reveal)
return nil
},
}
cmd.Flags().StringVarP(&flags.name, "name", "n", "", "Name of the client.")
cmd.Flags().StringVarP(&flags.appType, "type", "t", "", "Type of the client: [native|spa|regular|m2m]")
cmd.Flags().StringVarP(&flags.description, "description", "d", "", "Description of the client.")
cmd.Flags().BoolVarP(&flags.reveal, "reveal", "r", false, "⚠️ Reveal the SECRET of the created client.")

mustRequireFlags(cmd, "name", "type")

return cmd
}

func apiAppTypeFor(v string) string {
switch strings.ToLower(v) {
case "native":
return "native"
case "spa":
return "spa"
case "regular":
return "regular_web"
case "m2m":
return "non_interactive"

default:
return v
}
}
41 changes: 33 additions & 8 deletions internal/display/clients.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,38 +7,63 @@ import (
)

type clientView struct {
Name string
Type string
ClientID string
Name string
Type string
ClientID string
ClientSecret string
revealSecret bool
}

func (v *clientView) AsTableHeader() []string {
if v.revealSecret {
return []string{"Name", "Type", "ClientID", "Client Secret"}
}
return []string{"Name", "Type", "ClientID"}

}

func (v *clientView) AsTableRow() []string {
if v.revealSecret {
return []string{v.Name, v.Type, ansi.Faint(v.ClientID), ansi.Italic(v.ClientSecret)}
}
return []string{v.Name, v.Type, ansi.Faint(v.ClientID)}

}

func (r *Renderer) ClientList(clients []*management.Client) {
r.Heading(ansi.Bold(r.Tenant), "clients\n")

var res []View
for _, c := range clients {
if auth0.StringValue(c.Name) == deprecatedAppName {
continue
}
res = append(res, &clientView{
Name: auth0.StringValue(c.Name),
Type: appTypeFor(c.AppType),
ClientID: auth0.StringValue(c.ClientID),
Name: auth0.StringValue(c.Name),
Type: appTypeFor(c.AppType),
ClientID: auth0.StringValue(c.ClientID),
ClientSecret: auth0.StringValue(c.ClientSecret),
})

}

r.Results(res)
}

func (r *Renderer) ClientCreate(client *management.Client, revealSecrets bool) {
r.Heading(ansi.Bold(r.Tenant), "client created\n")

// note(jfatta): list and create uses the same view for now,
// eventually we might want to show different columns for each command:
v := &clientView{
revealSecret: revealSecrets,
Name: auth0.StringValue(client.Name),
Type: appTypeFor(client.AppType),
ClientID: auth0.StringValue(client.ClientID),
ClientSecret: auth0.StringValue(client.ClientSecret),
}

r.Results([]View{v})
}

// TODO(cyx): determine if there's a better way to filter this out.
const deprecatedAppName = "All Applications"

Expand Down

0 comments on commit 0d36b7d

Please sign in to comment.