From 60048b3fb19413ea91c602c98271dd7d9d2be777 Mon Sep 17 00:00:00 2001 From: Cyril David Date: Wed, 27 Jan 2021 11:01:34 -0800 Subject: [PATCH 1/5] This just moves quickstart to root and adds an alias I'll follow up with the actual nitty gritty to use the map and such --- internal/cli/clients.go | 1 - internal/cli/clients_quickstart.go | 182 ----------------------------- internal/cli/root.go | 1 + 3 files changed, 1 insertion(+), 183 deletions(-) delete mode 100644 internal/cli/clients_quickstart.go diff --git a/internal/cli/clients.go b/internal/cli/clients.go index 633b7ed8a..ebeb33227 100644 --- a/internal/cli/clients.go +++ b/internal/cli/clients.go @@ -20,7 +20,6 @@ func clientsCmd(cli *cli) *cobra.Command { cmd.SetUsageTemplate(resourceUsageTemplate()) cmd.AddCommand(clientsListCmd(cli)) cmd.AddCommand(clientsCreateCmd(cli)) - cmd.AddCommand(clientsQuickstartCmd(cli)) return cmd } diff --git a/internal/cli/clients_quickstart.go b/internal/cli/clients_quickstart.go deleted file mode 100644 index 5141e55be..000000000 --- a/internal/cli/clients_quickstart.go +++ /dev/null @@ -1,182 +0,0 @@ -package cli - -import ( - "bytes" - "context" - "encoding/json" - "fmt" - "io" - "io/ioutil" - "net/http" - "os" - "path" - "regexp" - - "github.com/auth0/auth0-cli/internal/ansi" - "github.com/mholt/archiver/v3" - "github.com/spf13/cobra" - "gopkg.in/auth0.v5/management" -) - -func clientsQuickstartCmd(cli *cli) *cobra.Command { - var flags struct { - ClientID string - Type string - } - - cmd := &cobra.Command{ - Use: "quickstart", - Short: "Clients quickstart support for getting bootstrapped.", - Long: `$ auth0 clients quickstart --type --client-id `, - RunE: func(cmd *cobra.Command, args []string) error { - client, err := cli.api.Client.Read(flags.ClientID) - if err != nil { - return err - } - - target, exists, err := quickstartPathFor(client) - if err != nil { - return err - } - - if exists { - // TODO(cyx): prompt for a warning to force overwrite. - // For now, we're just exiting to simplify this first stab. - cli.renderer.Warnf("WARNING: %s already exists. Run with --force to overwrite", target) - return nil - } - - err = ansi.Spinner("Downloading quickstart", func() error { - return downloadQuickStart(context.TODO(), cli, client, target) - }) - - if err != nil { - return err - } - - cli.renderer.Infof("Quickstart sucessfully downloaded at %s", target) - return nil - }, - } - - cmd.SetUsageTemplate(resourceUsageTemplate()) - cmd.Flags().StringVar(&flags.ClientID, "client-id", "", "ID of the client.") - cmd.Flags().StringVarP(&flags.Type, "type", "t", "", "Type of the quickstart to download.") - mustRequireFlags(cmd, "client-id", "type") - - return cmd -} - -const ( - quickstartEndpoint = `https://auth0.com/docs/package/v2` - quickstartContentType = `application/json` - quickstartOrg = "auth0-samples" - quickstartDefaultCallbackURL = `https://YOUR_APP/callback` -) - -func downloadQuickStart(ctx context.Context, cli *cli, client *management.Client, target string) error { - var payload struct { - Branch string `json:"branch"` - Org string `json:"org"` - Repo string `json:"repo"` - Path string `json:"path"` - ClientID string `json:"client_id"` - ClientSecret string `json:"client_secret"` - CallbackURL string `json:"callback_url"` - Domain string `json:"domain"` - Tenant string `json:"tenant"` - } - - ten, err := cli.getTenant() - if err != nil { - return err - } - - payload.Tenant = ten.Name - payload.Domain = ten.Domain - - // FIXME(cyx): these are hard coded. We can followup with a lookup - // table -- which I don't know if there's a canonical place for that - // already. - payload.Branch = "master" - payload.Repo = "auth0-cordova-samples" - payload.Path = "01-Login" - - // These appear to be largely constant and refers to the github - // username they're under. - payload.Org = quickstartOrg - payload.ClientID = client.GetClientID() - payload.ClientSecret = client.GetClientSecret() - - // Callback URL, if not set, will just take the default one. - payload.CallbackURL = quickstartDefaultCallbackURL - if list := callbacksFor(client.Callbacks); len(list) > 0 { - payload.CallbackURL = list[0] - } - - buf := &bytes.Buffer{} - if err := json.NewEncoder(buf).Encode(payload); err != nil { - return err - } - - req, err := http.NewRequest("POST", quickstartEndpoint, buf) - if err != nil { - return err - } - req.Header.Set("Content-Type", quickstartContentType) - - res, err := http.DefaultClient.Do(req) - if err != nil { - return err - } - - if res.StatusCode != http.StatusOK { - return fmt.Errorf("Expected status %d, got %d", http.StatusOK, res.StatusCode) - } - - tmpfile, err := ioutil.TempFile("", "auth0-quickstart*.zip") - if err != nil { - return err - } - - _, err = io.Copy(tmpfile, res.Body) - if err != nil { - return err - } - - if err := tmpfile.Close(); err != nil { - return err - } - defer os.Remove(tmpfile.Name()) - - if err := archiver.Unarchive(tmpfile.Name(), target); err != nil { - return err - } - - return nil -} - -func quickstartPathFor(client *management.Client) (p string, exists bool, err error) { - wd, err := os.Getwd() - if err != nil { - return "", false, err - } - - re := regexp.MustCompile(`[^\w]+`) - friendlyName := re.ReplaceAllString(client.GetName(), "-") - target := path.Join(wd, friendlyName) - - exists = true - if _, err := os.Stat(target); err != nil { - if !os.IsNotExist(err) { - return "", false, err - } - exists = false - } - - if err := os.MkdirAll(target, 0755); err != nil { - return "", false, err - } - - return target, exists, nil -} diff --git a/internal/cli/root.go b/internal/cli/root.go index 321269639..6772d7d47 100644 --- a/internal/cli/root.go +++ b/internal/cli/root.go @@ -59,6 +59,7 @@ func Execute() { // order of the comamnds here matters // so add new commands in a place that reflect its relevance or relation with other commands: rootCmd.AddCommand(loginCmd(cli)) + rootCmd.AddCommand(quickstartCmd(cli)) rootCmd.AddCommand(clientsCmd(cli)) rootCmd.AddCommand(apisCmd(cli)) rootCmd.AddCommand(tryLoginCmd(cli)) From 0c819fa0edfe92bcf705a5a792d2f2bf2109a2e2 Mon Sep 17 00:00:00 2001 From: Cyril David Date: Wed, 27 Jan 2021 11:05:32 -0800 Subject: [PATCH 2/5] Add quickstart cmd --- internal/cli/quickstart.go | 197 +++++++++++++++++++++++++++++++++++++ 1 file changed, 197 insertions(+) create mode 100644 internal/cli/quickstart.go diff --git a/internal/cli/quickstart.go b/internal/cli/quickstart.go new file mode 100644 index 000000000..b39f4d8d2 --- /dev/null +++ b/internal/cli/quickstart.go @@ -0,0 +1,197 @@ +package cli + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "io" + "io/ioutil" + "net/http" + "os" + "path" + "regexp" + + "github.com/auth0/auth0-cli/internal/ansi" + "github.com/mholt/archiver/v3" + "github.com/spf13/cobra" + "gopkg.in/auth0.v5/management" +) + +func quickstartCmd(cli *cli) *cobra.Command { + cmd := &cobra.Command{ + Use: "quickstart", + Short: "quickstart support for getting bootstrapped.", + Aliases: []string{"qs"}, + } + + cmd.SetUsageTemplate(resourceUsageTemplate()) + cmd.AddCommand(quickstartDownloadCmd(cli)) + + return cmd +} + +func quickstartDownloadCmd(cli *cli) *cobra.Command { + var flags struct { + ClientID string + Type string + Stack string + } + + cmd := &cobra.Command{ + Use: "download", + Short: "Download a specific type and tech stack for quick starts.", + Long: `$ auth0 quickstart download --type --client-id --stack `, + RunE: func(cmd *cobra.Command, args []string) error { + client, err := cli.api.Client.Read(flags.ClientID) + if err != nil { + return err + } + + target, exists, err := quickstartPathFor(client) + if err != nil { + return err + } + + if exists { + // TODO(cyx): prompt for a warning to force overwrite. + // For now, we're just exiting to simplify this first stab. + cli.renderer.Warnf("WARNING: %s already exists. Run with --force to overwrite", target) + return nil + } + + err = ansi.Spinner("Downloading quickstart", func() error { + return downloadQuickStart(context.TODO(), cli, client, flags.Stack, target) + }) + + if err != nil { + return err + } + + cli.renderer.Infof("Quickstart sucessfully downloaded at %s", target) + return nil + }, + } + + cmd.SetUsageTemplate(resourceUsageTemplate()) + cmd.Flags().StringVar(&flags.ClientID, "client-id", "", "ID of the client.") + cmd.Flags().StringVarP(&flags.Type, "type", "t", "", "Type of the quickstart to download.") + cmd.Flags().StringVarP(&flags.Stack, "stack", "s", "", "Tech stack of the quickstart to use.") + mustRequireFlags(cmd, "client-id", "type", "stack") + + return cmd +} + +const ( + quickstartEndpoint = `https://auth0.com/docs/package/v2` + quickstartContentType = `application/json` + quickstartOrg = "auth0-samples" + quickstartDefaultCallbackURL = `https://YOUR_APP/callback` +) + +func downloadQuickStart(ctx context.Context, cli *cli, client *management.Client, target, stack string) error { + var payload struct { + Branch string `json:"branch"` + Org string `json:"org"` + Repo string `json:"repo"` + Path string `json:"path"` + ClientID string `json:"client_id"` + ClientSecret string `json:"client_secret"` + CallbackURL string `json:"callback_url"` + Domain string `json:"domain"` + Tenant string `json:"tenant"` + } + + ten, err := cli.getTenant() + if err != nil { + return err + } + + payload.Tenant = ten.Name + payload.Domain = ten.Domain + + // FIXME(cyx): these are hard coded. We can followup with a lookup + // table -- which I don't know if there's a canonical place for that + // already. + payload.Branch = "master" + payload.Repo = "auth0-cordova-samples" + payload.Path = "01-Login" + + // These appear to be largely constant and refers to the github + // username they're under. + payload.Org = quickstartOrg + payload.ClientID = client.GetClientID() + payload.ClientSecret = client.GetClientSecret() + + // Callback URL, if not set, will just take the default one. + payload.CallbackURL = quickstartDefaultCallbackURL + if list := callbacksFor(client.Callbacks); len(list) > 0 { + payload.CallbackURL = list[0] + } + + buf := &bytes.Buffer{} + if err := json.NewEncoder(buf).Encode(payload); err != nil { + return err + } + + req, err := http.NewRequest("POST", quickstartEndpoint, buf) + if err != nil { + return err + } + req.Header.Set("Content-Type", quickstartContentType) + + res, err := http.DefaultClient.Do(req) + if err != nil { + return err + } + + if res.StatusCode != http.StatusOK { + return fmt.Errorf("Expected status %d, got %d", http.StatusOK, res.StatusCode) + } + + tmpfile, err := ioutil.TempFile("", "auth0-quickstart*.zip") + if err != nil { + return err + } + + _, err = io.Copy(tmpfile, res.Body) + if err != nil { + return err + } + + if err := tmpfile.Close(); err != nil { + return err + } + defer os.Remove(tmpfile.Name()) + + if err := archiver.Unarchive(tmpfile.Name(), target); err != nil { + return err + } + + return nil +} + +func quickstartPathFor(client *management.Client) (p string, exists bool, err error) { + wd, err := os.Getwd() + if err != nil { + return "", false, err + } + + re := regexp.MustCompile(`[^\w]+`) + friendlyName := re.ReplaceAllString(client.GetName(), "-") + target := path.Join(wd, friendlyName) + + exists = true + if _, err := os.Stat(target); err != nil { + if !os.IsNotExist(err) { + return "", false, err + } + exists = false + } + + if err := os.MkdirAll(target, 0755); err != nil { + return "", false, err + } + + return target, exists, nil +} From 100d9b3ebd1c890f4686d50f4e5fe70a1792c0bd Mon Sep 17 00:00:00 2001 From: Cyril David Date: Wed, 27 Jan 2021 11:09:10 -0800 Subject: [PATCH 3/5] Update internal/cli/quickstart.go Co-authored-by: Jorge L. Fatta --- internal/cli/quickstart.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/cli/quickstart.go b/internal/cli/quickstart.go index b39f4d8d2..9f651b676 100644 --- a/internal/cli/quickstart.go +++ b/internal/cli/quickstart.go @@ -21,7 +21,7 @@ import ( func quickstartCmd(cli *cli) *cobra.Command { cmd := &cobra.Command{ Use: "quickstart", - Short: "quickstart support for getting bootstrapped.", + Short: "Quickstart support for getting bootstrapped", Aliases: []string{"qs"}, } From 6adbf6cf3f8386af50ce53cee76fa95c39e15b63 Mon Sep 17 00:00:00 2001 From: Cyril David Date: Wed, 27 Jan 2021 11:09:19 -0800 Subject: [PATCH 4/5] Update internal/cli/quickstart.go Co-authored-by: Jorge L. Fatta --- internal/cli/quickstart.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/cli/quickstart.go b/internal/cli/quickstart.go index 9f651b676..2d224740f 100644 --- a/internal/cli/quickstart.go +++ b/internal/cli/quickstart.go @@ -40,7 +40,7 @@ func quickstartDownloadCmd(cli *cli) *cobra.Command { cmd := &cobra.Command{ Use: "download", - Short: "Download a specific type and tech stack for quick starts.", + Short: "Download a specific type and tech stack for quick starts", Long: `$ auth0 quickstart download --type --client-id --stack `, RunE: func(cmd *cobra.Command, args []string) error { client, err := cli.api.Client.Read(flags.ClientID) From 570216c478236e0a9965c16229917cffcc33ee9a Mon Sep 17 00:00:00 2001 From: Cyril David Date: Wed, 27 Jan 2021 11:09:31 -0800 Subject: [PATCH 5/5] Update internal/cli/quickstart.go Co-authored-by: Jorge L. Fatta --- internal/cli/quickstart.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/cli/quickstart.go b/internal/cli/quickstart.go index 2d224740f..c1f1377d8 100644 --- a/internal/cli/quickstart.go +++ b/internal/cli/quickstart.go @@ -41,7 +41,7 @@ func quickstartDownloadCmd(cli *cli) *cobra.Command { cmd := &cobra.Command{ Use: "download", Short: "Download a specific type and tech stack for quick starts", - Long: `$ auth0 quickstart download --type --client-id --stack `, + Long: `auth0 quickstart download --type --client-id --stack `, RunE: func(cmd *cobra.Command, args []string) error { client, err := cli.api.Client.Read(flags.ClientID) if err != nil {