Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: auth0 clients create improvements #44

Merged
merged 9 commits into from
Jan 26, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,11 @@ cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohl
cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=
cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
github.com/AlecAivazis/survey v1.8.8 h1:Y4yypp763E8cbqb5RBqZhGgkCFLRFnbRBHrxnpMMsgQ=
github.com/AlecAivazis/survey/v2 v2.2.7 h1:5NbxkF4RSKmpywYdcRgUmos1o+roJY8duCLZXbVjoig=
github.com/AlecAivazis/survey/v2 v2.2.7/go.mod h1:9DYvHgXtiXm6nCn+jXnOXLKbH+Yo9u8fAS/SduGdoPk=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/Netflix/go-expect v0.0.0-20180615182759-c93bf25de8e8 h1:xzYJEypr/85nBpB11F9br+3HUrpgb+fcm5iADzXXYEw=
github.com/Netflix/go-expect v0.0.0-20180615182759-c93bf25de8e8/go.mod h1:oX5x61PbNXchhh0oikYAH+4Pcfw5LKv21+Jnpr6r6Pc=
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
github.com/PuerkitoBio/rehttp v1.0.0 h1:aJ7A7YI2lIvOxcJVeUZY4P6R7kKZtLeONjgyKGwOIu8=
Expand Down Expand Up @@ -152,6 +152,7 @@ github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
github.com/hinshun/vt10x v0.0.0-20180616224451-1954e6464174 h1:WlZsjVhE8Af9IcZDGgJGQpNflI3+MJSBhsgT5PCtzBQ=
github.com/hinshun/vt10x v0.0.0-20180616224451-1954e6464174/go.mod h1:DqJ97dSdRW1W22yXSB90986pcOyQ7r45iio1KN2ez1A=
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
Expand All @@ -166,8 +167,10 @@ github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvW
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/pty v1.1.4 h1:5Myjjh3JY/NaAi4IsUbHADytDyl1VE1Y9PXDlL+P/VQ=
github.com/kr/pty v1.1.4/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
Expand Down Expand Up @@ -502,6 +505,7 @@ google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlba
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
Expand Down
110 changes: 89 additions & 21 deletions internal/cli/clients.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package cli
import (
"strings"

"github.com/AlecAivazis/survey/v2"
"github.com/auth0/auth0-cli/internal/ansi"
"github.com/auth0/auth0-cli/internal/auth0"
"github.com/spf13/cobra"
Expand Down Expand Up @@ -53,11 +54,11 @@ Lists your existing clients. To create one try:

func clientsCreateCmd(cli *cli) *cobra.Command {
var flags struct {
name string
appType string
description string
reveal bool
callbacks []string
Name string
AppType string
Description string
Callbacks []string
TokenEndpointAuthMethod string
}
cmd := &cobra.Command{
Use: "create",
Expand All @@ -73,13 +74,67 @@ auth0 clients create --name myapp --type [native|spa|regular|m2m]
- 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
// todo(jfatta) on non-interactive the cmd should fail on missing mandatory args (name, type)
if !cmd.Flags().Changed("name") {
qs := []*survey.Question{
{
Name: "Name",
Prompt: &survey.Input{
Message: "Name:",
Default: "My App",
Help: "Name of the client (also known as application). You can change the application name later in the application settings.",
},
},
}

err := survey.Ask(qs, &flags)
if err != nil {
return err
}
}

if !cmd.Flags().Changed("type") {
qs := []*survey.Question{
{
Name: "AppType",
Prompt: &survey.Select{
Message: "Type:",
Help: "\n- Native: Mobile, desktop, CLI and smart device apps running natively." +
"\n- Single Page Web Application: A JavaScript front-end app that uses an API." +
"\n- Regular Web Application: Traditional web app using redirects." +
"\n- Machine To Machine: CLIs, daemons or services running on your backend.",
Options: []string{"Native", "Single Page Web Application", "Regular Web Application", "Machine to Machine"},
},
},
}
err := survey.Ask(qs, &flags)
if err != nil {
return err
}
}

if !cmd.Flags().Changed("description") {
qs := []*survey.Question{
{
Name: "Description",
Prompt: &survey.Input{
Message: "Description:",
Help: "A free text description of the application.",
},
},
}
err := survey.Ask(qs, &flags)
if err != nil {
return err
}
}

c := &management.Client{
Name: &flags.name,
Description: &flags.description,
AppType: auth0.String(apiAppTypeFor(flags.appType)),
Callbacks: apiCallbacksFor(flags.callbacks),
Name: &flags.Name,
Description: &flags.Description,
AppType: auth0.String(apiAppTypeFor(flags.AppType)),
Callbacks: apiCallbacksFor(flags.Callbacks),
TokenEndpointAuthMethod: apiTokenEndpointAuthMethodFor(flags.TokenEndpointAuthMethod),
}

err := ansi.Spinner("Creating client", func() error {
Expand All @@ -91,17 +146,17 @@ auth0 clients create --name myapp --type [native|spa|regular|m2m]
}

// note: c is populated with the rest of the client fields by the API during creation.
cli.renderer.ClientCreate(c, flags.reveal)
revealClientSecret := auth0.StringValue(c.AppType) != "native" && auth0.StringValue(c.AppType) != "spa"
cli.renderer.ClientCreate(c, revealClientSecret)
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, or m2m.")
cmd.Flags().StringVarP(&flags.description, "description", "d", "", "A free text description of the application. Max character count is 140.")
cmd.Flags().BoolVarP(&flags.reveal, "reveal", "r", false, "⚠️ Reveal the SECRET of the created client.")
cmd.Flags().StringSliceVarP(&flags.callbacks, "callbacks", "c", nil, "After the user authenticates we will only call back to any of these URLs. You can specify multiple valid URLs by comma-separating them (typically to handle different environments like QA or testing). Make sure to specify the protocol (https://) otherwise the callback may fail in some cases. With the exception of custom URI schemes for native clients, all callbacks should use protocol https://.")
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, or m2m.")
cmd.Flags().StringVarP(&flags.Description, "description", "d", "", "A free text description of the application. Max character count is 140.")
cmd.Flags().StringSliceVarP(&flags.Callbacks, "callbacks", "c", nil, "After the user authenticates we will only call back to any of these URLs. You can specify multiple valid URLs by comma-separating them (typically to handle different environments like QA or testing). Make sure to specify the protocol (https://) otherwise the callback may fail in some cases. With the exception of custom URI schemes for native clients, all callbacks should use protocol https://.")

mustRequireFlags(cmd, "name", "type")
cmd.Flags().StringVar(&flags.TokenEndpointAuthMethod, "auth-method", "", "Defines the requested authentication method for the token endpoint. Possible values are 'None' (public application without a client secret), 'Post' (application uses HTTP POST parameters) or 'Basic' (application uses HTTP Basic).")

return cmd
}
Expand All @@ -110,11 +165,11 @@ func apiAppTypeFor(v string) string {
switch strings.ToLower(v) {
case "native":
return "native"
case "spa":
case "spa", "single page web application":
return "spa"
case "regular":
case "regular", "regular web application":
return "regular_web"
case "m2m":
case "m2m", "machine to machine":
return "non_interactive"

default:
Expand All @@ -130,3 +185,16 @@ func apiCallbacksFor(s []string) []interface{} {
return res

}

func apiTokenEndpointAuthMethodFor(v string) *string {
switch strings.ToLower(v) {
case "none":
return auth0.String("none")
case "post":
return auth0.String("client_secret_post")
case "basic":
return auth0.String("client_secret_basic")
default:
return nil
}
}
25 changes: 25 additions & 0 deletions internal/display/clients.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,14 @@ import (
"gopkg.in/auth0.v5/management"
)

const (
quickstartsNative = "https://auth0.com/docs/quickstart/native"
quickstartsSPA = "https://auth0.com/docs/quickstart/spa"
quickstartsRegularWeb = "https://auth0.com/docs/quickstart/webapp"
quickstartsM2M = "https://auth0.com/docs/quickstart/backend"
quickstartsGeneric = "https://auth0.com/docs/quickstarts"
)

type clientView struct {
Name string
Type string
Expand Down Expand Up @@ -79,6 +87,8 @@ func (r *Renderer) ClientCreate(client *management.Client, revealSecrets bool) {
}

r.Results([]View{v})

r.Infof("\nQuickstarts: %s", quickstartsURIFor(client.AppType))
}

// TODO(cyx): determine if there's a better way to filter this out.
Expand Down Expand Up @@ -106,6 +116,21 @@ func appTypeFor(v *string) string {
}
}

func quickstartsURIFor(v *string) string {
switch {
case *v == "native":
return quickstartsNative
case *v == "spa":
return quickstartsSPA
case *v == "regular_web":
return quickstartsRegularWeb
case *v == "non_interactive":
return quickstartsM2M
default:
return quickstartsGeneric
}
}

func callbacksFor(s []interface{}) []string {
res := make([]string, len(s))
for i, v := range s {
Expand Down