auth0: support explicit domains in the service account (#2980)

* auth0: support explicit domains in the service account

* also handle FromOptions
This commit is contained in:
Caleb Doxsey 2022-02-02 08:58:05 -07:00 committed by GitHub
parent 72dc9413cc
commit d1c4c55fd9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 52 additions and 15 deletions

View file

@ -4,8 +4,6 @@ package auth0
import (
"context"
"encoding/base64"
"encoding/json"
"errors"
"fmt"
"sort"
@ -13,6 +11,7 @@ import (
"github.com/rs/zerolog"
"gopkg.in/auth0.v5/management"
"github.com/pomerium/pomerium/internal/encoding"
"github.com/pomerium/pomerium/internal/log"
"github.com/pomerium/pomerium/pkg/grpc/directory"
)
@ -36,6 +35,10 @@ type (
type newManagersFunc = func(ctx context.Context, domain string, serviceAccount *ServiceAccount) (RoleManager, UserManager, error)
func defaultNewManagersFunc(ctx context.Context, domain string, serviceAccount *ServiceAccount) (RoleManager, UserManager, error) {
// override the domain for the management api if supplied
if serviceAccount.Domain != "" {
domain = serviceAccount.Domain
}
m, err := management.New(domain,
management.WithClientCredentials(serviceAccount.ClientID, serviceAccount.Secret),
management.WithContext(ctx))
@ -224,7 +227,9 @@ func getRoleUserIDs(rm RoleManager, roleID string) ([]string, error) {
// A ServiceAccount is used by the Auth0 provider to query the API.
type ServiceAccount struct {
Domain string `json:"domain"`
ClientID string `json:"client_id"`
ClientSecret string `json:"client_secret"`
Secret string `json:"secret"`
}
@ -245,6 +250,15 @@ func parseServiceAccountFromOptions(clientID, clientSecret string) (*ServiceAcco
if serviceAccount.ClientID == "" {
return nil, fmt.Errorf("auth0: client_id is required")
}
// for backwards compatibility we support secret and client_secret
if serviceAccount.Secret == "" {
serviceAccount.Secret = serviceAccount.ClientSecret
}
if serviceAccount.ClientSecret == "" {
serviceAccount.ClientSecret = serviceAccount.Secret
}
if serviceAccount.Secret == "" {
return nil, fmt.Errorf("auth0: client_secret is required")
}
@ -253,13 +267,8 @@ func parseServiceAccountFromOptions(clientID, clientSecret string) (*ServiceAcco
}
func parseServiceAccountFromString(rawServiceAccount string) (*ServiceAccount, error) {
bs, err := base64.StdEncoding.DecodeString(rawServiceAccount)
if err != nil {
return nil, fmt.Errorf("auth0: could not decode base64: %w", err)
}
var serviceAccount ServiceAccount
if err := json.Unmarshal(bs, &serviceAccount); err != nil {
if err := encoding.DecodeBase64OrJSON(rawServiceAccount, &serviceAccount); err != nil {
return nil, fmt.Errorf("auth0: could not unmarshal json: %w", err)
}
@ -267,6 +276,14 @@ func parseServiceAccountFromString(rawServiceAccount string) (*ServiceAccount, e
return nil, errors.New("auth0: client_id is required")
}
// for backwards compatibility we support secret and client_secret
if serviceAccount.Secret == "" {
serviceAccount.Secret = serviceAccount.ClientSecret
}
if serviceAccount.ClientSecret == "" {
serviceAccount.ClientSecret = serviceAccount.Secret
}
if serviceAccount.Secret == "" {
return nil, errors.New("auth0: secret is required")
}

View file

@ -155,8 +155,8 @@ func stringPtr(in string) *string {
}
func TestProvider_UserGroups(t *testing.T) {
expectedDomain := "example.com"
expectedServiceAccount := &ServiceAccount{ClientID: "c_id", Secret: "secret"}
expectedDomain := "login.example.com"
expectedServiceAccount := &ServiceAccount{Domain: "login-example.auth0.com", ClientID: "c_id", Secret: "secret"}
tests := []struct {
name string
@ -518,11 +518,31 @@ func TestParseServiceAccount(t *testing.T) {
"valid", "eyJjbGllbnRfaWQiOiJpLWFtLWNsaWVudC1pZCIsInNlY3JldCI6ImktYW0tc2VjcmV0In0K",
&ServiceAccount{
ClientID: "i-am-client-id",
ClientSecret: "i-am-secret",
Secret: "i-am-secret",
},
nil,
},
{"base64 err", "!!!!", nil, errors.New("auth0: could not decode base64: illegal base64 data at input byte 0")},
{
"json", `{"client_id": "i-am-client-id", "client_secret": "i-am-secret"}`,
&ServiceAccount{
ClientID: "i-am-client-id",
ClientSecret: "i-am-secret",
Secret: "i-am-secret",
},
nil,
},
{
"domain", `{"domain": "example.auth0.com", "client_id": "i-am-client-id", "client_secret": "i-am-secret"}`,
&ServiceAccount{
ClientID: "i-am-client-id",
ClientSecret: "i-am-secret",
Domain: "example.auth0.com",
Secret: "i-am-secret",
},
nil,
},
{"base64 err", "!!!!", nil, errors.New("auth0: could not unmarshal json: illegal base64 data at input byte 0")},
{"json err", "PAo=", nil, errors.New("auth0: could not unmarshal json: invalid character '<' looking for beginning of value")},
{"no client_id", "eyJzZWNyZXQiOiJpLWFtLXNlY3JldCJ9Cg==", nil, errors.New("auth0: client_id is required")},
{"no secret", "eyJjbGllbnRfaWQiOiJpLWFtLWNsaWVudC1pZCJ9Cg==", nil, errors.New("auth0: secret is required")},