Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support custom url params for test login and token cmd #1130

Merged
merged 9 commits into from
Feb 3, 2025
5 changes: 4 additions & 1 deletion docs/auth0_test_login.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,12 @@ auth0 test login [flags]
auth0 test login <client-id>
auth0 test login <client-id> --connection-name <connection-name>
auth0 test login <client-id> --connection-name <connection-name> --audience <api-identifier|api-audience>
auth0 test login <client-id> --connection-name <connection-name> --audience <api-identifier|api-audience> --domain <domain>
auth0 test login <client-id> --connection-name <connection-name> --audience <api-identifier|api-audience> --domain <domain> --params "foo=bar"
auth0 test login <client-id> --connection-name <connection-name> --audience <api-identifier|api-audience> --domain <domain> --scopes <scope1,scope2>
auth0 test login <client-id> -c <connection-name> -a <api-identifier|api-audience> -d <domain> -s <scope1,scope2> --force
auth0 test login <client-id> -c <connection-name> -a <api-identifier|api-audience> -d <domain> -s <scope1,scope2> --json
auth0 test login <client-id> -c <connection-name> -a <api-identifier|api-audience> -d <domain> -s <scope1,scope2> -p "foo=bar" -p "bazz=buzz" --json
auth0 test login <client-id> -c <connection-name> -a <api-identifier|api-audience> -d <domain> -s <scope1,scope2> -p "foo=bar","bazz=buzz" --json
auth0 test login <client-id> -c <connection-name> -a <api-identifier|api-audience> -d <domain> -s <scope1,scope2> --force --json
```

Expand All @@ -35,6 +37,7 @@ auth0 test login [flags]
-d, --domain string One of your custom domains.
--force Skip confirmation.
--json Output in json format.
-p, --params stringToString Custom parameters to include in the login URL. (default [])
-s, --scopes strings The list of scopes you want to use. (default [openid,profile])
```

Expand Down
13 changes: 8 additions & 5 deletions docs/auth0_test_token.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,21 +16,24 @@ auth0 test token [flags]

```
auth0 test token
auth0 test token <client-id> --audience <api-audience|api-identifier> --scopes <scope1,scope2>
auth0 test token <client-id> --audience <api-audience|api-identifier> --scopes <scope1,scope2> --params "foo=bar"
auth0 test token <client-id> -a <api-audience|api-identifier> -s <scope1,scope2>
auth0 test token <client-id> -a <api-audience|api-identifier> -s <scope1,scope2> --force
auth0 test token <client-id> -a <api-audience|api-identifier> -s <scope1,scope2> -p "foo=bar" -p "bazz=buzz" --force
auth0 test token <client-id> -a <api-audience|api-identifier> -s <scope1,scope2> --json
auth0 test token <client-id> -a <api-audience|api-identifier> -s <scope1,scope2> -p "foo=bar","bazz=buzz" --json
auth0 test token <client-id> -a <api-audience|api-identifier> -s <scope1,scope2> --force --json
```


## Flags

```
-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.
-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.
-p, --params stringToString Custom parameters to include in the login URL. (default [])
-s, --scopes strings The list of scopes you want to use.
```


Expand Down
8 changes: 7 additions & 1 deletion internal/auth/authutil/login.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import (

// BuildLoginURL constructs a URL + query string that can be used to
// initiate a user-facing login-flow from the CLI.
func BuildLoginURL(domain, clientID, callbackURL, state, connectionName, audience, prompt string, scopes []string) (string, error) {
func BuildLoginURL(domain, clientID, callbackURL, state, connectionName, audience, prompt string, scopes []string, customParams map[string]string) (string, error) {
q := url.Values{}
q.Add("client_id", clientID)
q.Add("response_type", "code")
Expand All @@ -30,6 +30,12 @@ func BuildLoginURL(domain, clientID, callbackURL, state, connectionName, audienc
q.Add("scope", strings.Join(scopes, " "))
}

if len(customParams) > 0 {
for k, v := range customParams {
q.Add(k, v)
}
}

u := &url.URL{
Scheme: "https",
Host: domain,
Expand Down
4 changes: 2 additions & 2 deletions internal/auth/authutil/login_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ import (
)

func TestBuildLoginURL(t *testing.T) {
url, err := BuildLoginURL("cli-demo.us.auth0.com", "some-client-id", "http://localhost:8484", "some-state", "some-conn", "some-aud", "none", []string{"some-scope", "some-other-scope"})
url, err := BuildLoginURL("cli-demo.us.auth0.com", "some-client-id", "http://localhost:8484", "some-state", "some-conn", "some-aud", "none", []string{"some-scope", "some-other-scope"}, map[string]string{"foo": "bar", "bazz": "buzz"})

assert.NoError(t, err)
assert.Equal(t, url, "https://cli-demo.us.auth0.com/authorize?audience=some-aud&client_id=some-client-id&connection=some-conn&prompt=none&redirect_uri=http%3A%2F%2Flocalhost%3A8484&response_type=code&scope=some-scope+some-other-scope&state=some-state")
assert.Equal(t, url, "https://cli-demo.us.auth0.com/authorize?audience=some-aud&bazz=buzz&client_id=some-client-id&connection=some-conn&foo=bar&prompt=none&redirect_uri=http%3A%2F%2Flocalhost%3A8484&response_type=code&scope=some-scope+some-other-scope&state=some-state")
}
20 changes: 18 additions & 2 deletions internal/cli/test.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,13 @@ var (
Help: "One of your custom domains.",
}

testCustomParams = Flag{
Name: "Custom Params",
LongForm: "params",
ShortForm: "p",
Help: "Custom parameters to include in the login URL.",
}

errNoCustomDomains = errors.New("there are currently no custom domains. Create one by running: `auth0 domains create`")
)

Expand All @@ -71,6 +78,7 @@ type testCmdInputs struct {
Scopes []string
ConnectionName string
CustomDomain string
CustomParams map[string]string
}

func testCmd(cli *cli) *cobra.Command {
Expand Down Expand Up @@ -99,10 +107,12 @@ func testLoginCmd(cli *cli) *cobra.Command {
auth0 test login <client-id>
auth0 test login <client-id> --connection-name <connection-name>
auth0 test login <client-id> --connection-name <connection-name> --audience <api-identifier|api-audience>
auth0 test login <client-id> --connection-name <connection-name> --audience <api-identifier|api-audience> --domain <domain>
auth0 test login <client-id> --connection-name <connection-name> --audience <api-identifier|api-audience> --domain <domain> --params "foo=bar"
auth0 test login <client-id> --connection-name <connection-name> --audience <api-identifier|api-audience> --domain <domain> --scopes <scope1,scope2>
auth0 test login <client-id> -c <connection-name> -a <api-identifier|api-audience> -d <domain> -s <scope1,scope2> --force
auth0 test login <client-id> -c <connection-name> -a <api-identifier|api-audience> -d <domain> -s <scope1,scope2> --json
auth0 test login <client-id> -c <connection-name> -a <api-identifier|api-audience> -d <domain> -s <scope1,scope2> -p "foo=bar" -p "bazz=buzz" --json
auth0 test login <client-id> -c <connection-name> -a <api-identifier|api-audience> -d <domain> -s <scope1,scope2> -p "foo=bar","bazz=buzz" --json
auth0 test login <client-id> -c <connection-name> -a <api-identifier|api-audience> -d <domain> -s <scope1,scope2> --force --json`,
RunE: func(cmd *cobra.Command, args []string) error {
client, err := selectClientToUseForTestsAndValidateExistence(cli, cmd, args, &inputs)
Expand Down Expand Up @@ -143,6 +153,7 @@ func testLoginCmd(cli *cli) *cobra.Command {
"login", // Force a login page when using the test login command.
inputs.Scopes,
inputs.CustomDomain,
inputs.CustomParams,
)
if err != nil {
return fmt.Errorf("failed to log into the client with ID %q: %w", inputs.ClientID, err)
Expand All @@ -168,6 +179,7 @@ func testLoginCmd(cli *cli) *cobra.Command {
testScopes.RegisterStringSlice(cmd, &inputs.Scopes, cliLoginTestingScopes)
testConnectionName.RegisterString(cmd, &inputs.ConnectionName, "")
testDomain.RegisterString(cmd, &inputs.CustomDomain, "")
testCustomParams.RegisterStringMap(cmd, &inputs.CustomParams, nil)

return cmd
}
Expand All @@ -183,10 +195,12 @@ func testTokenCmd(cli *cli) *cobra.Command {
"Specify the API you want this token for with `--audience` (API Identifier). " +
"Additionally, you can also specify the `--scopes` to grant.",
Example: ` auth0 test token
auth0 test token <client-id> --audience <api-audience|api-identifier> --scopes <scope1,scope2>
auth0 test token <client-id> --audience <api-audience|api-identifier> --scopes <scope1,scope2> --params "foo=bar"
auth0 test token <client-id> -a <api-audience|api-identifier> -s <scope1,scope2>
auth0 test token <client-id> -a <api-audience|api-identifier> -s <scope1,scope2> --force
auth0 test token <client-id> -a <api-audience|api-identifier> -s <scope1,scope2> -p "foo=bar" -p "bazz=buzz" --force
auth0 test token <client-id> -a <api-audience|api-identifier> -s <scope1,scope2> --json
auth0 test token <client-id> -a <api-audience|api-identifier> -s <scope1,scope2> -p "foo=bar","bazz=buzz" --json
auth0 test token <client-id> -a <api-audience|api-identifier> -s <scope1,scope2> --force --json`,
RunE: func(cmd *cobra.Command, args []string) error {
client, err := selectClientToUseForTestsAndValidateExistence(cli, cmd, args, &inputs)
Expand Down Expand Up @@ -245,6 +259,7 @@ func testTokenCmd(cli *cli) *cobra.Command {
"", // We don't want to force a prompt for the test token command.
inputs.Scopes,
"", // Specifying a custom domain is only supported for the test login command.
inputs.CustomParams,
)
if err != nil {
return fmt.Errorf("failed to log into the client with ID %q: %w", inputs.ClientID, err)
Expand All @@ -261,6 +276,7 @@ func testTokenCmd(cli *cli) *cobra.Command {
cmd.Flags().BoolVar(&cli.json, "json", false, "Output in json format.")
testAudienceRequired.RegisterString(cmd, &inputs.Audience, "")
testScopes.RegisterStringSlice(cmd, &inputs.Scopes, nil)
testCustomParams.RegisterStringMap(cmd, &inputs.CustomParams, nil)

return cmd
}
Expand Down
4 changes: 2 additions & 2 deletions internal/cli/utils_shared.go
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ func runLoginFlowPreflightChecks(cli *cli, c *management.Client) (abort bool) {

// runLoginFlow initiates a full user-facing login flow, waits for a response
// and returns the retrieved tokens to the caller when done.
func runLoginFlow(ctx context.Context, cli *cli, c *management.Client, connName, audience, prompt string, scopes []string, customDomain string) (*authutil.TokenResponse, error) {
func runLoginFlow(ctx context.Context, cli *cli, c *management.Client, connName, audience, prompt string, scopes []string, customDomain string, customParams map[string]string) (*authutil.TokenResponse, error) {
var tokenResponse *authutil.TokenResponse

err := ansi.Spinner("Waiting for login flow to complete", func() error {
Expand All @@ -143,7 +143,7 @@ func runLoginFlow(ctx context.Context, cli *cli, c *management.Client, connName,
}

// Build a login URL and initiate login in a browser window.
loginURL, err := authutil.BuildLoginURL(domain, c.GetClientID(), cliLoginTestingCallbackURL, state, connName, audience, prompt, scopes)
loginURL, err := authutil.BuildLoginURL(domain, c.GetClientID(), cliLoginTestingCallbackURL, state, connName, audience, prompt, scopes, customParams)
if err != nil {
return err
}
Expand Down
Loading