diff --git a/go.mod b/go.mod index 3bdffe579..2847f6e0b 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/auth0/auth0-cli -go 1.20 +go 1.21 require ( github.com/AlecAivazis/survey/v2 v2.3.7 diff --git a/internal/cli/actions.go b/internal/cli/actions.go index 20999caad..12994ded4 100644 --- a/internal/cli/actions.go +++ b/internal/cli/actions.go @@ -371,7 +371,7 @@ func deleteActionCmd(cli *cli) *cobra.Command { auth0 actions delete auth0 actions delete --force`, RunE: func(cmd *cobra.Command, args []string) error { - var ids []string + ids := make([]string, len(args)) if len(args) == 0 { if err := actionID.PickMany(cmd, &ids, cli.actionPickerOptions); err != nil { return err diff --git a/internal/cli/apis.go b/internal/cli/apis.go index ffb91f9a4..f68cc9e67 100644 --- a/internal/cli/apis.go +++ b/internal/cli/apis.go @@ -390,14 +390,10 @@ func updateAPICmd(cli *cli) *cobra.Command { } func deleteAPICmd(cli *cli) *cobra.Command { - var inputs struct { - ID string - } - cmd := &cobra.Command{ Use: "delete", Aliases: []string{"rm"}, - Args: cobra.MaximumNArgs(1), + Args: cobra.MinimumNArgs(0), Short: "Delete an API", Long: "Delete an API.\n\n" + "To delete interactively, use `auth0 apis delete` with no arguments.\n\n" + @@ -407,13 +403,15 @@ func deleteAPICmd(cli *cli) *cobra.Command { auth0 apis delete auth0 apis delete --force`, RunE: func(cmd *cobra.Command, args []string) error { + var ids []string if len(args) == 0 { - err := apiID.Pick(cmd, &inputs.ID, cli.apiPickerOptions) - if err != nil { + if err := apiID.PickMany(cmd, &ids, cli.apiPickerOptions); err != nil { return err } } else { - inputs.ID = args[0] + for _, id := range args[0:] { + ids = append(ids, id) + } } if !cli.force && canPrompt(cmd) { @@ -423,13 +421,17 @@ func deleteAPICmd(cli *cli) *cobra.Command { } return ansi.Spinner("Deleting API", func() error { - _, err := cli.api.ResourceServer.Read(cmd.Context(), url.PathEscape(inputs.ID)) + var errs []error + for _, id := range ids { + if _, err := cli.api.ResourceServer.Read(cmd.Context(), url.PathEscape(id)); err != nil { + errs = append(errs, fmt.Errorf("Unable to read API for deletion: %w", err)) + } - if err != nil { - return fmt.Errorf("Unable to delete API: %w", err) + if err := cli.api.ResourceServer.Delete(cmd.Context(), url.PathEscape(id)); err != nil { + errs = append(errs, fmt.Errorf("Unable to delete API: %w", err)) + } } - - return cli.api.ResourceServer.Delete(cmd.Context(), url.PathEscape(inputs.ID)) + return errors.Join(errs...) }) }, } diff --git a/internal/cli/apps.go b/internal/cli/apps.go index 6eb76c7ea..d39bd5e9e 100644 --- a/internal/cli/apps.go +++ b/internal/cli/apps.go @@ -4,6 +4,7 @@ import ( "context" "errors" "fmt" + "net/url" "strings" "github.com/auth0/go-auth0/management" @@ -302,14 +303,10 @@ func showAppCmd(cli *cli) *cobra.Command { } func deleteAppCmd(cli *cli) *cobra.Command { - var inputs struct { - ID string - } - cmd := &cobra.Command{ Use: "delete", Aliases: []string{"rm"}, - Args: cobra.MaximumNArgs(1), + Args: cobra.MinimumNArgs(0), Short: "Delete an application", Long: "Delete an application.\n\n" + "To delete interactively, use `auth0 apps delete` with no arguments.\n\n" + @@ -320,13 +317,16 @@ func deleteAppCmd(cli *cli) *cobra.Command { auth0 apps delete auth0 apps delete --force`, RunE: func(cmd *cobra.Command, args []string) error { + ids := make([]string, len(args)) if len(args) == 0 { - err := appID.Pick(cmd, &inputs.ID, cli.appPickerOptions()) + err := appID.PickMany(cmd, &ids, cli.appPickerOptions()) if err != nil { return err } } else { - inputs.ID = args[0] + for _, id := range args[0:] { + ids = append(ids, id) + } } if !cli.force && canPrompt(cmd) { @@ -336,13 +336,17 @@ func deleteAppCmd(cli *cli) *cobra.Command { } return ansi.Spinner("Deleting Application", func() error { - _, err := cli.api.Client.Read(cmd.Context(), inputs.ID) + var errs []error + for _, id := range ids { + if _, err := cli.api.Client.Read(cmd.Context(), url.PathEscape(id)); err != nil { + errs = append(errs, fmt.Errorf("Unable to read application for deletion: %w", err)) + } - if err != nil { - return fmt.Errorf("Unable to delete application: %w", err) + if err := cli.api.Client.Delete(cmd.Context(), url.PathEscape(id)); err != nil { + errs = append(errs, fmt.Errorf("Unable to delete application: %w", err)) + } } - - return cli.api.Client.Delete(cmd.Context(), inputs.ID) + return errors.Join(errs...) }) }, } diff --git a/internal/cli/custom_domains.go b/internal/cli/custom_domains.go index f651204c6..d5e348e0c 100644 --- a/internal/cli/custom_domains.go +++ b/internal/cli/custom_domains.go @@ -2,6 +2,7 @@ package cli import ( "context" + "errors" "fmt" "net/url" @@ -323,14 +324,10 @@ func updateCustomDomainCmd(cli *cli) *cobra.Command { } func deleteCustomDomainCmd(cli *cli) *cobra.Command { - var inputs struct { - ID string - } - cmd := &cobra.Command{ Use: "delete", Aliases: []string{"rm"}, - Args: cobra.MaximumNArgs(1), + Args: cobra.MinimumNArgs(0), Short: "Delete a custom domain", Long: "Delete a custom domain.\n\n" + "To delete interactively, use `auth0 domains delete` with no arguments.\n\n" + @@ -341,13 +338,16 @@ func deleteCustomDomainCmd(cli *cli) *cobra.Command { auth0 domains delete auth0 domains delete --force`, RunE: func(cmd *cobra.Command, args []string) error { + ids := make([]string, len(args)) if len(args) == 0 { - err := customDomainID.Pick(cmd, &inputs.ID, cli.customDomainsPickerOptions) + err := customDomainID.PickMany(cmd, &ids, cli.customDomainsPickerOptions) if err != nil { return err } } else { - inputs.ID = args[0] + for _, id := range args[0:] { + ids = append(ids, id) + } } if !cli.force && canPrompt(cmd) { @@ -357,13 +357,18 @@ func deleteCustomDomainCmd(cli *cli) *cobra.Command { } return ansi.Spinner("Deleting custom domain", func() error { - _, err := cli.api.CustomDomain.Read(cmd.Context(), url.PathEscape(inputs.ID)) - - if err != nil { - return fmt.Errorf("Unable to delete custom domain: %w", err) + var errs []error + for _, id := range ids { + if _, err := cli.api.CustomDomain.Read(cmd.Context(), url.PathEscape(id)); err != nil { + return fmt.Errorf("Unable to read custom domain for deletion: %w", err) + } + + if err := cli.api.CustomDomain.Delete(cmd.Context(), url.PathEscape(id)); err != nil { + return fmt.Errorf("Unable to delete custom domain: %w", err) + } } - return cli.api.CustomDomain.Delete(cmd.Context(), url.PathEscape(inputs.ID)) + return errors.Join(errs...) }) }, } diff --git a/internal/cli/log_streams.go b/internal/cli/log_streams.go index 64d671016..6d4a497e1 100644 --- a/internal/cli/log_streams.go +++ b/internal/cli/log_streams.go @@ -168,14 +168,10 @@ func updateLogStreamCmd(cli *cli) *cobra.Command { } func deleteLogStreamCmd(cli *cli) *cobra.Command { - var inputs struct { - ID string - } - cmd := &cobra.Command{ Use: "delete", Aliases: []string{"rm"}, - Args: cobra.MaximumNArgs(1), + Args: cobra.MinimumNArgs(0), Short: "Delete a log stream", Long: "Delete a log stream.\n\n" + "To delete interactively, use `auth0 logs streams delete` with no arguments.\n\n" + @@ -186,13 +182,16 @@ func deleteLogStreamCmd(cli *cli) *cobra.Command { auth0 logs streams delete auth0 logs streams delete --force`, RunE: func(cmd *cobra.Command, args []string) error { + ids := make([]string, len(args)) if len(args) == 0 { - err := logStreamID.Pick(cmd, &inputs.ID, cli.allLogStreamsPickerOptions) + err := logStreamID.PickMany(cmd, &ids, cli.allLogStreamsPickerOptions) if err != nil { return err } } else { - inputs.ID = args[0] + for _, id := range args[0:] { + ids = append(ids, id) + } } if !cli.force && canPrompt(cmd) { @@ -202,13 +201,17 @@ func deleteLogStreamCmd(cli *cli) *cobra.Command { } return ansi.Spinner("Deleting Log Stream", func() error { - _, err := cli.api.LogStream.Read(cmd.Context(), inputs.ID) - - if err != nil { - return fmt.Errorf("Unable to delete log stream: %w", err) + var errs []error + for _, id := range ids { + if _, err := cli.api.LogStream.Read(cmd.Context(), id); err != nil { + errs = append(errs, fmt.Errorf("Unable to read log stream for deletion: %w", err)) + } + if err := cli.api.LogStream.Delete(cmd.Context(), id); err != nil { + errs = append(errs, fmt.Errorf("Unable to delete log stream: %w", err)) + } } - return cli.api.LogStream.Delete(cmd.Context(), inputs.ID) + return errors.Join(errs...) }) }, } diff --git a/internal/cli/organizations.go b/internal/cli/organizations.go index ba5192eb3..71795c99c 100644 --- a/internal/cli/organizations.go +++ b/internal/cli/organizations.go @@ -408,14 +408,10 @@ func updateOrganizationCmd(cli *cli) *cobra.Command { } func deleteOrganizationCmd(cli *cli) *cobra.Command { - var inputs struct { - ID string - } - cmd := &cobra.Command{ Use: "delete", Aliases: []string{"rm"}, - Args: cobra.MaximumNArgs(1), + Args: cobra.MinimumNArgs(0), Short: "Delete an organization", Long: "Delete an organization.\n\n" + "To delete interactively, use `auth0 orgs delete` with no arguments.\n\n" + @@ -426,13 +422,16 @@ func deleteOrganizationCmd(cli *cli) *cobra.Command { auth0 orgs delete auth0 orgs delete --force`, RunE: func(cmd *cobra.Command, args []string) error { + ids := make([]string, len(args)) if len(args) == 0 { - err := organizationID.Pick(cmd, &inputs.ID, cli.organizationPickerOptions) + err := organizationID.PickMany(cmd, &ids, cli.organizationPickerOptions) if err != nil { return err } } else { - inputs.ID = args[0] + for _, id := range args { + ids = append(ids, id) + } } if !cli.force && canPrompt(cmd) { @@ -442,13 +441,17 @@ func deleteOrganizationCmd(cli *cli) *cobra.Command { } return ansi.Spinner("Deleting organization", func() error { - _, err := cli.api.Organization.Read(cmd.Context(), url.PathEscape(inputs.ID)) + var errs []error + for _, id := range ids { + if _, err := cli.api.Organization.Read(cmd.Context(), url.PathEscape(id)); err != nil { + errs = append(errs, fmt.Errorf("Unable to read organization for deletion: %w", err)) + } - if err != nil { - return fmt.Errorf("Unable to delete organization: %w", err) + if err := cli.api.Organization.Delete(cmd.Context(), url.PathEscape(id)); err != nil { + errs = append(errs, fmt.Errorf("Unable to delete organization: %w", err)) + } } - - return cli.api.Organization.Delete(cmd.Context(), url.PathEscape(inputs.ID)) + return errors.Join(errs...) }) }, } diff --git a/internal/cli/roles.go b/internal/cli/roles.go index 96e25e420..c4789a6ef 100644 --- a/internal/cli/roles.go +++ b/internal/cli/roles.go @@ -282,14 +282,10 @@ func updateRoleCmd(cli *cli) *cobra.Command { } func deleteRoleCmd(cli *cli) *cobra.Command { - var inputs struct { - ID string - } - cmd := &cobra.Command{ Use: "delete", Aliases: []string{"rm"}, - Args: cobra.MaximumNArgs(1), + Args: cobra.MinimumNArgs(0), Short: "Delete a role", Long: "Delete a role.\n\n" + "To delete interactively, use `auth0 roles delete`.\n\n" + @@ -299,13 +295,16 @@ func deleteRoleCmd(cli *cli) *cobra.Command { auth0 roles delete auth0 roles delete --force`, RunE: func(cmd *cobra.Command, args []string) error { + ids := make([]string, len(args)) if len(args) == 0 { - err := roleID.Pick(cmd, &inputs.ID, cli.rolePickerOptions) + err := roleID.PickMany(cmd, &ids, cli.rolePickerOptions) if err != nil { return err } } else { - inputs.ID = args[0] + for _, id := range args { + ids = append(ids, id) + } } if !cli.force && canPrompt(cmd) { @@ -315,13 +314,17 @@ func deleteRoleCmd(cli *cli) *cobra.Command { } return ansi.Spinner("Deleting Role", func() error { - _, err := cli.api.Role.Read(cmd.Context(), inputs.ID) + var errs []error + for _, id := range ids { + if _, err := cli.api.Role.Read(cmd.Context(), id); err != nil { + errs = append(errs, fmt.Errorf("Unable to read role for deletion: %w", err)) + } - if err != nil { - return fmt.Errorf("Unable to delete role: %w", err) + if err := cli.api.Role.Delete(cmd.Context(), id); err != nil { + errs = append(errs, fmt.Errorf("Unable to delete role: %w", err)) + } } - - return cli.api.Role.Delete(cmd.Context(), inputs.ID) + return errors.Join(errs...) }) }, } diff --git a/internal/cli/rules.go b/internal/cli/rules.go index ac2f9d20b..a357416be 100644 --- a/internal/cli/rules.go +++ b/internal/cli/rules.go @@ -249,14 +249,10 @@ func showRuleCmd(cli *cli) *cobra.Command { } func deleteRuleCmd(cli *cli) *cobra.Command { - var inputs struct { - ID string - } - cmd := &cobra.Command{ Use: "delete", Aliases: []string{"rm"}, - Args: cobra.MaximumNArgs(1), + Args: cobra.MinimumNArgs(0), Short: "Delete a rule", Long: rulesDeprecationDocumentationText + "Delete a rule.\n\n" + "To delete interactively, use `auth0 rules delete` with no arguments.\n\n" + @@ -266,13 +262,16 @@ func deleteRuleCmd(cli *cli) *cobra.Command { auth0 rules delete auth0 rules delete --force`, RunE: func(cmd *cobra.Command, args []string) error { - if len(args) > 0 { - inputs.ID = args[0] - } else { - err := ruleID.Pick(cmd, &inputs.ID, cli.rulePickerOptions) + ids := make([]string, len(args)) + if len(args) == 0 { + err := ruleID.PickMany(cmd, &ids, cli.rulePickerOptions) if err != nil { return err } + } else { + for _, id := range args { + ids = append(ids, id) + } } if !cli.force && canPrompt(cmd) { @@ -282,13 +281,17 @@ func deleteRuleCmd(cli *cli) *cobra.Command { } return ansi.Spinner("Deleting Rule", func() error { - _, err := cli.api.Rule.Read(cmd.Context(), inputs.ID) + var errs []error + for _, id := range ids { + if _, err := cli.api.Rule.Read(cmd.Context(), id); err != nil { + errs = append(errs, fmt.Errorf("Unable to read rule for deletion: %w", err)) + } - if err != nil { - return fmt.Errorf("Unable to delete rule: %w", err) + if err := cli.api.Rule.Delete(cmd.Context(), id); err != nil { + errs = append(errs, fmt.Errorf("Unable to delete rule: %w", err)) + } } - - return cli.api.Rule.Delete(cmd.Context(), inputs.ID) + return errors.Join(errs...) }) }, } diff --git a/internal/cli/users.go b/internal/cli/users.go index 1e2fad6b6..9d95e6831 100644 --- a/internal/cli/users.go +++ b/internal/cli/users.go @@ -357,14 +357,10 @@ func showUserCmd(cli *cli) *cobra.Command { } func deleteUserCmd(cli *cli) *cobra.Command { - var inputs struct { - ID string - } - cmd := &cobra.Command{ Use: "delete", Aliases: []string{"rm"}, - Args: cobra.MaximumNArgs(1), + Args: cobra.MinimumNArgs(0), Short: "Delete a user", Long: "Delete a user.\n\n" + "To delete interactively, use `auth0 users delete` with no arguments.\n\n" + @@ -374,12 +370,17 @@ func deleteUserCmd(cli *cli) *cobra.Command { auth0 users delete auth0 users delete --force`, RunE: func(cmd *cobra.Command, args []string) error { + ids := make([]string, len(args)) if len(args) == 0 { - if err := userID.Ask(cmd, &inputs.ID); err != nil { + var id string + if err := userID.Ask(cmd, &id); err != nil { return err } + ids = append(ids, id) } else { - inputs.ID = args[0] + for _, id := range args { + ids = append(ids, id) + } } if !cli.force && canPrompt(cmd) { @@ -389,13 +390,17 @@ func deleteUserCmd(cli *cli) *cobra.Command { } return ansi.Spinner("Deleting user", func() error { - _, err := cli.api.User.Read(cmd.Context(), inputs.ID) + var errs []error + for _, id := range ids { + if _, err := cli.api.User.Read(cmd.Context(), id); err != nil { + errs = append(errs, fmt.Errorf("Unable to read user for deletion: %w", err)) + } - if err != nil { - return fmt.Errorf("Unable to delete user: %w", err) + if err := cli.api.User.Delete(cmd.Context(), id); err != nil { + errs = append(errs, fmt.Errorf("Unable to delete user: %w", err)) + } } - - return cli.api.User.Delete(cmd.Context(), inputs.ID) + return errors.Join(errs...) }) }, } diff --git a/internal/cli/users_blocks.go b/internal/cli/users_blocks.go index 657a930cf..8eb75a83f 100644 --- a/internal/cli/users_blocks.go +++ b/internal/cli/users_blocks.go @@ -1,6 +1,7 @@ package cli import ( + "errors" "fmt" "github.com/auth0/go-auth0/management" @@ -64,33 +65,35 @@ func listUserBlocksCmd(cli *cli) *cobra.Command { } func deleteUserBlocksCmd(cli *cli) *cobra.Command { - var inputs struct { - userID string - } - cmd := &cobra.Command{ Use: "unblock", - Args: cobra.MaximumNArgs(1), + Args: cobra.MinimumNArgs(0), Short: "Remove brute-force protection blocks for a given user", Long: "Remove brute-force protection blocks for a given user.", Example: ` auth0 users blocks unblock `, RunE: func(cmd *cobra.Command, args []string) error { + ids := make([]string, len(args)) if len(args) == 0 { - if err := userID.Ask(cmd, &inputs.userID); err != nil { + var id string + if err := userID.Ask(cmd, &id); err != nil { return err } + ids = append(ids, id) } else { - inputs.userID = args[0] + for _, id := range args { + ids = append(ids, id) + } } - err := ansi.Spinner("Unblocking user...", func() error { - return cli.api.User.Unblock(cmd.Context(), inputs.userID) + return ansi.Spinner("Unblocking user...", func() error { + var errs []error + for _, id := range ids { + if err := cli.api.User.Unblock(cmd.Context(), id); err != nil { + errs = append(errs, fmt.Errorf("failed to unblock user with ID %s: %w", id, err)) + } + } + return errors.Join(errs...) }) - if err != nil { - return fmt.Errorf("failed to unblock user with ID %s: %w", inputs.userID, err) - } - - return nil }, }