diff --git a/README.md b/README.md index 945fd7b..5f3c914 100644 --- a/README.md +++ b/README.md @@ -262,17 +262,17 @@ $ oauth2l fetch --type oauth --credentials ~/client_credentials.json --scope clo When jwt is selected and the json file specified in the `--credentials` option is a service account key file, a JWT token signed by the service account private -key will be generated. Either `--scope` or `--audience` must be specified for +key will be generated. Either `--audience` or `--scope` must be specified for this option. See how to construct the audience [here](https://developers.google.com/identity/protocols/OAuth2ServiceAccount#jwt-auth). -- With scope: +- With audience: ```bash - $ oauth2l fetch --type jwt --credentials ~/client_credentials.json --scope cloud-platform + $ oauth2l fetch --type jwt --credentials ~/service_account.json --audience https://pubsub.googleapis.com/ ``` -- With audience: +- With scope: ```bash - $ oauth2l fetch --type jwt --credentials ~/service_account.json --audience https://pubsub.googleapis.com/ + $ oauth2l fetch --type jwt --credentials ~/service_account.json --scope cloud-platform ``` #### sso diff --git a/integration/golden/no-scope-or-audience.golden b/integration/golden/no-scope-or-audience.golden index 6ea3344..8fa6903 100644 --- a/integration/golden/no-scope-or-audience.golden +++ b/integration/golden/no-scope-or-audience.golden @@ -1 +1 @@ -neither audience nor scope is provided +Neither audience nor scope argument is provided for JWT diff --git a/main.go b/main.go index 2b2c2b8..877fc8b 100644 --- a/main.go +++ b/main.go @@ -316,11 +316,17 @@ func main() { } } + scopes := getScopesWithFallback(scope, remainingArgs...) + if audience == "" && len(scopes) < 1 { + fmt.Println("Neither audience nor scope argument is provided for JWT") + return + } + settings = &util.Settings{ AuthType: util.AuthTypeJWT, CredentialsJSON: json, Audience: audience, - Scope: scope, + Scope: parseScopes(scopes), } } else if authType == util.AuthTypeSSO { // Fallback to reading email from first remaining arg diff --git a/util/cache.go b/util/cache.go index 3e0cf8f..b15e1e6 100644 --- a/util/cache.go +++ b/util/cache.go @@ -53,7 +53,6 @@ func LookupCache(settings *Settings) (*oauth2.Token, error) { if CacheLocation == "" { return nil, nil } - var token oauth2.Token var cache, err = loadCache() if err != nil { return nil, err @@ -63,11 +62,7 @@ func LookupCache(settings *Settings) (*oauth2.Token, error) { return nil, err } val := cache[string(key)] - err = json.Unmarshal(val, &token) - if err != nil { - return nil, err - } - return &token, nil + return UnmarshalWithExtras(val) } func InsertCache(settings *Settings, token *oauth2.Token) error { @@ -78,7 +73,7 @@ func InsertCache(settings *Settings, token *oauth2.Token) error { if err != nil { return err } - val, err := json.Marshal(*token) + val, err := MarshalWithExtras(token, "") if err != nil { return err } @@ -155,3 +150,43 @@ func GuessUnixHomeDir() string { } return "" } + +// Marshals the given oauth2.Token into a JSON bytearray and include Extra +// fields that normally would be omitted with default marshalling. +func MarshalWithExtras(token *oauth2.Token, indent string) ([]byte, error) { + data, err := json.Marshal(token) + if err != nil { + return nil, err + } + var m map[string]string + err = json.Unmarshal(data, &m) + if err != nil { + return nil, err + } + if token.Extra("issued_token_type") != nil { + m["issued_token_type"] = token.Extra("issued_token_type").(string) + } + if token.Extra("id_token") != nil { + m["id_token"] = token.Extra("id_token").(string) + } + if token.Extra("scope") != nil { + m["scope"] = token.Extra("scope").(string) + } + return json.MarshalIndent(m, "", indent) +} + +// Unmarshals the given JSON bytearray into oauth2.Token and include Extra +// fields that normally would be omitted with default unmarshalling. +func UnmarshalWithExtras(data []byte) (*oauth2.Token, error) { + var extra map[string]interface{} + err := json.Unmarshal(data, &extra) + if err != nil { + return nil, err + } + var token oauth2.Token + err = json.Unmarshal(data, &token) + if err != nil { + return nil, err + } + return token.WithExtra(extra), nil +} diff --git a/util/fetch.go b/util/fetch.go index f91ba7a..5077ea2 100644 --- a/util/fetch.go +++ b/util/fetch.go @@ -40,8 +40,7 @@ func newTokenSource(ctx context.Context, settings *Settings) (*oauth2.TokenSourc } else if settings.GetAuthType() == AuthTypeJWT { ts, err = JWTTokenSource(ctx, settings) } else { - return nil, fmt.Errorf( - "Unsupported authentcation method: %s", settings.GetAuthType()) + return nil, fmt.Errorf("Unsupported authentcation method: %s", settings.GetAuthType()) } if err != nil { return nil, err @@ -86,7 +85,7 @@ func JWTTokenSource(ctx context.Context, settings *Settings) (oauth2.TokenSource } else if settings.Scope != "" { return google.JWTAccessTokenSourceWithScope(creds.JSON, settings.Scope) } else { - return nil, errors.New("neither audience nor scope is provided") + return nil, errors.New("Neither audience nor scope is provided for JWTTokenSource") } } diff --git a/util/tasks.go b/util/tasks.go index ff894ae..3b62291 100644 --- a/util/tasks.go +++ b/util/tasks.go @@ -227,27 +227,6 @@ func getCredentialType(creds *google.Credentials) string { return "" } -// Marshals the given oauth2.Token into a JSON bytearray and include Extra -// fields that normally would be omitted with default marshalling. -func marshalWithExtras(token *oauth2.Token, indent string) ([]byte, error) { - data, err := json.Marshal(token) - if err != nil { - return nil, err - } - var m map[string]string - err = json.Unmarshal(data, &m) - if err != nil { - return nil, err - } - if token.Extra("issued_token_type") != nil { - m["issued_token_type"] = token.Extra("issued_token_type").(string) - } - if token.Extra("id_token") != nil { - m["id_token"] = token.Extra("id_token").(string) - } - return json.MarshalIndent(m, "", indent) -} - // Prints the token with the specified format. func printToken(token *oauth2.Token, format string, settings *Settings) { if token != nil { @@ -295,7 +274,7 @@ func printHeader(tokenType string, token string) { } func printJson(token *oauth2.Token, indent string) { - data, err := marshalWithExtras(token, indent) + data, err := MarshalWithExtras(token, indent) if err != nil { log.Fatal(err.Error()) return