Skip to content

Commit

Permalink
Add the get-tokens command
Browse files Browse the repository at this point in the history
  • Loading branch information
xer0x committed Jan 28, 2021
1 parent 4bc412e commit fc8025e
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 1 deletion.
12 changes: 11 additions & 1 deletion internal/cli/get_token.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,19 @@ Fetch an access token for the given client and API.
return err
}

// TODO: We can check here if the client is an m2m client, and if so
// We can check here if the client is an m2m client, and if so
// initiate the client credentials flow instead to fetch a token,
// avoiding the browser and HTTP server shenanigans altogether.
if client.GetAppType() == "non_interactive" {
tokenResponse, err := runClientCredentialsFlow(cli, client, clientID, audience)
if err != nil {
return err
}

fmt.Fprint(cli.renderer.MessageWriter, "\n")
cli.renderer.GetToken(client, tokenResponse)
return nil
}

if proceed := runLoginFlowPreflightChecks(cli, client); !proceed {
return nil
Expand Down
49 changes: 49 additions & 0 deletions internal/cli/utils_shared.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,15 @@ package cli
import (
"fmt"

"encoding/json"
"github.com/auth0/auth0-cli/internal/ansi"
"github.com/auth0/auth0-cli/internal/auth/authutil"
"github.com/auth0/auth0-cli/internal/auth0"
"github.com/auth0/auth0-cli/internal/open"
"github.com/auth0/auth0-cli/internal/prompt"
"gopkg.in/auth0.v5/management"
"net/http"
"strings"
)

const (
Expand All @@ -23,6 +26,52 @@ var (
cliLoginTestingScopes []string = []string{"openid", "profile"}
)

// runClientCredentialsFlow runs an M2M client credentials flow without opening a browser
func runClientCredentialsFlow(cli *cli, c *management.Client, clientID string, audience string) (*authutil.TokenResponse, error) {

var tokenResponse *authutil.TokenResponse

tenant, err := cli.getTenant()
if err != nil {
return tokenResponse, err
}

url := "https://" + tenant.Domain + "/oauth/token"

cli.renderer.Infof("Domain: " + tenant.Domain)
cli.renderer.Infof("ClientID: " + clientID)
cli.renderer.Infof("Type: Machine to Machine")
fmt.Println()

client_secret := c.GetClientSecret()

// TODO: Check if the audience is valid, and suggest a different client if it is wrong.

payload := strings.NewReader("grant_type=client_credentials&client_id=" + clientID + "&client_secret=" + client_secret + "&audience=" + audience)

err = ansi.Spinner("Waiting for token", func() error {
req, _ := http.NewRequest("POST", url, payload)

req.Header.Add("content-type", "application/x-www-form-urlencoded")

res, err := http.DefaultClient.Do(req)

if err != nil {
return err
}

defer res.Body.Close()

err = json.NewDecoder(res.Body).Decode(&tokenResponse)
if err != nil {
return fmt.Errorf("cannot decode response: %w", err)
}
return nil
})

return tokenResponse, err
}

// runLoginFlowPreflightChecks checks if we need to make any updates to the
// client being tested in order to log in successfully. If so, it asks the user
// to confirm whether to proceed.
Expand Down

0 comments on commit fc8025e

Please sign in to comment.