diff --git a/internal/cli/apis.go b/internal/cli/apis.go index a6a478861..9c33009b5 100644 --- a/internal/cli/apis.go +++ b/internal/cli/apis.go @@ -8,15 +8,15 @@ import ( ) const ( - id = "id" - name = "name" - identifier = "identifier" + apiID = "id" + apiName = "name" + apiIdentifier = "identifier" ) func apisCmd(cli *cli) *cobra.Command { cmd := &cobra.Command{ - Use: "apis", - Short: "manage resources for APIs.", + Use: "apis", + Short: "manage resources for APIs.", Aliases: []string{"resource-servers"}, } @@ -62,7 +62,7 @@ Lists your existing APIs. To create one try: func showApiCmd(cli *cli) *cobra.Command { var flags struct { - ID string + ID string } cmd := &cobra.Command{ @@ -72,12 +72,12 @@ func showApiCmd(cli *cli) *cobra.Command { auth0 apis show --id id `, - PreRun: func(cmd *cobra.Command, args []string) { + PreRun: func(cmd *cobra.Command, args []string) { prepareInteractivity(cmd) }, RunE: func(cmd *cobra.Command, args []string) error { - if shouldPrompt(cmd, id) { - input := prompt.TextInput(id, "Id:", "Id of the API.", "", true) + if shouldPrompt(cmd, apiID) { + input := prompt.TextInput(apiID, "Id:", "Id of the API.", "", true) if err := prompt.AskOne(input, &flags); err != nil { return err @@ -101,8 +101,8 @@ auth0 apis show --id id }, } - cmd.Flags().StringVarP(&flags.ID, id, "i", "", "ID of the API.") - mustRequireFlags(cmd, id) + cmd.Flags().StringVarP(&flags.ID, apiID, "i", "", "ID of the API.") + mustRequireFlags(cmd, apiID) return cmd } @@ -120,15 +120,15 @@ func createApiCmd(cli *cli) *cobra.Command { auth0 apis create --name myapi --identifier http://my-api `, - PreRun: func(cmd *cobra.Command, args []string) { + PreRun: func(cmd *cobra.Command, args []string) { prepareInteractivity(cmd) }, RunE: func(cmd *cobra.Command, args []string) error { - if shouldPrompt(cmd, name) { + if shouldPrompt(cmd, apiName) { input := prompt.TextInput( - name, "Name:", - "Name of the API. You can change the API name later in the API settings.", - "", + apiName, "Name:", + "Name of the API. You can change the API name later in the API settings.", + "", true) if err := prompt.AskOne(input, &flags); err != nil { @@ -136,11 +136,11 @@ auth0 apis create --name myapi --identifier http://my-api } } - if shouldPrompt(cmd, identifier) { + if shouldPrompt(cmd, apiIdentifier) { input := prompt.TextInput( - identifier, "Identifier:", - "Identifier of the API. Cannot be changed once set.", - "", + apiIdentifier, "Identifier:", + "Identifier of the API. Cannot be changed once set.", + "", true) if err := prompt.AskOne(input, &flags); err != nil { @@ -166,9 +166,9 @@ auth0 apis create --name myapi --identifier http://my-api }, } - cmd.Flags().StringVarP(&flags.Name, name, "n", "", "Name of the API.") - cmd.Flags().StringVarP(&flags.Identifier, identifier, "i", "", "Identifier of the API.") - mustRequireFlags(cmd, name, identifier) + cmd.Flags().StringVarP(&flags.Name, apiName, "n", "", "Name of the API.") + cmd.Flags().StringVarP(&flags.Identifier, apiIdentifier, "i", "", "Identifier of the API.") + mustRequireFlags(cmd, apiName, apiIdentifier) return cmd } @@ -186,20 +186,20 @@ func updateApiCmd(cli *cli) *cobra.Command { auth0 apis update --id id --name myapi `, - PreRun: func(cmd *cobra.Command, args []string) { + PreRun: func(cmd *cobra.Command, args []string) { prepareInteractivity(cmd) }, RunE: func(cmd *cobra.Command, args []string) error { - if shouldPrompt(cmd, id) { - input := prompt.TextInput(id, "Id:", "Id of the API.", "", true) + if shouldPrompt(cmd, apiID) { + input := prompt.TextInput(apiID, "Id:", "Id of the API.", "", true) if err := prompt.AskOne(input, &flags); err != nil { return err } } - if shouldPrompt(cmd, name) { - input := prompt.TextInput(name, "Name:", "Name of the API.", "", true) + if shouldPrompt(cmd, apiName) { + input := prompt.TextInput(apiName, "Name:", "Name of the API.", "", true) if err := prompt.AskOne(input, &flags); err != nil { return err @@ -221,17 +221,16 @@ auth0 apis update --id id --name myapi }, } - cmd.Flags().StringVarP(&flags.ID, id, "i", "", "ID of the API.") - cmd.Flags().StringVarP(&flags.Name, name, "n", "", "Name of the API.") - mustRequireFlags(cmd, id, name) + cmd.Flags().StringVarP(&flags.ID, apiID, "i", "", "ID of the API.") + cmd.Flags().StringVarP(&flags.Name, apiName, "n", "", "Name of the API.") + mustRequireFlags(cmd, apiID, apiName) return cmd } func deleteApiCmd(cli *cli) *cobra.Command { var flags struct { - ID string - force bool + ID string } cmd := &cobra.Command{ @@ -239,26 +238,26 @@ func deleteApiCmd(cli *cli) *cobra.Command { Short: "Delete an API", Long: `Deletes an API: -auth0 apis delete --id id --force +auth0 apis delete --id id `, - PreRun: func(cmd *cobra.Command, args []string) { + PreRun: func(cmd *cobra.Command, args []string) { prepareInteractivity(cmd) }, RunE: func(cmd *cobra.Command, args []string) error { - if shouldPrompt(cmd, id) { - input := prompt.TextInput(id, "Id:", "Id of the API.", "", true) + if shouldPrompt(cmd, apiID) { + input := prompt.TextInput(apiID, "Id:", "Id of the API.", "", true) if err := prompt.AskOne(input, &flags); err != nil { return err } } - if !flags.force && canPrompt() { + if !cli.force && canPrompt() { if confirmed := prompt.Confirm("Are you sure you want to proceed?"); !confirmed { return nil } } - + err := ansi.Spinner("Deleting API", func() error { return cli.api.ResourceServer.Delete(flags.ID) }) @@ -271,9 +270,8 @@ auth0 apis delete --id id --force }, } - cmd.Flags().StringVarP(&flags.ID, id, "i", "", "ID of the API.") - cmd.Flags().BoolVarP(&flags.force, "force", "f", false, "Do not ask for confirmation.") - mustRequireFlags(cmd, id) + cmd.Flags().StringVarP(&flags.ID, apiID, "i", "", "ID of the API.") + mustRequireFlags(cmd, apiID) return cmd } diff --git a/internal/cli/cli.go b/internal/cli/cli.go index 72201ef87..933439f7b 100644 --- a/internal/cli/cli.go +++ b/internal/cli/cli.go @@ -223,16 +223,6 @@ func (c *cli) initContext() (err error) { return nil } -func hasFlags(cmd *cobra.Command) bool { - return cmd.Flags().NFlag() > 0 -} - -func checkFlags(cmd *cobra.Command) { - if (!hasFlags(cmd)) { - cmd.ResetFlags() - } -} - func mustRequireFlags(cmd *cobra.Command, flags ...string) { for _, f := range flags { if err := cmd.MarkFlagRequired(f); err != nil { @@ -246,7 +236,7 @@ func canPrompt() bool { } func shouldPrompt(cmd *cobra.Command, flag string) bool { - return ansi.IsTerminal() && !cmd.Flags().Changed(flag) + return canPrompt() && !cmd.Flags().Changed(flag) } func prepareInteractivity(cmd *cobra.Command) { diff --git a/internal/cli/rules.go b/internal/cli/rules.go index f8fc98938..32d5665d8 100644 --- a/internal/cli/rules.go +++ b/internal/cli/rules.go @@ -4,7 +4,6 @@ import ( "fmt" "regexp" - "github.com/AlecAivazis/survey/v2" "github.com/auth0/auth0-cli/internal/ansi" "github.com/auth0/auth0-cli/internal/auth0" "github.com/auth0/auth0-cli/internal/prompt" @@ -12,6 +11,14 @@ import ( "gopkg.in/auth0.v5/management" ) +const ( + ruleID = "id" + ruleName = "name" + ruleScript = "script" + ruleOrder = "order" + ruleEnabled = "enabled" +) + func rulesCmd(cli *cli) *cobra.Command { cmd := &cobra.Command{ Use: "rules", @@ -54,11 +61,29 @@ func listRulesCmd(cli *cli) *cobra.Command { } func enableRuleCmd(cli *cli) *cobra.Command { - var name string + var flags struct { + Name string + } + cmd := &cobra.Command{ Use: "enable", - Short: "enable rule", + Short: "Emable a rule", + PreRun: func(cmd *cobra.Command, args []string) { + prepareInteractivity(cmd) + }, RunE: func(cmd *cobra.Command, args []string) error { + if shouldPrompt(cmd, ruleName) { + input := prompt.TextInput( + ruleName, "Name:", + "Name of the rule.", + "", + true) + + if err := prompt.AskOne(input, &flags); err != nil { + return err + } + } + err := ansi.Spinner("Enabling rule", func() error { var err error data, err := getRules(cli) @@ -66,14 +91,14 @@ func enableRuleCmd(cli *cli) *cobra.Command { return err } - rule := findRuleByName(name, data.Rules) + rule := findRuleByName(flags.Name, data.Rules) if rule != nil { err := enableRule(rule, cli) if err != nil { return err } } else { - return fmt.Errorf("No rule found with name: %q", name) + return fmt.Errorf("No rule found with name: %q", flags.Name) } return nil }) @@ -95,17 +120,36 @@ func enableRuleCmd(cli *cli) *cobra.Command { }, } - cmd.Flags().StringVarP(&name, "name", "n", "", "rule name") - mustRequireFlags(cmd, "name") + cmd.Flags().StringVarP(&flags.Name, ruleName, "n", "", "Name of the rule.") + mustRequireFlags(cmd, ruleName) + return cmd } func disableRuleCmd(cli *cli) *cobra.Command { - var name string + var flags struct { + Name string + } + cmd := &cobra.Command{ Use: "disable", - Short: "disable rule", + Short: "Disable a rule", + PreRun: func(cmd *cobra.Command, args []string) { + prepareInteractivity(cmd) + }, RunE: func(cmd *cobra.Command, args []string) error { + if shouldPrompt(cmd, ruleName) { + input := prompt.TextInput( + ruleName, "Name:", + "Name of the rule.", + "", + true) + + if err := prompt.AskOne(input, &flags); err != nil { + return err + } + } + err := ansi.Spinner("Disabling rule", func() error { var err error data, err := getRules(cli) @@ -113,13 +157,13 @@ func disableRuleCmd(cli *cli) *cobra.Command { return err } - rule := findRuleByName(name, data.Rules) + rule := findRuleByName(flags.Name, data.Rules) if rule != nil { if err := disableRule(rule, cli); err != nil { return err } } else { - return fmt.Errorf("No rule found with name: %q", name) + return fmt.Errorf("No rule found with name: %q", flags.Name) } return nil }) @@ -141,8 +185,8 @@ func disableRuleCmd(cli *cli) *cobra.Command { }, } - cmd.Flags().StringVarP(&name, "name", "n", "", "rule name") - mustRequireFlags(cmd, "name") + cmd.Flags().StringVarP(&flags.Name, ruleName, "n", "", "rule name") + mustRequireFlags(cmd, ruleName) return cmd } @@ -163,21 +207,41 @@ func createRulesCmd(cli *cli) *cobra.Command { auth0 rules create --name "My Rule" --script "function (user, context, callback) { console.log( 'Hello, world!' ); return callback(null, user, context); }" `, PreRun: func(cmd *cobra.Command, args []string) { - checkFlags(cmd) + prepareInteractivity(cmd) }, RunE: func(cmd *cobra.Command, args []string) error { - if !hasFlags(cmd) { - name := prompt.TextInput( - "name", "Name:", - "Name of the rule. You can change the rule name later in the rule settings.", - "", + if shouldPrompt(cmd, ruleName) { + input := prompt.TextInput( + "name", "Name:", + "Name of the rule. You can change the rule name later in the rule settings.", + "", true) - script := prompt.TextInput("script", "Script:", "Script of the rule.", "", true) - order := prompt.TextInput("order", "Order:", "Order of the rule.", "0", false) - enabled := prompt.BoolInput("enabled", "Enabled:", "Enable the rule.", false) + if err := prompt.AskOne(input, &flags); err != nil { + return err + } + } + + if shouldPrompt(cmd, ruleScript) { + input := prompt.TextInput(ruleScript, "Script:", "Script of the rule.", "", true) - if err := prompt.Ask([]*survey.Question {name, script, order, enabled}, &flags); err != nil { + if err := prompt.AskOne(input, &flags); err != nil { + return err + } + } + + if shouldPrompt(cmd, ruleOrder) { + input := prompt.TextInput(ruleOrder, "Order:", "Order of the rule.", "0", false) + + if err := prompt.AskOne(input, &flags); err != nil { + return err + } + } + + if shouldPrompt(cmd, ruleEnabled) { + input := prompt.BoolInput(ruleEnabled, "Enabled:", "Enable the rule.", false) + + if err := prompt.AskOne(input, &flags); err != nil { return err } } @@ -202,19 +266,19 @@ func createRulesCmd(cli *cli) *cobra.Command { }, } - cmd.Flags().StringVarP(&flags.Name, "name", "n", "", "Name of this rule (required)") - cmd.Flags().StringVarP(&flags.Script, "script", "s", "", "Code to be executed when this rule runs (required)") - cmd.Flags().IntVarP(&flags.Order, "order", "o", 0, "Order that this rule should execute in relative to other rules. Lower-valued rules execute first.") - cmd.Flags().BoolVarP(&flags.Enabled, "enabled", "e", false, "Whether the rule is enabled (true), or disabled (false).") - mustRequireFlags(cmd, "name", "script") + cmd.Flags().StringVarP(&flags.Name, ruleName, "n", "", "Name of this rule (required)") + cmd.Flags().StringVarP(&flags.Script, ruleScript, "s", "", "Code to be executed when this rule runs (required)") + cmd.Flags().IntVarP(&flags.Order, ruleOrder, "o", 0, "Order that this rule should execute in relative to other rules. Lower-valued rules execute first.") + cmd.Flags().BoolVarP(&flags.Enabled, ruleEnabled, "e", false, "Whether the rule is enabled (true), or disabled (false).") + mustRequireFlags(cmd, ruleName, ruleScript) + return cmd } func deleteRulesCmd(cli *cli) *cobra.Command { var flags struct { - id string - name string - force bool + ID string + Name string } cmd := &cobra.Command{ @@ -222,45 +286,54 @@ func deleteRulesCmd(cli *cli) *cobra.Command { Short: "Delete a rule", Long: `Delete a rule: - auth0 rules delete --id "12345" --force`, + auth0 rules delete --id "12345"`, PreRunE: func(cmd *cobra.Command, args []string) error { - if flags.id != "" && flags.name != "" { + if flags.ID != "" && flags.Name != "" { return fmt.Errorf("TMI! 🤯 use either --name or --id") } + + prepareInteractivity(cmd) return nil }, RunE: func(cmd *cobra.Command, args []string) error { - if !flags.force { + if shouldPrompt(cmd, ruleID) { + input := prompt.TextInput(ruleID, "Id:", "Id of the rule.", "", true) + + if err := prompt.AskOne(input, &flags); err != nil { + return err + } + } + + if !cli.force && canPrompt() { if confirmed := prompt.Confirm("Are you sure you want to proceed?"); !confirmed { return nil } } - // TODO: Should add validation of rule var r *management.Rule - ruleIDPattern := "^rul_[A-Za-z0-9]{16}$" - re := regexp.MustCompile(ruleIDPattern) - - if flags.id != "" { - if !re.Match([]byte(flags.id)) { - return fmt.Errorf("Rule with id %q does not match pattern %s", flags.id, ruleIDPattern) - } - - rule, err := cli.api.Rule.Read(flags.id) - if err != nil { - return err - } - r = rule - } else { - data, err := getRules(cli) - if err != nil { - return err - } - if rule := findRuleByName(flags.name, data.Rules); rule != nil { - r = rule - } else { - return fmt.Errorf("No rule found with name: %q", flags.name) - } + ruleIDPattern := "^rul_[A-Za-z0-9]{16}$" + re := regexp.MustCompile(ruleIDPattern) + + if flags.ID != "" { + if !re.Match([]byte(flags.ID)) { + return fmt.Errorf("Rule with id %q does not match pattern %s", flags.ID, ruleIDPattern) + } + + rule, err := cli.api.Rule.Read(flags.ID) + if err != nil { + return err + } + r = rule + } else { + data, err := getRules(cli) + if err != nil { + return err + } + if rule := findRuleByName(flags.Name, data.Rules); rule != nil { + r = rule + } else { + return fmt.Errorf("No rule found with name: %q", flags.Name) + } } err := ansi.Spinner("Deleting rule", func() error { @@ -275,9 +348,8 @@ func deleteRulesCmd(cli *cli) *cobra.Command { }, } - cmd.Flags().StringVarP(&flags.id, "id", "i", "", "ID of the rule to delete (required)") - cmd.Flags().StringVarP(&flags.name, "name", "n", "", "Name of the rule to delete") - cmd.Flags().BoolVarP(&flags.force, "force", "f", false, "Do not ask for confirmation.") + cmd.Flags().StringVarP(&flags.ID, ruleID, "i", "", "ID of the rule to delete (required)") + cmd.Flags().StringVarP(&flags.Name, ruleName, "n", "", "Name of the rule to delete") return cmd } diff --git a/internal/prompt/prompt.go b/internal/prompt/prompt.go index 07c117eeb..1f0b09684 100644 --- a/internal/prompt/prompt.go +++ b/internal/prompt/prompt.go @@ -9,7 +9,7 @@ import ( var stdErrWriter = survey.WithStdio(os.Stdin, os.Stderr, os.Stderr) var icons = survey.WithIcons(func(icons *survey.IconSet) { - icons.Question.Text = "" + icons.Question.Text = "" }) func Ask(inputs []*survey.Question, response interface{}) error { @@ -17,7 +17,7 @@ func Ask(inputs []*survey.Question, response interface{}) error { } func AskOne(input *survey.Question, response interface{}) error { - return survey.Ask([]*survey.Question {input}, response, stdErrWriter, icons) + return survey.Ask([]*survey.Question{input}, response, stdErrWriter, icons) } func askOne(prompt survey.Prompt, response interface{}) error { @@ -26,8 +26,8 @@ func askOne(prompt survey.Prompt, response interface{}) error { func TextInput(name string, message string, help string, value string, required bool) *survey.Question { input := &survey.Question{ - Name: name, - Prompt: &survey.Input{Message: message, Help: help, Default: value}, + Name: name, + Prompt: &survey.Input{Message: message, Help: help, Default: value}, } if required { diff --git a/vendor/modules.txt b/vendor/modules.txt index ce40a8c49..a29bdb6bd 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -43,6 +43,7 @@ github.com/logrusorgru/aurora ## explicit github.com/mattn/go-colorable # github.com/mattn/go-isatty v0.0.12 +## explicit github.com/mattn/go-isatty # github.com/mattn/go-runewidth v0.0.10 ## explicit