From 44613508af7487779af8f0a797390ffdf6281609 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 13 Nov 2023 10:44:33 +0000 Subject: [PATCH 01/19] Bump github.com/auth0/go-auth0 from 1.2.0 to 1.3.0 (#908) Bumps [github.com/auth0/go-auth0](https://github.com/auth0/go-auth0) from 1.2.0 to 1.3.0. - [Release notes](https://github.com/auth0/go-auth0/releases) - [Changelog](https://github.com/auth0/go-auth0/blob/main/CHANGELOG.md) - [Commits](https://github.com/auth0/go-auth0/compare/v1.2.0...v1.3.0) --- updated-dependencies: - dependency-name: github.com/auth0/go-auth0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index c8e27160a..3070443bd 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,7 @@ go 1.20 require ( github.com/AlecAivazis/survey/v2 v2.3.7 github.com/PuerkitoBio/rehttp v1.3.0 - github.com/auth0/go-auth0 v1.2.0 + github.com/auth0/go-auth0 v1.3.0 github.com/briandowns/spinner v1.23.0 github.com/charmbracelet/glamour v0.6.0 github.com/fsnotify/fsnotify v1.7.0 diff --git a/go.sum b/go.sum index 0a663f00d..a6e48e491 100644 --- a/go.sum +++ b/go.sum @@ -18,8 +18,8 @@ github.com/andybalholm/brotli v1.0.5 h1:8uQZIdzKmjc/iuPu7O2ioW48L81FgatrcpfFmiq/ github.com/andybalholm/brotli v1.0.5/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= github.com/apparentlymart/go-textseg/v15 v15.0.0 h1:uYvfpb3DyLSCGWnctWKGj857c6ew1u1fNQOlOtuGxQY= github.com/apparentlymart/go-textseg/v15 v15.0.0/go.mod h1:K8XmNZdhEBkdlyDdvbmmsvpAG721bKi0joRfFdHIWJ4= -github.com/auth0/go-auth0 v1.2.0 h1:pZWzWCWk038jDsItwfqrbuoN37xcNHUClfPzW+rk1ok= -github.com/auth0/go-auth0 v1.2.0/go.mod h1:tLH1Qv816g3dpqituiPNN4ET+YoNtk5++68aRg+MxaA= +github.com/auth0/go-auth0 v1.3.0 h1:46bo0C6HYtsdSj4BEF4j6IaQrSAiUqehwuv+IO3qDJ0= +github.com/auth0/go-auth0 v1.3.0/go.mod h1:gm0NUM340x77a9YVZB50HUrJJkSchD9DkiqqbAl+s34= github.com/aybabtme/iocontrol v0.0.0-20150809002002-ad15bcfc95a0 h1:0NmehRCgyk5rljDQLKUO+cRJCnduDyn11+zGZIc9Z48= github.com/aybabtme/iocontrol v0.0.0-20150809002002-ad15bcfc95a0/go.mod h1:6L7zgvqo0idzI7IO8de6ZC051AfXb5ipkIJ7bIA2tGA= github.com/aymanbagabas/go-osc52 v1.0.3 h1:DTwqENW7X9arYimJrPeGZcV0ln14sGMt3pHZspWD+Mg= From 205439459fbb500b6518083d5a2a9d181ca905a5 Mon Sep 17 00:00:00 2001 From: Michael Christenson II Date: Mon, 13 Nov 2023 12:10:00 -0500 Subject: [PATCH 02/19] dxcdt-615-goreleaser-upgrade (#909) * Fix: Remove or replace deprecations for GoReleaser config Remove deprecated replacements Replace deprecated brews tap Replace deprecated scoop entries Fix name_template to reflect exact current naming conventions * DXCDT-582: Convert audience into a drop down in interactive mode in test token cmd (#906) Convert audience into a drop down in interactive mode in test token cmd * Bump github.com/auth0/go-auth0 from 1.2.0 to 1.3.0 (#908) Bumps [github.com/auth0/go-auth0](https://github.com/auth0/go-auth0) from 1.2.0 to 1.3.0. - [Release notes](https://github.com/auth0/go-auth0/releases) - [Changelog](https://github.com/auth0/go-auth0/blob/main/CHANGELOG.md) - [Commits](https://github.com/auth0/go-auth0/compare/v1.2.0...v1.3.0) --- updated-dependencies: - dependency-name: github.com/auth0/go-auth0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --------- Signed-off-by: dependabot[bot] Co-authored-by: Sergiu Ghitea <28300158+sergiught@users.noreply.github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .gitignore | 1 + .goreleaser.yml | 37 ++++++++++++++++--------------------- 2 files changed, 17 insertions(+), 21 deletions(-) diff --git a/.gitignore b/.gitignore index a1560ab06..2d6eec10e 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,7 @@ /auth0 /test/integration/identifiers coverage* +/dist # Swap [._]*.s[a-v][a-z] diff --git a/.goreleaser.yml b/.goreleaser.yml index 2fdc5222f..e044543cc 100644 --- a/.goreleaser.yml +++ b/.goreleaser.yml @@ -18,12 +18,7 @@ builds: - -X 'github.com/auth0/auth0-cli/internal/buildinfo.BuildDate={{.Date}}' - -X 'github.com/auth0/auth0-cli/internal/instrumentation.SentryDSN={{.Env.SENTRY_DSN}}' archives: - - replacements: - darwin: Darwin - linux: Linux - windows: Windows - 386: i386 - amd64: x86_64 + - name_template: '{{ .ProjectName }}_{{ .Version }}_{{ .Os }}_{{ if eq .Arch "arm64" }}arm64{{ else }}x86_64{{ end }}' files: - none* format_overrides: @@ -37,7 +32,7 @@ changelog: skip: true brews: - name: auth0 - tap: + repository: owner: auth0 name: homebrew-auth0-cli commit_author: @@ -54,17 +49,17 @@ brews: (fish_completion/"auth0.fish").write `#{bin}/auth0 completion fish` (zsh_completion/"_auth0").write `#{bin}/auth0 completion zsh` caveats: "Thanks for installing the Auth0 CLI" -scoop: - name: auth0 - bucket: - owner: auth0 - name: scoop-auth0-cli - commit_author: - name: auth0 - email: support@auth0.com - commit_msg_template: "Scoop manifest update for {{ .ProjectName }} version {{ .Tag }}" - homepage: https://auth0.github.io/auth0-cli - description: Build, manage and test your Auth0 integrations from the command line - license: MIT - skip_upload: auto - post_install: ["Write-Host 'Thanks for installing the Auth0 CLI'"] +scoops: + - name: auth0 + repository: + owner: auth0 + name: scoop-auth0-cli + commit_author: + name: auth0 + email: support@auth0.com + commit_msg_template: "Scoop manifest update for {{ .ProjectName }} version {{ .Tag }}" + homepage: https://auth0.github.io/auth0-cli + description: Build, manage and test your Auth0 integrations from the command line + license: MIT + skip_upload: auto + post_install: ["Write-Host 'Thanks for installing the Auth0 CLI'"] From 1da363159ffebcde4680b5fc9c4c54d19ad83c1b Mon Sep 17 00:00:00 2001 From: Sergiu Ghitea <28300158+sergiught@users.noreply.github.com> Date: Sat, 11 Nov 2023 09:05:49 +0100 Subject: [PATCH 03/19] DXCDT-582: Convert audience into a drop down in interactive mode in test token cmd (#906) Convert audience into a drop down in interactive mode in test token cmd Title Os for final release name fit --- .goreleaser.yml | 2 +- docs/auth0_test_login.md | 2 +- docs/auth0_test_token.md | 2 +- internal/cli/test.go | 78 ++++++++++++++++++++++++++++++++++++---- 4 files changed, 75 insertions(+), 9 deletions(-) diff --git a/.goreleaser.yml b/.goreleaser.yml index e044543cc..8b2e336e9 100644 --- a/.goreleaser.yml +++ b/.goreleaser.yml @@ -18,7 +18,7 @@ builds: - -X 'github.com/auth0/auth0-cli/internal/buildinfo.BuildDate={{.Date}}' - -X 'github.com/auth0/auth0-cli/internal/instrumentation.SentryDSN={{.Env.SENTRY_DSN}}' archives: - - name_template: '{{ .ProjectName }}_{{ .Version }}_{{ .Os }}_{{ if eq .Arch "arm64" }}arm64{{ else }}x86_64{{ end }}' + - name_template: '{{ .ProjectName }}_{{ .Version }}_{{ title .Os }}_{{ if eq .Arch "arm64" }}arm64{{ else }}x86_64{{ end }}' files: - none* format_overrides: diff --git a/docs/auth0_test_login.md b/docs/auth0_test_login.md index 6dd41ee08..27a031a53 100644 --- a/docs/auth0_test_login.md +++ b/docs/auth0_test_login.md @@ -30,7 +30,7 @@ auth0 test login [flags] ## Flags ``` - -a, --audience string The unique identifier of the target API you want to access. + -a, --audience string The unique identifier of the target API you want to access. For Machine to Machine and Regular Web Applications, only the enabled APIs will be shown within the interactive prompt. -c, --connection-name string The connection name to test during login. -d, --domain string One of your custom domains. --force Skip confirmation. diff --git a/docs/auth0_test_token.md b/docs/auth0_test_token.md index 5ad8e2850..cdc62f310 100644 --- a/docs/auth0_test_token.md +++ b/docs/auth0_test_token.md @@ -27,7 +27,7 @@ auth0 test token [flags] ## Flags ``` - -a, --audience string The unique identifier of the target API you want to access. + -a, --audience string The unique identifier of the target API you want to access. For Machine to Machine and Regular Web Applications, only the enabled APIs will be shown within the interactive prompt. --force Skip confirmation. --json Output in json format. -s, --scopes strings The list of scopes you want to use. diff --git a/internal/cli/test.go b/internal/cli/test.go index e8f59f29f..b17f9d40a 100644 --- a/internal/cli/test.go +++ b/internal/cli/test.go @@ -36,7 +36,7 @@ var ( Name: "Audience", LongForm: "audience", ShortForm: "a", - Help: "The unique identifier of the target API you want to access.", + Help: "The unique identifier of the target API you want to access. For Machine to Machine and Regular Web Applications, only the enabled APIs will be shown within the interactive prompt.", } testAudienceRequired = Flag{ @@ -193,18 +193,20 @@ func testTokenCmd(cli *cli) *cobra.Command { return err } - if err := testAudience.Ask(cmd, &inputs.Audience, nil); err != nil { + if err := testAudienceRequired.Pick( + cmd, + &inputs.Audience, + cli.audiencePickerOptions(client), + ); err != nil { return err } - appType := client.GetAppType() - cli.renderer.Infof("Domain : " + ansi.Blue(cli.tenant)) cli.renderer.Infof("Client ID : " + ansi.Bold(client.GetClientID())) - cli.renderer.Infof("Type : " + display.ApplyColorToFriendlyAppType(display.FriendlyAppType(appType))) + cli.renderer.Infof("Type : " + display.ApplyColorToFriendlyAppType(display.FriendlyAppType(client.GetAppType()))) cli.renderer.Newline() - if appType == appTypeNonInteractive { + if client.GetAppType() == appTypeNonInteractive { tokenResponse, err := runClientCredentialsFlow(cmd.Context(), cli, client, inputs.Audience, cli.tenant) if err != nil { return fmt.Errorf( @@ -342,6 +344,70 @@ func (c *cli) appPickerWithCreateOption(ctx context.Context) (pickerOptions, err return enhancedOptions, nil } +func (c *cli) audiencePickerOptions(client *management.Client) func(ctx context.Context) (pickerOptions, error) { + return func(ctx context.Context) (pickerOptions, error) { + var opts pickerOptions + + switch client.GetAppType() { + case "regular_web", "non_interactive": + clientGrants, err := c.api.ClientGrant.List( + ctx, + management.PerPage(100), + management.Parameter("client_id", client.GetClientID()), + ) + if err != nil { + return nil, err + } + + if len(clientGrants.ClientGrants) == 0 { + return nil, fmt.Errorf( + "the %s application is not authorized to request access tokens for any APIs.\n\n"+ + "Run: 'auth0 apps open %s' to open the dashboard and authorize the application.", + ansi.Bold(client.GetName()), + client.GetClientID(), + ) + } + + for _, grant := range clientGrants.ClientGrants { + resourceServer, err := c.api.ResourceServer.Read(ctx, grant.GetAudience()) + if err != nil { + return nil, err + } + + label := fmt.Sprintf( + "%s %s", + resourceServer.GetName(), + ansi.Faint(fmt.Sprintf("(%s)", resourceServer.GetIdentifier())), + ) + + opts = append(opts, pickerOption{ + label: label, + value: resourceServer.GetIdentifier(), + }) + } + default: + resourceServerList, err := c.api.ResourceServer.List(ctx, management.PerPage(100)) + if err != nil { + return nil, err + } + + for _, resourceServer := range resourceServerList.ResourceServers { + label := fmt.Sprintf( + "%s %s", + resourceServer.GetName(), + ansi.Faint(fmt.Sprintf("(%s)", resourceServer.GetIdentifier())), + ) + opts = append(opts, pickerOption{ + label: label, + value: resourceServer.GetIdentifier(), + }) + } + } + + return opts, nil + } +} + func checkClientIsAuthorizedForAPI(ctx context.Context, cli *cli, client *management.Client, audience string) error { var list *management.ClientGrantList if err := ansi.Waiting(func() (err error) { From 3068c0718b8515893372125f79d3b45fdaa56be7 Mon Sep 17 00:00:00 2001 From: Michael Christenson II Date: Fri, 1 Dec 2023 11:36:59 -0500 Subject: [PATCH 04/19] Bump goreleaser version --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 4a72051b8..ec3bc0c9d 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -27,7 +27,7 @@ jobs: - name: Run GoReleaser uses: goreleaser/goreleaser-action@336e29918d653399e599bfca99fadc1d7ffbc9f7 # pin@4.3.0 with: - version: v1.18.2 + version: v1.22.1 args: release --rm-dist env: GITHUB_TOKEN: ${{ secrets.GORELEASER_GITHUB_TOKEN }} From c0deaff76f880ada3e3c01f6c67346ccea04adbe Mon Sep 17 00:00:00 2001 From: Michael Christenson II Date: Wed, 13 Dec 2023 12:05:03 -0500 Subject: [PATCH 05/19] Use progress bars for long multistep processes Create generic ProgressBar Ensure 1 or less items behaves like Spinner Add progress bars to possibly longer processes --- go.mod | 4 +++- go.sum | 11 ++++++++++- internal/ansi/progress.go | 29 +++++++++++++++++++++++++++++ internal/cli/actions.go | 13 ++++--------- internal/cli/apis.go | 22 ++++++++-------------- internal/cli/apps.go | 22 +++++++++------------- internal/cli/custom_domains.go | 23 +++++++++-------------- internal/cli/log_streams.go | 21 ++++++++------------- internal/cli/organizations.go | 23 ++++++++--------------- internal/cli/roles.go | 22 +++++++++------------- internal/cli/rules.go | 22 +++++++++------------- internal/cli/users.go | 22 +++++++++------------- internal/cli/users_blocks.go | 33 ++++++++++++++------------------- 13 files changed, 129 insertions(+), 138 deletions(-) create mode 100644 internal/ansi/progress.go diff --git a/go.mod b/go.mod index f5260d4fa..61f08d58f 100644 --- a/go.mod +++ b/go.mod @@ -25,6 +25,7 @@ require ( github.com/olekukonko/tablewriter v0.0.5 github.com/pkg/browser v0.0.0-20210706143420-7d21f8c997e2 github.com/pkg/errors v0.9.1 + github.com/schollz/progressbar/v3 v3.14.1 github.com/spf13/cobra v1.8.0 github.com/spf13/pflag v1.0.5 github.com/stretchr/testify v1.8.4 @@ -76,12 +77,13 @@ require ( github.com/mattn/go-runewidth v0.0.14 // indirect github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d // indirect github.com/microcosm-cc/bluemonday v1.0.23 // indirect + github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db // indirect github.com/muesli/reflow v0.3.0 // indirect github.com/muesli/termenv v0.13.0 // indirect github.com/nwaples/rardecode v1.1.0 // indirect github.com/pierrec/lz4/v4 v4.1.3 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/rivo/uniseg v0.2.0 // indirect + github.com/rivo/uniseg v0.4.4 // indirect github.com/ulikunitz/xz v0.5.10 // indirect github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 // indirect github.com/yuin/goldmark v1.5.2 // indirect diff --git a/go.sum b/go.sum index ea69bedf7..81ddbc180 100644 --- a/go.sum +++ b/go.sum @@ -114,6 +114,7 @@ github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOl github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo= github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0= github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= +github.com/k0kubun/go-ansi v0.0.0-20180517002512-3bf9e2903213/go.mod h1:vNUNkEQ1e29fT/6vq2aBdFsgNPmy8qMdSay1npru+Sw= github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs= github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8= github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4gf13a4= @@ -171,6 +172,8 @@ github.com/mholt/archiver/v3 v3.5.1/go.mod h1:e3dqJ7H78uzsRSEACH1joayhuSyhnonssn github.com/microcosm-cc/bluemonday v1.0.21/go.mod h1:ytNkv4RrDrLJ2pqlsSI46O6IVXmZOBBD4SaJyDwwTkM= github.com/microcosm-cc/bluemonday v1.0.23 h1:SMZe2IGa0NuHvnVNAZ+6B38gsTbi5e4sViiWJyDDqFY= github.com/microcosm-cc/bluemonday v1.0.23/go.mod h1:mN70sk7UkkF8TUr2IGBpNN0jAgStuPzlK76QuruE/z4= +github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db h1:62I3jR2EmQ4l5rM/4FEfDWcRD+abF5XlKShorW5LRoQ= +github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db/go.mod h1:l0dey0ia/Uv7NcFFVbCLtqEBQbrT4OCwCSKTEv6enCw= github.com/muesli/reflow v0.3.0 h1:IFsN6K9NfGtjeggFP+68I4chLZV2yIKsXJFNZ+eWh6s= github.com/muesli/reflow v0.3.0/go.mod h1:pbwTDkVPibjO2kyvBQRBxTWEEGDGq0FlB1BIKtnHY/8= github.com/muesli/termenv v0.13.0 h1:wK20DRpJdDX8b7Ek2QfhvqhRQFZ237RGRO0RQ/Iqdy0= @@ -193,11 +196,14 @@ github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= -github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= +github.com/rivo/uniseg v0.4.4 h1:8TfxU8dW6PdqD27gjM8MVNuicgxIjxpm4K7x4jp8sis= +github.com/rivo/uniseg v0.4.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= github.com/rogpeppe/go-internal v1.6.1 h1:/FiVV8dS/e+YqF2JvO3yXRFbBLTIuSDkuC7aBOAvL+k= github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/schollz/progressbar/v3 v3.14.1 h1:VD+MJPCr4s3wdhTc7OEJ/Z3dAeBzJ7yKH/P4lC5yRTI= +github.com/schollz/progressbar/v3 v3.14.1/go.mod h1:Zc9xXneTzWXF81TGoqL71u0sBPjULtEHYtj/WVgVy8E= github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ= github.com/sergi/go-diff v1.2.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= github.com/skeema/knownhosts v1.2.1 h1:SHWdIUa82uGZz+F+47k8SY4QhhI291cXCpopT1lK2AQ= @@ -210,6 +216,7 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+ github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= @@ -294,6 +301,7 @@ golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc= golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= @@ -302,6 +310,7 @@ golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= +golang.org/x/term v0.14.0/go.mod h1:TySc+nGkYR6qt8km8wUhuFRTVSMIX3XPR58y2lC8vww= golang.org/x/term v0.15.0 h1:y/Oo/a/q3IXu26lQgl04j/gjuBDOBlx7X6Om1j2CPW4= golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= diff --git a/internal/ansi/progress.go b/internal/ansi/progress.go new file mode 100644 index 000000000..cde1be499 --- /dev/null +++ b/internal/ansi/progress.go @@ -0,0 +1,29 @@ +package ansi + +import ( + "errors" + "github.com/schollz/progressbar/v3" +) + +func ProgressBar[T comparable](desc string, items []T, fn func(int, T) error) error { + switch len(items) { + case 0: + return Spinner(desc, func() error { + return nil + }) + case 1: + return Spinner(desc, func() error { + return fn(1, items[0]) + }) + default: + bar := progressbar.Default(int64(len(items)), desc) + var errs []error + for i, item := range items { + bar.Add(1) + if err := fn(i, item); err != nil { + errs = append(errs, err) + } + } + return errors.Join(errs...) + } +} diff --git a/internal/cli/actions.go b/internal/cli/actions.go index 5885c11ff..7bfeea8a6 100644 --- a/internal/cli/actions.go +++ b/internal/cli/actions.go @@ -387,16 +387,11 @@ func deleteActionCmd(cli *cli) *cobra.Command { } } - return ansi.Spinner("Deleting action(s)", func() error { - var errs []error - for _, id := range ids { - if id != "" { - if err := cli.api.Action.Delete(cmd.Context(), id); err != nil { - errs = append(errs, err) - } - } + return ansi.ProgressBar("Deleting action(s)", ids, func(i int, id string) error { + if id != "" { + return cli.api.Action.Delete(cmd.Context(), id) } - return errors.Join(errs...) + return nil }) }, } diff --git a/internal/cli/apis.go b/internal/cli/apis.go index d7aa66a5a..0d210a239 100644 --- a/internal/cli/apis.go +++ b/internal/cli/apis.go @@ -445,21 +445,15 @@ func deleteAPICmd(cli *cli) *cobra.Command { } } - return ansi.Spinner("Deleting API(s)", func() error { - var errs []error - for _, id := range ids { - if id != "" { - if _, err := cli.api.ResourceServer.Read(cmd.Context(), url.PathEscape(id)); err != nil { - errs = append(errs, fmt.Errorf("Unable to delete API (%s): %w", id, err)) - continue - } - - if err := cli.api.ResourceServer.Delete(cmd.Context(), url.PathEscape(id)); err != nil { - errs = append(errs, fmt.Errorf("Unable to delete API (%s): %w", id, err)) - } - } + return ansi.ProgressBar("Deleting API(s)", ids, func(_ int, id string) error { + if _, err := cli.api.ResourceServer.Read(cmd.Context(), url.PathEscape(id)); err != nil { + return fmt.Errorf("Unable to delete API (%s): %w", id, err) + } + + if err := cli.api.ResourceServer.Delete(cmd.Context(), url.PathEscape(id)); err != nil { + return fmt.Errorf("Unable to delete API (%s): %w", id, err) } - return errors.Join(errs...) + return nil }) }, } diff --git a/internal/cli/apps.go b/internal/cli/apps.go index 010eae98f..3d19ec566 100644 --- a/internal/cli/apps.go +++ b/internal/cli/apps.go @@ -343,21 +343,17 @@ func deleteAppCmd(cli *cli) *cobra.Command { } } - return ansi.Spinner("Deleting Application(s)", func() error { - var errs []error - for _, id := range ids { - if id != "" { - if _, err := cli.api.Client.Read(cmd.Context(), id); err != nil { - errs = append(errs, fmt.Errorf("Unable to delete application (%s): %w", id, err)) - continue - } - - if err := cli.api.Client.Delete(cmd.Context(), id); err != nil { - errs = append(errs, fmt.Errorf("Unable to delete application (%s): %w", id, err)) - } + return ansi.ProgressBar("Deleting Application(s)", ids, func(_ int, id string) error { + if id != "" { + if _, err := cli.api.Client.Read(cmd.Context(), id); err != nil { + return fmt.Errorf("Unable to delete application (%s): %w", id, err) + } + + if err := cli.api.Client.Delete(cmd.Context(), id); err != nil { + return fmt.Errorf("Unable to delete application (%s): %w", id, err) } } - return errors.Join(errs...) + return nil }) }, } diff --git a/internal/cli/custom_domains.go b/internal/cli/custom_domains.go index e36e234cc..81c9ba42a 100644 --- a/internal/cli/custom_domains.go +++ b/internal/cli/custom_domains.go @@ -2,7 +2,6 @@ package cli import ( "context" - "errors" "fmt" "net/url" @@ -355,21 +354,17 @@ func deleteCustomDomainCmd(cli *cli) *cobra.Command { } } - return ansi.Spinner("Deleting custom domain", func() error { - var errs []error - for _, id := range ids { - if id != "" { - if _, err := cli.api.CustomDomain.Read(cmd.Context(), url.PathEscape(id)); err != nil { - return fmt.Errorf("Unable to delete custom domain (%s): %w", id, err) - } - - if err := cli.api.CustomDomain.Delete(cmd.Context(), url.PathEscape(id)); err != nil { - return fmt.Errorf("Unable to delete custom domain (%s): %w", id, err) - } + return ansi.ProgressBar("Deleting custom domain", ids, func(_ int, id string) error { + if id != "" { + if _, err := cli.api.CustomDomain.Read(cmd.Context(), url.PathEscape(id)); err != nil { + return fmt.Errorf("Unable to delete custom domain (%s): %w", id, err) } - } - return errors.Join(errs...) + if err := cli.api.CustomDomain.Delete(cmd.Context(), url.PathEscape(id)); err != nil { + return fmt.Errorf("Unable to delete custom domain (%s): %w", id, err) + } + } + return nil }) }, } diff --git a/internal/cli/log_streams.go b/internal/cli/log_streams.go index d33e92247..51596cf3e 100644 --- a/internal/cli/log_streams.go +++ b/internal/cli/log_streams.go @@ -199,21 +199,16 @@ func deleteLogStreamCmd(cli *cli) *cobra.Command { } } - return ansi.Spinner("Deleting Log Stream(s)", func() error { - var errs []error - for _, id := range ids { - if id != "" { - if _, err := cli.api.LogStream.Read(cmd.Context(), id); err != nil { - errs = append(errs, fmt.Errorf("Unable to delete log stream (%s): %w", id, err)) - continue - } - if err := cli.api.LogStream.Delete(cmd.Context(), id); err != nil { - errs = append(errs, fmt.Errorf("Unable to delete log stream (%s): %w", id, err)) - } + return ansi.ProgressBar("Deleting Log Stream(s)", ids, func(_ int, id string) error { + if id != "" { + if _, err := cli.api.LogStream.Read(cmd.Context(), id); err != nil { + return fmt.Errorf("Unable to delete log stream (%s): %w", id, err) + } + if err := cli.api.LogStream.Delete(cmd.Context(), id); err != nil { + return fmt.Errorf("Unable to delete log stream (%s): %w", id, err) } } - - return errors.Join(errs...) + return nil }) }, } diff --git a/internal/cli/organizations.go b/internal/cli/organizations.go index b39e7e5e2..746b05b06 100644 --- a/internal/cli/organizations.go +++ b/internal/cli/organizations.go @@ -439,21 +439,15 @@ func deleteOrganizationCmd(cli *cli) *cobra.Command { } } - return ansi.Spinner("Deleting organization(s)", func() error { - var errs []error - for _, id := range ids { - if id != "" { - if _, err := cli.api.Organization.Read(cmd.Context(), id); err != nil { - errs = append(errs, fmt.Errorf("Unable to delete organization (%s): %w", id, err)) - continue - } - - if err := cli.api.Organization.Delete(cmd.Context(), id); err != nil { - errs = append(errs, fmt.Errorf("Unable to delete organization (%s): %w", id, err)) - } - } + return ansi.ProgressBar("Deleting organization(s)", ids, func(_ int, id string) error { + if _, err := cli.api.Organization.Read(cmd.Context(), id); err != nil { + return fmt.Errorf("Unable to delete organization (%s): %w", id, err) + } + + if err := cli.api.Organization.Delete(cmd.Context(), id); err != nil { + return fmt.Errorf("Unable to delete organization (%s): %w", id, err) } - return errors.Join(errs...) + return nil }) }, } @@ -599,7 +593,6 @@ func listRolesOrganizationCmd(cli *cli) *cobra.Command { } else { inputs.OrgID = args[0] } - members, err := cli.getOrgMembersWithSpinner(cmd.Context(), inputs.OrgID, inputs.Number) if err != nil { return err diff --git a/internal/cli/roles.go b/internal/cli/roles.go index e63091e55..14b5e6018 100644 --- a/internal/cli/roles.go +++ b/internal/cli/roles.go @@ -312,21 +312,17 @@ func deleteRoleCmd(cli *cli) *cobra.Command { } } - return ansi.Spinner("Deleting Role(s)", func() error { - var errs []error - for _, id := range ids { - if id != "" { - if _, err := cli.api.Role.Read(cmd.Context(), id); err != nil { - errs = append(errs, fmt.Errorf("Unable to delete role (%s): %w", id, err)) - continue - } - - if err := cli.api.Role.Delete(cmd.Context(), id); err != nil { - errs = append(errs, fmt.Errorf("Unable to delete role (%s): %w", id, err)) - } + return ansi.ProgressBar("Deleting Role(s)", ids, func(_ int, id string) error { + if id != "" { + if _, err := cli.api.Role.Read(cmd.Context(), id); err != nil { + return fmt.Errorf("Unable to delete role (%s): %w", id, err) + } + + if err := cli.api.Role.Delete(cmd.Context(), id); err != nil { + return fmt.Errorf("Unable to delete role (%s): %w", id, err) } } - return errors.Join(errs...) + return nil }) }, } diff --git a/internal/cli/rules.go b/internal/cli/rules.go index 5a317d2cb..87b9c01d2 100644 --- a/internal/cli/rules.go +++ b/internal/cli/rules.go @@ -279,21 +279,17 @@ func deleteRuleCmd(cli *cli) *cobra.Command { } } - return ansi.Spinner("Deleting Rule(s)", func() error { - var errs []error - for _, id := range ids { - if id != "" { - if _, err := cli.api.Rule.Read(cmd.Context(), id); err != nil { - errs = append(errs, fmt.Errorf("Unable to delete rule (%s): %w", id, err)) - continue - } - - if err := cli.api.Rule.Delete(cmd.Context(), id); err != nil { - errs = append(errs, fmt.Errorf("Unable to delete rule (%s): %w", id, err)) - } + return ansi.ProgressBar("Deleting Rule(s)", ids, func(_ int, id string) error { + if id != "" { + if _, err := cli.api.Rule.Read(cmd.Context(), id); err != nil { + return fmt.Errorf("Unable to delete rule (%s): %w", id, err) + } + + if err := cli.api.Rule.Delete(cmd.Context(), id); err != nil { + fmt.Errorf("Unable to delete rule (%s): %w", id, err) } } - return errors.Join(errs...) + return nil }) }, } diff --git a/internal/cli/users.go b/internal/cli/users.go index 5f80b7627..d1d97d3a1 100644 --- a/internal/cli/users.go +++ b/internal/cli/users.go @@ -393,21 +393,17 @@ func deleteUserCmd(cli *cli) *cobra.Command { } } - return ansi.Spinner("Deleting user(s)", func() error { - var errs []error - for _, id := range ids { - if id != "" { - if _, err := cli.api.User.Read(cmd.Context(), id); err != nil { - errs = append(errs, fmt.Errorf("Unable to delete user (%s): %w", id, err)) - continue - } - - if err := cli.api.User.Delete(cmd.Context(), id); err != nil { - errs = append(errs, fmt.Errorf("Unable to delete user (%s): %w", id, err)) - } + return ansi.ProgressBar("Deleting user(s)", ids, func(_ int, id string) error { + if id != "" { + if _, err := cli.api.User.Read(cmd.Context(), id); err != nil { + return fmt.Errorf("Unable to delete user (%s): %w", id, err) + } + + if err := cli.api.User.Delete(cmd.Context(), id); err != nil { + return fmt.Errorf("Unable to delete user (%s): %w", id, err) } } - return errors.Join(errs...) + return nil }) }, } diff --git a/internal/cli/users_blocks.go b/internal/cli/users_blocks.go index 2491bde04..802daa086 100644 --- a/internal/cli/users_blocks.go +++ b/internal/cli/users_blocks.go @@ -1,7 +1,6 @@ package cli import ( - "errors" "fmt" "net/http" @@ -82,34 +81,30 @@ func deleteUserBlocksCmd(cli *cli) *cobra.Command { auth0 users blocks unblock "frederik@travel0.com" "poovam@travel0.com" `, RunE: func(cmd *cobra.Command, args []string) error { - identifiers := make([]string, len(args)) + ids := make([]string, len(args)) if len(args) == 0 { var id string if err := userIdentifier.Ask(cmd, &id); err != nil { return err } - identifiers = append(identifiers, id) + ids = append(ids, id) } else { - identifiers = append(identifiers, args...) + ids = append(ids, args...) } - return ansi.Spinner("Unblocking user(s)...", func() error { - var errs []error - for _, identifier := range identifiers { - if identifier != "" { - err := cli.api.User.Unblock(cmd.Context(), identifier) - if mErr, ok := err.(management.Error); ok && mErr.Status() != http.StatusBadRequest { - errs = append(errs, fmt.Errorf("failed to unblock user with identifier %s: %w", identifier, err)) - continue - } - - err = cli.api.User.UnblockByIdentifier(cmd.Context(), identifier) - if err != nil { - errs = append(errs, fmt.Errorf("failed to unblock user with identifier %s: %w", identifier, err)) - } + return ansi.ProgressBar("Unblocking user(s)", ids, func(_ int, id string) error { + if id != "" { + err := cli.api.User.Unblock(cmd.Context(), id) + if mErr, ok := err.(management.Error); ok && mErr.Status() != http.StatusBadRequest { + return fmt.Errorf("failed to unblock user with identifier %s: %w", id, err) + } + + err = cli.api.User.UnblockByIdentifier(cmd.Context(), id) + if err != nil { + return fmt.Errorf("failed to unblock user with identifier %s: %w", id, err) } } - return errors.Join(errs...) + return nil }) }, } From 09d32e9654fffc3047a475d3bda1809ae1c1a85c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 13 Dec 2023 12:02:10 +0100 Subject: [PATCH 06/19] Bump github.com/google/uuid from 1.4.0 to 1.5.0 (#942) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 61f08d58f..2d6a409ca 100644 --- a/go.mod +++ b/go.mod @@ -12,7 +12,7 @@ require ( github.com/getsentry/sentry-go v0.25.0 github.com/golang/mock v1.6.0 github.com/google/go-cmp v0.6.0 - github.com/google/uuid v1.4.0 + github.com/google/uuid v1.5.0 github.com/gorilla/websocket v1.5.1 github.com/hashicorp/go-version v1.6.0 github.com/hashicorp/hc-install v0.6.2 diff --git a/go.sum b/go.sum index 81ddbc180..ada44db23 100644 --- a/go.sum +++ b/go.sum @@ -90,8 +90,8 @@ github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEW github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/uuid v1.4.0 h1:MtMxsa51/r9yyhkyLsVeVt0B+BGQZzpQiTQ4eHZ8bc4= -github.com/google/uuid v1.4.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.5.0 h1:1p67kYwdtXjb0gL0BPiP1Av9wiZPo5A8z2cWkTZ+eyU= +github.com/google/uuid v1.5.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/gorilla/css v1.0.0 h1:BQqNyPTi50JCFMTw/b67hByjMVXZRwGha6wxVGkeihY= github.com/gorilla/css v1.0.0/go.mod h1:Dn721qIggHpt4+EFCcTLTU/vk5ySda2ReITrtgBl60c= github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/QY= From f51b8f7be5562d5b9ae2447b4635809b02e07235 Mon Sep 17 00:00:00 2001 From: Michael Christenson II Date: Wed, 13 Dec 2023 10:18:56 -0500 Subject: [PATCH 07/19] Dxcdt 578 increase results amount in lists (#940) * Bump github.com/auth0/go-auth0 from 1.2.0 to 1.3.0 (#908) Bumps [github.com/auth0/go-auth0](https://github.com/auth0/go-auth0) from 1.2.0 to 1.3.0. - [Release notes](https://github.com/auth0/go-auth0/releases) - [Changelog](https://github.com/auth0/go-auth0/blob/main/CHANGELOG.md) - [Commits](https://github.com/auth0/go-auth0/compare/v1.2.0...v1.3.0) --- updated-dependencies: - dependency-name: github.com/auth0/go-auth0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * dxcdt-615-goreleaser-upgrade (#909) * Fix: Remove or replace deprecations for GoReleaser config Remove deprecated replacements Replace deprecated brews tap Replace deprecated scoop entries Fix name_template to reflect exact current naming conventions * DXCDT-582: Convert audience into a drop down in interactive mode in test token cmd (#906) Convert audience into a drop down in interactive mode in test token cmd * Bump github.com/auth0/go-auth0 from 1.2.0 to 1.3.0 (#908) Bumps [github.com/auth0/go-auth0](https://github.com/auth0/go-auth0) from 1.2.0 to 1.3.0. - [Release notes](https://github.com/auth0/go-auth0/releases) - [Changelog](https://github.com/auth0/go-auth0/blob/main/CHANGELOG.md) - [Commits](https://github.com/auth0/go-auth0/compare/v1.2.0...v1.3.0) --- updated-dependencies: - dependency-name: github.com/auth0/go-auth0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --------- Signed-off-by: dependabot[bot] Co-authored-by: Sergiu Ghitea <28300158+sergiught@users.noreply.github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * DXCDT-582: Convert audience into a drop down in interactive mode in test token cmd (#906) Convert audience into a drop down in interactive mode in test token cmd Title Os for final release name fit * Bump goreleaser version * Increase default page amount to 100 results per page * Updated docs for defalut list limit --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Sergiu Ghitea <28300158+sergiught@users.noreply.github.com> --- docs/auth0_apis_list.md | 2 +- docs/auth0_apps_list.md | 2 +- docs/auth0_orgs_list.md | 2 +- docs/auth0_orgs_members_list.md | 2 +- docs/auth0_orgs_roles_list.md | 2 +- docs/auth0_orgs_roles_members_list.md | 2 +- docs/auth0_roles_list.md | 2 +- docs/auth0_roles_permissions_list.md | 2 +- docs/auth0_users_roles_show.md | 2 +- docs/auth0_users_search.md | 2 +- internal/cli/actions.go | 2 +- internal/cli/apps.go | 2 +- internal/cli/custom_domains.go | 2 +- internal/cli/log_streams.go | 2 +- internal/cli/logs.go | 2 +- 15 files changed, 15 insertions(+), 15 deletions(-) diff --git a/docs/auth0_apis_list.md b/docs/auth0_apis_list.md index 1c3d3c02c..3c45f3d15 100644 --- a/docs/auth0_apis_list.md +++ b/docs/auth0_apis_list.md @@ -26,7 +26,7 @@ auth0 apis list [flags] ``` --json Output in json format. - -n, --number int Number of APIs to retrieve. Minimum 1, maximum 1000. (default 50) + -n, --number int Number of APIs to retrieve. Minimum 1, maximum 1000. (default 100) ``` diff --git a/docs/auth0_apps_list.md b/docs/auth0_apps_list.md index 66af74c64..c5e89203e 100644 --- a/docs/auth0_apps_list.md +++ b/docs/auth0_apps_list.md @@ -27,7 +27,7 @@ auth0 apps list [flags] ``` --json Output in json format. - -n, --number int Number of apps to retrieve. Minimum 1, maximum 1000. (default 50) + -n, --number int Number of apps to retrieve. Minimum 1, maximum 1000. (default 100) -r, --reveal-secrets Display the application secrets ('signing_keys', 'client_secret') as part of the command output. ``` diff --git a/docs/auth0_orgs_list.md b/docs/auth0_orgs_list.md index c35b08953..fb165f5af 100644 --- a/docs/auth0_orgs_list.md +++ b/docs/auth0_orgs_list.md @@ -26,7 +26,7 @@ auth0 orgs list [flags] ``` --json Output in json format. - -n, --number int Number of organizations to retrieve. Minimum 1, maximum 1000. (default 50) + -n, --number int Number of organizations to retrieve. Minimum 1, maximum 1000. (default 100) ``` diff --git a/docs/auth0_orgs_members_list.md b/docs/auth0_orgs_members_list.md index 442bccaad..12058e087 100644 --- a/docs/auth0_orgs_members_list.md +++ b/docs/auth0_orgs_members_list.md @@ -26,7 +26,7 @@ auth0 orgs members list [flags] ``` --json Output in json format. - -n, --number int Number of organization members to retrieve. Minimum 1, maximum 1000. (default 50) + -n, --number int Number of organization members to retrieve. Minimum 1, maximum 1000. (default 100) ``` diff --git a/docs/auth0_orgs_roles_list.md b/docs/auth0_orgs_roles_list.md index fce9eef2b..d437b17c5 100644 --- a/docs/auth0_orgs_roles_list.md +++ b/docs/auth0_orgs_roles_list.md @@ -26,7 +26,7 @@ auth0 orgs roles list [flags] ``` --json Output in json format. - -n, --number int Number of organization roles to retrieve. Minimum 1, maximum 1000. (default 50) + -n, --number int Number of organization roles to retrieve. Minimum 1, maximum 1000. (default 100) ``` diff --git a/docs/auth0_orgs_roles_members_list.md b/docs/auth0_orgs_roles_members_list.md index 7c423f8e7..da59a7ced 100644 --- a/docs/auth0_orgs_roles_members_list.md +++ b/docs/auth0_orgs_roles_members_list.md @@ -28,7 +28,7 @@ auth0 orgs roles members list [flags] ``` --json Output in json format. - -n, --number int Number of members to retrieve. Minimum 1, maximum 1000. (default 50) + -n, --number int Number of members to retrieve. Minimum 1, maximum 1000. (default 100) -r, --role-id string Role Identifier. ``` diff --git a/docs/auth0_roles_list.md b/docs/auth0_roles_list.md index 6f67a5bf6..cbcc5ba02 100644 --- a/docs/auth0_roles_list.md +++ b/docs/auth0_roles_list.md @@ -26,7 +26,7 @@ auth0 roles list [flags] ``` --json Output in json format. - -n, --number int Number of roles to retrieve. Minimum 1, maximum 1000. (default 50) + -n, --number int Number of roles to retrieve. Minimum 1, maximum 1000. (default 100) ``` diff --git a/docs/auth0_roles_permissions_list.md b/docs/auth0_roles_permissions_list.md index 3a4657680..289bff008 100644 --- a/docs/auth0_roles_permissions_list.md +++ b/docs/auth0_roles_permissions_list.md @@ -26,7 +26,7 @@ auth0 roles permissions list [flags] ``` --json Output in json format. - -n, --number int Number of permissions to retrieve. Minimum 1, maximum 1000. (default 50) + -n, --number int Number of permissions to retrieve. Minimum 1, maximum 1000. (default 100) ``` diff --git a/docs/auth0_users_roles_show.md b/docs/auth0_users_roles_show.md index 1f5fc76f6..513c03b52 100644 --- a/docs/auth0_users_roles_show.md +++ b/docs/auth0_users_roles_show.md @@ -26,7 +26,7 @@ auth0 users roles show [flags] ``` --json Output in json format. - -n, --number int Number of user roles to retrieve. Minimum 1, maximum 1000. (default 50) + -n, --number int Number of user roles to retrieve. Minimum 1, maximum 1000. (default 100) ``` diff --git a/docs/auth0_users_search.md b/docs/auth0_users_search.md index f24111285..66825bb15 100644 --- a/docs/auth0_users_search.md +++ b/docs/auth0_users_search.md @@ -27,7 +27,7 @@ auth0 users search [flags] ``` --json Output in json format. - -n, --number int Number of users, that match the search criteria, to retrieve. Minimum 1, maximum 1000. If limit is hit, refine the search query. (default 50) + -n, --number int Number of users, that match the search criteria, to retrieve. Minimum 1, maximum 1000. If limit is hit, refine the search query. (default 100) -q, --query email:"user123@*.com" OR (user_id:"user-id-123" AND name:"Bob") Search query in Lucene query syntax. For example: email:"user123@*.com" OR (user_id:"user-id-123" AND name:"Bob") diff --git a/internal/cli/actions.go b/internal/cli/actions.go index 7bfeea8a6..61fee6739 100644 --- a/internal/cli/actions.go +++ b/internal/cli/actions.go @@ -103,7 +103,7 @@ func listActionsCmd(cli *cli) *cobra.Command { var list *management.ActionList if err := ansi.Waiting(func() (err error) { - list, err = cli.api.Action.List(cmd.Context(), management.PerPage(100)) + list, err = cli.api.Action.List(cmd.Context(), management.PerPage(defaultPageSize)) return err }); err != nil { return fmt.Errorf("failed to retrieve actions: %w", err) diff --git a/internal/cli/apps.go b/internal/cli/apps.go index 3d19ec566..3f3887ac6 100644 --- a/internal/cli/apps.go +++ b/internal/cli/apps.go @@ -25,7 +25,7 @@ const ( appTypeRegularWeb = "regular_web" appTypeNonInteractive = "non_interactive" appDefaultURL = "http://localhost:3000" - defaultPageSize = 50 + defaultPageSize = 100 ) var ( diff --git a/internal/cli/custom_domains.go b/internal/cli/custom_domains.go index 81c9ba42a..c04c4ea19 100644 --- a/internal/cli/custom_domains.go +++ b/internal/cli/custom_domains.go @@ -108,7 +108,7 @@ func listCustomDomainsCmd(cli *cli) *cobra.Command { if err := ansi.Waiting(func() error { var err error - list, err = cli.api.CustomDomain.List(cmd.Context()) + list, err = cli.api.CustomDomain.List(cmd.Context(), management.PerPage(defaultPageSize)) return err }); err != nil { return fmt.Errorf("An unexpected error occurred: %w", err) diff --git a/internal/cli/log_streams.go b/internal/cli/log_streams.go index 51596cf3e..26300e34d 100644 --- a/internal/cli/log_streams.go +++ b/internal/cli/log_streams.go @@ -72,7 +72,7 @@ func listLogStreamsCmd(cli *cli) *cobra.Command { if err := ansi.Waiting(func() error { var err error - list, err = cli.api.LogStream.List(cmd.Context()) + list, err = cli.api.LogStream.List(cmd.Context(), management.PerPage(defaultPageSize)) return err }); err != nil { return fmt.Errorf("An unexpected error occurred: %w", err) diff --git a/internal/cli/logs.go b/internal/cli/logs.go index 7792f95c8..89f778f1a 100644 --- a/internal/cli/logs.go +++ b/internal/cli/logs.go @@ -82,7 +82,7 @@ func listLogsCmd(cli *cli) *cobra.Command { } logsFilter.RegisterString(cmd, &inputs.Filter, "") - logsNum.RegisterInt(cmd, &inputs.Num, 100) + logsNum.RegisterInt(cmd, &inputs.Num, defaultPageSize) cmd.Flags().BoolVar(&cli.json, "json", false, "Output in json format.") From a2550ed4bbced4ac479ee5ee4a22171c06a2f2d7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 15 Dec 2023 12:57:17 +0000 Subject: [PATCH 08/19] Bump github.com/auth0/go-auth0 from 1.3.1 to 1.4.0 (#944) --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 2d6a409ca..7a8ef704a 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,7 @@ go 1.21 require ( github.com/AlecAivazis/survey/v2 v2.3.7 github.com/PuerkitoBio/rehttp v1.3.0 - github.com/auth0/go-auth0 v1.3.1 + github.com/auth0/go-auth0 v1.4.0 github.com/briandowns/spinner v1.23.0 github.com/charmbracelet/glamour v0.6.0 github.com/fsnotify/fsnotify v1.7.0 diff --git a/go.sum b/go.sum index ada44db23..5d488879e 100644 --- a/go.sum +++ b/go.sum @@ -19,8 +19,8 @@ github.com/andybalholm/brotli v1.0.5 h1:8uQZIdzKmjc/iuPu7O2ioW48L81FgatrcpfFmiq/ github.com/andybalholm/brotli v1.0.5/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= github.com/apparentlymart/go-textseg/v15 v15.0.0 h1:uYvfpb3DyLSCGWnctWKGj857c6ew1u1fNQOlOtuGxQY= github.com/apparentlymart/go-textseg/v15 v15.0.0/go.mod h1:K8XmNZdhEBkdlyDdvbmmsvpAG721bKi0joRfFdHIWJ4= -github.com/auth0/go-auth0 v1.3.1 h1:J9QIKOMKs/uE9eo1OvTHfci8inuPau0M4WSgdNmPRaQ= -github.com/auth0/go-auth0 v1.3.1/go.mod h1:lpfYGQAGw5RFFWCmVc0kJI4c6w9mA1CbEaJfZ7xZycw= +github.com/auth0/go-auth0 v1.4.0 h1:oZL3xIBBPW2ckLQmp6BSqpx5RV5yuqqOEVEPp4cipR4= +github.com/auth0/go-auth0 v1.4.0/go.mod h1:X1o5gVvYUYAQltayD5HrLimFZN9tfZUlJDUh+lz8h9I= github.com/aybabtme/iocontrol v0.0.0-20150809002002-ad15bcfc95a0 h1:0NmehRCgyk5rljDQLKUO+cRJCnduDyn11+zGZIc9Z48= github.com/aybabtme/iocontrol v0.0.0-20150809002002-ad15bcfc95a0/go.mod h1:6L7zgvqo0idzI7IO8de6ZC051AfXb5ipkIJ7bIA2tGA= github.com/aymanbagabas/go-osc52 v1.0.3 h1:DTwqENW7X9arYimJrPeGZcV0ln14sGMt3pHZspWD+Mg= From 364b64391d093cc44ba67e3631c29f5c952f515a Mon Sep 17 00:00:00 2001 From: Sergiu Ghitea <28300158+sergiught@users.noreply.github.com> Date: Tue, 19 Dec 2023 12:07:28 +0100 Subject: [PATCH 09/19] DXCDT-396: Standardize error messages (#943) --- .golangci.yml | 6 +- internal/analytics/analytics.go | 14 ++-- internal/analytics/analytics_test.go | 2 +- internal/ansi/ansi_test.go | 10 +-- internal/auth/auth.go | 10 ++- internal/auth/auth_test.go | 18 +++-- internal/auth/authutil/browser.go | 2 +- internal/auth/authutil/browser_test.go | 14 ++-- internal/auth/authutil/exchange.go | 4 +- internal/auth/authutil/exchange_test.go | 7 +- internal/auth/authutil/user_info.go | 4 +- internal/auth/authutil/user_info_test.go | 10 ++- internal/auth/token.go | 5 +- internal/auth0/log.go | 2 +- internal/auth0/quickstart.go | 12 ++-- internal/auth0/quickstarts_test.go | 4 +- internal/auth0/user.go | 2 +- internal/cli/actions.go | 36 ++++++---- internal/cli/actions_test.go | 8 +-- internal/cli/api.go | 6 +- internal/cli/api_test.go | 4 +- internal/cli/apis.go | 30 ++++---- internal/cli/apis_test.go | 2 +- internal/cli/apps.go | 72 +++++++++---------- internal/cli/custom_domains.go | 54 ++++++-------- .../universal-login/assets/index-89540052.js | 2 +- internal/cli/doc-gen.go | 4 +- internal/cli/email_templates.go | 13 ++-- internal/cli/flags.go | 2 +- internal/cli/input.go | 4 +- internal/cli/log_streams.go | 17 ++--- internal/cli/log_streams_datadog.go | 6 +- internal/cli/log_streams_event_bridge.go | 4 +- internal/cli/log_streams_event_grid.go | 4 +- internal/cli/log_streams_http.go | 6 +- internal/cli/log_streams_splunk.go | 6 +- internal/cli/log_streams_sumo.go | 6 +- internal/cli/log_streams_test.go | 4 +- internal/cli/login.go | 6 +- internal/cli/logout.go | 2 +- internal/cli/logs.go | 4 +- internal/cli/logs_test.go | 2 +- internal/cli/organizations.go | 51 ++++++------- internal/cli/organizations_test.go | 2 +- internal/cli/prompts_custom_text.go | 10 +-- internal/cli/prompts_custom_text_test.go | 2 +- internal/cli/quickstarts.go | 6 +- internal/cli/roles.go | 28 +++----- internal/cli/roles_permissions.go | 29 ++++---- internal/cli/roles_test.go | 2 +- internal/cli/root.go | 31 +++++--- internal/cli/rules.go | 70 +++++++++--------- internal/cli/rules_test.go | 2 +- internal/cli/tenants.go | 2 +- internal/cli/terraform.go | 10 ++- internal/cli/terraform_fetcher.go | 2 +- internal/cli/terraform_test.go | 18 +++-- internal/cli/test.go | 10 +-- internal/cli/universal_login.go | 17 ++--- internal/cli/universal_login_customize.go | 4 +- internal/cli/universal_login_templates.go | 14 ++-- internal/cli/users.go | 35 +++++---- internal/cli/users_blocks.go | 2 +- internal/cli/users_roles.go | 18 ++--- internal/cli/users_roles_test.go | 8 +-- internal/cli/utils_shared.go | 28 ++++---- internal/config/config.go | 2 +- internal/config/config_test.go | 2 +- internal/display/actions.go | 2 +- internal/display/apis.go | 4 +- internal/display/display.go | 6 +- internal/display/rules.go | 2 +- internal/keyring/keyring.go | 6 +- internal/keyring/keyring_test.go | 8 +-- internal/prompt/editor.go | 14 ++-- internal/prompt/prompt.go | 2 +- internal/prompt/surveyext.go | 10 +-- test/integration/api-test-cases.yaml | 4 +- test/integration/apis-test-cases.yaml | 2 +- test/integration/apps-test-cases.yaml | 6 +- .../custom-domains-test-cases.yaml | 2 +- test/integration/logs-test-cases.yaml | 4 +- .../integration/organizations-test-cases.yaml | 12 ++-- test/integration/roles-test-cases.yaml | 4 +- test/integration/terraform-test-cases.yaml | 4 +- .../integration/test-commands-test-cases.yaml | 4 +- .../universal-login-test-cases.yaml | 2 +- test/integration/users-test-cases.yaml | 4 +- 88 files changed, 496 insertions(+), 441 deletions(-) diff --git a/.golangci.yml b/.golangci.yml index e1278a0c3..d523aa57e 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -16,7 +16,7 @@ linters: - whitespace - goimports - gosimple -# - errcheck + - errcheck - unconvert - gocritic # - gosec @@ -28,8 +28,9 @@ linters-settings: staticcheck: checks: [ "all" ] godot: - scope: declarations + scope: all capital: true + period: true goimports: local-prefixes: "github.com/auth0/auth0-cli" @@ -40,5 +41,4 @@ issues: - "package comment should be of the form" - "should have comment" - "be unexported" - - "error strings should not be capitalized or end with punctuation or a newline" - "blank-imports" diff --git a/internal/analytics/analytics.go b/internal/analytics/analytics.go index bcbff3de5..38336d724 100644 --- a/internal/analytics/analytics.go +++ b/internal/analytics/analytics.go @@ -63,7 +63,7 @@ func (t *Tracker) Wait(ctx context.Context) { }() select { - case <-ch: // waitgroup is done + case <-ch: // Waitgroup is done. return case <-ctx.Done(): return @@ -101,9 +101,11 @@ func (t *Tracker) sendEvent(event *event) { return } - // defers execute in LIFO order + // Defers execute in LIFO order. defer t.wg.Done() - defer resp.Body.Close() + defer func() { + _ = resp.Body.Close() + }() } func newEvent(eventName string, id string) *event { @@ -131,9 +133,9 @@ func generateEventName(command string, action string) string { } switch length := len(commands); { - case length == 1: // the root command + case length == 1: // The root command. return fmt.Sprintf("%s - %s - %s", eventNamePrefix, commands[0], action) - case length == 2: // a top-level command e.g. auth0 apps + case length == 2: // A top-level command e.g. auth0 apps. return fmt.Sprintf("%s - %s - %s - %s", eventNamePrefix, commands[0], commands[1], action) case length >= 3: return fmt.Sprintf("%s - %s - %s - %s", eventNamePrefix, commands[1], strings.Join(commands[2:], " "), action) @@ -143,7 +145,7 @@ func generateEventName(command string, action string) string { } func shouldTrack() bool { - if os.Getenv("AUTH0_CLI_ANALYTICS") == "false" || buildinfo.Version == "" { // Do not track debug builds + if os.Getenv("AUTH0_CLI_ANALYTICS") == "false" || buildinfo.Version == "" { // Do not track debug builds. return false } diff --git a/internal/analytics/analytics_test.go b/internal/analytics/analytics_test.go index d61a44502..5b15c6b50 100644 --- a/internal/analytics/analytics_test.go +++ b/internal/analytics/analytics_test.go @@ -63,7 +63,7 @@ func TestGenerateRunEventName(t *testing.T) { func TestNewEvent(t *testing.T) { t.Run("creates a new event instance", func(t *testing.T) { event := newEvent("event", "id") - // Assert that the interval between the event timestamp and now is within 1 second + // Assert that the interval between the event timestamp and now is within 1 second. assert.WithinDuration(t, time.Now(), time.Unix(0, event.Timestamp*int64(1000000)), 1*time.Second) assert.Equal(t, event.App, appID) assert.Equal(t, event.Event, "event") diff --git a/internal/ansi/ansi_test.go b/internal/ansi/ansi_test.go index 13a6217bc..84feb9345 100644 --- a/internal/ansi/ansi_test.go +++ b/internal/ansi/ansi_test.go @@ -1,22 +1,18 @@ package ansi import ( - "os" "testing" "github.com/stretchr/testify/assert" ) func TestShouldUseColors(t *testing.T) { - os.Setenv("CLICOLOR_FORCE", "true") + t.Setenv("CLICOLOR_FORCE", "true") assert.True(t, shouldUseColors()) - os.Setenv("CLICOLOR_FORCE", "0") + t.Setenv("CLICOLOR_FORCE", "0") assert.False(t, shouldUseColors()) - os.Unsetenv("CLI_COLOR_FORCE") - - os.Setenv("CLICOLOR", "0") + t.Setenv("CLICOLOR", "0") assert.False(t, shouldUseColors()) - os.Unsetenv("CLICOLOR") } diff --git a/internal/auth/auth.go b/internal/auth/auth.go index ef8786d35..2122e78b1 100644 --- a/internal/auth/auth.go +++ b/internal/auth/auth.go @@ -73,7 +73,9 @@ func WaitUntilUserLogsIn(ctx context.Context, httpClient *http.Client, state Sta if err != nil { return Result{}, fmt.Errorf("cannot get device code: %w", err) } - defer r.Body.Close() + defer func() { + _ = r.Body.Close() + }() var res struct { AccessToken string `json:"access_token"` @@ -118,7 +120,7 @@ func WaitUntilUserLogsIn(ctx context.Context, httpClient *http.Client, state Sta var RequiredScopes = []string{ "openid", - "offline_access", // for retrieving refresh token + "offline_access", // For retrieving refresh token. "create:clients", "delete:clients", "read:clients", "update:clients", "read:client_grants", "create:resource_servers", "delete:resource_servers", "read:resource_servers", "update:resource_servers", @@ -167,7 +169,9 @@ func GetDeviceCode(ctx context.Context, httpClient *http.Client, additionalScope if err != nil { return State{}, fmt.Errorf("failed to send the request: %w", err) } - defer response.Body.Close() + defer func() { + _ = response.Body.Close() + }() if response.StatusCode != http.StatusOK { bodyBytes, err := io.ReadAll(response.Body) diff --git a/internal/auth/auth_test.go b/internal/auth/auth_test.go index 3b6d1134b..ba63540f8 100644 --- a/internal/auth/auth_test.go +++ b/internal/auth/auth_test.go @@ -10,6 +10,7 @@ import ( "time" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestWaitUntilUserLogsIn(t *testing.T) { @@ -34,12 +35,14 @@ func TestWaitUntilUserLogsIn(t *testing.T) { ts := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusOK) if counter < 1 { - io.WriteString(w, `{ + _, err := io.WriteString(w, `{ "error": "authorization_pending", "error_description": "still pending auth" }`) + require.NoError(t, err) } else { - io.WriteString(w, tokenResponse) + _, err := io.WriteString(w, tokenResponse) + require.NoError(t, err) } counter++ })) @@ -89,7 +92,8 @@ func TestWaitUntilUserLogsIn(t *testing.T) { ts := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(testCase.httpStatus) if testCase.response != "" { - io.WriteString(w, testCase.response) + _, err := io.WriteString(w, testCase.response) + require.NoError(t, err) } })) @@ -111,13 +115,14 @@ func TestGetDeviceCode(t *testing.T) { t.Run("successfully retrieve state from response", func(t *testing.T) { ts := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") - io.WriteString(w, `{ + _, err := io.WriteString(w, `{ "device_code": "device-code-here", "user_code": "user-code-here", "verification_uri_complete": "verification-uri-here", "expires_in": 1000, "interval": 1 }`) + require.NoError(t, err) })) defer ts.Close() @@ -163,7 +168,8 @@ func TestGetDeviceCode(t *testing.T) { ts := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(testCase.httpStatus) if testCase.response != "" { - io.WriteString(w, testCase.response) + _, err := io.WriteString(w, testCase.response) + require.NoError(t, err) } })) @@ -201,7 +207,7 @@ func TestParseTenant(t *testing.T) { }, { name: "bad json encoding", - accessToken: "Zm9v.Zm9v", // foo encoded in base64 + accessToken: "Zm9v.Zm9v", // Foo encoded in base64. err: "invalid character 'o' in literal false (expecting 'a')", }, { diff --git a/internal/auth/authutil/browser.go b/internal/auth/authutil/browser.go index 10e03b7ca..d470e307c 100644 --- a/internal/auth/authutil/browser.go +++ b/internal/auth/authutil/browser.go @@ -35,7 +35,7 @@ func WaitForBrowserCallback(addr string) (code string, state string, err error) if cb.code == "" { _, _ = w.Write([]byte(resultPage("Login Failed", - "Unable to extract code from request, please try authenticating again.", + "Failed to extract code from request, please try authenticating again.", "error-denied"))) } else { _, _ = w.Write([]byte(resultPage("Login Successful", diff --git a/internal/auth/authutil/browser_test.go b/internal/auth/authutil/browser_test.go index b215d6f24..d6fa39afc 100644 --- a/internal/auth/authutil/browser_test.go +++ b/internal/auth/authutil/browser_test.go @@ -23,7 +23,9 @@ func TestWaitForBrowserCallback(t *testing.T) { assert.NoError(t, err) body := string(bytes) - defer resp.Body.Close() + defer func() { + _ = resp.Body.Close() + }() assert.Contains(t, body, "You can close the window and go back to the CLI to see the user info and tokens.") }) @@ -43,9 +45,11 @@ func TestWaitForBrowserCallback(t *testing.T) { bytes, err := io.ReadAll(resp.Body) assert.NoError(t, err) body := string(bytes) - defer resp.Body.Close() + defer func() { + _ = resp.Body.Close() + }() - assert.Contains(t, body, "Unable to extract code from request, please try authenticating again") + assert.Contains(t, body, "Failed to extract code from request, please try authenticating again") }) code, state, callbackErr := WaitForBrowserCallback("localhost:1234") @@ -65,7 +69,9 @@ func TestWaitForBrowserCallback(t *testing.T) { time.Sleep(1 * time.Second) - defer s.Close() + defer func() { + _ = s.Close() + }() code, state, callbackErr := WaitForBrowserCallback("localhost:1234") diff --git a/internal/auth/authutil/exchange.go b/internal/auth/authutil/exchange.go index 4ef66c5f4..99ebaa130 100644 --- a/internal/auth/authutil/exchange.go +++ b/internal/auth/authutil/exchange.go @@ -32,7 +32,9 @@ func ExchangeCodeForToken(httpClient *http.Client, baseDomain, clientID, clientS if err != nil { return nil, fmt.Errorf("unable to exchange code for token: %w", err) } - defer r.Body.Close() + defer func() { + _ = r.Body.Close() + }() if r.StatusCode != http.StatusOK { return nil, fmt.Errorf("unable to exchange code for token: %s", r.Status) diff --git a/internal/auth/authutil/exchange_test.go b/internal/auth/authutil/exchange_test.go index ee12bdbfc..aaafa4e7b 100644 --- a/internal/auth/authutil/exchange_test.go +++ b/internal/auth/authutil/exchange_test.go @@ -8,18 +8,20 @@ import ( "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestExchangeCodeForToken(t *testing.T) { t.Run("Successfully call token endpoint", func(t *testing.T) { ts := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") - io.WriteString(w, `{ + _, err := io.WriteString(w, `{ "access_token": "access-token-here", "id_token": "id-token-here", "token_type": "token-type-here", "expires_in": 1000 }`) + require.NoError(t, err) })) defer ts.Close() @@ -59,7 +61,8 @@ func TestExchangeCodeForToken(t *testing.T) { ts := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(testCase.httpStatus) if testCase.response != "" { - io.WriteString(w, testCase.response) + _, err := io.WriteString(w, testCase.response) + require.NoError(t, err) } })) diff --git a/internal/auth/authutil/user_info.go b/internal/auth/authutil/user_info.go index eebcc5fb2..eceacf433 100644 --- a/internal/auth/authutil/user_info.go +++ b/internal/auth/authutil/user_info.go @@ -82,7 +82,9 @@ func FetchUserInfo(httpClient *http.Client, baseDomain, token string) (*UserInfo if err != nil { return nil, fmt.Errorf("unable to exchange code for token: %w", err) } - defer res.Body.Close() + defer func() { + _ = res.Body.Close() + }() if res.StatusCode != http.StatusOK { return nil, fmt.Errorf("unable to fetch user info: %s", res.Status) diff --git a/internal/auth/authutil/user_info_test.go b/internal/auth/authutil/user_info_test.go index d0f79d1ec..0ad620d5f 100644 --- a/internal/auth/authutil/user_info_test.go +++ b/internal/auth/authutil/user_info_test.go @@ -8,6 +8,7 @@ import ( "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestUserInfo(t *testing.T) { @@ -16,7 +17,8 @@ func TestUserInfo(t *testing.T) { assert.Equal(t, "Bearer token", r.Header.Get("authorization")) w.Header().Set("Content-Type", "application/json") - io.WriteString(w, `{"name": "Joe Bloggs","email_verified":true}`) + _, err := io.WriteString(w, `{"name": "Joe Bloggs","email_verified":true}`) + require.NoError(t, err) })) defer ts.Close() @@ -35,7 +37,8 @@ func TestUserInfo(t *testing.T) { assert.Equal(t, "Bearer token", r.Header.Get("authorization")) w.Header().Set("Content-Type", "application/json") - io.WriteString(w, `{"email_verified":"true"}`) + _, err := io.WriteString(w, `{"email_verified":"true"}`) + require.NoError(t, err) })) defer ts.Close() @@ -78,7 +81,8 @@ func TestUserInfo(t *testing.T) { ts := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(testCase.httpStatus) if testCase.response != "" { - io.WriteString(w, testCase.response) + _, err := io.WriteString(w, testCase.response) + require.NoError(t, err) } })) diff --git a/internal/auth/token.go b/internal/auth/token.go index adf4c5546..732d3cee5 100644 --- a/internal/auth/token.go +++ b/internal/auth/token.go @@ -40,7 +40,10 @@ func RefreshAccessToken(httpClient *http.Client, tenant string) (TokenResponse, return TokenResponse{}, fmt.Errorf("cannot get a new access token from the refresh token: %w", err) } - defer r.Body.Close() + defer func() { + _ = r.Body.Close() + }() + if r.StatusCode != http.StatusOK { b, _ := io.ReadAll(r.Body) bodyStr := string(b) diff --git a/internal/auth0/log.go b/internal/auth0/log.go index a32ab74bf..6098e6926 100644 --- a/internal/auth0/log.go +++ b/internal/auth0/log.go @@ -21,6 +21,6 @@ type LogAPI interface { // and descriptions, Log Data Event Listing. List(ctx context.Context, opts ...management.RequestOption) (l []*management.Log, err error) - // Search is an alias for List + // Search is an alias for List. Search(ctx context.Context, opts ...management.RequestOption) ([]*management.Log, error) } diff --git a/internal/auth0/quickstart.go b/internal/auth0/quickstart.go index f746716e5..d5d952d50 100644 --- a/internal/auth0/quickstart.go +++ b/internal/auth0/quickstart.go @@ -83,7 +83,9 @@ func (q Quickstart) Download(ctx context.Context, downloadPath string, client *m if err := tmpFile.Close(); err != nil { return err } - defer os.Remove(tmpFile.Name()) + defer func() { + _ = os.Remove(tmpFile.Name()) + }() if err := os.RemoveAll(downloadPath); err != nil { return err @@ -102,7 +104,9 @@ func GetQuickstarts(ctx context.Context) (Quickstarts, error) { if err != nil { return nil, err } - defer response.Body.Close() + defer func() { + _ = response.Body.Close() + }() if response.StatusCode != http.StatusOK { return nil, fmt.Errorf( @@ -126,7 +130,7 @@ func (q Quickstarts) FindByStack(stack string) (Quickstart, error) { } } - return Quickstart{}, fmt.Errorf("quickstart not found for %s", stack) + return Quickstart{}, fmt.Errorf("failed to find any quickstarts for stack: %q", stack) } func (q Quickstarts) FilterByType(qsType string) (Quickstarts, error) { @@ -138,7 +142,7 @@ func (q Quickstarts) FilterByType(qsType string) (Quickstarts, error) { } if len(filteredQuickstarts) == 0 { - return nil, fmt.Errorf("unable to find any quickstarts for: %s", qsType) + return nil, fmt.Errorf("failed to find any quickstarts for type: %q", qsType) } return filteredQuickstarts, nil diff --git a/internal/auth0/quickstarts_test.go b/internal/auth0/quickstarts_test.go index f97d9b99d..0fe3f2489 100644 --- a/internal/auth0/quickstarts_test.go +++ b/internal/auth0/quickstarts_test.go @@ -43,7 +43,7 @@ func TestFilterByType(t *testing.T) { res, err := mockQuickStarts.FilterByType("some-unknown-type") assert.Nil(t, res) assert.Error(t, err) - assert.Equal(t, fmt.Sprintf("unable to find any quickstarts for: %s", "some-unknown-type"), err.Error()) + assert.Equal(t, fmt.Sprintf("failed to find any quickstarts for type: %q", "some-unknown-type"), err.Error()) }) } @@ -68,6 +68,6 @@ func TestFindByStack(t *testing.T) { res, err := mockQuickStarts.FindByStack("some-non-existent-qs-type") assert.Error(t, err) assert.Empty(t, res) - assert.Equal(t, fmt.Sprintf("quickstart not found for %s", "some-non-existent-qs-type"), err.Error()) + assert.Equal(t, fmt.Sprintf("failed to find any quickstarts for stack: %q", "some-non-existent-qs-type"), err.Error()) }) } diff --git a/internal/auth0/user.go b/internal/auth0/user.go index ed32a85a2..18319b13c 100644 --- a/internal/auth0/user.go +++ b/internal/auth0/user.go @@ -37,7 +37,7 @@ type UserAPI interface { // List all users. List(ctx context.Context, opts ...management.RequestOption) (ul *management.UserList, err error) - // Search for users + // Search for users. Search(ctx context.Context, opts ...management.RequestOption) (us *management.UserList, err error) // Roles lists all roles associated with a user. diff --git a/internal/cli/actions.go b/internal/cli/actions.go index 61fee6739..89d9654a6 100644 --- a/internal/cli/actions.go +++ b/internal/cli/actions.go @@ -106,10 +106,11 @@ func listActionsCmd(cli *cli) *cobra.Command { list, err = cli.api.Action.List(cmd.Context(), management.PerPage(defaultPageSize)) return err }); err != nil { - return fmt.Errorf("failed to retrieve actions: %w", err) + return fmt.Errorf("failed to list actions: %w", err) } cli.renderer.ActionList(list.Actions) + return nil }, } @@ -147,10 +148,11 @@ func showActionCmd(cli *cli) *cobra.Command { action, err = cli.api.Action.Read(cmd.Context(), inputs.ID) return err }); err != nil { - return fmt.Errorf("failed to get action with ID %q: %w", inputs.ID, err) + return fmt.Errorf("failed to read action with ID %q: %w", inputs.ID, err) } cli.renderer.ActionShow(action) + return nil }, } @@ -191,7 +193,7 @@ func createActionCmd(cli *cli) *cobra.Command { triggers, err := getCurrentTriggers(cmd.Context(), cli) if err != nil { - return err + return fmt.Errorf("failed to retrieve available triggers: %w", err) } triggerIDs := make([]string, 0) @@ -241,6 +243,7 @@ func createActionCmd(cli *cli) *cobra.Command { } cli.renderer.ActionCreate(action) + return nil }, } @@ -294,7 +297,7 @@ func updateActionCmd(cli *cli) *cobra.Command { return err }) if err != nil { - return fmt.Errorf("failed to fetch action with ID %s: %w", inputs.ID, err) + return fmt.Errorf("failed to read action with ID %q: %w", inputs.ID, err) } if err := actionName.AskU(cmd, &inputs.Name, oldAction.Name); err != nil { @@ -343,6 +346,7 @@ func updateActionCmd(cli *cli) *cobra.Command { } cli.renderer.ActionUpdate(updatedAction) + return nil }, } @@ -420,7 +424,7 @@ func deployActionCmd(cli *cli) *cobra.Command { auth0 actions deploy --json`, RunE: func(cmd *cobra.Command, args []string) error { if len(args) == 0 { - if err := actionID.Pick(cmd, &inputs.ID, cli.undeployedActionPickerOptions); err != nil { + if err := actionID.Pick(cmd, &inputs.ID, cli.unDeployedActionPickerOptions); err != nil { return err } } else { @@ -428,19 +432,23 @@ func deployActionCmd(cli *cli) *cobra.Command { } var action *management.Action + if err := ansi.Waiting(func() (err error) { if _, err = cli.api.Action.Deploy(cmd.Context(), inputs.ID); err != nil { return fmt.Errorf("failed to deploy action with ID %q: %w", inputs.ID, err) } + if action, err = cli.api.Action.Read(cmd.Context(), inputs.ID); err != nil { - return fmt.Errorf("failed to get deployed action with ID %q: %w", inputs.ID, err) + return fmt.Errorf("failed to read deployed action with ID %q: %w", inputs.ID, err) } + return nil }); err != nil { return err } cli.renderer.ActionDeploy(action) + return nil }, } @@ -472,6 +480,7 @@ func openActionCmd(cli *cli) *cobra.Command { } openManageURL(cli, cli.Config.DefaultTenant, formatActionDetailsPath(url.PathEscape(inputs.ID))) + return nil }, } @@ -493,16 +502,16 @@ func (c *cli) actionPickerOptions(ctx context.Context) (pickerOptions, error) { } if len(opts) == 0 { - return nil, errors.New("There are currently no actions.") + return nil, errors.New("there are currently no actions to choose from. Create one by running: `auth0 actions create`") } return opts, nil } -func (c *cli) undeployedActionPickerOptions(ctx context.Context) (pickerOptions, error) { +func (c *cli) unDeployedActionPickerOptions(ctx context.Context) (pickerOptions, error) { list, err := c.api.Action.List(ctx, management.Parameter("deployed", "false")) if err != nil { - return nil, err + return nil, fmt.Errorf("failed to list actions: %w", err) } var opts pickerOptions @@ -513,7 +522,7 @@ func (c *cli) undeployedActionPickerOptions(ctx context.Context) (pickerOptions, } if len(opts) == 0 { - return nil, errors.New("There are currently no actions to deploy.") + return nil, errors.New("there are currently no actions to deploy") } return opts, nil @@ -530,7 +539,7 @@ func formatActionDetailsPath(id string) string { return fmt.Sprintf("actions/library/details/%s", id) } -func filterDeprecatedActionTriggers(list []*management.ActionTrigger) []*management.ActionTrigger { +func filterOutDeprecatedActionTriggers(list []*management.ActionTrigger) []*management.ActionTrigger { res := []*management.ActionTrigger{} for _, t := range list { if t.GetStatus() == "CURRENT" { @@ -542,18 +551,21 @@ func filterDeprecatedActionTriggers(list []*management.ActionTrigger) []*managem func getCurrentTriggers(ctx context.Context, cli *cli) ([]*management.ActionTrigger, error) { var triggers []*management.ActionTrigger + if err := ansi.Waiting(func() error { list, err := cli.api.Action.Triggers(ctx) if err != nil { return err } + triggers = list.Triggers + return nil }); err != nil { return nil, err } - return filterDeprecatedActionTriggers(triggers), nil + return filterOutDeprecatedActionTriggers(triggers), nil } func actionTemplate(key string) string { diff --git a/internal/cli/actions_test.go b/internal/cli/actions_test.go index dee12f61b..565bac35b 100644 --- a/internal/cli/actions_test.go +++ b/internal/cli/actions_test.go @@ -128,7 +128,7 @@ func TestActionsDeployCmd(t *testing.T) { cmd.SetArgs([]string{actionID}) err := cmd.Execute() - assert.EqualError(t, err, `failed to get deployed action with ID "1221c74c-cfd6-40db-af13-7bc9bb1c38db": 400 Bad Request`) + assert.EqualError(t, err, `failed to read deployed action with ID "1221c74c-cfd6-40db-af13-7bc9bb1c38db": 400 Bad Request`) }) } @@ -170,7 +170,7 @@ func TestActionsPickerOptions(t *testing.T) { t.Fail() }, assertError: func(t testing.TB, err error) { - assert.ErrorContains(t, err, "There are currently no actions.") + assert.ErrorContains(t, err, "there are currently no actions to choose from. Create one by running: `auth0 actions create`") }, }, { @@ -249,7 +249,7 @@ func TestUndeployedActionsPickerOptions(t *testing.T) { t.Fail() }, assertError: func(t testing.TB, err error) { - assert.ErrorContains(t, err, "There are currently no actions to deploy.") + assert.ErrorContains(t, err, "there are currently no actions to deploy") }, }, { @@ -279,7 +279,7 @@ func TestUndeployedActionsPickerOptions(t *testing.T) { api: &auth0.API{Action: actionAPI}, } - options, err := cli.undeployedActionPickerOptions(context.Background()) + options, err := cli.unDeployedActionPickerOptions(context.Background()) if err != nil { test.assertError(t, err) diff --git a/internal/cli/api.go b/internal/cli/api.go index 94be6f987..8d4a2f0b0 100644 --- a/internal/cli/api.go +++ b/internal/cli/api.go @@ -157,7 +157,9 @@ func apiCmdRun(cli *cli, inputs *apiCmdInputs) func(cmd *cobra.Command, args []s }); err != nil { return fmt.Errorf("failed to send request: %w", err) } - defer response.Body.Close() + defer func() { + _ = response.Body.Close() + }() if err := isInsufficientScopeError(response); err != nil { return err @@ -299,7 +301,7 @@ func isInsufficientScopeError(r *http.Response) error { return fmt.Errorf( "request failed because access token lacks scope: %s.\n "+ "If authenticated via client credentials, add this scope to the designated client. "+ - "If authenticated as a user, request this scope during login by running `auth0 login --scopes %s`.", + "If authenticated as a user, request this scope during login by running `auth0 login --scopes %s`", recommendedScopeToAdd, recommendedScopeToAdd, ) diff --git a/internal/cli/api_test.go b/internal/cli/api_test.go index 8d63685cd..44d256049 100644 --- a/internal/cli/api_test.go +++ b/internal/cli/api_test.go @@ -126,7 +126,7 @@ func TestAPICmd_IsInsufficientScopeError(t *testing.T) { "message": "Insufficient scope, expected any of: create:client_grants", "errorCode": "insufficient_scope" }`, - expectedError: "request failed because access token lacks scope: create:client_grants.\n If authenticated via client credentials, add this scope to the designated client. If authenticated as a user, request this scope during login by running `auth0 login --scopes create:client_grants`.", + expectedError: "request failed because access token lacks scope: create:client_grants.\n If authenticated via client credentials, add this scope to the designated client. If authenticated as a user, request this scope during login by running `auth0 login --scopes create:client_grants`", }, { name: "it correctly detects an insufficient scope error with multiple scope", @@ -137,7 +137,7 @@ func TestAPICmd_IsInsufficientScopeError(t *testing.T) { "message": "Insufficient scope, expected any of: read:clients, read:client_summary", "errorCode": "insufficient_scope" }`, - expectedError: "request failed because access token lacks scope: read:clients.\n If authenticated via client credentials, add this scope to the designated client. If authenticated as a user, request this scope during login by running `auth0 login --scopes read:clients`.", + expectedError: "request failed because access token lacks scope: read:clients.\n If authenticated via client credentials, add this scope to the designated client. If authenticated as a user, request this scope during login by running `auth0 login --scopes read:clients`", }, } diff --git a/internal/cli/apis.go b/internal/cli/apis.go index 0d210a239..053995470 100644 --- a/internal/cli/apis.go +++ b/internal/cli/apis.go @@ -141,7 +141,7 @@ func listApisCmd(cli *cli) *cobra.Command { }, ) if err != nil { - return fmt.Errorf("An unexpected error occurred while listing apis: %w", err) + return fmt.Errorf("failed to list APIs: %w", err) } var apis []*management.ResourceServer @@ -191,7 +191,7 @@ func showAPICmd(cli *cli) *cobra.Command { api, err = cli.api.ResourceServer.Read(cmd.Context(), url.PathEscape(inputs.ID)) return err }); err != nil { - return fmt.Errorf("Unable to get an API with Id '%s': %w", inputs.ID, err) + return fmt.Errorf("failed to read API with ID %q: %w", inputs.ID, err) } cli.renderer.APIShow(api, cli.json) @@ -278,7 +278,7 @@ func createAPICmd(cli *cli) *cobra.Command { return cli.api.ResourceServer.Create(cmd.Context(), api) }); err != nil { return fmt.Errorf( - "failed to create an API with name '%s' and identifier '%s': %w", + "failed to create API with name %q and identifier %q: %w", inputs.Name, inputs.Identifier, err, @@ -396,7 +396,7 @@ func updateAPICmd(cli *cli) *cobra.Command { if err := ansi.Waiting(func() error { return cli.api.ResourceServer.Update(cmd.Context(), current.GetID(), api) }); err != nil { - return fmt.Errorf("failed to update the API with ID %q: %w", inputs.ID, err) + return fmt.Errorf("failed to update API with ID %q: %w", inputs.ID, err) } cli.renderer.APIUpdate(api) @@ -447,11 +447,11 @@ func deleteAPICmd(cli *cli) *cobra.Command { return ansi.ProgressBar("Deleting API(s)", ids, func(_ int, id string) error { if _, err := cli.api.ResourceServer.Read(cmd.Context(), url.PathEscape(id)); err != nil { - return fmt.Errorf("Unable to delete API (%s): %w", id, err) + return fmt.Errorf("Failed to delete API (%s): %w", id, err) } if err := cli.api.ResourceServer.Delete(cmd.Context(), url.PathEscape(id)); err != nil { - return fmt.Errorf("Unable to delete API (%s): %w", id, err) + return fmt.Errorf("Failed to delete API (%s): %w", id, err) } return nil }) @@ -490,21 +490,24 @@ func openAPICmd(cli *cli) *cobra.Command { // So here if the value is not a URL, we then check if has the length of an ID // If the length check fails, we know it's a non-URL audience value // This will fail for non-URL audience values with the same length as the ID - // But it should cover the vast majority of users + // But it should cover the vast majority of users. if _, err := url.ParseRequestURI(inputs.ID); err == nil || len(inputs.ID) != 24 { if err := ansi.Waiting(func() error { - api, err := cli.api.ResourceServer.Read(cmd.Context(), url.PathEscape(inputs.ID)) + api, err := cli.api.ResourceServer.Read(cmd.Context(), inputs.ID) if err != nil { return err } - inputs.ID = auth0.StringValue(api.ID) + + inputs.ID = api.GetID() + return nil }); err != nil { - return fmt.Errorf("An unexpected error occurred while trying to get the API Id for '%s': %w", inputs.ID, err) + return fmt.Errorf("failed to read API with ID %q: %w", inputs.ID, err) } } openManageURL(cli, cli.Config.DefaultTenant, formatAPISettingsPath(inputs.ID)) + return nil }, } @@ -543,10 +546,11 @@ func listScopesCmd(cli *cli) *cobra.Command { api, err = cli.api.ResourceServer.Read(cmd.Context(), url.PathEscape(inputs.ID)) return err }); err != nil { - return fmt.Errorf("An unexpected error occurred while getting scopes for an API with Id '%s': %w", inputs.ID, err) + return fmt.Errorf("failed to read scopes for API with ID %q: %w", inputs.ID, err) } cli.renderer.ScopesList(api.GetName(), api.GetScopes()) + return nil }, } @@ -583,7 +587,7 @@ func (c *cli) apiPickerOptions(ctx context.Context) (pickerOptions, error) { func (c *cli) filteredAPIPickerOptions(ctx context.Context, include func(r *management.ResourceServer) bool) (pickerOptions, error) { list, err := c.api.ResourceServer.List(ctx) if err != nil { - return nil, err + return nil, fmt.Errorf("failed to list APIs: %w", err) } // NOTE: because client names are not unique, we'll just number these @@ -599,7 +603,7 @@ func (c *cli) filteredAPIPickerOptions(ctx context.Context, include func(r *mana } if len(opts) == 0 { - return nil, errors.New("There are currently no APIs.") + return nil, errors.New("there are currently no APIs to choose from. Create one by running: `auth0 apis create`") } return opts, nil diff --git a/internal/cli/apis_test.go b/internal/cli/apis_test.go index 069972f3a..6fe474000 100644 --- a/internal/cli/apis_test.go +++ b/internal/cli/apis_test.go @@ -54,7 +54,7 @@ func TestAPIsPickerOptions(t *testing.T) { t.Fail() }, assertError: func(t testing.TB, err error) { - assert.ErrorContains(t, err, "There are currently no APIs.") + assert.ErrorContains(t, err, "there are currently no APIs to choose from. Create one by running: `auth0 apis create`") }, }, { diff --git a/internal/cli/apps.go b/internal/cli/apps.go index 3f3887ac6..7f77aab23 100644 --- a/internal/cli/apps.go +++ b/internal/cli/apps.go @@ -178,8 +178,7 @@ func useAppCmd(cli *cli) *cobra.Command { inputs.ID = "" } else { if len(args) == 0 { - err := appID.Pick(cmd, &inputs.ID, cli.appPickerOptions()) - if err != nil { + if err := appID.Pick(cmd, &inputs.ID, cli.appPickerOptions()); err != nil { return err } } else { @@ -244,13 +243,16 @@ func listAppsCmd(cli *cli) *cobra.Command { return output, res.HasNext(), nil }) if err != nil { - return fmt.Errorf("An unexpected error occurred: %w", err) + return fmt.Errorf("failed to list applications: %w", err) } + var typedList []*management.Client for _, item := range list { typedList = append(typedList, item.(*management.Client)) } + cli.renderer.ApplicationList(typedList, inputs.RevealSecrets) + return nil }, } @@ -287,17 +289,20 @@ func showAppCmd(cli *cli) *cobra.Command { inputs.ID = args[0] } - a := &management.Client{ClientID: &inputs.ID} + a := &management.Client{ + ClientID: &inputs.ID, + } if err := ansi.Waiting(func() error { var err error a, err = cli.api.Client.Read(cmd.Context(), inputs.ID) return err }); err != nil { - return fmt.Errorf("Unable to load application: %w", err) + return fmt.Errorf("failed to read application with ID %q: %w", inputs.ID, err) } cli.renderer.ApplicationShow(a, inputs.RevealSecrets) + return nil }, } @@ -326,8 +331,7 @@ func deleteAppCmd(cli *cli) *cobra.Command { RunE: func(cmd *cobra.Command, args []string) error { ids := make([]string, len(args)) if len(args) == 0 { - err := appID.PickMany(cmd, &ids, cli.appPickerOptions()) - if err != nil { + if err := appID.PickMany(cmd, &ids, cli.appPickerOptions()); err != nil { return err } } else { @@ -346,11 +350,11 @@ func deleteAppCmd(cli *cli) *cobra.Command { return ansi.ProgressBar("Deleting Application(s)", ids, func(_ int, id string) error { if id != "" { if _, err := cli.api.Client.Read(cmd.Context(), id); err != nil { - return fmt.Errorf("Unable to delete application (%s): %w", id, err) + return fmt.Errorf("Failed to delete application (%s): %w", id, err) } if err := cli.api.Client.Delete(cmd.Context(), id); err != nil { - return fmt.Errorf("Unable to delete application (%s): %w", id, err) + return fmt.Errorf("Failed to delete application (%s): %w", id, err) } } return nil @@ -397,17 +401,14 @@ func createAppCmd(cli *cli) *cobra.Command { auth0 apps create -n myapp -d -t [native|spa|regular|m2m] -r --json --metadata "foo=bar" --metadata "bazz=buzz" auth0 apps create -n myapp -d -t [native|spa|regular|m2m] -r --json --metadata "foo=bar,bazz=buzz"`, RunE: func(cmd *cobra.Command, args []string) error { - // Prompt for app name if err := appName.Ask(cmd, &inputs.Name, nil); err != nil { return err } - // Prompt for app description if err := appDescription.Ask(cmd, &inputs.Description, nil); err != nil { return err } - // Prompt for app type if err := appType.Select(cmd, &inputs.Type, appTypeOptions, nil); err != nil { return err } @@ -416,7 +417,7 @@ func createAppCmd(cli *cli) *cobra.Command { appIsNative := apiTypeFor(inputs.Type) == appTypeNative appIsSPA := apiTypeFor(inputs.Type) == appTypeSPA - // Prompt for callback URLs if app is not m2m + // Prompt for callback URLs if app is not m2m. if !appIsM2M { var defaultValue string @@ -429,7 +430,7 @@ func createAppCmd(cli *cli) *cobra.Command { } } - // Prompt for logout URLs if app is not m2m + // Prompt for logout URLs if app is not m2m. if !appIsM2M { var defaultValue string @@ -442,7 +443,7 @@ func createAppCmd(cli *cli) *cobra.Command { } } - // Prompt for allowed origins URLs if app is SPA + // Prompt for allowed origins URLs if app is SPA. if appIsSPA { defaultValue := appDefaultURL @@ -451,7 +452,7 @@ func createAppCmd(cli *cli) *cobra.Command { } } - // Prompt for allowed web origins URLs if app is SPA + // Prompt for allowed web origins URLs if app is SPA. if appIsSPA { defaultValue := appDefaultURL @@ -465,7 +466,7 @@ func createAppCmd(cli *cli) *cobra.Command { clientMetadata[k] = v } - // Load values into a fresh app instance + // Load values into a fresh app instance. a := &management.Client{ Name: &inputs.Name, Description: &inputs.Description, @@ -479,32 +480,31 @@ func createAppCmd(cli *cli) *cobra.Command { ClientMetadata: &clientMetadata, } - // Set token endpoint auth method + // Set token endpoint auth method. if len(inputs.AuthMethod) == 0 { a.TokenEndpointAuthMethod = apiDefaultAuthMethodFor(inputs.Type) } else { a.TokenEndpointAuthMethod = apiAuthMethodFor(inputs.AuthMethod) } - // Set grants + // Set grants. if len(inputs.Grants) == 0 { a.GrantTypes = apiDefaultGrantsFor(inputs.Type) } else { a.GrantTypes = apiGrantsFor(inputs.Grants) } - // Create app + // Create app. if err := ansi.Waiting(func() error { return cli.api.Client.Create(cmd.Context(), a) }); err != nil { - return fmt.Errorf("Unable to create application: %v", err) + return fmt.Errorf("failed to create application: %w", err) } if err := cli.Config.SetDefaultAppIDForTenant(cli.tenant, a.GetClientID()); err != nil { return err } - // Render result cli.renderer.ApplicationCreate(a, inputs.RevealSecrets) return nil @@ -572,21 +572,17 @@ func updateAppCmd(cli *cli) *cobra.Command { inputs.ID = args[0] } - // Load app by id - if err := ansi.Waiting(func() error { - var err error + if err := ansi.Waiting(func() (err error) { current, err = cli.api.Client.Read(cmd.Context(), inputs.ID) return err }); err != nil { - return fmt.Errorf("Unable to load application: %w", err) + return fmt.Errorf("failed to find application with ID %q: %w", inputs.ID, err) } - // Prompt for app name if err := appName.AskU(cmd, &inputs.Name, current.Name); err != nil { return err } - // Prompt for app type if err := appType.SelectU(cmd, &inputs.Type, appTypeOptions, typeFor(current.AppType)); err != nil { return err } @@ -595,7 +591,7 @@ func updateAppCmd(cli *cli) *cobra.Command { appIsNative := apiTypeFor(inputs.Type) == appTypeNative appIsSPA := apiTypeFor(inputs.Type) == appTypeSPA - // Prompt for callback URLs if app is not m2m + // Prompt for callback URLs if app is not m2m. if !appIsM2M { var defaultValue string @@ -612,7 +608,7 @@ func updateAppCmd(cli *cli) *cobra.Command { } } - // Prompt for logout URLs if app is not m2m + // Prompt for logout URLs if app is not m2m. if !appIsM2M { var defaultValue string @@ -629,7 +625,7 @@ func updateAppCmd(cli *cli) *cobra.Command { } } - // Prompt for allowed origins URLs if app is SPA + // Prompt for allowed origins URLs if app is SPA. if appIsSPA { defaultValue := appDefaultURL @@ -642,7 +638,7 @@ func updateAppCmd(cli *cli) *cobra.Command { } } - // Prompt for allowed web origins URLs if app is SPA + // Prompt for allowed web origins URLs if app is SPA. if appIsSPA { defaultValue := appDefaultURL @@ -655,7 +651,7 @@ func updateAppCmd(cli *cli) *cobra.Command { } } - // Load updated values into a fresh app instance + // Load updated values into a fresh app instance. a := &management.Client{} if len(inputs.Name) == 0 { @@ -722,14 +718,12 @@ func updateAppCmd(cli *cli) *cobra.Command { a.ClientMetadata = &clientMetadata } - // Update app if err := ansi.Waiting(func() error { return cli.api.Client.Update(cmd.Context(), inputs.ID, a) }); err != nil { - return fmt.Errorf("Unable to update application %v: %v", inputs.ID, err) + return fmt.Errorf("failed to update application with ID %q: %w", inputs.ID, err) } - // Render result cli.renderer.ApplicationUpdate(a, inputs.RevealSecrets) return nil @@ -766,8 +760,7 @@ func openAppCmd(cli *cli) *cobra.Command { auth0 apps open `, RunE: func(cmd *cobra.Command, args []string) error { if len(args) == 0 { - err := appID.Pick(cmd, &inputs.ID, cli.appPickerOptions()) - if err != nil { + if err := appID.Pick(cmd, &inputs.ID, cli.appPickerOptions()); err != nil { return err } } else { @@ -775,6 +768,7 @@ func openAppCmd(cli *cli) *cobra.Command { } openManageURL(cli, cli.Config.DefaultTenant, formatAppSettingsPath(inputs.ID)) + return nil }, } @@ -913,7 +907,7 @@ func (c *cli) appPickerOptions(requestOpts ...management.RequestOption) pickerOp return func(ctx context.Context) (pickerOptions, error) { clientList, err := c.api.Client.List(ctx, requestOpts...) if err != nil { - return nil, err + return nil, fmt.Errorf("failed to list applications: %w", err) } tenant, err := c.Config.GetTenant(c.tenant) diff --git a/internal/cli/custom_domains.go b/internal/cli/custom_domains.go index c04c4ea19..ad7cda0f4 100644 --- a/internal/cli/custom_domains.go +++ b/internal/cli/custom_domains.go @@ -106,15 +106,15 @@ func listCustomDomainsCmd(cli *cli) *cobra.Command { RunE: func(cmd *cobra.Command, args []string) error { var list []*management.CustomDomain - if err := ansi.Waiting(func() error { - var err error + if err := ansi.Waiting(func() (err error) { list, err = cli.api.CustomDomain.List(cmd.Context(), management.PerPage(defaultPageSize)) return err }); err != nil { - return fmt.Errorf("An unexpected error occurred: %w", err) + return fmt.Errorf("failed to list custom domains: %w", err) } cli.renderer.CustomDomainList(list) + return nil }, } @@ -139,8 +139,7 @@ func showCustomDomainCmd(cli *cli) *cobra.Command { auth0 domains show --json`, RunE: func(cmd *cobra.Command, args []string) error { if len(args) == 0 { - err := customDomainID.Pick(cmd, &inputs.ID, cli.customDomainsPickerOptions) - if err != nil { + if err := customDomainID.Pick(cmd, &inputs.ID, cli.customDomainsPickerOptions); err != nil { return err } } else { @@ -149,15 +148,15 @@ func showCustomDomainCmd(cli *cli) *cobra.Command { var customDomain *management.CustomDomain - if err := ansi.Waiting(func() error { - var err error + if err := ansi.Waiting(func() (err error) { customDomain, err = cli.api.CustomDomain.Read(cmd.Context(), url.PathEscape(inputs.ID)) return err }); err != nil { - return fmt.Errorf("Unable to get a custom domain with Id '%s': %w", inputs.ID, err) + return fmt.Errorf("failed to read custom domain with ID %q: %w", inputs.ID, err) } cli.renderer.CustomDomainShow(customDomain) + return nil }, } @@ -220,10 +219,11 @@ func createCustomDomainCmd(cli *cli) *cobra.Command { if err := ansi.Waiting(func() error { return cli.api.CustomDomain.Create(cmd.Context(), customDomain) }); err != nil { - return fmt.Errorf("An unexpected error occurred while attempting to create the custom domain '%s': %w", inputs.Domain, err) + return fmt.Errorf("failed to create custom domain %q: %w", inputs.Domain, err) } cli.renderer.CustomDomainCreate(customDomain) + return nil }, } @@ -261,29 +261,24 @@ func updateCustomDomainCmd(cli *cli) *cobra.Command { var current *management.CustomDomain if len(args) == 0 { - err := customDomainID.Pick(cmd, &inputs.ID, cli.customDomainsPickerOptions) - if err != nil { + if err := customDomainID.Pick(cmd, &inputs.ID, cli.customDomainsPickerOptions); err != nil { return err } } else { inputs.ID = args[0] } - // Load custom domain by id - if err := ansi.Waiting(func() error { - var err error + if err := ansi.Waiting(func() (err error) { current, err = cli.api.CustomDomain.Read(cmd.Context(), inputs.ID) return err }); err != nil { - return fmt.Errorf("Unable to load custom domain: %w", err) + return fmt.Errorf("failed to read custom domain: %w", err) } - // Prompt for TLS policy if err := customDomainPolicy.SelectU(cmd, &inputs.TLSPolicy, customDomainPolicyOptions, current.TLSPolicy); err != nil { return err } - // Prompt for custom domain custom client IP header if err := customDomainIPHeader.AskU(cmd, &inputs.CustomClientIPHeader, current.CustomClientIPHeader); err != nil { return err } @@ -301,15 +296,14 @@ func updateCustomDomainCmd(cli *cli) *cobra.Command { c.CustomClientIPHeader = &inputs.CustomClientIPHeader } - // Update custom domain if err := ansi.Waiting(func() error { return cli.api.CustomDomain.Update(cmd.Context(), inputs.ID, c) }); err != nil { - return fmt.Errorf("Unable to update custom domain: %v", err) + return fmt.Errorf("failed to update custom domain: %w", err) } - // Render custom domain update specific view cli.renderer.CustomDomainUpdate(c) + return nil }, } @@ -340,8 +334,7 @@ func deleteCustomDomainCmd(cli *cli) *cobra.Command { RunE: func(cmd *cobra.Command, args []string) error { ids := make([]string, len(args)) if len(args) == 0 { - err := customDomainID.PickMany(cmd, &ids, cli.customDomainsPickerOptions) - if err != nil { + if err := customDomainID.PickMany(cmd, &ids, cli.customDomainsPickerOptions); err != nil { return err } } else { @@ -357,11 +350,11 @@ func deleteCustomDomainCmd(cli *cli) *cobra.Command { return ansi.ProgressBar("Deleting custom domain", ids, func(_ int, id string) error { if id != "" { if _, err := cli.api.CustomDomain.Read(cmd.Context(), url.PathEscape(id)); err != nil { - return fmt.Errorf("Unable to delete custom domain (%s): %w", id, err) + return fmt.Errorf("Failed to delete custom domain (%s): %w", id, err) } if err := cli.api.CustomDomain.Delete(cmd.Context(), url.PathEscape(id)); err != nil { - return fmt.Errorf("Unable to delete custom domain (%s): %w", id, err) + return fmt.Errorf("Failed to delete custom domain (%s): %w", id, err) } } return nil @@ -390,8 +383,7 @@ func verifyCustomDomainCmd(cli *cli) *cobra.Command { auth0 domains verify `, RunE: func(cmd *cobra.Command, args []string) error { if len(args) == 0 { - err := customDomainID.Pick(cmd, &inputs.ID, cli.customDomainsPickerOptions) - if err != nil { + if err := customDomainID.Pick(cmd, &inputs.ID, cli.customDomainsPickerOptions); err != nil { return err } } else { @@ -400,15 +392,15 @@ func verifyCustomDomainCmd(cli *cli) *cobra.Command { var customDomain *management.CustomDomain - if err := ansi.Waiting(func() error { - var err error + if err := ansi.Waiting(func() (err error) { customDomain, err = cli.api.CustomDomain.Verify(cmd.Context(), url.PathEscape(inputs.ID)) return err }); err != nil { - return fmt.Errorf("Unable to verify a custom domain with Id '%s': %w", inputs.ID, err) + return fmt.Errorf("failed to verify custom domain with ID %q: %w", inputs.ID, err) } cli.renderer.CustomDomainShow(customDomain) + return nil }, } @@ -456,12 +448,12 @@ func (c *cli) customDomainsPickerOptions(ctx context.Context) (pickerOptions, er if err != nil { errStatus := err.(management.Error) // 403 is a valid response for free tenants that don't have - // custom domains enabled + // custom domains enabled. if errStatus != nil && errStatus.Status() == 403 { return nil, errNoCustomDomains } - return nil, err + return nil, fmt.Errorf("failed to list custom domains: %w", err) } for _, d := range domains { diff --git a/internal/cli/data/universal-login/assets/index-89540052.js b/internal/cli/data/universal-login/assets/index-89540052.js index f54ecc8ea..c512fa07a 100644 --- a/internal/cli/data/universal-login/assets/index-89540052.js +++ b/internal/cli/data/universal-login/assets/index-89540052.js @@ -9363,7 +9363,7 @@ function encode_char(c) { return _ENCODE_HTML_RULES[c] || c; }; `;e.escapeXML=function(g){return g==null?"":String(g).replace(i,r)};function p(){return Function.prototype.toString.call(this)+`; -`+c}try{typeof Object.defineProperty=="function"?Object.defineProperty(e.escapeXML,"toString",{value:p}):e.escapeXML.toString=p}catch{console.warn("Unable to set escapeXML.toString (is the Function prototype frozen?)")}e.shallowCopy=function(g,h){if(h=h||{},g!=null)for(var b in h)a(h,b)&&(b==="__proto__"||b==="constructor"||(g[b]=h[b]));return g},e.shallowCopyFromList=function(g,h,b){if(b=b||[],h=h||{},g!=null)for(var y=0;y (http://fleegix.org)",Cct="Apache-2.0",Bct={ejs:"./bin/cli.js"},Mct="./lib/ejs.js",Lct="ejs.min.js",Ict="ejs.min.js",Rct={type:"git",url:"git://github.com/mde/ejs.git"},Fct="https://github.com/mde/ejs/issues",Dct="https://github.com/mde/ejs",Vct={jake:"^10.8.5"},Uct={browserify:"^16.5.1",eslint:"^6.8.0","git-directory-deploy":"^1.5.1",jsdoc:"^4.0.2","lru-cache":"^4.0.1",mocha:"^10.2.0","uglify-js":"^3.3.16"},Kct={node:">=0.10.0"},Gct={test:"mocha -u tdd"},qct={name:zct,description:Pct,keywords:Sct,version:Ect,author:Oct,license:Cct,bin:Bct,main:Mct,jsdelivr:Lct,unpkg:Ict,repository:Rct,bugs:Fct,homepage:Dct,dependencies:Vct,devDependencies:Uct,engines:Kct,scripts:Gct};(function(e){/** +`+c}try{typeof Object.defineProperty=="function"?Object.defineProperty(e.escapeXML,"toString",{value:p}):e.escapeXML.toString=p}catch{console.warn("Failed to set escapeXML.toString (is the Function prototype frozen?)")}e.shallowCopy=function(g,h){if(h=h||{},g!=null)for(var b in h)a(h,b)&&(b==="__proto__"||b==="constructor"||(g[b]=h[b]));return g},e.shallowCopyFromList=function(g,h,b){if(b=b||[],h=h||{},g!=null)for(var y=0;y (http://fleegix.org)",Cct="Apache-2.0",Bct={ejs:"./bin/cli.js"},Mct="./lib/ejs.js",Lct="ejs.min.js",Ict="ejs.min.js",Rct={type:"git",url:"git://github.com/mde/ejs.git"},Fct="https://github.com/mde/ejs/issues",Dct="https://github.com/mde/ejs",Vct={jake:"^10.8.5"},Uct={browserify:"^16.5.1",eslint:"^6.8.0","git-directory-deploy":"^1.5.1",jsdoc:"^4.0.2","lru-cache":"^4.0.1",mocha:"^10.2.0","uglify-js":"^3.3.16"},Kct={node:">=0.10.0"},Gct={test:"mocha -u tdd"},qct={name:zct,description:Pct,keywords:Sct,version:Ect,author:Oct,license:Cct,bin:Bct,main:Mct,jsdelivr:Lct,unpkg:Ict,repository:Rct,bugs:Fct,homepage:Dct,dependencies:Vct,devDependencies:Uct,engines:Kct,scripts:Gct};(function(e){/** * @file Embedded JavaScript templating engine. {@link http://ejs.co} * @author Matthew Eernisse * @author Tiancheng "Timothy" Gu diff --git a/internal/cli/doc-gen.go b/internal/cli/doc-gen.go index 7ff1d094e..7a4568048 100644 --- a/internal/cli/doc-gen.go +++ b/internal/cli/doc-gen.go @@ -180,7 +180,9 @@ func GenMarkdownTree(cmd *cobra.Command, dir string) error { if err != nil { return err } - defer f.Close() + defer func() { + _ = f.Close() + }() isHomepage := cmd.CommandPath() == "auth0" if isHomepage { diff --git a/internal/cli/email_templates.go b/internal/cli/email_templates.go index a255f214e..22988dee0 100644 --- a/internal/cli/email_templates.go +++ b/internal/cli/email_templates.go @@ -127,8 +127,7 @@ func showEmailTemplateCmd(cli *cli) *cobra.Command { auth0 email templates show welcome`, RunE: func(cmd *cobra.Command, args []string) error { if len(args) == 0 { - err := emailTemplateTemplate.Pick(cmd, &inputs.Template, cli.emailTemplatePickerOptions) - if err != nil { + if err := emailTemplateTemplate.Pick(cmd, &inputs.Template, cli.emailTemplatePickerOptions); err != nil { return err } } else { @@ -140,10 +139,11 @@ func showEmailTemplateCmd(cli *cli) *cobra.Command { email, err = cli.api.EmailTemplate.Read(cmd.Context(), apiEmailTemplateFor(inputs.Template)) return err }); err != nil { - return fmt.Errorf("failed to get the email template '%s': %w", inputs.Template, err) + return fmt.Errorf("failed to read email template %q: %w", inputs.Template, err) } cli.renderer.EmailTemplateShow(email) + return nil }, } @@ -186,8 +186,7 @@ func updateEmailTemplateCmd(cli *cli) *cobra.Command { if len(args) > 0 { inputs.Template = args[0] } else { - err := emailTemplateTemplate.Pick(cmd, &inputs.Template, cli.emailTemplatePickerOptions) - if err != nil { + if err := emailTemplateTemplate.Pick(cmd, &inputs.Template, cli.emailTemplatePickerOptions); err != nil { return err } } @@ -201,7 +200,7 @@ func updateEmailTemplateCmd(cli *cli) *cobra.Command { if err != nil { mErr, ok := err.(management.Error) if !ok || mErr.Status() != http.StatusNotFound { - return fmt.Errorf("failed to get the email template '%s': %w", inputs.Template, err) + return fmt.Errorf("failed to read email template %q: %w", inputs.Template, err) } templateExists = false @@ -272,7 +271,7 @@ func updateEmailTemplateCmd(cli *cli) *cobra.Command { return cli.api.EmailTemplate.Create(cmd.Context(), emailTemplate) }); err != nil { - return fmt.Errorf("failed to update the email template '%s': %w", inputs.Template, err) + return fmt.Errorf("failed to update email template %q: %w", inputs.Template, err) } cli.renderer.EmailTemplateUpdate(emailTemplate) diff --git a/internal/cli/flags.go b/internal/cli/flags.go index 029acfcbd..acea7d85f 100644 --- a/internal/cli/flags.go +++ b/internal/cli/flags.go @@ -229,7 +229,7 @@ func askPasswordFlag(cmd *cobra.Command, f *Flag, value *string, isUpdate bool) } func openEditorFlag(cmd *cobra.Command, f *Flag, value *string, defaultValue string, filename string, infoFn func(), tempFileFn func(string), isUpdate bool) error { - if shouldAsk(cmd, f, false) { // Always open the editor on update + if shouldAsk(cmd, f, false) { // Always open the editor on update. if isUpdate { return openUpdateEditor(f, value, defaultValue, filename) } diff --git a/internal/cli/input.go b/internal/cli/input.go index f861dcbdb..e805ed6c8 100644 --- a/internal/cli/input.go +++ b/internal/cli/input.go @@ -62,11 +62,11 @@ func askPassword(i commandInput, value interface{}, isUpdate bool) error { func askMultiSelect(i commandInput, value interface{}, options ...string) error { v := reflect.ValueOf(value) if v.Kind() != reflect.Slice || v.Len() <= 0 { - handleInputError(fmt.Errorf("there is not enough data to select from")) + return handleInputError(fmt.Errorf("there is not enough data to select from")) } if err := prompt.AskMultiSelect(i.GetLabel(), value, options...); err != nil { - handleInputError(err) + return handleInputError(err) } return nil diff --git a/internal/cli/log_streams.go b/internal/cli/log_streams.go index 26300e34d..248647a72 100644 --- a/internal/cli/log_streams.go +++ b/internal/cli/log_streams.go @@ -75,7 +75,7 @@ func listLogStreamsCmd(cli *cli) *cobra.Command { list, err = cli.api.LogStream.List(cmd.Context(), management.PerPage(defaultPageSize)) return err }); err != nil { - return fmt.Errorf("An unexpected error occurred: %w", err) + return fmt.Errorf("failed to list log streams: %w", err) } cli.renderer.LogStreamList(list) @@ -119,7 +119,7 @@ func showLogStreamCmd(cli *cli) *cobra.Command { a, err = cli.api.LogStream.Read(cmd.Context(), inputs.ID) return err }); err != nil { - return fmt.Errorf("Unable to load log stream: %w", err) + return fmt.Errorf("failed to read log stream: %w", err) } cli.renderer.LogStreamShow(a) return nil @@ -202,10 +202,10 @@ func deleteLogStreamCmd(cli *cli) *cobra.Command { return ansi.ProgressBar("Deleting Log Stream(s)", ids, func(_ int, id string) error { if id != "" { if _, err := cli.api.LogStream.Read(cmd.Context(), id); err != nil { - return fmt.Errorf("Unable to delete log stream (%s): %w", id, err) + return fmt.Errorf("Failed to delete log stream (%s): %w", id, err) } if err := cli.api.LogStream.Delete(cmd.Context(), id); err != nil { - return fmt.Errorf("Unable to delete log stream (%s): %w", id, err) + return fmt.Errorf("Failed to delete log stream (%s): %w", id, err) } } return nil @@ -258,7 +258,7 @@ func formatLogStreamSettingsPath(id string) string { func (c *cli) allLogStreamsPickerOptions(ctx context.Context) (pickerOptions, error) { logStreams, err := c.api.LogStream.List(ctx) if err != nil { - return nil, err + return nil, fmt.Errorf("failed to list log streams: %w", err) } var options pickerOptions @@ -267,8 +267,9 @@ func (c *cli) allLogStreamsPickerOptions(ctx context.Context) (pickerOptions, er label := fmt.Sprintf("%s %s", logStream.GetName(), ansi.Faint("("+value+")")) options = append(options, pickerOption{value: value, label: label}) } + if len(options) == 0 { - return nil, errors.New("There are currently no log streams.") + return nil, errors.New("there are currently no log streams to choose from. Create one by running: `auth0 logs streams create`") } return options, nil @@ -278,7 +279,7 @@ func (c *cli) logStreamPickerOptionsByType(desiredType logStreamType) pickerOpti return func(ctx context.Context) (pickerOptions, error) { logStreams, err := c.api.LogStream.List(ctx) if err != nil { - return nil, err + return nil, fmt.Errorf("failed to list log streams: %w", err) } var options pickerOptions @@ -291,7 +292,7 @@ func (c *cli) logStreamPickerOptionsByType(desiredType logStreamType) pickerOpti } if len(options) == 0 { return nil, fmt.Errorf( - "There are currently no log streams of type: %q, use 'auth0 logs streams create %s' to create one.", + "there are currently no log streams of type: %q, use `auth0 logs streams create %s` to create one", desiredType, desiredType, ) diff --git a/internal/cli/log_streams_datadog.go b/internal/cli/log_streams_datadog.go index 1115f05e6..fae7019e0 100644 --- a/internal/cli/log_streams_datadog.go +++ b/internal/cli/log_streams_datadog.go @@ -76,7 +76,7 @@ func createLogStreamsDatadogCmd(cli *cli) *cobra.Command { if err := ansi.Waiting(func() error { return cli.api.LogStream.Create(cmd.Context(), newLogStream) }); err != nil { - return fmt.Errorf("failed to create log stream: %v", err) + return fmt.Errorf("failed to create log stream: %w", err) } cli.renderer.LogStreamCreate(newLogStream) @@ -129,7 +129,7 @@ func updateLogStreamsDatadogCmd(cli *cli) *cobra.Command { oldLogStream, err = cli.api.LogStream.Read(cmd.Context(), inputs.ID) return err }); err != nil { - return fmt.Errorf("failed to read log stream with ID %s: %w", inputs.ID, err) + return fmt.Errorf("failed to read log stream with ID %q: %w", inputs.ID, err) } if oldLogStream.GetType() != string(logStreamTypeDatadog) { @@ -167,7 +167,7 @@ func updateLogStreamsDatadogCmd(cli *cli) *cobra.Command { if err := ansi.Waiting(func() error { return cli.api.LogStream.Update(cmd.Context(), oldLogStream.GetID(), updatedLogStream) }); err != nil { - return fmt.Errorf("failed to update log stream with ID %s: %w", oldLogStream.GetID(), err) + return fmt.Errorf("failed to update log stream with ID %q: %w", oldLogStream.GetID(), err) } cli.renderer.LogStreamUpdate(updatedLogStream) diff --git a/internal/cli/log_streams_event_bridge.go b/internal/cli/log_streams_event_bridge.go index ed13b7b37..46251e870 100644 --- a/internal/cli/log_streams_event_bridge.go +++ b/internal/cli/log_streams_event_bridge.go @@ -121,7 +121,7 @@ func updateLogStreamsAmazonEventBridgeCmd(cli *cli) *cobra.Command { oldLogStream, err = cli.api.LogStream.Read(cmd.Context(), inputs.ID) return err }); err != nil { - return fmt.Errorf("failed to read log stream with ID %s: %w", inputs.ID, err) + return fmt.Errorf("failed to read log stream with ID %q: %w", inputs.ID, err) } if oldLogStream.GetType() != string(logStreamTypeAmazonEventBridge) { @@ -141,7 +141,7 @@ func updateLogStreamsAmazonEventBridgeCmd(cli *cli) *cobra.Command { if err := ansi.Waiting(func() error { return cli.api.LogStream.Update(cmd.Context(), oldLogStream.GetID(), updatedLogStream) }); err != nil { - return fmt.Errorf("failed to update log stream with ID %s: %w", oldLogStream.GetID(), err) + return fmt.Errorf("failed to update log stream with ID %q: %w", oldLogStream.GetID(), err) } cli.renderer.LogStreamUpdate(updatedLogStream) diff --git a/internal/cli/log_streams_event_grid.go b/internal/cli/log_streams_event_grid.go index 9f7f06a25..05e9276ae 100644 --- a/internal/cli/log_streams_event_grid.go +++ b/internal/cli/log_streams_event_grid.go @@ -136,7 +136,7 @@ func updateLogStreamsAzureEventGridCmd(cli *cli) *cobra.Command { oldLogStream, err = cli.api.LogStream.Read(cmd.Context(), inputs.ID) return err }); err != nil { - return fmt.Errorf("failed to read log stream with ID %s: %w", inputs.ID, err) + return fmt.Errorf("failed to read log stream with ID %q: %w", inputs.ID, err) } if oldLogStream.GetType() != string(logStreamTypeAzureEventGrid) { @@ -155,7 +155,7 @@ func updateLogStreamsAzureEventGridCmd(cli *cli) *cobra.Command { if err := ansi.Waiting(func() error { return cli.api.LogStream.Update(cmd.Context(), oldLogStream.GetID(), updatedLogStream) }); err != nil { - return fmt.Errorf("failed to update log stream with ID %s: %w", oldLogStream.GetID(), err) + return fmt.Errorf("failed to update log stream with ID %q: %w", oldLogStream.GetID(), err) } cli.renderer.LogStreamUpdate(updatedLogStream) diff --git a/internal/cli/log_streams_http.go b/internal/cli/log_streams_http.go index 45cf5ac10..c67f20335 100644 --- a/internal/cli/log_streams_http.go +++ b/internal/cli/log_streams_http.go @@ -111,7 +111,7 @@ func createLogStreamsCustomWebhookCmd(cli *cli) *cobra.Command { if err := ansi.Waiting(func() error { return cli.api.LogStream.Create(cmd.Context(), newLogStream) }); err != nil { - return fmt.Errorf("failed to create log stream: %v", err) + return fmt.Errorf("failed to create log stream: %w", err) } cli.renderer.LogStreamCreate(newLogStream) @@ -170,7 +170,7 @@ func updateLogStreamsCustomWebhookCmd(cli *cli) *cobra.Command { oldLogStream, err = cli.api.LogStream.Read(cmd.Context(), inputs.ID) return err }); err != nil { - return fmt.Errorf("failed to read log stream with ID %s: %w", inputs.ID, err) + return fmt.Errorf("failed to read log stream with ID %q: %w", inputs.ID, err) } if oldLogStream.GetType() != string(logStreamTypeHTTP) { @@ -219,7 +219,7 @@ func updateLogStreamsCustomWebhookCmd(cli *cli) *cobra.Command { if err := ansi.Waiting(func() error { return cli.api.LogStream.Update(cmd.Context(), oldLogStream.GetID(), updatedLogStream) }); err != nil { - return fmt.Errorf("failed to update log stream with ID %s: %w", oldLogStream.GetID(), err) + return fmt.Errorf("failed to update log stream with ID %q: %w", oldLogStream.GetID(), err) } cli.renderer.LogStreamUpdate(updatedLogStream) diff --git a/internal/cli/log_streams_splunk.go b/internal/cli/log_streams_splunk.go index 5766eb216..091e91c38 100644 --- a/internal/cli/log_streams_splunk.go +++ b/internal/cli/log_streams_splunk.go @@ -101,7 +101,7 @@ func createLogStreamsSplunkCmd(cli *cli) *cobra.Command { if err := ansi.Waiting(func() error { return cli.api.LogStream.Create(cmd.Context(), newLogStream) }); err != nil { - return fmt.Errorf("failed to create log stream: %v", err) + return fmt.Errorf("failed to create log stream: %w", err) } cli.renderer.LogStreamCreate(newLogStream) @@ -160,7 +160,7 @@ func updateLogStreamsSplunkCmd(cli *cli) *cobra.Command { oldLogStream, err = cli.api.LogStream.Read(cmd.Context(), inputs.ID) return err }); err != nil { - return fmt.Errorf("failed to read log stream with ID %s: %w", inputs.ID, err) + return fmt.Errorf("failed to read log stream with ID %q: %w", inputs.ID, err) } if oldLogStream.GetType() != string(logStreamTypeSplunk) { @@ -205,7 +205,7 @@ func updateLogStreamsSplunkCmd(cli *cli) *cobra.Command { if err := ansi.Waiting(func() error { return cli.api.LogStream.Update(cmd.Context(), oldLogStream.GetID(), updatedLogStream) }); err != nil { - return fmt.Errorf("failed to update log stream with ID %s: %w", oldLogStream.GetID(), err) + return fmt.Errorf("failed to update log stream with ID %q: %w", oldLogStream.GetID(), err) } cli.renderer.LogStreamUpdate(updatedLogStream) diff --git a/internal/cli/log_streams_sumo.go b/internal/cli/log_streams_sumo.go index 711be2ed7..f4971c209 100644 --- a/internal/cli/log_streams_sumo.go +++ b/internal/cli/log_streams_sumo.go @@ -58,7 +58,7 @@ func createLogStreamsSumoLogicCmd(cli *cli) *cobra.Command { if err := ansi.Waiting(func() error { return cli.api.LogStream.Create(cmd.Context(), newLogStream) }); err != nil { - return fmt.Errorf("failed to create log stream: %v", err) + return fmt.Errorf("failed to create log stream: %w", err) } cli.renderer.LogStreamCreate(newLogStream) @@ -108,7 +108,7 @@ func updateLogStreamsSumoLogicCmd(cli *cli) *cobra.Command { oldLogStream, err = cli.api.LogStream.Read(cmd.Context(), inputs.ID) return err }); err != nil { - return fmt.Errorf("failed to read log stream with ID %s: %w", inputs.ID, err) + return fmt.Errorf("failed to read log stream with ID %q: %w", inputs.ID, err) } if oldLogStream.GetType() != string(logStreamTypeSumo) { @@ -136,7 +136,7 @@ func updateLogStreamsSumoLogicCmd(cli *cli) *cobra.Command { if err := ansi.Waiting(func() error { return cli.api.LogStream.Update(cmd.Context(), oldLogStream.GetID(), updatedLogStream) }); err != nil { - return fmt.Errorf("failed to update log stream with ID %s: %w", oldLogStream.GetID(), err) + return fmt.Errorf("failed to update log stream with ID %q: %w", oldLogStream.GetID(), err) } cli.renderer.LogStreamUpdate(updatedLogStream) diff --git a/internal/cli/log_streams_test.go b/internal/cli/log_streams_test.go index 47745c893..5791d4325 100644 --- a/internal/cli/log_streams_test.go +++ b/internal/cli/log_streams_test.go @@ -52,7 +52,7 @@ func TestLogStreamsPickerOptions(t *testing.T) { t.Fail() }, assertError: func(t testing.TB, err error) { - assert.ErrorContains(t, err, "There are currently no log streams.") + assert.ErrorContains(t, err, "there are currently no log streams to choose from. Create one by running: `auth0 logs streams create`") }, }, { @@ -146,7 +146,7 @@ func TestLogStreamsPickerOptionsByType(t *testing.T) { t.Fail() }, assertError: func(t testing.TB, err error) { - assert.ErrorContains(t, err, "There are currently no log streams of type: \"foo\", use 'auth0 logs streams create foo' to create one.") + assert.ErrorContains(t, err, "there are currently no log streams of type: \"foo\", use `auth0 logs streams create foo` to create one") }, }, { diff --git a/internal/cli/login.go b/internal/cli/login.go index ea81330e4..527371e69 100644 --- a/internal/cli/login.go +++ b/internal/cli/login.go @@ -218,7 +218,7 @@ func RunLoginAsUser(ctx context.Context, cli *cli, additionalScopes []string) (c err = cli.Config.AddTenant(tenant) if err != nil { - return config.Tenant{}, fmt.Errorf("Failed to add the tenant to the config: %w", err) + return config.Tenant{}, fmt.Errorf("failed to add the tenant to the config: %w", err) } cli.tracker.TrackFirstLogin(cli.Config.InstallID) @@ -265,7 +265,7 @@ func RunLoginAsMachine(ctx context.Context, inputs LoginInputs, cli *cli, cmd *c }, ) if err != nil { - return fmt.Errorf("failed to fetch access token using client credentials. \n\nEnsure that the provided client-id, client-secret and domain are correct. \n\nerror: %w\n", err) + return fmt.Errorf("failed to fetch access token using client credentials. \n\nEnsure that the provided client-id, client-secret and domain are correct. \n\nerror: %w", err) } tenant := config.Tenant{ @@ -287,7 +287,7 @@ func RunLoginAsMachine(ctx context.Context, inputs LoginInputs, cli *cli, cmd *c } if err = cli.Config.AddTenant(tenant); err != nil { - return fmt.Errorf("unexpected error when attempting to save tenant data: %w", err) + return fmt.Errorf("failed to save tenant data: %w", err) } cli.renderer.Newline() diff --git a/internal/cli/logout.go b/internal/cli/logout.go index 013e2cd6a..0e9b82657 100644 --- a/internal/cli/logout.go +++ b/internal/cli/logout.go @@ -24,7 +24,7 @@ func logoutCmd(cli *cli) *cobra.Command { } if err := cli.Config.RemoveTenant(selectedTenant); err != nil { - return fmt.Errorf("failed to log out from the tenant %s: %w", selectedTenant, err) + return fmt.Errorf("failed to log out from the tenant %q: %w", selectedTenant, err) } if err := keyring.DeleteSecretsForTenant(selectedTenant); err != nil { diff --git a/internal/cli/logs.go b/internal/cli/logs.go index 89f778f1a..8be847ff6 100644 --- a/internal/cli/logs.go +++ b/internal/cli/logs.go @@ -72,7 +72,7 @@ func listLogsCmd(cli *cli) *cobra.Command { } list, err := getLatestLogs(cmd.Context(), cli, inputs.Num, inputs.Filter) if err != nil { - return fmt.Errorf("failed to get logs: %w", err) + return fmt.Errorf("failed to list logs: %w", err) } hasFilter := inputs.Filter != "" @@ -114,7 +114,7 @@ func tailLogsCmd(cli *cli) *cobra.Command { } list, err := getLatestLogs(cmd.Context(), cli, inputs.Num, inputs.Filter) if err != nil { - return fmt.Errorf("failed to get logs: %w", err) + return fmt.Errorf("failed to list logs: %w", err) } logsCh := make(chan []*management.Log) diff --git a/internal/cli/logs_test.go b/internal/cli/logs_test.go index 5ba1eef28..9f861a785 100644 --- a/internal/cli/logs_test.go +++ b/internal/cli/logs_test.go @@ -34,7 +34,7 @@ func TestTailLogsCommand(t *testing.T) { cmd.SetArgs([]string{"--number", "90", "--filter", "user_id:123"}) err := cmd.Execute() - assert.EqualError(t, err, "failed to get logs: generic error") + assert.EqualError(t, err, "failed to list logs: generic error") }) t.Run("it returns an error when it fails to get the logs on the 3rd request", func(t *testing.T) { diff --git a/internal/cli/organizations.go b/internal/cli/organizations.go index 746b05b06..08dccea8d 100644 --- a/internal/cli/organizations.go +++ b/internal/cli/organizations.go @@ -144,7 +144,7 @@ func listOrganizationsCmd(cli *cli) *cobra.Command { }, ) if err != nil { - return fmt.Errorf("An unexpected error occurred: %w", err) + return fmt.Errorf("failed to list organizations: %w", err) } var orgs []*management.Organization @@ -180,8 +180,7 @@ func showOrganizationCmd(cli *cli) *cobra.Command { auth0 orgs show --json`, RunE: func(cmd *cobra.Command, args []string) error { if len(args) == 0 { - err := organizationID.Pick(cmd, &inputs.ID, cli.organizationPickerOptions) - if err != nil { + if err := organizationID.Pick(cmd, &inputs.ID, cli.organizationPickerOptions); err != nil { return err } } else { @@ -195,10 +194,11 @@ func showOrganizationCmd(cli *cli) *cobra.Command { organization, err = cli.api.Organization.Read(cmd.Context(), url.PathEscape(inputs.ID)) return err }); err != nil { - return fmt.Errorf("Unable to get an organization with ID '%s': %w", inputs.ID, err) + return fmt.Errorf("failed to read organization with ID %q: %w", inputs.ID, err) } cli.renderer.OrganizationShow(organization) + return nil }, } @@ -271,7 +271,7 @@ func createOrganizationCmd(cli *cli) *cobra.Command { if err := ansi.Waiting(func() error { return cli.api.Organization.Create(cmd.Context(), newOrg) }); err != nil { - return fmt.Errorf("failed to create an organization with name '%s': %w", inputs.Name, err) + return fmt.Errorf("failed to create organization with name %q: %w", inputs.Name, err) } cli.renderer.OrganizationCreate(newOrg) @@ -317,20 +317,18 @@ func updateOrganizationCmd(cli *cli) *cobra.Command { if len(args) > 0 { inputs.ID = args[0] } else { - err := organizationID.Pick(cmd, &inputs.ID, cli.organizationPickerOptions) - if err != nil { + if err := organizationID.Pick(cmd, &inputs.ID, cli.organizationPickerOptions); err != nil { return err } } var oldOrg *management.Organization - err := ansi.Waiting(func() error { - var err error + err := ansi.Waiting(func() (err error) { oldOrg, err = cli.api.Organization.Read(cmd.Context(), inputs.ID) return err }) if err != nil { - return fmt.Errorf("failed to fetch organization with ID: %s %w", inputs.ID, err) + return fmt.Errorf("failed to read organization with ID %q: %w", inputs.ID, err) } if err := organizationDisplay.AskU(cmd, &inputs.DisplayName, oldOrg.DisplayName); err != nil { @@ -388,10 +386,11 @@ func updateOrganizationCmd(cli *cli) *cobra.Command { if err = ansi.Waiting(func() error { return cli.api.Organization.Update(cmd.Context(), inputs.ID, newOrg) }); err != nil { - return err + return fmt.Errorf("failed to update organization with ID %q: %w", inputs.ID, err) } cli.renderer.OrganizationUpdate(newOrg) + return nil }, } @@ -425,8 +424,7 @@ func deleteOrganizationCmd(cli *cli) *cobra.Command { RunE: func(cmd *cobra.Command, args []string) error { ids := make([]string, len(args)) if len(args) == 0 { - err := organizationID.PickMany(cmd, &ids, cli.organizationPickerOptions) - if err != nil { + if err := organizationID.PickMany(cmd, &ids, cli.organizationPickerOptions); err != nil { return err } } else { @@ -441,11 +439,11 @@ func deleteOrganizationCmd(cli *cli) *cobra.Command { return ansi.ProgressBar("Deleting organization(s)", ids, func(_ int, id string) error { if _, err := cli.api.Organization.Read(cmd.Context(), id); err != nil { - return fmt.Errorf("Unable to delete organization (%s): %w", id, err) + return fmt.Errorf("Failed to delete organization (%s): %w", id, err) } if err := cli.api.Organization.Delete(cmd.Context(), id); err != nil { - return fmt.Errorf("Unable to delete organization (%s): %w", id, err) + return fmt.Errorf("Failed to delete organization (%s): %w", id, err) } return nil }) @@ -658,13 +656,11 @@ func listMembersRolesOrganizationCmd(cli *cli) *cobra.Command { } if len(args) == 0 { - err := organizationID.Pick(cmd, &inputs.OrgID, cli.organizationPickerOptions) - if err != nil { + if err := organizationID.Pick(cmd, &inputs.OrgID, cli.organizationPickerOptions); err != nil { return err } if inputs.RoleID == "" { - err = roleID.Pick(cmd, &inputs.RoleID, cli.rolePickerOptions) - if err != nil { + if err := roleID.Pick(cmd, &inputs.RoleID, cli.rolePickerOptions); err != nil { return err } } @@ -681,8 +677,11 @@ func listMembersRolesOrganizationCmd(cli *cli) *cobra.Command { if err != nil { return err } + sortMembers(roleMembers) + cli.renderer.MembersList(roleMembers) + return nil }, } @@ -710,7 +709,7 @@ func (cli *cli) organizationPickerOptions(ctx context.Context) (pickerOptions, e } if len(opts) == 0 { - return nil, errors.New("There are currently no organizations.") + return nil, errors.New("there are currently no organizations to choose from. Create one by running: `auth0 orgs create`") } return opts, nil @@ -733,7 +732,7 @@ func getWithPagination( page := 0 for { if limit > 0 { - // determine page size to avoid getting unwanted elements + // Determine page size to avoid getting unwanted elements. want := limit - len(list) if want == 0 { return nil @@ -782,7 +781,7 @@ func (cli *cli) getOrgMembers( }, ) if err != nil { - return nil, fmt.Errorf("failed to list members of an organization with ID %q: %w", orgID, err) + return nil, fmt.Errorf("failed to list members of organization with ID %q: %w", orgID, err) } var typedList []management.OrganizationMember @@ -811,7 +810,10 @@ func (cli *cli) getOrgMembersWithSpinner(context context.Context, orgID string, return members, err } -func (cli *cli) getOrgMemberRolesWithSpinner(ctx context.Context, orgID string, members []management.OrganizationMember, +func (cli *cli) getOrgMemberRolesWithSpinner( + ctx context.Context, + orgID string, + members []management.OrganizationMember, ) (map[string]management.OrganizationMemberRole, error) { roleMap := make(map[string]management.OrganizationMemberRole) @@ -838,7 +840,8 @@ func (cli *cli) getOrgMemberRolesWithSpinner(ctx context.Context, orgID string, return roleMap, err } -func (cli *cli) convertOrgRolesToManagementRoles(roleMap map[string]management.OrganizationMemberRole, +func (cli *cli) convertOrgRolesToManagementRoles( + roleMap map[string]management.OrganizationMemberRole, ) []*management.Role { var roles []*management.Role for _, role := range roleMap { diff --git a/internal/cli/organizations_test.go b/internal/cli/organizations_test.go index 1054cedc4..d27a65c1d 100644 --- a/internal/cli/organizations_test.go +++ b/internal/cli/organizations_test.go @@ -52,7 +52,7 @@ func TestOrganizationsPickerOptions(t *testing.T) { t.Fail() }, assertError: func(t testing.TB, err error) { - assert.ErrorContains(t, err, "There are currently no organizations.") + assert.ErrorContains(t, err, "there are currently no organizations to choose from. Create one by running: `auth0 orgs create`") }, }, { diff --git a/internal/cli/prompts_custom_text.go b/internal/cli/prompts_custom_text.go index 484c2011f..c201c1f27 100644 --- a/internal/cli/prompts_custom_text.go +++ b/internal/cli/prompts_custom_text.go @@ -128,7 +128,7 @@ func showPromptsText(cli *cli, inputs *promptsTextInput) func(cmd *cobra.Command return err }); err != nil { return fmt.Errorf( - "unable to fetch custom text for prompt %s and language %s: %w", + "failed to fetch custom text for prompt %q and language %q: %w", inputs.Prompt, inputs.Language, err, @@ -171,7 +171,7 @@ func updateBrandingText(cli *cli, inputs *promptsTextInput) func(cmd *cobra.Comm return cli.api.Prompt.SetCustomText(cmd.Context(), inputs.Prompt, inputs.Language, editedBrandingText) }); err != nil { return fmt.Errorf( - "unable to set custom text for prompt %s and language %s: %w", + "failed to set custom text for prompt %q and language %q: %w", inputs.Prompt, inputs.Language, err, @@ -209,7 +209,7 @@ func fetchBrandingTextContentToEdit(ctx context.Context, cli *cli, inputs *promp return nil }); err != nil { return "", fmt.Errorf( - "unable to load custom text for prompt %s and language %s: %w", + "failed to load custom text for prompt %q and language %q: %w", inputs.Prompt, inputs.Language, err, @@ -235,7 +235,9 @@ func downloadDefaultBrandingTextTranslations(prompt, language string) map[string return nil } - defer response.Body.Close() + defer func() { + _ = response.Body.Close() + }() if response.StatusCode == http.StatusOK { var allPrompts []map[string]interface{} diff --git a/internal/cli/prompts_custom_text_test.go b/internal/cli/prompts_custom_text_test.go index 7c83b833a..f46960c99 100644 --- a/internal/cli/prompts_custom_text_test.go +++ b/internal/cli/prompts_custom_text_test.go @@ -77,7 +77,7 @@ func TestBrandingTextsShowCmd(t *testing.T) { if test.returnedError != nil { expectedErrorMessage := fmt.Errorf( - "unable to fetch custom text for prompt %s and language %s: %w", + "failed to fetch custom text for prompt %q and language %q: %w", test.inputPrompt, test.inputLanguage, test.returnedError, diff --git a/internal/cli/quickstarts.go b/internal/cli/quickstarts.go index 89e1f56e2..78650d32c 100644 --- a/internal/cli/quickstarts.go +++ b/internal/cli/quickstarts.go @@ -155,7 +155,7 @@ func downloadQuickstart(cli *cli, inputs *qsInputs) func(cmd *cobra.Command, arg return inputs.Quickstart.Download(cmd.Context(), quickstartPath, inputs.Client) }) if err != nil { - return fmt.Errorf("failed to download quickstart sample: %v", err) + return fmt.Errorf("failed to download quickstart sample: %w", err) } cli.renderer.Infof("Quickstart sample successfully downloaded at %s", quickstartPath) @@ -373,7 +373,7 @@ func (i *qsInputs) fromArgs(cmd *cobra.Command, args []string, cli *cli) error { return }) if err != nil { - return fmt.Errorf("an unexpected error occurred, please verify your client ID: %w", err) + return fmt.Errorf("failed to find client with ID %q, please verify your client ID: %w", i.ClientID, err) } i.Client = client @@ -391,7 +391,7 @@ func (i *qsInputs) fromArgs(cmd *cobra.Command, args []string, cli *cli) error { if i.Stack == "" { quickstartsByType, err := quickstarts.FilterByType(i.QsTypeForClient) if err != nil { - return fmt.Errorf("an unexpected error occurred: %w", err) + return err } if err := qsStack.Select(cmd, &i.Stack, quickstartsByType.Stacks(), nil); err != nil { diff --git a/internal/cli/roles.go b/internal/cli/roles.go index 14b5e6018..77a325ace 100644 --- a/internal/cli/roles.go +++ b/internal/cli/roles.go @@ -94,7 +94,7 @@ func listRolesCmd(cli *cli) *cobra.Command { }, ) if err != nil { - return fmt.Errorf("An unexpected error occurred: %w", err) + return fmt.Errorf("failed to list roles: %w", err) } var roles []*management.Role @@ -129,8 +129,7 @@ func showRoleCmd(cli *cli) *cobra.Command { auth0 roles show --json`, RunE: func(cmd *cobra.Command, args []string) error { if len(args) == 0 { - err := roleID.Pick(cmd, &inputs.ID, cli.rolePickerOptions) - if err != nil { + if err := roleID.Pick(cmd, &inputs.ID, cli.rolePickerOptions); err != nil { return err } } else { @@ -144,7 +143,7 @@ func showRoleCmd(cli *cli) *cobra.Command { r, err = cli.api.Role.Read(cmd.Context(), inputs.ID) return err }); err != nil { - return fmt.Errorf("Unable to load role: %w", err) + return fmt.Errorf("failed to read role with ID %q: %w", inputs.ID, err) } cli.renderer.RoleShow(r) @@ -174,31 +173,27 @@ func createRoleCmd(cli *cli) *cobra.Command { auth0 roles create --name myrole --description "awesome role" auth0 roles create -n myrole -d "awesome role" --json`, RunE: func(cmd *cobra.Command, args []string) error { - // Prompt for role name if err := roleName.Ask(cmd, &inputs.Name, nil); err != nil { return err } - // Prompt for role description if err := roleDescription.Ask(cmd, &inputs.Description, nil); err != nil { return err } - // Load values into a fresh role instance r := &management.Role{ Name: &inputs.Name, Description: &inputs.Description, } - // Create role if err := ansi.Waiting(func() error { return cli.api.Role.Create(cmd.Context(), r) }); err != nil { - return fmt.Errorf("Unable to create role: %v", err) + return fmt.Errorf("failed to create role: %w", err) } - // Render role creation specific view cli.renderer.RoleCreate(r) + return nil }, } @@ -242,7 +237,7 @@ func updateRoleCmd(cli *cli) *cobra.Command { currentRole, err = cli.api.Role.Read(cmd.Context(), inputs.ID) return err }); err != nil { - return fmt.Errorf("failed to find role with ID %q: %v", inputs.ID, err) + return fmt.Errorf("failed to read role with ID %q: %w", inputs.ID, err) } if err := roleName.AskU(cmd, &inputs.Name, currentRole.Name); err != nil { @@ -265,7 +260,7 @@ func updateRoleCmd(cli *cli) *cobra.Command { if err := ansi.Waiting(func() error { return cli.api.Role.Update(cmd.Context(), inputs.ID, updatedRole) }); err != nil { - return fmt.Errorf("failed to update role with ID %q: %v", inputs.ID, err) + return fmt.Errorf("failed to update role with ID %q: %w", inputs.ID, err) } cli.renderer.RoleUpdate(updatedRole) @@ -298,8 +293,7 @@ func deleteRoleCmd(cli *cli) *cobra.Command { RunE: func(cmd *cobra.Command, args []string) error { ids := make([]string, len(args)) if len(args) == 0 { - err := roleID.PickMany(cmd, &ids, cli.rolePickerOptions) - if err != nil { + if err := roleID.PickMany(cmd, &ids, cli.rolePickerOptions); err != nil { return err } } else { @@ -315,11 +309,11 @@ func deleteRoleCmd(cli *cli) *cobra.Command { return ansi.ProgressBar("Deleting Role(s)", ids, func(_ int, id string) error { if id != "" { if _, err := cli.api.Role.Read(cmd.Context(), id); err != nil { - return fmt.Errorf("Unable to delete role (%s): %w", id, err) + return fmt.Errorf("Failed to delete role (%s): %w", id, err) } if err := cli.api.Role.Delete(cmd.Context(), id); err != nil { - return fmt.Errorf("Unable to delete role (%s): %w", id, err) + return fmt.Errorf("Failed to delete role (%s): %w", id, err) } } return nil @@ -347,7 +341,7 @@ func (c *cli) rolePickerOptions(ctx context.Context) (pickerOptions, error) { } if len(opts) == 0 { - return nil, errors.New("There are currently no roles.") + return nil, errors.New("there are currently no roles to choose from. Create one by running: `auth0 roles create`") } return opts, nil diff --git a/internal/cli/roles_permissions.go b/internal/cli/roles_permissions.go index 88afc00f8..60159d85b 100644 --- a/internal/cli/roles_permissions.go +++ b/internal/cli/roles_permissions.go @@ -74,8 +74,7 @@ func listRolePermissionsCmd(cli *cli) *cobra.Command { } if len(args) == 0 { - err := roleID.Pick(cmd, &inputs.ID, cli.rolePickerOptions) - if err != nil { + if err := roleID.Pick(cmd, &inputs.ID, cli.rolePickerOptions); err != nil { return err } } else { @@ -98,7 +97,7 @@ func listRolePermissionsCmd(cli *cli) *cobra.Command { ) if err != nil { - return fmt.Errorf("Failed to get permissions for role '%s': %w", inputs.ID, err) + return fmt.Errorf("failed to read permissions for role with ID %q: %w", inputs.ID, err) } var permissions []*management.Permission @@ -136,8 +135,7 @@ func addRolePermissionsCmd(cli *cli) *cobra.Command { auth0 roles permissions add -a -p `, RunE: func(cmd *cobra.Command, args []string) error { if len(args) == 0 { - err := roleID.Pick(cmd, &inputs.ID, cli.rolePickerOptions) - if err != nil { + if err := roleID.Pick(cmd, &inputs.ID, cli.rolePickerOptions); err != nil { return err } } else { @@ -149,9 +147,9 @@ func addRolePermissionsCmd(cli *cli) *cobra.Command { } var rs *management.ResourceServer - rs, err := cli.api.ResourceServer.Read(cmd.Context(), url.PathEscape(inputs.APIIdentifier)) + rs, err := cli.api.ResourceServer.Read(cmd.Context(), inputs.APIIdentifier) if err != nil { - return err + return fmt.Errorf("failed to read API with identifier %q: %w", inputs.APIIdentifier, err) } if len(inputs.Permissions) == 0 { @@ -163,15 +161,16 @@ func addRolePermissionsCmd(cli *cli) *cobra.Command { ps := makePermissions(rs.GetIdentifier(), inputs.Permissions) if err := cli.api.Role.AssociatePermissions(cmd.Context(), inputs.ID, ps); err != nil { - return err + return fmt.Errorf("failed to associate permissions to role with ID %q: %w", inputs.ID, err) } role, err := cli.api.Role.Read(cmd.Context(), inputs.ID) if err != nil { - return err + return fmt.Errorf("failed to read role with ID %q: %w", inputs.ID, err) } cli.renderer.RolePermissionAdd(role, rs, inputs.Permissions) + return nil }, } @@ -201,8 +200,7 @@ func removeRolePermissionsCmd(cli *cli) *cobra.Command { auth0 roles permissions rm -a -p `, RunE: func(cmd *cobra.Command, args []string) error { if len(args) == 0 { - err := roleID.Pick(cmd, &inputs.ID, cli.rolePickerOptions) - if err != nil { + if err := roleID.Pick(cmd, &inputs.ID, cli.rolePickerOptions); err != nil { return err } } else { @@ -214,9 +212,9 @@ func removeRolePermissionsCmd(cli *cli) *cobra.Command { } var rs *management.ResourceServer - rs, err := cli.api.ResourceServer.Read(cmd.Context(), url.PathEscape(inputs.APIIdentifier)) + rs, err := cli.api.ResourceServer.Read(cmd.Context(), inputs.APIIdentifier) if err != nil { - return err + return fmt.Errorf("failed to read API with identifier %q: %w", inputs.APIIdentifier, err) } if len(inputs.Permissions) == 0 { @@ -228,15 +226,16 @@ func removeRolePermissionsCmd(cli *cli) *cobra.Command { ps := makePermissions(rs.GetIdentifier(), inputs.Permissions) if err := cli.api.Role.RemovePermissions(cmd.Context(), inputs.ID, ps); err != nil { - return err + return fmt.Errorf("failed to remove permissions from role with ID %q: %w", inputs.ID, err) } role, err := cli.api.Role.Read(cmd.Context(), inputs.ID) if err != nil { - return err + return fmt.Errorf("failed to read role with ID %q: %w", inputs.ID, err) } cli.renderer.RolePermissionRemove(role, rs, inputs.Permissions) + return nil }, } diff --git a/internal/cli/roles_test.go b/internal/cli/roles_test.go index 3baf1b3e9..343a3ca32 100644 --- a/internal/cli/roles_test.go +++ b/internal/cli/roles_test.go @@ -52,7 +52,7 @@ func TestRolesPickerOptions(t *testing.T) { t.Fail() }, assertError: func(t testing.TB, err error) { - assert.ErrorContains(t, err, "There are currently no roles.") + assert.ErrorContains(t, err, "there are currently no roles to choose from. Create one by running: `auth0 roles create`") }, }, { diff --git a/internal/cli/root.go b/internal/cli/root.go index b6d467058..bdb86cde0 100644 --- a/internal/cli/root.go +++ b/internal/cli/root.go @@ -6,6 +6,7 @@ import ( "os" "os/signal" "time" + "unicode" "github.com/spf13/cobra" @@ -55,24 +56,23 @@ func Execute() { } }() - // platform specific terminal initialization: + // Platform specific terminal initialization: // this should run for all commands, - // for most of the architectures there's no requirements: + // for most of the architectures there's no requirements. ansi.InitConsole() cancelCtx := contextWithCancel() if err := rootCmd.ExecuteContext(cancelCtx); err != nil { - cli.renderer.Heading("error") - cli.renderer.Errorf(err.Error()) + renderErrorMessage(cli.renderer, err.Error()) instrumentation.ReportException(err) os.Exit(1) // nolint:gocritic } timeoutCtx, cancel := context.WithTimeout(cancelCtx, 3*time.Second) - // defers are executed in LIFO order + // Defers are executed in LIFO order. defer cancel() - defer cli.tracker.Wait(timeoutCtx) // No event should be tracked after this has run, or it will panic e.g. in earlier deferred functions + defer cli.tracker.Wait(timeoutCtx) // No event should be tracked after this has run, or it will panic e.g. in earlier deferred functions. } func buildRootCmd(cli *cli) *cobra.Command { @@ -149,7 +149,7 @@ func addPersistentFlags(rootCmd *cobra.Command, cli *cli) { func addSubCommands(rootCmd *cobra.Command, cli *cli) { // The order of the commands here matters. // Add new commands in a place that reflect its - // relevance or relation with other commands: + // relevance or relation with other commands. rootCmd.AddCommand(loginCmd(cli)) rootCmd.AddCommand(logoutCmd(cli)) rootCmd.AddCommand(tenantsCmd(cli)) @@ -170,7 +170,7 @@ func addSubCommands(rootCmd *cobra.Command, cli *cli) { rootCmd.AddCommand(apiCmd(cli)) rootCmd.AddCommand(terraformCmd(cli)) - // keep completion at the bottom: + // Keep completion at the bottom. rootCmd.AddCommand(completionCmd(cli)) } @@ -204,3 +204,18 @@ func overrideHelpAndVersionFlagText(cmd *cobra.Command) { } } } + +func renderErrorMessage(display *display.Renderer, errorMessage string) { + display.Heading(ansi.Red("error")) + + rawErrorMessage := []rune(errorMessage) + humanReadableErrorMessage := string( + append( + []rune{unicode.ToUpper(rawErrorMessage[0])}, + rawErrorMessage[1:]..., + ), + ) + "." + + display.Errorf(humanReadableErrorMessage) + display.Newline() +} diff --git a/internal/cli/rules.go b/internal/cli/rules.go index 87b9c01d2..8e16931e0 100644 --- a/internal/cli/rules.go +++ b/internal/cli/rules.go @@ -98,20 +98,24 @@ func listRulesCmd(cli *cli) *cobra.Command { auth0 rules ls --json`, RunE: func(cmd *cobra.Command, args []string) error { var rules []*management.Rule + err := ansi.Waiting(func() error { ruleList, err := cli.api.Rule.List(cmd.Context()) if err != nil { return err } + rules = ruleList.Rules + return nil }) - if err != nil { - return err + return fmt.Errorf("failed to list rules: %w", err) } + cli.renderer.Warnf(rulesDeprecationLogText) cli.renderer.RulesList(rules) + return nil }, } @@ -150,7 +154,7 @@ func createRuleCmd(cli *cli) *cobra.Command { if len(pipedInput) > 0 { err := json.Unmarshal(pipedInput, rule) if err != nil { - return fmt.Errorf("Invalid JSON input: %w", err) + return fmt.Errorf("failed to unmarshal JSON input: %w", err) } } else { if err := ruleName.Ask(cmd, &inputs.Name, nil); err != nil { @@ -169,7 +173,7 @@ func createRuleCmd(cli *cli) *cobra.Command { cli.ruleEditorHint, ) if err != nil { - return fmt.Errorf("Failed to capture input from the editor: %w", err) + return fmt.Errorf("failed to capture input from the editor: %w", err) } rule = &management.Rule{ @@ -179,16 +183,15 @@ func createRuleCmd(cli *cli) *cobra.Command { } } - err := ansi.Waiting(func() error { + if err := ansi.Waiting(func() error { return cli.api.Rule.Create(cmd.Context(), rule) - }) - - if err != nil { - return fmt.Errorf("Unable to create rule: %w", err) + }); err != nil { + return fmt.Errorf("failed to create rule: %w", err) } cli.renderer.Warnf(rulesDeprecationLogText) cli.renderer.RuleCreate(rule) + return nil }, } @@ -219,8 +222,7 @@ func showRuleCmd(cli *cli) *cobra.Command { if len(args) > 0 { inputs.ID = args[0] } else { - err := ruleID.Pick(cmd, &inputs.ID, cli.rulePickerOptions) - if err != nil { + if err := ruleID.Pick(cmd, &inputs.ID, cli.rulePickerOptions); err != nil { return err } } @@ -234,11 +236,12 @@ func showRuleCmd(cli *cli) *cobra.Command { }) if err != nil { - return fmt.Errorf("Unable to load rule: %w", err) + return fmt.Errorf("failed to read rule with ID %q: %w", inputs.ID, err) } cli.renderer.Warnf(rulesDeprecationLogText) cli.renderer.RuleShow(rule) + return nil }, } @@ -265,8 +268,7 @@ func deleteRuleCmd(cli *cli) *cobra.Command { RunE: func(cmd *cobra.Command, args []string) error { ids := make([]string, len(args)) if len(args) == 0 { - err := ruleID.PickMany(cmd, &ids, cli.rulePickerOptions) - if err != nil { + if err := ruleID.PickMany(cmd, &ids, cli.rulePickerOptions); err != nil { return err } } else { @@ -282,11 +284,11 @@ func deleteRuleCmd(cli *cli) *cobra.Command { return ansi.ProgressBar("Deleting Rule(s)", ids, func(_ int, id string) error { if id != "" { if _, err := cli.api.Rule.Read(cmd.Context(), id); err != nil { - return fmt.Errorf("Unable to delete rule (%s): %w", id, err) + return fmt.Errorf("Failed to delete rule (%s): %w", id, err) } if err := cli.api.Rule.Delete(cmd.Context(), id); err != nil { - fmt.Errorf("Unable to delete rule (%s): %w", id, err) + fmt.Errorf("Failed to delete rule (%s): %w", id, err) } } return nil @@ -345,7 +347,7 @@ func updateRuleCmd(cli *cli) *cobra.Command { return err }) if err != nil { - return fmt.Errorf("failed to fetch rule with ID %s: %w", inputs.ID, err) + return fmt.Errorf("failed to fetch rule with ID %q: %w", inputs.ID, err) } if err := ruleName.AskU(cmd, &inputs.Name, oldRule.Name); err != nil { @@ -388,7 +390,7 @@ func updateRuleCmd(cli *cli) *cobra.Command { return cli.api.Rule.Update(cmd.Context(), inputs.ID, updatedRule) }) if err != nil { - return fmt.Errorf("failed to update rule with ID %s: %w", inputs.ID, err) + return fmt.Errorf("failed to update rule with ID %q: %w", inputs.ID, err) } cli.renderer.Warnf(rulesDeprecationLogText) @@ -425,8 +427,7 @@ func enableRuleCmd(cli *cli) *cobra.Command { if len(args) > 0 { inputs.ID = args[0] } else { - err := ruleID.Pick(cmd, &inputs.ID, cli.rulePickerOptions) - if err != nil { + if err := ruleID.Pick(cmd, &inputs.ID, cli.rulePickerOptions); err != nil { return err } } @@ -438,23 +439,22 @@ func enableRuleCmd(cli *cli) *cobra.Command { return err }) if err != nil { - return fmt.Errorf("Failed to fetch rule with ID: %s %v", inputs.ID, err) + return fmt.Errorf("failed to fetch rule with ID %q: %w", inputs.ID, err) } rule = &management.Rule{ Enabled: auth0.Bool(true), } - err = ansi.Waiting(func() error { + if err = ansi.Waiting(func() error { return cli.api.Rule.Update(cmd.Context(), inputs.ID, rule) - }) - - if err != nil { - return err + }); err != nil { + return fmt.Errorf("failed to update rule with ID %q: %w", inputs.ID, err) } cli.renderer.Warnf(rulesDeprecationLogText) cli.renderer.RuleEnable(rule) + return nil }, } @@ -482,32 +482,28 @@ func disableRuleCmd(cli *cli) *cobra.Command { if len(args) > 0 { inputs.ID = args[0] } else { - err := ruleID.Pick(cmd, &inputs.ID, cli.rulePickerOptions) - if err != nil { + if err := ruleID.Pick(cmd, &inputs.ID, cli.rulePickerOptions); err != nil { return err } } var rule *management.Rule - err := ansi.Waiting(func() error { - var err error + err := ansi.Waiting(func() (err error) { rule, err = cli.api.Rule.Read(cmd.Context(), inputs.ID) return err }) if err != nil { - return fmt.Errorf("Failed to fetch rule with ID: %s %v", inputs.ID, err) + return fmt.Errorf("failed to fetch rule with ID %q: %w", inputs.ID, err) } rule = &management.Rule{ Enabled: auth0.Bool(false), } - err = ansi.Waiting(func() error { + if err = ansi.Waiting(func() error { return cli.api.Rule.Update(cmd.Context(), inputs.ID, rule) - }) - - if err != nil { - return err + }); err != nil { + return fmt.Errorf("failed to update rule with ID %q: %w", inputs.ID, err) } cli.renderer.RuleDisable(rule) @@ -534,7 +530,7 @@ func (c *cli) rulePickerOptions(ctx context.Context) (pickerOptions, error) { } if len(opts) == 0 { - return nil, errors.New("There are currently no rules.") + return nil, errors.New("there are currently no rules to choose from") } return opts, nil diff --git a/internal/cli/rules_test.go b/internal/cli/rules_test.go index 26723966d..f7a44bbed 100644 --- a/internal/cli/rules_test.go +++ b/internal/cli/rules_test.go @@ -52,7 +52,7 @@ func TestRulesPickerOptions(t *testing.T) { t.Fail() }, assertError: func(t testing.TB, err error) { - assert.ErrorContains(t, err, "There are currently no rules.") + assert.ErrorContains(t, err, "there are currently no rules to choose from") }, }, { diff --git a/internal/cli/tenants.go b/internal/cli/tenants.go index fb1ce740d..fa1810c91 100644 --- a/internal/cli/tenants.go +++ b/internal/cli/tenants.go @@ -137,7 +137,7 @@ func (c *cli) tenantPickerOptions(_ context.Context) (pickerOptions, error) { } if len(opts)+len(priorityOpts) == 0 { - return nil, fmt.Errorf("There are no tenants to pick from. Add tenants by running `auth0 login`.") + return nil, fmt.Errorf("there are no tenants to pick from. Add tenants by running `auth0 login`") } return append(priorityOpts, opts...), nil diff --git a/internal/cli/terraform.go b/internal/cli/terraform.go index 6b9a1272a..9f71b661d 100644 --- a/internal/cli/terraform.go +++ b/internal/cli/terraform.go @@ -266,7 +266,9 @@ func createMainFile(outputDIR string) error { if err != nil { return err } - defer file.Close() + defer func() { + _ = file.Close() + }() fileContent := `terraform { required_version = "~> 1.5.0" @@ -294,7 +296,9 @@ func createImportFile(outputDIR string, data importDataList) error { if err != nil { return err } - defer file.Close() + defer func() { + _ = file.Close() + }() fileContent := `# This file is automatically generated via the Auth0 CLI. # It can be safely removed after the successful generation @@ -361,7 +365,7 @@ func checkTerraformProviderAndCLIDomainsMatch(currentCLIDomain string) error { if providerDomain == currentCLIDomain { return nil } - return fmt.Errorf("Terraform provider tenant domain '%s' does not match current CLI tenant '%s'", providerDomain, currentCLIDomain) + return fmt.Errorf("terraform provider tenant domain %q does not match current CLI tenant %q", providerDomain, currentCLIDomain) } func deduplicateResourceNames(data importDataList) importDataList { diff --git a/internal/cli/terraform_fetcher.go b/internal/cli/terraform_fetcher.go index ee8e96271..94a2e3839 100644 --- a/internal/cli/terraform_fetcher.go +++ b/internal/cli/terraform_fetcher.go @@ -416,7 +416,7 @@ func (f *roleResourceFetcher) FetchData(ctx context.Context) (importDataList, er return data, nil } if len(rolePerms.Permissions) > 0 { - // `permissions` block a required field for TF Provider; cannot have empty permissions + // `permissions` block a required field for TF Provider; cannot have empty permissions. data = append(data, importDataItem{ ResourceName: "auth0_role_permissions." + sanitizeResourceName(role.GetName()), ImportID: role.GetID(), diff --git a/internal/cli/terraform_test.go b/internal/cli/terraform_test.go index 73d7b6247..c55f37b9b 100644 --- a/internal/cli/terraform_test.go +++ b/internal/cli/terraform_test.go @@ -174,7 +174,7 @@ func setupTestDIRAndImportData(t *testing.T) (string, importDataList) { ImportID: "actionID_1", }, { - ResourceName: "auth0_action.MyTestAction", //NOTE: duplicate name + ResourceName: "auth0_action.MyTestAction", // NOTE: duplicate name. ImportID: "actionID_2", }, } @@ -206,7 +206,7 @@ provider "auth0" { debug = true } ` - // Read the file content and check if it matches the expected content + // Read the file content and check if it matches the expected content. content, err := os.ReadFile(filePath) assert.NoError(t, err) assert.Equal(t, expectedContent, string(content)) @@ -240,7 +240,7 @@ import { err = tmpl.Execute(&expectedContent, data) require.NoError(t, err) - // Read the file content and check if it matches the expected content + // Read the file content and check if it matches the expected content. content, err := os.ReadFile(filePath) assert.NoError(t, err) assert.Equal(t, expectedContent.String(), string(content)) @@ -494,7 +494,7 @@ func TestSanitizeResourceName(t *testing.T) { input string expected string }{ - // Test cases with valid names + // Test cases with valid names. {"ValidName123", "validname123"}, {"_Another_Valid-Name", "another_valid_name"}, {"name_with_123", "name_with_123"}, @@ -503,7 +503,7 @@ func TestSanitizeResourceName(t *testing.T) { {"multiple spaces between", "multiple_spaces_between"}, {"https://travel0.us.auth0.com/api/v2/", "https_travel0_us_auth0_com_api_v2"}, - // Test cases with invalid names to be sanitized + // Test cases with invalid names to be sanitized. {"Invalid@Name", "invalid_name"}, {"Invalid Name", "invalid_name"}, {"123 Starts With Number", "starts_with_number"}, @@ -523,17 +523,15 @@ func TestCheckTerraformProviderAndCLIDomainsMatch(t *testing.T) { t.Run("it should return no error if provided domain and TF provider env var domain match", func(t *testing.T) { domain := "travel0.us.auth0.com" - os.Setenv("AUTH0_DOMAIN", domain) + t.Setenv("AUTH0_DOMAIN", domain) err := checkTerraformProviderAndCLIDomainsMatch(domain) assert.NoError(t, err) - os.Unsetenv("AUTH0_DOMAIN") }) t.Run("it should return an error if provided domain and TF provider env var domain do not match", func(t *testing.T) { - os.Setenv("AUTH0_DOMAIN", "different-tenant.eu.auth0.com") + t.Setenv("AUTH0_DOMAIN", "different-tenant.eu.auth0.com") err := checkTerraformProviderAndCLIDomainsMatch("travel0.us.auth0.com") assert.Error(t, err) - assert.Equal(t, err.Error(), "Terraform provider tenant domain 'different-tenant.eu.auth0.com' does not match current CLI tenant 'travel0.us.auth0.com'") - os.Unsetenv("AUTH0_DOMAIN") + assert.Equal(t, err.Error(), "terraform provider tenant domain \"different-tenant.eu.auth0.com\" does not match current CLI tenant \"travel0.us.auth0.com\"") }) } diff --git a/internal/cli/test.go b/internal/cli/test.go index 1c0b42976..1c4eb8bbb 100644 --- a/internal/cli/test.go +++ b/internal/cli/test.go @@ -62,7 +62,7 @@ var ( Help: "One of your custom domains.", } - errNoCustomDomains = errors.New("there are currently no custom domains") + errNoCustomDomains = errors.New("there are currently no custom domains. Create one by running: `auth0 domains create`") ) type testCmdInputs struct { @@ -145,7 +145,7 @@ func testLoginCmd(cli *cli) *cobra.Command { inputs.CustomDomain, ) if err != nil { - return fmt.Errorf("failed to log into the client %s: %w", inputs.ClientID, err) + return fmt.Errorf("failed to log into the client with ID %q: %w", inputs.ClientID, err) } var userInfo *authutil.UserInfo @@ -247,7 +247,7 @@ func testTokenCmd(cli *cli) *cobra.Command { "", // Specifying a custom domain is only supported for the test login command. ) if err != nil { - return fmt.Errorf("failed to log into the client %s: %w", inputs.ClientID, err) + return fmt.Errorf("failed to log into the client with ID %q: %w", inputs.ClientID, err) } cli.renderer.TestToken(client, tokenResponse) @@ -300,7 +300,7 @@ func selectClientToUseForTestsAndValidateExistence(cli *cli, cmd *cobra.Command, client, err := cli.api.Client.Read(cmd.Context(), inputs.ClientID) if err != nil { - return nil, fmt.Errorf("failed to find client with ID :%q: %w", inputs.ClientID, err) + return nil, fmt.Errorf("failed to find client with ID %q: %w", inputs.ClientID, err) } return client, nil @@ -313,7 +313,7 @@ func (c *cli) customDomainPickerOptions(ctx context.Context) (pickerOptions, err if err != nil { errStatus := err.(management.Error) // 403 is a valid response for free tenants that don't have - // custom domains enabled + // custom domains enabled. if errStatus != nil && errStatus.Status() == 403 { return nil, errNoCustomDomains } diff --git a/internal/cli/universal_login.go b/internal/cli/universal_login.go index 6c7819930..514599715 100644 --- a/internal/cli/universal_login.go +++ b/internal/cli/universal_login.go @@ -118,7 +118,7 @@ func showUniversalLoginCmd(cli *cli) *cobra.Command { myBranding, err = cli.api.Branding.Read(cmd.Context()) return err }); err != nil { - return fmt.Errorf("unable to load branding settings due to an unexpected error: %w", err) + return fmt.Errorf("failed to read branding settings: %w", err) } cli.renderer.BrandingShow(myBranding) @@ -157,25 +157,21 @@ func updateUniversalLoginCmd(cli *cli) *cobra.Command { RunE: func(cmd *cobra.Command, args []string) error { var current *management.Branding - if err := ansi.Waiting(func() error { - var err error + if err := ansi.Waiting(func() (err error) { current, err = cli.api.Branding.Read(cmd.Context()) return err }); err != nil { - return fmt.Errorf("unable to load branding settings due to an unexpected error: %w", err) + return fmt.Errorf("failed to read branding settings: %w", err) } - // Prompt for accent color if err := brandingAccent.AskU(cmd, &inputs.AccentColor, auth0.String(current.GetColors().GetPrimary())); err != nil { return err } - // Prompt for background color if err := brandingBackground.AskU(cmd, &inputs.BackgroundColor, auth0.String(current.GetColors().GetPageBackground())); err != nil { return err } - // Load updated values into a fresh branding instance b := &management.Branding{} isAccentColorSet := len(inputs.AccentColor) > 0 isBackgroundColorSet := len(inputs.BackgroundColor) > 0 @@ -205,19 +201,18 @@ func updateUniversalLoginCmd(cli *cli) *cobra.Command { b.FaviconURL = &inputs.FaviconURL } - // API2 will produce an error if we send an empty font struct + // API2 will produce an error if we send an empty font struct. if b.Font == nil && inputs.CustomFontURL != "" { b.Font = &management.BrandingFont{URL: &inputs.CustomFontURL} } - // Update branding + // Update branding. if err := ansi.Waiting(func() error { return cli.api.Branding.Update(cmd.Context(), b) }); err != nil { - return fmt.Errorf("unable to update branding settings: %v", err) + return fmt.Errorf("failed to update branding settings: %w", err) } - // Render result cli.renderer.BrandingUpdate(b) return nil diff --git a/internal/cli/universal_login_customize.go b/internal/cli/universal_login_customize.go index 32940c0bd..dc346272e 100644 --- a/internal/cli/universal_login_customize.go +++ b/internal/cli/universal_login_customize.go @@ -203,7 +203,9 @@ func startWebSocketServer( if err != nil { return err } - defer listener.Close() + defer func() { + _ = listener.Close() + }() handler := &webSocketHandler{ display: display, diff --git a/internal/cli/universal_login_templates.go b/internal/cli/universal_login_templates.go index b2c5602f5..816f44ca2 100644 --- a/internal/cli/universal_login_templates.go +++ b/internal/cli/universal_login_templates.go @@ -260,7 +260,7 @@ func ensureCustomDomainIsEnabled(ctx context.Context, api *auth0.API) error { domains, err := api.CustomDomain.List(ctx) if err != nil { if mErr, ok := err.(management.Error); ok && mErr.Status() == http.StatusForbidden { - return errNotAllowed // 403 is a valid response for free tenants that don't have custom domains enabled + return errNotAllowed // 403 is a valid response for free tenants that don't have custom domains enabled. } return err @@ -335,7 +335,9 @@ func previewTemplate(ctx context.Context, data *TemplateData) error { if err != nil { return err } - defer listener.Close() + defer func() { + _ = listener.Close() + }() changesChan, err := broadcastTemplateChanges(ctx, data.Filename) if err != nil { @@ -348,7 +350,9 @@ func previewTemplate(ctx context.Context, data *TemplateData) error { ReadTimeout: requestTimeout + time.Minute, WriteTimeout: requestTimeout + time.Minute, } - defer server.Close() + defer func() { + _ = server.Close() + }() go func() { if err = server.Serve(listener); err != http.ErrServerClosed { @@ -367,7 +371,7 @@ func previewTemplate(ctx context.Context, data *TemplateData) error { return err } - // Wait until the file is closed or input is cancelled + // Wait until the file is closed or input is cancelled. <-ctx.Done() return nil } @@ -446,7 +450,7 @@ func broadcastTemplateChanges(ctx context.Context, filename string) (chan bool, go func() { <-ctx.Done() - watcher.Close() + _ = watcher.Close() close(changesChan) }() diff --git a/internal/cli/users.go b/internal/cli/users.go index d1d97d3a1..3aa1f43dd 100644 --- a/internal/cli/users.go +++ b/internal/cli/users.go @@ -268,12 +268,12 @@ func createUserCmd(cli *cli) *cobra.Command { } // The getConnReqUsername returns the value for the requires_username field for the selected connection - // The result will be used to determine whether to prompt for username + // The result will be used to determine whether to prompt for username. conn := cli.getConnReqUsername(cmd.Context(), auth0.StringValue(&inputs.ConnectionName)) requireUsername := auth0.BoolValue(conn) // Prompt for username if the requireUsername is set to true - // Load values including the username's field into a fresh users instance + // Load values including the username's field into a fresh users instance. a := &management.User{ Connection: &inputs.ConnectionName, Email: &inputs.Email, @@ -287,14 +287,13 @@ func createUserCmd(cli *cli) *cobra.Command { } a.Username = &inputs.Username } - // Create app + if err := ansi.Waiting(func() error { return cli.api.User.Create(cmd.Context(), a) }); err != nil { - return fmt.Errorf("Unable to create user: %w", err) + return fmt.Errorf("failed to create user: %w", err) } - // Render Result cli.renderer.UserCreate(a, requireUsername) return nil @@ -340,14 +339,14 @@ func showUserCmd(cli *cli) *cobra.Command { a, err = cli.api.User.Read(cmd.Context(), inputs.ID) return err }); err != nil { - return fmt.Errorf("Unable to load user: %w", err) + return fmt.Errorf("failed to load user with ID %q: %w", inputs.ID, err) } - // get the current connection + // Get the current connection. conn := stringSliceToCommaSeparatedString(cli.getUserConnection(a)) a.Connection = auth0.String(conn) - // parse the connection name to get the requireUsername status + // Parse the connection name to get the requireUsername status. u := cli.getConnReqUsername(cmd.Context(), auth0.StringValue(a.Connection)) requireUsername := auth0.BoolValue(u) @@ -396,11 +395,11 @@ func deleteUserCmd(cli *cli) *cobra.Command { return ansi.ProgressBar("Deleting user(s)", ids, func(_ int, id string) error { if id != "" { if _, err := cli.api.User.Read(cmd.Context(), id); err != nil { - return fmt.Errorf("Unable to delete user (%s): %w", id, err) + return fmt.Errorf("Failed to delete user (%s): %w", id, err) } if err := cli.api.User.Delete(cmd.Context(), id); err != nil { - return fmt.Errorf("Unable to delete user (%s): %w", id, err) + return fmt.Errorf("Failed to delete user (%s): %w", id, err) } } return nil @@ -449,10 +448,10 @@ func updateUserCmd(cli *cli) *cobra.Command { current, err = cli.api.User.Read(cmd.Context(), inputs.ID) return err }); err != nil { - return fmt.Errorf("Unable to load user: %w", err) + return fmt.Errorf("failed to read user with ID %q: %w", inputs.ID, err) } - // using getUserConnection to get connection name from user Identities - // just using current.connection will return empty + // Using getUserConnection to get connection name from user Identities + // just using current.connection will return empty. conn := stringSliceToCommaSeparatedString(cli.getUserConnection(current)) current.Connection = auth0.String(conn) @@ -468,10 +467,10 @@ func updateUserCmd(cli *cli) *cobra.Command { return err } - // username cannot be updated for database connections + // Username cannot be updated for database connections // if err := userUsername.AskU(cmd, &inputs.Username, current.Username); err != nil { // return err - // } + // }. user := &management.User{} @@ -498,7 +497,7 @@ func updateUserCmd(cli *cli) *cobra.Command { if err := ansi.Waiting(func() error { return cli.api.User.Update(cmd.Context(), current.GetID(), user) }); err != nil { - return fmt.Errorf("An unexpected error occurred while trying to update an user with Id '%s': %w", inputs.ID, err) + return fmt.Errorf("failed to update user with ID %q: %w", inputs.ID, err) } con := cli.getConnReqUsername(cmd.Context(), auth0.StringValue(user.Connection)) @@ -589,7 +588,7 @@ The file size limit for a bulk import is 500KB. You will need to start multiple connection, err := cli.api.Connection.ReadByName(cmd.Context(), inputs.ConnectionName) if err != nil { - return fmt.Errorf("failed to find connection with name %q: %w", inputs.ConnectionName, err) + return fmt.Errorf("failed to read connection with name %q: %w", inputs.ConnectionName, err) } if len(connection.GetEnabledClients()) == 0 { @@ -648,7 +647,7 @@ The file size limit for a bulk import is 500KB. You will need to start multiple if err := ansi.Waiting(func() error { return cli.api.Jobs.ImportUsers(cmd.Context(), job) }); err != nil { - return err + return fmt.Errorf("failed to import users: %w", err) } cli.renderer.Heading("started user import job") diff --git a/internal/cli/users_blocks.go b/internal/cli/users_blocks.go index 802daa086..e338b2ae0 100644 --- a/internal/cli/users_blocks.go +++ b/internal/cli/users_blocks.go @@ -58,7 +58,7 @@ func listUserBlocksCmd(cli *cli) *cobra.Command { return err }) if err != nil { - return fmt.Errorf("failed to list user blocks for user with ID %s: %w", inputs.userIdentifier, err) + return fmt.Errorf("failed to list user blocks for user with ID %q: %w", inputs.userIdentifier, err) } cli.renderer.UserBlocksList(userBlocks) diff --git a/internal/cli/users_roles.go b/internal/cli/users_roles.go index d0846a905..b01904f65 100644 --- a/internal/cli/users_roles.go +++ b/internal/cli/users_roles.go @@ -102,7 +102,7 @@ func showUserRolesCmd(cli *cli) *cobra.Command { }, ) if err != nil { - return fmt.Errorf("failed to find roles for user with ID %s: %w", inputs.ID, err) + return fmt.Errorf("failed to read roles for user with ID %q: %w", inputs.ID, err) } var userRoles []*management.Role @@ -159,7 +159,7 @@ func addUserRolesCmd(cli *cli) *cobra.Command { if err := ansi.Waiting(func() (err error) { return cli.api.User.AssignRoles(cmd.Context(), inputs.ID, rolesToAssign) }); err != nil { - return fmt.Errorf("failed to assign roles for user with ID %s: %w", inputs.ID, err) + return fmt.Errorf("failed to assign roles for user with ID %q: %w", inputs.ID, err) } var userRoleList *management.RoleList @@ -167,7 +167,7 @@ func addUserRolesCmd(cli *cli) *cobra.Command { userRoleList, err = cli.api.User.Roles(cmd.Context(), inputs.ID) return err }); err != nil { - return fmt.Errorf("failed to find roles for user with ID %s: %w", inputs.ID, err) + return fmt.Errorf("failed to read roles for user with ID %q: %w", inputs.ID, err) } cli.renderer.UserRoleList(userRoleList.Roles) @@ -219,7 +219,7 @@ func removeUserRolesCmd(cli *cli) *cobra.Command { if err := ansi.Waiting(func() (err error) { return cli.api.User.RemoveRoles(cmd.Context(), inputs.ID, rolesToRemove) }); err != nil { - return fmt.Errorf("failed to remove roles for user with ID %s: %w", inputs.ID, err) + return fmt.Errorf("failed to remove roles for user with ID %q: %w", inputs.ID, err) } var userRoleList *management.RoleList @@ -227,7 +227,7 @@ func removeUserRolesCmd(cli *cli) *cobra.Command { userRoleList, err = cli.api.User.Roles(cmd.Context(), inputs.ID) return err }); err != nil { - return fmt.Errorf("failed to find roles for user with ID %s: %w", inputs.ID, err) + return fmt.Errorf("failed to read roles for user with ID %q: %w", inputs.ID, err) } cli.renderer.UserRoleList(userRoleList.Roles) @@ -285,17 +285,17 @@ func pickUserRoles(options []string) ([]string, error) { func userRolesToAddPickerOptions(ctx context.Context, cli *cli, userID string) ([]string, error) { currentUserRoleList, err := cli.api.User.Roles(ctx, userID, management.PerPage(100)) if err != nil { - return nil, fmt.Errorf("Failed to find the current roles for user with ID %q: %w.", userID, err) + return nil, fmt.Errorf("failed to read the current roles for user with ID %q: %w", userID, err) } var roleList *management.RoleList roleList, err = cli.api.Role.List(ctx) if err != nil { - return nil, fmt.Errorf("Failed to list all roles: %w.", err) + return nil, fmt.Errorf("failed to list all roles: %w", err) } if len(roleList.Roles) == len(currentUserRoleList.Roles) { - return nil, fmt.Errorf("The user with ID %q has all roles assigned already.", userID) + return nil, fmt.Errorf("the user with ID %q has all roles assigned already", userID) } var options []string @@ -311,7 +311,7 @@ func userRolesToAddPickerOptions(ctx context.Context, cli *cli, userID string) ( func userRolesToRemovePickerOptions(ctx context.Context, cli *cli, userID string) ([]string, error) { currentUserRoleList, err := cli.api.User.Roles(ctx, userID, management.PerPage(100)) if err != nil { - return nil, fmt.Errorf("Failed to find the current roles for user with ID %q: %w.", userID, err) + return nil, fmt.Errorf("failed to read the current roles for user with ID %q: %w", userID, err) } var options []string diff --git a/internal/cli/users_roles_test.go b/internal/cli/users_roles_test.go index 4554e650f..2bae3b9ff 100644 --- a/internal/cli/users_roles_test.go +++ b/internal/cli/users_roles_test.go @@ -132,7 +132,7 @@ func TestUserRolesToAddPickerOptions(t *testing.T) { t.Fail() }, assertError: func(t testing.TB, err error) { - assert.ErrorContains(t, err, "Failed to find the current roles for user with ID \"some-id\": error.") + assert.ErrorContains(t, err, "failed to read the current roles for user with ID \"some-id\": error") }, }, { @@ -142,7 +142,7 @@ func TestUserRolesToAddPickerOptions(t *testing.T) { t.Fail() }, assertError: func(t testing.TB, err error) { - assert.ErrorContains(t, err, "Failed to list all roles: error.") + assert.ErrorContains(t, err, "failed to list all roles: error") }, }, { @@ -172,7 +172,7 @@ func TestUserRolesToAddPickerOptions(t *testing.T) { t.Fail() }, assertError: func(t testing.TB, err error) { - assert.ErrorContains(t, err, "The user with ID \"some-id\" has all roles assigned already.") + assert.ErrorContains(t, err, "the user with ID \"some-id\" has all roles assigned already") }, }, } @@ -263,7 +263,7 @@ func TestUserRolesToRemovePickerOptions(t *testing.T) { t.Fail() }, assertError: func(t testing.TB, err error) { - assert.ErrorContains(t, err, "Failed to find the current roles for user with ID \"some-id\": error.") + assert.ErrorContains(t, err, "failed to read the current roles for user with ID \"some-id\": error") }, }, } diff --git a/internal/cli/utils_shared.go b/internal/cli/utils_shared.go index e18f129e7..2e31586dc 100644 --- a/internal/cli/utils_shared.go +++ b/internal/cli/utils_shared.go @@ -76,7 +76,9 @@ func runClientCredentialsFlow( if err != nil { return err } - defer response.Body.Close() + defer func() { + _ = response.Body.Close() + }() if err = json.NewDecoder(response.Body).Decode(&tokenResponse); err != nil { return fmt.Errorf("failed to decode the response: %w", err) @@ -154,7 +156,7 @@ func runLoginFlow(ctx context.Context, cli *cli, c *management.Client, connName, } } - // launch a HTTP server to wait for the callback to capture the auth + // Launch a HTTP server to wait for the callback to capture the auth // code. authCode, authState, err := authutil.WaitForBrowserCallback(cliLoginTestingCallbackAddr) if err != nil { @@ -165,7 +167,7 @@ func runLoginFlow(ctx context.Context, cli *cli, c *management.Client, connName, return fmt.Errorf("unexpected auth state") } - // once the callback is received, exchange the code for an access + // Once the callback is received, exchange the code for an access // token. tokenResponse, err = authutil.ExchangeCodeForToken( http.DefaultClient, @@ -179,12 +181,12 @@ func runLoginFlow(ctx context.Context, cli *cli, c *management.Client, connName, return fmt.Errorf("%w", err) } - // if we added the local callback URL to the client then we need to - // remove it when we're done + // If we added the local callback URL to the client then we need to + // remove it when we're done. defer func() { if callbackAdded { - if err := removeLocalCallbackURLFromClient(ctx, cli.api.Client, c); err != nil { // TODO: Make it a warning - cli.renderer.Errorf("Unable to remove callback URL '%s' from client: %s", cliLoginTestingCallbackURL, err) + if err := removeLocalCallbackURLFromClient(ctx, cli.api.Client, c); err != nil { // TODO: Make it a warning. + cli.renderer.Errorf("Failed to remove callback URL '%s' from client: %s", cliLoginTestingCallbackURL, err) } } }() @@ -218,8 +220,8 @@ func addLocalCallbackURLToClient(ctx context.Context, clientManager auth0.Client updatedClient := &management.Client{ Callbacks: &callbacks, } - // reflect the changes in the original client instance so when we check it - // later it has the proper values in Callbacks + // Reflect the changes in the original client instance so when we check it + // later it has the proper values in Callbacks. client.Callbacks = updatedClient.Callbacks return true, clientManager.Update(ctx, client.GetClientID(), updatedClient) } @@ -232,12 +234,12 @@ func removeLocalCallbackURLFromClient(ctx context.Context, clientManager auth0.C } } - // no callback URLs to remove, so don't attempt to do so + // No callback URLs to remove, so don't attempt to do so. if len(client.GetCallbacks()) == len(callbacks) { return nil } - // can't update a client to have 0 callback URLs, so don't attempt it + // Can't update a client to have 0 callback URLs, so don't attempt it. if len(callbacks) == 0 { return nil } @@ -273,7 +275,7 @@ func containsStr(s []string, u string) bool { func openManageURL(cli *cli, tenant string, path string) { manageTenantURL := formatManageTenantURL(tenant, &cli.Config) if len(manageTenantURL) == 0 || len(path) == 0 { - cli.renderer.Warnf("Unable to format the correct URL, please ensure you have run 'auth0 login' and try again.") + cli.renderer.Warnf("Failed to format the correct URL, please ensure you have run 'auth0 login' and try again.") return } @@ -301,7 +303,7 @@ func formatManageTenantURL(tenant string, cfg *config.Config) string { } var region string - if len(s) == 3 { // It's a PUS1 tenant, ex: dev-tti06f6y.auth0.com + if len(s) == 3 { // It's a PUS1 tenant, ex: dev-tti06f6y.auth0.com. region = "us" } else { region = s[len(s)-3] diff --git a/internal/config/config.go b/internal/config/config.go index 7fcb4685b..8c1e7ebdb 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -17,7 +17,7 @@ import ( var ErrConfigFileMissing = errors.New("config.json file is missing") // ErrNoAuthenticatedTenants is thrown when the config file has no authenticated tenants. -var ErrNoAuthenticatedTenants = errors.New("Not logged in. Try `auth0 login`.") +var ErrNoAuthenticatedTenants = errors.New("not logged in. Try `auth0 login`") // Config holds cli configuration settings. type Config struct { diff --git a/internal/config/config_test.go b/internal/config/config_test.go index 667fc2024..ac381a752 100644 --- a/internal/config/config_test.go +++ b/internal/config/config_test.go @@ -805,7 +805,7 @@ func TestConfig_Validate(t *testing.T) { config := &Config{path: tempFile} err := config.Validate() - assert.EqualError(t, err, "Not logged in. Try `auth0 login`.") + assert.EqualError(t, err, "not logged in. Try `auth0 login`") }) t.Run("it fixes the default tenant if there are tenant entries and the default is empty", func(t *testing.T) { diff --git a/internal/display/actions.go b/internal/display/actions.go index ee3e7c303..3b055ea8a 100644 --- a/internal/display/actions.go +++ b/internal/display/actions.go @@ -137,7 +137,7 @@ func actionStatus(v string) string { return ansi.Blue(v) case "built": return ansi.Green(v) - default: // including "unspecified" + default: // Including "unspecified". return v } } diff --git a/internal/display/apis.go b/internal/display/apis.go index 581c318a4..25177bd89 100644 --- a/internal/display/apis.go +++ b/internal/display/apis.go @@ -185,7 +185,7 @@ func makeScopeView(scope management.ResourceServerScope) *scopeView { func getScopes(scopes []management.ResourceServerScope) (string, bool) { ellipsis := "..." separator := " " - padding := 22 // the longest apiView key plus two spaces before and after in the label column + padding := 22 // The longest apiView key plus two spaces before and after in the label column. terminalWidth, _, err := term.GetSize(int(iostream.Input.Fd())) if err != nil { terminalWidth = 80 @@ -197,7 +197,7 @@ func getScopes(scopes []management.ResourceServerScope) (string, bool) { for i, scope := range scopes { prepend := separator - // no separator prepended for first value + // No separator prepended for first value. if i == 0 { prepend = "" } diff --git a/internal/display/display.go b/internal/display/display.go index afce4d393..2c187ca90 100644 --- a/internal/display/display.go +++ b/internal/display/display.go @@ -23,13 +23,13 @@ type OutputFormat string type Renderer struct { Tenant string - // MessageWriter receives the renderer messages (typically os.Stderr) + // MessageWriter receives the renderer messages (typically os.Stderr). MessageWriter io.Writer - // ResultWriter writes the final result of the commands (typically os.Stdout which can be piped to other commands) + // ResultWriter writes the final result of the commands (typically os.Stdout which can be piped to other commands). ResultWriter io.Writer - // Format indicates how the results are rendered. Default (empty) will write as table + // Format indicates how the results are rendered. Default (empty) will write as table. Format OutputFormat } diff --git a/internal/display/rules.go b/internal/display/rules.go index 83bb9a3c4..62c5d7e70 100644 --- a/internal/display/rules.go +++ b/internal/display/rules.go @@ -54,7 +54,7 @@ func (r *Renderer) RulesList(rules []*management.Rule) { var res []View - // @TODO Provide sort options via flags + // @TODO Provide sort options via flags. sort.Slice(rules, func(i, j int) bool { return rules[i].GetOrder() < rules[j].GetOrder() }) diff --git a/internal/keyring/keyring.go b/internal/keyring/keyring.go index 9973351ee..6a946eca4 100644 --- a/internal/keyring/keyring.go +++ b/internal/keyring/keyring.go @@ -89,7 +89,7 @@ func GetAccessToken(tenant string) (string, error) { for i := 0; i < secretAccessTokenMaxChunks; i++ { a, err := keyring.Get(fmt.Sprintf("%s %d", secretAccessToken, i), tenant) // Only return if we have pulled more than 1 item from the keyring, otherwise this will be - // a valid "secret not found in keyring" + // a valid "secret not found in keyring". if err == keyring.ErrNotFound && i > 0 { return accessToken, nil } @@ -107,8 +107,8 @@ func chunk(slice string, chunkSize int) []string { for i := 0; i < len(slice); i += chunkSize { end := i + chunkSize - // necessary check to avoid slicing beyond - // slice capacity + // Necessary check to avoid slicing beyond + // slice capacity. if end > len(slice) { end = len(slice) } diff --git a/internal/keyring/keyring_test.go b/internal/keyring/keyring_test.go index ffb952809..949dd9d18 100644 --- a/internal/keyring/keyring_test.go +++ b/internal/keyring/keyring_test.go @@ -78,7 +78,7 @@ func TestSecrets(t *testing.T) { t.Run("it successfully stores an access token", func(t *testing.T) { keyring.MockInit() - expectedAccessToken := randomStringOfLength((2048 * 5) + 1) // Some arbitrarily long random string + expectedAccessToken := randomStringOfLength((2048 * 5) + 1) // Some arbitrarily long random string. err := StoreAccessToken(testTenantName, expectedAccessToken) assert.NoError(t, err) @@ -105,8 +105,8 @@ func TestSecrets(t *testing.T) { t.Run("it successfully deletes all secrets for a tenant", func(t *testing.T) { keyring.MockInit() - // Store keys and check they were set - expectedAccessToken := randomStringOfLength((2048 * 5) + 1) // Some arbitrarily long random string + // Store keys and check they were set. + expectedAccessToken := randomStringOfLength((2048 * 5) + 1) // Some arbitrarily long random string. err := StoreAccessToken(testTenantName, expectedAccessToken) assert.NoError(t, err) actualAccessToken, err := GetAccessToken(testTenantName) @@ -130,7 +130,7 @@ func TestSecrets(t *testing.T) { err = DeleteSecretsForTenant(testTenantName) assert.NoError(t, err) - // Assert that values were deleted + // Assert that values were deleted. actualAccessToken, err = GetAccessToken(testTenantName) assert.EqualError(t, err, keyring.ErrNotFound.Error()) assert.Equal(t, "", actualAccessToken) diff --git a/internal/prompt/editor.go b/internal/prompt/editor.go index 23795cd40..153601ad7 100644 --- a/internal/prompt/editor.go +++ b/internal/prompt/editor.go @@ -81,7 +81,9 @@ func (p *editorPrompt) captureInput(contents []byte, pattern string, infoFn func if err != nil { return []byte{}, err } - defer os.Remove(dir) + defer func() { + _ = os.Remove(dir) + }() file, err := os.CreateTemp(dir, pattern) if err != nil { @@ -95,9 +97,11 @@ func (p *editorPrompt) captureInput(contents []byte, pattern string, infoFn func } // Defer removal of the temporary file in case any of the next steps fail. - defer os.Remove(filename) + defer func() { + _ = os.Remove(filename) + }() - // write utf8 BOM header + // Write utf8 BOM header // The reason why we do this is because notepad.exe on Windows determines the // encoding of an "empty" text file by the locale, for example, GBK in China, // while golang string only handles utf8 well. However, a text file with utf8 @@ -109,7 +113,7 @@ func (p *editorPrompt) captureInput(contents []byte, pattern string, infoFn func if len(contents) > 0 { if _, err := file.Write(contents); err != nil { - return nil, fmt.Errorf("Failed to write to file: %w", err) + return nil, fmt.Errorf("failed to write to file: %w", err) } } @@ -126,7 +130,7 @@ func (p *editorPrompt) captureInput(contents []byte, pattern string, infoFn func return []byte{}, err } - // strip BOM header + // Strip BOM header. return bytes.TrimPrefix(raw, bom), nil } diff --git a/internal/prompt/prompt.go b/internal/prompt/prompt.go index 2d2598962..2e81c6c9e 100644 --- a/internal/prompt/prompt.go +++ b/internal/prompt/prompt.go @@ -87,7 +87,7 @@ func BoolInput(name string, message string, help string, defaultValue bool, requ } func SelectInput(name string, message string, help string, options []string, defaultValue string, required bool) *survey.Question { - // force options "page" size to full, + // Force options "page" size to full, // since there's not visual clue about extra options. pageSize := len(options) input := &survey.Question{ diff --git a/internal/prompt/surveyext.go b/internal/prompt/surveyext.go index c44e3fa9b..8c7026be1 100644 --- a/internal/prompt/surveyext.go +++ b/internal/prompt/surveyext.go @@ -48,7 +48,7 @@ type EditorTemplateData struct { func (e *Editor) prompt(initialValue string, config *survey.PromptConfig) (interface{}, error) { err := e.Render( EditorQuestionTemplate, - // EXTENDED to support printing editor in prompt and BlankAllowed + // EXTENDED to support printing editor in prompt and BlankAllowed. EditorTemplateData{ Editor: *e.Editor, BlankAllowed: e.BlankAllowed, @@ -60,7 +60,7 @@ func (e *Editor) prompt(initialValue string, config *survey.PromptConfig) (inter return "", err } - // start reading runes from the standard in + // Start reading runes from the standard in. rr := e.NewRuneReader() _ = rr.SetTermMode() defer func() { _ = rr.RestoreTermMode() }() @@ -73,7 +73,7 @@ func (e *Editor) prompt(initialValue string, config *survey.PromptConfig) (inter }() for { - // EXTENDED to handle the e to edit / enter to skip behavior + BlankAllowed + // EXTENDED to handle the e to edit / enter to skip behavior + BlankAllowed. r, _, err := rr.ReadRune() if err != nil { return "", err @@ -97,7 +97,7 @@ func (e *Editor) prompt(initialValue string, config *survey.PromptConfig) (inter err = e.Render( EditorQuestionTemplate, EditorTemplateData{ - // EXTENDED to support printing editor in prompt, BlankAllowed + // EXTENDED to support printing editor in prompt, BlankAllowed. Editor: *e.Editor, BlankAllowed: e.BlankAllowed, EditorCommand: filepath.Base(e.editorCommand()), @@ -117,7 +117,7 @@ func (e *Editor) prompt(initialValue string, config *survey.PromptConfig) (inter return "", err } - // check length, return default value on empty + // Check length, return default value on empty. if len(text) == 0 && !e.AppendDefault { return e.Default, nil } diff --git a/test/integration/api-test-cases.yaml b/test/integration/api-test-cases.yaml index 538632041..f414effc5 100644 --- a/test/integration/api-test-cases.yaml +++ b/test/integration/api-test-cases.yaml @@ -43,14 +43,14 @@ tests: exit-code: 1 stderr: contains: - - "failed to parse command inputs: invalid json data given" + - "Failed to parse command inputs: invalid json data given" 007 - it fails to use the api command if an invalid method is given: command: auth0 api conquer "tenants/settings" exit-code: 1 stderr: contains: - - "failed to parse command inputs: invalid method given" + - "Failed to parse command inputs: invalid method given" 008 - it throws a warning when both piped data and the data flag are present: command: cat ./test/integration/fixtures/update-tenant-settings.json | auth0 api patch "tenants/settings" --data "{\"idle_session_lifetime\":72}" diff --git a/test/integration/apis-test-cases.yaml b/test/integration/apis-test-cases.yaml index 780c0932a..e499c636d 100644 --- a/test/integration/apis-test-cases.yaml +++ b/test/integration/apis-test-cases.yaml @@ -19,7 +19,7 @@ tests: exit-code: 1 stderr: contains: - - number flag invalid, please pass a number between 1 and 1000 + - Number flag invalid, please pass a number between 1 and 1000 003 - apis create and check data: command: auth0 apis create --name integration-test-api-def1 --identifier http://integration-test-api-def1 --scopes read:todos,write:todos --signing-alg RS256 --json diff --git a/test/integration/apps-test-cases.yaml b/test/integration/apps-test-cases.yaml index 616d9a943..3111567cd 100644 --- a/test/integration/apps-test-cases.yaml +++ b/test/integration/apps-test-cases.yaml @@ -17,7 +17,7 @@ tests: exit-code: 1 stderr: contains: - - "number flag invalid, please pass a number between 1 and 1000" + - "Number flag invalid, please pass a number between 1 and 1000" 003 - it successfully creates a native app: command: auth0 apps create --name integration-test-app-nativeapp1 --type native --description NativeApp1 @@ -76,7 +76,7 @@ tests: exit-code: 1 stderr: contains: - - "Unable to create application" + - "Failed to create application" 010 - it successfully creates a regular app with auth method set to post and outputs in json: command: auth0 apps create --name integration-test-app-regapp2 --type regular --description RegApp2 --auth-method Post --json @@ -132,7 +132,7 @@ tests: exit-code: 1 stderr: contains: - - "Unable to create application" + - "Failed to create application" 018 - it successfully creates a native app with logout urls and outputs in json: command: auth0 apps create --name integration-test-app-regapp6 --type native --description RegularApp --logout-urls https://*.example.com/logout,https://example.com/logout --json diff --git a/test/integration/custom-domains-test-cases.yaml b/test/integration/custom-domains-test-cases.yaml index 2118aa158..42e48e88d 100644 --- a/test/integration/custom-domains-test-cases.yaml +++ b/test/integration/custom-domains-test-cases.yaml @@ -32,7 +32,7 @@ tests: exit-code: 1 stderr: contains: - - "An unexpected error occurred while attempting to create the custom domain 'custom-domain.com': 409 Conflict: The specified custom domain already exists" + - "Failed to create custom domain \"custom-domain.com\": 409 Conflict: The specified custom domain already exists" 005 - show domain: command: auth0 domains show $(./test/integration/scripts/get-custom-domain-id.sh) --no-input diff --git a/test/integration/logs-test-cases.yaml b/test/integration/logs-test-cases.yaml index 64408610b..eeacf45ea 100644 --- a/test/integration/logs-test-cases.yaml +++ b/test/integration/logs-test-cases.yaml @@ -29,14 +29,14 @@ tests: exit-code: 1 stderr: contains: - - "number flag invalid, please pass a number between 1 and 1000" + - "Number flag invalid, please pass a number between 1 and 1000" 005 - it errors because of invalid number arg: command: auth0 logs list --number 1001 --json exit-code: 1 stderr: contains: - - "number flag invalid, please pass a number between 1 and 1000" + - "Number flag invalid, please pass a number between 1 and 1000" 006 - it successfully lists all log streams with no data: command: auth0 logs streams list diff --git a/test/integration/organizations-test-cases.yaml b/test/integration/organizations-test-cases.yaml index e8148be99..6f209f450 100644 --- a/test/integration/organizations-test-cases.yaml +++ b/test/integration/organizations-test-cases.yaml @@ -22,7 +22,7 @@ tests: exit-code: 1 stderr: contains: - - number flag invalid, please pass a number between 1 and 1000 + - Number flag invalid, please pass a number between 1 and 1000 004 - create organization and check json output: command: auth0 orgs create --name integration-test-org-new --display "Integration Test Organization" --json --no-input @@ -49,7 +49,7 @@ tests: exit-code: 1 stderr: contains: - - failed to create an organization with name 'integration-test-org-new2' + - Failed to create organization with name "integration-test-org-new2" 007 - list organizations with data: command: auth0 orgs list @@ -81,7 +81,7 @@ tests: exit-code: 1 stderr: contains: - - "Unable to get an organization with ID 'this-org-id-does-not-exist'" + - "Failed to read organization with ID \"this-org-id-does-not-exist\"" 011 - update organization with minimal flags: command: auth0 orgs update $(./test/integration/scripts/get-org-id.sh) --no-input @@ -151,7 +151,7 @@ tests: exit-code: 1 stderr: contains: - - number flag invalid, please pass a number between 1 and 1000 + - Number flag invalid, please pass a number between 1 and 1000 config: retries: 3 @@ -164,7 +164,7 @@ tests: exit-code: 1 stderr: contains: - - number flag invalid, please pass a number between 1 and 1000 + - Number flag invalid, please pass a number between 1 and 1000 021 - list organization roles members: command: auth0 orgs roles members list $(./test/integration/scripts/get-org-id.sh) @@ -175,4 +175,4 @@ tests: exit-code: 1 stderr: contains: - - number flag invalid, please pass a number between 1 and 1000 + - Number flag invalid, please pass a number between 1 and 1000 diff --git a/test/integration/roles-test-cases.yaml b/test/integration/roles-test-cases.yaml index c8fa9fbcf..bfa3a6b1c 100644 --- a/test/integration/roles-test-cases.yaml +++ b/test/integration/roles-test-cases.yaml @@ -47,7 +47,7 @@ tests: exit-code: 1 stderr: contains: - - number flag invalid, please pass a number between 1 and 1000 + - Number flag invalid, please pass a number between 1 and 1000 007 - roles show json: command: auth0 roles show $(./test/integration/scripts/get-role-id.sh) --json @@ -97,7 +97,7 @@ tests: exit-code: 1 stderr: contains: - - number flag invalid, please pass a number between 1 and 1000 + - Number flag invalid, please pass a number between 1 and 1000 014 - add role permissions: command: auth0 roles permissions add $(./test/integration/scripts/get-role-id.sh) --api-id $(./test/integration/scripts/get-api-id.sh) --permissions read:todos diff --git a/test/integration/terraform-test-cases.yaml b/test/integration/terraform-test-cases.yaml index 132929a0b..5b1490fcc 100644 --- a/test/integration/terraform-test-cases.yaml +++ b/test/integration/terraform-test-cases.yaml @@ -63,11 +63,11 @@ tests: exit-code: 1 stderr: contains: - - "unsupported resource type: auth0_computer" + - "Unsupported resource type: auth0_computer" 005 - it errors if AUTH0_DOMAIN values for provider and CLI do not match: command: AUTH0_DOMAIN=some-other-domain.us.auth0.com auth0 tf generate --output-dir tmp-tf-gen exit-code: 1 stderr: contains: - - "Terraform provider tenant domain 'some-other-domain.us.auth0.com' does not match current CLI tenant '" + - "Terraform provider tenant domain \"some-other-domain.us.auth0.com\" does not match current CLI tenant" diff --git a/test/integration/test-commands-test-cases.yaml b/test/integration/test-commands-test-cases.yaml index 50b8fb768..a2c63421d 100644 --- a/test/integration/test-commands-test-cases.yaml +++ b/test/integration/test-commands-test-cases.yaml @@ -19,14 +19,14 @@ tests: exit-code: 1 stderr: contains: - - "cannot test the Universal Login with a Machine to Machine application." + - "Cannot test the Universal Login with a Machine to Machine application." 003 - test token without client grant: command: auth0 test token $(./test/integration/scripts/get-m2m-app-id.sh) --audience "$(./test/integration/scripts/get-manage-api-audience.sh)" --no-input exit-code: 1 stderr: contains: - - "failed to log in with client credentials for client with ID " + - "Failed to log in with client credentials for client with ID " - "the integration-test-app-m2m application is not authorized to request access tokens for this API " - ".auth0.com/api/v2/." diff --git a/test/integration/universal-login-test-cases.yaml b/test/integration/universal-login-test-cases.yaml index 8b06d72d3..2c6ae4fd1 100644 --- a/test/integration/universal-login-test-cases.yaml +++ b/test/integration/universal-login-test-cases.yaml @@ -84,7 +84,7 @@ tests: exit-code: 1 stderr: contains: - - "failed to fetch the Universal Login template data: this feature requires at least one custom domain to be set and verified for the tenant, use 'auth0 domains create' to create one and 'auth0 domains verify' to have it verified" + - "Failed to fetch the Universal Login template data: this feature requires at least one custom domain to be set and verified for the tenant, use 'auth0 domains create' to create one and 'auth0 domains verify' to have it verified" 010 - update universal login branding prompts (login): command: cat ./test/integration/fixtures/update-ul-prompts-login.json | auth0 ul prompts update login diff --git a/test/integration/users-test-cases.yaml b/test/integration/users-test-cases.yaml index 55792066a..f4afc4376 100644 --- a/test/integration/users-test-cases.yaml +++ b/test/integration/users-test-cases.yaml @@ -50,7 +50,7 @@ tests: exit-code: 1 stderr: contains: - - number flag invalid, please pass a number between 1 and 1000 + - Number flag invalid, please pass a number between 1 and 1000 007 - users update minimal flags: command: auth0 users update $(./test/integration/scripts/get-user-id.sh) --json --no-input @@ -93,7 +93,7 @@ tests: exit-code: 1 stderr: contains: - - number flag invalid, please pass a number between 1 and 1000 + - Number flag invalid, please pass a number between 1 and 1000 013 - users roles add: command: auth0 users roles add $(./test/integration/scripts/get-user-id.sh) -r $(./test/integration/scripts/get-role-id.sh) From a87580da7189b818dbc13704c8f41498acc799a5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 19 Dec 2023 12:08:01 +0100 Subject: [PATCH 10/19] Bump golang.org/x/crypto from 0.16.0 to 0.17.0 (#947) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/go.mod b/go.mod index 7a8ef704a..6c0289861 100644 --- a/go.mod +++ b/go.mod @@ -89,7 +89,7 @@ require ( github.com/yuin/goldmark v1.5.2 // indirect github.com/yuin/goldmark-emoji v1.0.1 // indirect github.com/zclconf/go-cty v1.14.0 // indirect - golang.org/x/crypto v0.16.0 // indirect + golang.org/x/crypto v0.17.0 // indirect golang.org/x/mod v0.14.0 // indirect golang.org/x/tools v0.13.0 // indirect google.golang.org/appengine v1.6.7 // indirect diff --git a/go.sum b/go.sum index 5d488879e..9fb10589c 100644 --- a/go.sum +++ b/go.sum @@ -249,8 +249,9 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= -golang.org/x/crypto v0.16.0 h1:mMMrFzRSCF0GvB7Ne27XVtVAaXLrPmgPC7/v0tkwHaY= golang.org/x/crypto v0.16.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= +golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k= +golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= golang.org/x/exp v0.0.0-20230321023759-10a507213a29 h1:ooxPy7fPvB4kwsA2h+iBNHkAbp/4JxTSwCmvdjEYmug= golang.org/x/exp v0.0.0-20230321023759-10a507213a29/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= From a6e3565883f02fb53a07dd10e7508d60ed8e5283 Mon Sep 17 00:00:00 2001 From: Michael Christenson II Date: Wed, 20 Dec 2023 11:47:10 -0500 Subject: [PATCH 11/19] Ignore err for adding steps to the ProgressBar This is a specific error, internal to the developer and not of use to the user --- internal/ansi/progress.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/ansi/progress.go b/internal/ansi/progress.go index cde1be499..a9e252bbd 100644 --- a/internal/ansi/progress.go +++ b/internal/ansi/progress.go @@ -19,7 +19,7 @@ func ProgressBar[T comparable](desc string, items []T, fn func(int, T) error) er bar := progressbar.Default(int64(len(items)), desc) var errs []error for i, item := range items { - bar.Add(1) + _ = bar.Add(1) if err := fn(i, item); err != nil { errs = append(errs, err) } From ba1bf27ca8edc2a3b3f67d2b4ae6b8100283f072 Mon Sep 17 00:00:00 2001 From: Michael Christenson II Date: Thu, 21 Dec 2023 13:10:22 -0500 Subject: [PATCH 12/19] Organize imports --- internal/ansi/progress.go | 1 + 1 file changed, 1 insertion(+) diff --git a/internal/ansi/progress.go b/internal/ansi/progress.go index a9e252bbd..37ddd3d9d 100644 --- a/internal/ansi/progress.go +++ b/internal/ansi/progress.go @@ -2,6 +2,7 @@ package ansi import ( "errors" + "github.com/schollz/progressbar/v3" ) From d588b4fb924e83388620574afbf0e27fe7319636 Mon Sep 17 00:00:00 2001 From: Michael Christenson II Date: Thu, 21 Dec 2023 13:15:32 -0500 Subject: [PATCH 13/19] Improve error messages in APIs --- internal/cli/apis.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/internal/cli/apis.go b/internal/cli/apis.go index df916c999..cff67d867 100644 --- a/internal/cli/apis.go +++ b/internal/cli/apis.go @@ -447,11 +447,11 @@ func deleteAPICmd(cli *cli) *cobra.Command { return ansi.ProgressBar("Deleting API(s)", ids, func(_ int, id string) error { if _, err := cli.api.ResourceServer.Read(cmd.Context(), url.PathEscape(id)); err != nil { - return fmt.Errorf("failed to delete API (%s): %w", id, err) + return fmt.Errorf("failed to delete API with ID %q: %w", id, err) } if err := cli.api.ResourceServer.Delete(cmd.Context(), url.PathEscape(id)); err != nil { - return fmt.Errorf("failed to delete API (%s): %w", id, err) + return fmt.Errorf("failed to delete API with ID %q: %w", id, err) } return nil }) From 070b652d1fa21dc46486180e5a4a1627a998b4d4 Mon Sep 17 00:00:00 2001 From: Michael Christenson II Date: Thu, 21 Dec 2023 13:18:03 -0500 Subject: [PATCH 14/19] Add documentation comment for ProgressBar Co-authored-by: Sergiu Ghitea <28300158+sergiught@users.noreply.github.com> --- internal/ansi/progress.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/ansi/progress.go b/internal/ansi/progress.go index 37ddd3d9d..0fb26e639 100644 --- a/internal/ansi/progress.go +++ b/internal/ansi/progress.go @@ -5,7 +5,7 @@ import ( "github.com/schollz/progressbar/v3" ) - +// ProgressBar will display progress indication for the given items. func ProgressBar[T comparable](desc string, items []T, fn func(int, T) error) error { switch len(items) { case 0: From 8f759cf7918474e44d0ecdb861c18e5a812ef5d9 Mon Sep 17 00:00:00 2001 From: Michael Christenson II Date: Thu, 21 Dec 2023 13:29:05 -0500 Subject: [PATCH 15/19] Normalize delete error messages --- internal/cli/actions.go | 4 +++- internal/cli/apps.go | 4 ++-- internal/cli/custom_domains.go | 4 ++-- internal/cli/log_streams.go | 4 ++-- internal/cli/organizations.go | 4 ++-- internal/cli/roles.go | 4 ++-- internal/cli/rules.go | 4 ++-- internal/cli/users.go | 4 ++-- 8 files changed, 17 insertions(+), 15 deletions(-) diff --git a/internal/cli/actions.go b/internal/cli/actions.go index 89d9654a6..c0c2f7e5c 100644 --- a/internal/cli/actions.go +++ b/internal/cli/actions.go @@ -393,7 +393,9 @@ func deleteActionCmd(cli *cli) *cobra.Command { return ansi.ProgressBar("Deleting action(s)", ids, func(i int, id string) error { if id != "" { - return cli.api.Action.Delete(cmd.Context(), id) + if err := cli.api.Action.Delete(cmd.Context(), id); err != nil { + return fmt.Errorf("failed to delete Action with ID %q: %w", id, err) + } } return nil }) diff --git a/internal/cli/apps.go b/internal/cli/apps.go index 10bd601ca..c60483378 100644 --- a/internal/cli/apps.go +++ b/internal/cli/apps.go @@ -350,11 +350,11 @@ func deleteAppCmd(cli *cli) *cobra.Command { return ansi.ProgressBar("Deleting Application(s)", ids, func(_ int, id string) error { if id != "" { if _, err := cli.api.Client.Read(cmd.Context(), id); err != nil { - return fmt.Errorf("failed to delete application (%s): %w", id, err) + return fmt.Errorf("failed to delete application with ID %q: %w", id, err) } if err := cli.api.Client.Delete(cmd.Context(), id); err != nil { - return fmt.Errorf("failed to delete application (%s): %w", id, err) + return fmt.Errorf("failed to delete application with ID %q: %w", id, err) } } return nil diff --git a/internal/cli/custom_domains.go b/internal/cli/custom_domains.go index 18ba9cdbe..d21f75b63 100644 --- a/internal/cli/custom_domains.go +++ b/internal/cli/custom_domains.go @@ -350,11 +350,11 @@ func deleteCustomDomainCmd(cli *cli) *cobra.Command { return ansi.ProgressBar("Deleting custom domain", ids, func(_ int, id string) error { if id != "" { if _, err := cli.api.CustomDomain.Read(cmd.Context(), url.PathEscape(id)); err != nil { - return fmt.Errorf("failed to delete custom domain (%s): %w", id, err) + return fmt.Errorf("failed to delete custom domain with ID %q: %w", id, err) } if err := cli.api.CustomDomain.Delete(cmd.Context(), url.PathEscape(id)); err != nil { - return fmt.Errorf("failed to delete custom domain (%s): %w", id, err) + return fmt.Errorf("failed to delete custom domain with ID %q: %w", id, err) } } return nil diff --git a/internal/cli/log_streams.go b/internal/cli/log_streams.go index 769fd1f2c..6fab1292f 100644 --- a/internal/cli/log_streams.go +++ b/internal/cli/log_streams.go @@ -202,10 +202,10 @@ func deleteLogStreamCmd(cli *cli) *cobra.Command { return ansi.ProgressBar("Deleting Log Stream(s)", ids, func(_ int, id string) error { if id != "" { if _, err := cli.api.LogStream.Read(cmd.Context(), id); err != nil { - return fmt.Errorf("failed to delete log stream (%s): %w", id, err) + return fmt.Errorf("failed to delete log stream with ID %q: %w", id, err) } if err := cli.api.LogStream.Delete(cmd.Context(), id); err != nil { - return fmt.Errorf("failed to delete log stream (%s): %w", id, err) + return fmt.Errorf("failed to delete log stream with ID %q: %w", id, err) } } return nil diff --git a/internal/cli/organizations.go b/internal/cli/organizations.go index 21a5650e3..163338a1f 100644 --- a/internal/cli/organizations.go +++ b/internal/cli/organizations.go @@ -439,11 +439,11 @@ func deleteOrganizationCmd(cli *cli) *cobra.Command { return ansi.ProgressBar("Deleting organization(s)", ids, func(_ int, id string) error { if _, err := cli.api.Organization.Read(cmd.Context(), id); err != nil { - return fmt.Errorf("failed to delete organization (%s): %w", id, err) + return fmt.Errorf("failed to delete organization with ID %q: %w", id, err) } if err := cli.api.Organization.Delete(cmd.Context(), id); err != nil { - return fmt.Errorf("failed to delete organization (%s): %w", id, err) + return fmt.Errorf("failed to delete organization with ID %q: %w", id, err) } return nil }) diff --git a/internal/cli/roles.go b/internal/cli/roles.go index 20583f454..b15c9dbcf 100644 --- a/internal/cli/roles.go +++ b/internal/cli/roles.go @@ -309,11 +309,11 @@ func deleteRoleCmd(cli *cli) *cobra.Command { return ansi.ProgressBar("Deleting Role(s)", ids, func(_ int, id string) error { if id != "" { if _, err := cli.api.Role.Read(cmd.Context(), id); err != nil { - return fmt.Errorf("failed to delete role (%s): %w", id, err) + return fmt.Errorf("failed to delete role with ID %q: %w", id, err) } if err := cli.api.Role.Delete(cmd.Context(), id); err != nil { - return fmt.Errorf("failed to delete role (%s): %w", id, err) + return fmt.Errorf("failed to delete role with ID %q: %w", id, err) } } return nil diff --git a/internal/cli/rules.go b/internal/cli/rules.go index 5576c8c7b..046cd91ba 100644 --- a/internal/cli/rules.go +++ b/internal/cli/rules.go @@ -284,11 +284,11 @@ func deleteRuleCmd(cli *cli) *cobra.Command { return ansi.ProgressBar("Deleting Rule(s)", ids, func(_ int, id string) error { if id != "" { if _, err := cli.api.Rule.Read(cmd.Context(), id); err != nil { - return fmt.Errorf("failed to delete rule (%s): %w", id, err) + return fmt.Errorf("failed to delete rule with ID %q: %w", id, err) } if err := cli.api.Rule.Delete(cmd.Context(), id); err != nil { - return fmt.Errorf("failed to delete rule (%s): %w", id, err) + return fmt.Errorf("failed to delete rule with ID %q: %w", id, err) } } return nil diff --git a/internal/cli/users.go b/internal/cli/users.go index 4485b00af..a0498e21b 100644 --- a/internal/cli/users.go +++ b/internal/cli/users.go @@ -395,11 +395,11 @@ func deleteUserCmd(cli *cli) *cobra.Command { return ansi.ProgressBar("Deleting user(s)", ids, func(_ int, id string) error { if id != "" { if _, err := cli.api.User.Read(cmd.Context(), id); err != nil { - return fmt.Errorf("failed to delete user (%s): %w", id, err) + return fmt.Errorf("failed to delete user with ID %q: %w", id, err) } if err := cli.api.User.Delete(cmd.Context(), id); err != nil { - return fmt.Errorf("failed to delete user (%s): %w", id, err) + return fmt.Errorf("failed to delete user with ID %q: %w", id, err) } } return nil From 2c258c3962573a06f343109871b72537757649b9 Mon Sep 17 00:00:00 2001 From: Michael Christenson II Date: Thu, 21 Dec 2023 13:31:40 -0500 Subject: [PATCH 16/19] Discard duplicate path escape --- internal/cli/apis.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/internal/cli/apis.go b/internal/cli/apis.go index cff67d867..9775fe79b 100644 --- a/internal/cli/apis.go +++ b/internal/cli/apis.go @@ -446,11 +446,11 @@ func deleteAPICmd(cli *cli) *cobra.Command { } return ansi.ProgressBar("Deleting API(s)", ids, func(_ int, id string) error { - if _, err := cli.api.ResourceServer.Read(cmd.Context(), url.PathEscape(id)); err != nil { + if _, err := cli.api.ResourceServer.Read(cmd.Context(), id); err != nil { return fmt.Errorf("failed to delete API with ID %q: %w", id, err) } - if err := cli.api.ResourceServer.Delete(cmd.Context(), url.PathEscape(id)); err != nil { + if err := cli.api.ResourceServer.Delete(cmd.Context(), id); err != nil { return fmt.Errorf("failed to delete API with ID %q: %w", id, err) } return nil From ca57dfde97ab6191a5ac63291c1db7eef7b49eaf Mon Sep 17 00:00:00 2001 From: Michael Christenson II Date: Thu, 21 Dec 2023 13:38:40 -0500 Subject: [PATCH 17/19] Revert data file --- internal/cli/data/universal-login/assets/index-89540052.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/cli/data/universal-login/assets/index-89540052.js b/internal/cli/data/universal-login/assets/index-89540052.js index c512fa07a..f54ecc8ea 100644 --- a/internal/cli/data/universal-login/assets/index-89540052.js +++ b/internal/cli/data/universal-login/assets/index-89540052.js @@ -9363,7 +9363,7 @@ function encode_char(c) { return _ENCODE_HTML_RULES[c] || c; }; `;e.escapeXML=function(g){return g==null?"":String(g).replace(i,r)};function p(){return Function.prototype.toString.call(this)+`; -`+c}try{typeof Object.defineProperty=="function"?Object.defineProperty(e.escapeXML,"toString",{value:p}):e.escapeXML.toString=p}catch{console.warn("Failed to set escapeXML.toString (is the Function prototype frozen?)")}e.shallowCopy=function(g,h){if(h=h||{},g!=null)for(var b in h)a(h,b)&&(b==="__proto__"||b==="constructor"||(g[b]=h[b]));return g},e.shallowCopyFromList=function(g,h,b){if(b=b||[],h=h||{},g!=null)for(var y=0;y (http://fleegix.org)",Cct="Apache-2.0",Bct={ejs:"./bin/cli.js"},Mct="./lib/ejs.js",Lct="ejs.min.js",Ict="ejs.min.js",Rct={type:"git",url:"git://github.com/mde/ejs.git"},Fct="https://github.com/mde/ejs/issues",Dct="https://github.com/mde/ejs",Vct={jake:"^10.8.5"},Uct={browserify:"^16.5.1",eslint:"^6.8.0","git-directory-deploy":"^1.5.1",jsdoc:"^4.0.2","lru-cache":"^4.0.1",mocha:"^10.2.0","uglify-js":"^3.3.16"},Kct={node:">=0.10.0"},Gct={test:"mocha -u tdd"},qct={name:zct,description:Pct,keywords:Sct,version:Ect,author:Oct,license:Cct,bin:Bct,main:Mct,jsdelivr:Lct,unpkg:Ict,repository:Rct,bugs:Fct,homepage:Dct,dependencies:Vct,devDependencies:Uct,engines:Kct,scripts:Gct};(function(e){/** +`+c}try{typeof Object.defineProperty=="function"?Object.defineProperty(e.escapeXML,"toString",{value:p}):e.escapeXML.toString=p}catch{console.warn("Unable to set escapeXML.toString (is the Function prototype frozen?)")}e.shallowCopy=function(g,h){if(h=h||{},g!=null)for(var b in h)a(h,b)&&(b==="__proto__"||b==="constructor"||(g[b]=h[b]));return g},e.shallowCopyFromList=function(g,h,b){if(b=b||[],h=h||{},g!=null)for(var y=0;y (http://fleegix.org)",Cct="Apache-2.0",Bct={ejs:"./bin/cli.js"},Mct="./lib/ejs.js",Lct="ejs.min.js",Ict="ejs.min.js",Rct={type:"git",url:"git://github.com/mde/ejs.git"},Fct="https://github.com/mde/ejs/issues",Dct="https://github.com/mde/ejs",Vct={jake:"^10.8.5"},Uct={browserify:"^16.5.1",eslint:"^6.8.0","git-directory-deploy":"^1.5.1",jsdoc:"^4.0.2","lru-cache":"^4.0.1",mocha:"^10.2.0","uglify-js":"^3.3.16"},Kct={node:">=0.10.0"},Gct={test:"mocha -u tdd"},qct={name:zct,description:Pct,keywords:Sct,version:Ect,author:Oct,license:Cct,bin:Bct,main:Mct,jsdelivr:Lct,unpkg:Ict,repository:Rct,bugs:Fct,homepage:Dct,dependencies:Vct,devDependencies:Uct,engines:Kct,scripts:Gct};(function(e){/** * @file Embedded JavaScript templating engine. {@link http://ejs.co} * @author Matthew Eernisse * @author Tiancheng "Timothy" Gu From 973a813af669c37ff5328736e7c3b3065a748e95 Mon Sep 17 00:00:00 2001 From: Michael Christenson II Date: Thu, 21 Dec 2023 13:42:39 -0500 Subject: [PATCH 18/19] Return nil on 0 case --- internal/ansi/progress.go | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/internal/ansi/progress.go b/internal/ansi/progress.go index 0fb26e639..7d85c0eec 100644 --- a/internal/ansi/progress.go +++ b/internal/ansi/progress.go @@ -5,13 +5,12 @@ import ( "github.com/schollz/progressbar/v3" ) + // ProgressBar will display progress indication for the given items. func ProgressBar[T comparable](desc string, items []T, fn func(int, T) error) error { switch len(items) { case 0: - return Spinner(desc, func() error { - return nil - }) + return nil case 1: return Spinner(desc, func() error { return fn(1, items[0]) From 8733ebf1122eaf3f477aa58cd7c3c0c256255b02 Mon Sep 17 00:00:00 2001 From: Michael Christenson II Date: Thu, 21 Dec 2023 13:56:26 -0500 Subject: [PATCH 19/19] Ensure ID isn't empty when deleting an organization --- internal/cli/organizations.go | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/internal/cli/organizations.go b/internal/cli/organizations.go index 163338a1f..275a70a91 100644 --- a/internal/cli/organizations.go +++ b/internal/cli/organizations.go @@ -438,12 +438,14 @@ func deleteOrganizationCmd(cli *cli) *cobra.Command { } return ansi.ProgressBar("Deleting organization(s)", ids, func(_ int, id string) error { - if _, err := cli.api.Organization.Read(cmd.Context(), id); err != nil { - return fmt.Errorf("failed to delete organization with ID %q: %w", id, err) - } + if id != "" { + if _, err := cli.api.Organization.Read(cmd.Context(), id); err != nil { + return fmt.Errorf("failed to delete organization with ID %q: %w", id, err) + } - if err := cli.api.Organization.Delete(cmd.Context(), id); err != nil { - return fmt.Errorf("failed to delete organization with ID %q: %w", id, err) + if err := cli.api.Organization.Delete(cmd.Context(), id); err != nil { + return fmt.Errorf("failed to delete organization with ID %q: %w", id, err) + } } return nil })