Skip to content

Commit 36abf07

Browse files
authored
Merge pull request #146 from auth0/flags-poc
2 parents a5ce24e + 22291b7 commit 36abf07

File tree

3 files changed

+141
-68
lines changed

3 files changed

+141
-68
lines changed

internal/cli/apis.go

Lines changed: 28 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,28 @@ import (
1313

1414
const (
1515
apiID = "id"
16-
apiName = "name"
17-
apiIdentifier = "identifier"
1816
apiScopes = "scopes"
1917
)
2018

19+
var (
20+
apiName = Flag{
21+
Name: "Name",
22+
LongForm: "name",
23+
ShortForm: "n",
24+
DefaultValue: "",
25+
Help: "Name of the API.",
26+
IsRequired: true,
27+
}
28+
apiIdentifier = Flag{
29+
Name: "Identifier",
30+
LongForm: "identifier",
31+
ShortForm: "i",
32+
DefaultValue: "",
33+
Help: "Identifier of the API. Cannot be changed once set.",
34+
IsRequired: true,
35+
}
36+
)
37+
2138
func apisCmd(cli *cli) *cobra.Command {
2239
cmd := &cobra.Command{
2340
Use: "apis",
@@ -147,26 +164,12 @@ auth0 apis create --name myapi --identifier http://my-api
147164
prepareInteractivity(cmd)
148165
},
149166
RunE: func(cmd *cobra.Command, args []string) error {
150-
if shouldPrompt(cmd, apiName) {
151-
input := prompt.TextInput(
152-
apiName, "Name:",
153-
"Name of the API. You can change the name later in the API settings.",
154-
true)
155-
156-
if err := prompt.AskOne(input, &flags); err != nil {
157-
return fmt.Errorf("An unexpected error occurred: %w", err)
158-
}
167+
if err := apiName.Ask(cmd, &flags.Name); err != nil {
168+
return err
159169
}
160170

161-
if shouldPrompt(cmd, apiIdentifier) {
162-
input := prompt.TextInput(
163-
apiIdentifier, "Identifier:",
164-
"Identifier of the API. Cannot be changed once set.",
165-
true)
166-
167-
if err := prompt.AskOne(input, &flags); err != nil {
168-
return fmt.Errorf("An unexpected error occurred: %w", err)
169-
}
171+
if err := apiIdentifier.Ask(cmd, &flags.Identifier); err != nil {
172+
return err
170173
}
171174

172175
if shouldPrompt(cmd, apiScopes) {
@@ -199,10 +202,9 @@ auth0 apis create --name myapi --identifier http://my-api
199202
},
200203
}
201204

202-
cmd.Flags().StringVarP(&flags.Name, apiName, "n", "", "Name of the API.")
203-
cmd.Flags().StringVarP(&flags.Identifier, apiIdentifier, "i", "", "Identifier of the API.")
205+
apiName.RegisterString(cmd, &flags.Name)
206+
apiIdentifier.RegisterString(cmd, &flags.Identifier)
204207
cmd.Flags().StringVarP(&flags.Scopes, apiScopes, "s", "", "Space-separated list of scopes.")
205-
mustRequireFlags(cmd, apiName, apiIdentifier)
206208

207209
return cmd
208210
}
@@ -240,12 +242,8 @@ auth0 apis update <id> --name myapi
240242
inputs.ID = args[0]
241243
}
242244

243-
if shouldPromptWhenFlagless(cmd, apiName) {
244-
input := prompt.TextInput(apiName, "Name:", "Name of the API.", true)
245-
246-
if err := prompt.AskOne(input, &inputs); err != nil {
247-
return fmt.Errorf("An unexpected error occurred: %w", err)
248-
}
245+
if err := apiName.AskU(cmd, &inputs.Name); err != nil {
246+
return err
249247
}
250248

251249
if shouldPromptWhenFlagless(cmd, apiScopes) {
@@ -289,7 +287,7 @@ auth0 apis update <id> --name myapi
289287
},
290288
}
291289

292-
cmd.Flags().StringVarP(&inputs.Name, apiName, "n", "", "Name of the API.")
290+
apiName.RegisterStringU(cmd, &inputs.Name)
293291
cmd.Flags().StringVarP(&inputs.Scopes, apiScopes, "s", "", "Space-separated list of scopes.")
294292

295293
return cmd

internal/cli/apps.go

Lines changed: 44 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,35 @@ import (
1313
)
1414

1515
const (
16-
appID = "id"
17-
appName = "name"
18-
appType = "type"
19-
appDescription = "description"
16+
appID = "id"
17+
appType = "type"
18+
)
19+
20+
var (
21+
appName = Flag{
22+
Name: "Name",
23+
LongForm: "name",
24+
ShortForm: "n",
25+
DefaultValue: "",
26+
Help: "Name of the application.",
27+
IsRequired: true,
28+
}
29+
appDescription = Flag{
30+
Name: "Description",
31+
LongForm: "description",
32+
ShortForm: "d",
33+
DefaultValue: "",
34+
Help: "Description of the application. Max character count is 140.",
35+
IsRequired: false,
36+
}
37+
appAuthMethod = Flag{
38+
Name: "Auth Method",
39+
LongForm: "auth-method",
40+
ShortForm: "a",
41+
DefaultValue: "",
42+
Help: "Defines the requested authentication method for the token endpoint. Possible values are 'None' (public application without a client secret), 'Post' (application uses HTTP POST parameters) or 'Basic' (application uses HTTP Basic).",
43+
IsRequired: false,
44+
}
2045
)
2146

2247
func appsCmd(cli *cli) *cobra.Command {
@@ -188,15 +213,8 @@ auth0 apps create --name myapp --type [native|spa|regular|m2m]
188213
prepareInteractivity(cmd)
189214
},
190215
RunE: func(cmd *cobra.Command, args []string) error {
191-
if shouldPrompt(cmd, appName) {
192-
input := prompt.TextInput(
193-
appName, "Name:",
194-
"Name of the application. You can change the name later in the application settings.",
195-
true)
196-
197-
if err := prompt.AskOne(input, &flags); err != nil {
198-
return fmt.Errorf("An unexpected error occurred: %w", err)
199-
}
216+
if err := appName.Ask(cmd, &flags.Name); err != nil {
217+
return err
200218
}
201219

202220
if shouldPrompt(cmd, appType) {
@@ -215,12 +233,8 @@ auth0 apps create --name myapp --type [native|spa|regular|m2m]
215233
}
216234
}
217235

218-
if shouldPrompt(cmd, appDescription) {
219-
input := prompt.TextInput(appDescription, "Description:", "Description of the application.", false)
220-
221-
if err := prompt.AskOne(input, &flags); err != nil {
222-
return fmt.Errorf("An unexpected error occurred: %w", err)
223-
}
236+
if err := appDescription.Ask(cmd, &flags.Description); err != nil {
237+
return err
224238
}
225239

226240
a := &management.Client{
@@ -257,20 +271,20 @@ auth0 apps create --name myapp --type [native|spa|regular|m2m]
257271
},
258272
}
259273

260-
cmd.Flags().StringVarP(&flags.Name, "name", "n", "", "Name of the application.")
274+
appName.RegisterString(cmd, &flags.Name)
261275
cmd.Flags().StringVarP(&flags.Type, "type", "t", "", "Type of application:\n"+
262276
"- native: mobile, desktop, CLI and smart device apps running natively.\n"+
263277
"- spa (single page application): a JavaScript front-end app that uses an API.\n"+
264278
"- regular: Traditional web app using redirects.\n"+
265279
"- m2m (machine to machine): CLIs, daemons or services running on your backend.")
266-
cmd.Flags().StringVarP(&flags.Description, "description", "d", "", "Description of the application. Max character count is 140.")
280+
appDescription.RegisterString(cmd, &flags.Description)
267281
cmd.Flags().StringSliceVarP(&flags.Callbacks, "callbacks", "c", nil, "After the user authenticates we will only call back to any of these URLs. You can specify multiple valid URLs by comma-separating them (typically to handle different environments like QA or testing). Make sure to specify the protocol (https://) otherwise the callback may fail in some cases. With the exception of custom URI schemes for native apps, all callbacks should use protocol https://.")
268282
cmd.Flags().StringSliceVarP(&flags.AllowedOrigins, "origins", "o", nil, "Comma-separated list of URLs allowed to make requests from JavaScript to Auth0 API (typically used with CORS). By default, all your callback URLs will be allowed. This field allows you to enter other origins if necessary. You can also use wildcards at the subdomain level (e.g., https://*.contoso.com). Query strings and hash information are not taken into account when validating these URLs.")
269283
cmd.Flags().StringSliceVarP(&flags.AllowedWebOrigins, "web-origins", "w", nil, "Comma-separated list of allowed origins for use with Cross-Origin Authentication, Device Flow, and web message response mode.")
270284
cmd.Flags().StringSliceVarP(&flags.AllowedLogoutURLs, "logout-urls", "l", nil, "Comma-separated list of URLs that are valid to redirect to after logout from Auth0. Wildcards are allowed for subdomains.")
271-
cmd.Flags().StringVarP(&flags.AuthMethod, "auth-method", "a", "", "Defines the requested authentication method for the token endpoint. Possible values are 'None' (public application without a client secret), 'Post' (application uses HTTP POST parameters) or 'Basic' (application uses HTTP Basic).")
285+
appAuthMethod.RegisterString(cmd, &flags.AuthMethod)
272286
cmd.Flags().StringSliceVarP(&flags.Grants, "grants", "g", nil, "List of grant types supported for this application. Can include code, implicit, refresh-token, credentials, password, password-realm, mfa-oob, mfa-otp, mfa-recovery-code, and device-code.")
273-
mustRequireFlags(cmd, appName, appType)
287+
mustRequireFlags(cmd, appType)
274288

275289
return cmd
276290
}
@@ -316,12 +330,8 @@ auth0 apps update <id> --name myapp --type [native|spa|regular|m2m]
316330
inputs.ID = args[0]
317331
}
318332

319-
if shouldPromptWhenFlagless(cmd, appName) {
320-
input := prompt.TextInput(appName, "Name:", "Name of the application", true)
321-
322-
if err := prompt.AskOne(input, &inputs); err != nil {
323-
return fmt.Errorf("An unexpected error occurred: %w", err)
324-
}
333+
if err := appName.AskU(cmd, &inputs.Name); err != nil {
334+
return err
325335
}
326336

327337
if shouldPromptWhenFlagless(cmd, appType) {
@@ -340,12 +350,8 @@ auth0 apps update <id> --name myapp --type [native|spa|regular|m2m]
340350
}
341351
}
342352

343-
if shouldPromptWhenFlagless(cmd, appDescription) {
344-
input := prompt.TextInput(appDescription, "Description:", "Description of the application.", false)
345-
346-
if err := prompt.AskOne(input, &inputs); err != nil {
347-
return fmt.Errorf("An unexpected error occurred: %w", err)
348-
}
353+
if err := appDescription.AskU(cmd, &inputs.Description); err != nil {
354+
return err
349355
}
350356

351357
if shouldPromptWhenFlagless(cmd, "CallbacksString") {
@@ -437,18 +443,18 @@ auth0 apps update <id> --name myapp --type [native|spa|regular|m2m]
437443
},
438444
}
439445

440-
cmd.Flags().StringVarP(&inputs.Name, "name", "n", "", "Name of the application.")
446+
appName.RegisterStringU(cmd, &inputs.Name)
441447
cmd.Flags().StringVarP(&inputs.Type, "type", "t", "", "Type of application:\n"+
442448
"- native: mobile, desktop, CLI and smart device apps running natively.\n"+
443449
"- spa (single page application): a JavaScript front-end app that uses an API.\n"+
444450
"- regular: Traditional web app using redirects.\n"+
445451
"- m2m (machine to machine): CLIs, daemons or services running on your backend.")
446-
cmd.Flags().StringVarP(&inputs.Description, "description", "d", "", "Description of the application. Max character count is 140.")
452+
appDescription.RegisterStringU(cmd, &inputs.Description)
447453
cmd.Flags().StringSliceVarP(&inputs.Callbacks, "callbacks", "c", nil, "After the user authenticates we will only call back to any of these URLs. You can specify multiple valid URLs by comma-separating them (typically to handle different environments like QA or testing). Make sure to specify the protocol (https://) otherwise the callback may fail in some cases. With the exception of custom URI schemes for native apps, all callbacks should use protocol https://.")
448454
cmd.Flags().StringSliceVarP(&inputs.AllowedOrigins, "origins", "o", nil, "Comma-separated list of URLs allowed to make requests from JavaScript to Auth0 API (typically used with CORS). By default, all your callback URLs will be allowed. This field allows you to enter other origins if necessary. You can also use wildcards at the subdomain level (e.g., https://*.contoso.com). Query strings and hash information are not taken into account when validating these URLs.")
449455
cmd.Flags().StringSliceVarP(&inputs.AllowedWebOrigins, "web-origins", "w", nil, "Comma-separated list of allowed origins for use with Cross-Origin Authentication, Device Flow, and web message response mode.")
450456
cmd.Flags().StringSliceVarP(&inputs.AllowedLogoutURLs, "logout-urls", "l", nil, "Comma-separated list of URLs that are valid to redirect to after logout from Auth0. Wildcards are allowed for subdomains.")
451-
cmd.Flags().StringVarP(&inputs.AuthMethod, "auth-method", "a", "", "Defines the requested authentication method for the token endpoint. Possible values are 'None' (public application without a client secret), 'Post' (application uses HTTP POST parameters) or 'Basic' (application uses HTTP Basic).")
457+
appAuthMethod.RegisterStringU(cmd, &inputs.AuthMethod)
452458
cmd.Flags().StringSliceVarP(&inputs.Grants, "grants", "g", nil, "List of grant types supported for this application. Can include code, implicit, refresh-token, credentials, password, password-realm, mfa-oob, mfa-otp, mfa-recovery-code, and device-code.")
453459

454460
return cmd

internal/cli/flags.go

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
package cli
2+
3+
import (
4+
"fmt"
5+
6+
"github.com/auth0/auth0-cli/internal/prompt"
7+
"github.com/spf13/cobra"
8+
)
9+
10+
type Flag struct {
11+
Name string
12+
LongForm string
13+
ShortForm string
14+
DefaultValue string
15+
Help string
16+
IsRequired bool
17+
}
18+
19+
func (f *Flag) Ask(cmd *cobra.Command, value interface{}) error {
20+
return ask(cmd, f, value, false)
21+
}
22+
23+
func (f *Flag) AskU(cmd *cobra.Command, value interface{}) error {
24+
return ask(cmd, f, value, true)
25+
}
26+
27+
func (f *Flag) RegisterString(cmd *cobra.Command, value *string) {
28+
registerString(cmd, f, value, false)
29+
}
30+
31+
func (f *Flag) RegisterStringU(cmd *cobra.Command, value *string) {
32+
registerString(cmd, f, value, true)
33+
}
34+
35+
func ask(cmd *cobra.Command, f *Flag, value interface{}, isUpdate bool) error {
36+
var shouldAsk bool
37+
38+
if isUpdate {
39+
shouldAsk = shouldPromptWhenFlagless(cmd, f.LongForm)
40+
} else {
41+
shouldAsk = shouldPrompt(cmd, f.LongForm)
42+
}
43+
44+
if shouldAsk {
45+
input := prompt.TextInput("", fmt.Sprintf("%s:", f.Name), f.Help, f.IsRequired)
46+
47+
if err := prompt.AskOne(input, value); err != nil {
48+
return fmt.Errorf("An unexpected error occurred: %w", err)
49+
}
50+
}
51+
52+
return nil
53+
}
54+
55+
func registerString(cmd *cobra.Command, f *Flag, value *string, isUpdate bool) {
56+
cmd.Flags().StringVarP(value, f.LongForm, f.ShortForm, f.DefaultValue, f.Help)
57+
58+
if err := markFlagRequired(cmd, f, isUpdate); err != nil {
59+
panic(fmt.Errorf("An unexpected error occurred: %w", err)) // TODO: Handle
60+
}
61+
}
62+
63+
func markFlagRequired(cmd *cobra.Command, f *Flag, isUpdate bool) error {
64+
if f.IsRequired && !isUpdate {
65+
return cmd.MarkFlagRequired(f.LongForm)
66+
}
67+
68+
return nil
69+
}

0 commit comments

Comments
 (0)