Skip to content

Commit

Permalink
fix: support Auth0 connection url parameter (PS-28)
Browse files Browse the repository at this point in the history
  • Loading branch information
splaunov committed Nov 25, 2023
1 parent c25ddff commit 9bdd544
Show file tree
Hide file tree
Showing 22 changed files with 89 additions and 44 deletions.
5 changes: 5 additions & 0 deletions embedx/config.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -539,6 +539,11 @@
"type": "string",
"examples": ["12345678-1234-1234-1234-123456789012"]
}
},
"upstream_parameters": {
"title": "Parameters to be passed to OIDC provider as part of auth code URL",
"type": "object",
"additionalProperties": true
}
},
"additionalProperties": false,
Expand Down
2 changes: 1 addition & 1 deletion selfservice/strategy/oidc/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ type Provider interface {
Config() *Configuration
OAuth2(ctx context.Context) (*oauth2.Config, error)
Claims(ctx context.Context, exchange *oauth2.Token, query url.Values) (*Claims, error)
AuthCodeURLOptions(r ider) []oauth2.AuthCodeOption
AuthCodeURLOptions(r ider) ([]oauth2.AuthCodeOption, error)
}

type TokenExchanger interface {
Expand Down
4 changes: 2 additions & 2 deletions selfservice/strategy/oidc/provider_apple.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ func (a *ProviderApple) OAuth2(ctx context.Context) (*oauth2.Config, error) {
return a.oauth2(ctx)
}

func (a *ProviderApple) AuthCodeURLOptions(r ider) []oauth2.AuthCodeOption {
func (a *ProviderApple) AuthCodeURLOptions(r ider) ([]oauth2.AuthCodeOption, error) {

Check warning on line 93 in selfservice/strategy/oidc/provider_apple.go

View check run for this annotation

Codecov / codecov/patch

selfservice/strategy/oidc/provider_apple.go#L93

Added line #L93 was not covered by tests
var options []oauth2.AuthCodeOption

if isForced(r) {
Expand All @@ -109,7 +109,7 @@ func (a *ProviderApple) AuthCodeURLOptions(r ider) []oauth2.AuthCodeOption {
}
}

return options
return options, nil

Check warning on line 112 in selfservice/strategy/oidc/provider_apple.go

View check run for this annotation

Codecov / codecov/patch

selfservice/strategy/oidc/provider_apple.go#L112

Added line #L112 was not covered by tests
}

func (a *ProviderApple) Claims(ctx context.Context, exchange *oauth2.Token, query url.Values) (*Claims, error) {
Expand Down
3 changes: 3 additions & 0 deletions selfservice/strategy/oidc/provider_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,9 @@ type Configuration struct {
// AdditionalIDTokenAudiences is a list of additional audiences allowed in the ID Token.
// This is only relevant in OIDC flows that submit an IDToken instead of using the callback from the OIDC provider.
AdditionalIDTokenAudiences []string `json:"additional_id_token_audiences"`

// Parameters to be passed to OIDC provider as part of auth code URL
UpstreamParameters json.RawMessage `json:"upstream_parameters"`
}

func (p Configuration) Redir(public *url.URL) string {
Expand Down
4 changes: 2 additions & 2 deletions selfservice/strategy/oidc/provider_dingtalk.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,10 +55,10 @@ func (g *ProviderDingTalk) oauth2(ctx context.Context) *oauth2.Config {
}
}

func (g *ProviderDingTalk) AuthCodeURLOptions(r ider) []oauth2.AuthCodeOption {
func (g *ProviderDingTalk) AuthCodeURLOptions(r ider) ([]oauth2.AuthCodeOption, error) {

Check warning on line 58 in selfservice/strategy/oidc/provider_dingtalk.go

View check run for this annotation

Codecov / codecov/patch

selfservice/strategy/oidc/provider_dingtalk.go#L58

Added line #L58 was not covered by tests
return []oauth2.AuthCodeOption{
oauth2.SetAuthURLParam("prompt", "consent"),
}
}, nil

Check warning on line 61 in selfservice/strategy/oidc/provider_dingtalk.go

View check run for this annotation

Codecov / codecov/patch

selfservice/strategy/oidc/provider_dingtalk.go#L61

Added line #L61 was not covered by tests
}

func (g *ProviderDingTalk) OAuth2(ctx context.Context) (*oauth2.Config, error) {
Expand Down
6 changes: 3 additions & 3 deletions selfservice/strategy/oidc/provider_discord.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,15 +55,15 @@ func (d *ProviderDiscord) OAuth2(ctx context.Context) (*oauth2.Config, error) {
return d.oauth2(ctx), nil
}

func (d *ProviderDiscord) AuthCodeURLOptions(r ider) []oauth2.AuthCodeOption {
func (d *ProviderDiscord) AuthCodeURLOptions(r ider) ([]oauth2.AuthCodeOption, error) {

Check warning on line 58 in selfservice/strategy/oidc/provider_discord.go

View check run for this annotation

Codecov / codecov/patch

selfservice/strategy/oidc/provider_discord.go#L58

Added line #L58 was not covered by tests
if isForced(r) {
return []oauth2.AuthCodeOption{
oauth2.SetAuthURLParam("prompt", "consent"),
}
}, nil

Check warning on line 62 in selfservice/strategy/oidc/provider_discord.go

View check run for this annotation

Codecov / codecov/patch

selfservice/strategy/oidc/provider_discord.go#L62

Added line #L62 was not covered by tests
}
return []oauth2.AuthCodeOption{
oauth2.SetAuthURLParam("prompt", "none"),
}
}, nil

Check warning on line 66 in selfservice/strategy/oidc/provider_discord.go

View check run for this annotation

Codecov / codecov/patch

selfservice/strategy/oidc/provider_discord.go#L66

Added line #L66 was not covered by tests
}

func (d *ProviderDiscord) Claims(ctx context.Context, exchange *oauth2.Token, query url.Values) (*Claims, error) {
Expand Down
15 changes: 13 additions & 2 deletions selfservice/strategy/oidc/provider_generic_oidc.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ package oidc

import (
"context"
"encoding/json"
"net/url"

"github.com/pkg/errors"
Expand Down Expand Up @@ -74,7 +75,7 @@ func (g *ProviderGenericOIDC) OAuth2(ctx context.Context) (*oauth2.Config, error
return g.oauth2ConfigFromEndpoint(ctx, endpoint), nil
}

func (g *ProviderGenericOIDC) AuthCodeURLOptions(r ider) []oauth2.AuthCodeOption {
func (g *ProviderGenericOIDC) AuthCodeURLOptions(r ider) ([]oauth2.AuthCodeOption, error) {
var options []oauth2.AuthCodeOption

if isForced(r) {
Expand All @@ -84,7 +85,17 @@ func (g *ProviderGenericOIDC) AuthCodeURLOptions(r ider) []oauth2.AuthCodeOption
options = append(options, oauth2.SetAuthURLParam("claims", string(g.config.RequestedClaims)))
}

return options
if len(g.config.UpstreamParameters) != 0 {
var params map[string]string
if err := json.Unmarshal(g.config.UpstreamParameters, &params); err != nil {
return nil, err

Check warning on line 91 in selfservice/strategy/oidc/provider_generic_oidc.go

View check run for this annotation

Codecov / codecov/patch

selfservice/strategy/oidc/provider_generic_oidc.go#L91

Added line #L91 was not covered by tests
}
for key, value := range params {
options = append(options, oauth2.SetAuthURLParam(key, value))
}
}

return options, nil
}

func (g *ProviderGenericOIDC) verifyAndDecodeClaimsWithProvider(ctx context.Context, provider *gooidc.Provider, raw string) (*Claims, error) {
Expand Down
26 changes: 18 additions & 8 deletions selfservice/strategy/oidc/provider_generic_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,17 +37,20 @@ func makeOIDCClaims() json.RawMessage {

func makeAuthCodeURL(t *testing.T, r *login.Flow, reg *driver.RegistryDefault) string {
p := oidc.NewProviderGenericOIDC(&oidc.Configuration{
Provider: "generic",
ID: "valid",
ClientID: "client",
ClientSecret: "secret",
IssuerURL: "https://accounts.google.com",
Mapper: "file://./stub/hydra.schema.json",
RequestedClaims: makeOIDCClaims(),
Provider: "generic",
ID: "valid",
ClientID: "client",
ClientSecret: "secret",
IssuerURL: "https://accounts.google.com",
Mapper: "file://./stub/hydra.schema.json",
RequestedClaims: makeOIDCClaims(),
UpstreamParameters: json.RawMessage(`{"connection": "c1"}`),
}, reg)
c, err := p.OAuth2(context.Background())
require.NoError(t, err)
return c.AuthCodeURL("state", p.AuthCodeURLOptions(r)...)
options, err := p.AuthCodeURLOptions(r)
require.NoError(t, err)
return c.AuthCodeURL("state", options...)
}

func TestProviderGenericOIDC_AddAuthCodeURLOptions(t *testing.T) {
Expand Down Expand Up @@ -93,4 +96,11 @@ func TestProviderGenericOIDC_AddAuthCodeURLOptions(t *testing.T) {
}
assert.Contains(t, makeAuthCodeURL(t, r, reg), "claims="+url.QueryEscape(string(makeOIDCClaims())))
})

t.Run("case=expect connection to be set", func(t *testing.T) {
r := &login.Flow{
ID: x.NewUUID(),
}
assert.Contains(t, makeAuthCodeURL(t, r, reg), "connection=c1")
})
}
4 changes: 2 additions & 2 deletions selfservice/strategy/oidc/provider_github.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,8 @@ func (g *ProviderGitHub) OAuth2(ctx context.Context) (*oauth2.Config, error) {
return g.oauth2(ctx), nil
}

func (g *ProviderGitHub) AuthCodeURLOptions(r ider) []oauth2.AuthCodeOption {
return []oauth2.AuthCodeOption{}
func (g *ProviderGitHub) AuthCodeURLOptions(r ider) ([]oauth2.AuthCodeOption, error) {
return []oauth2.AuthCodeOption{}, nil

Check warning on line 60 in selfservice/strategy/oidc/provider_github.go

View check run for this annotation

Codecov / codecov/patch

selfservice/strategy/oidc/provider_github.go#L59-L60

Added lines #L59 - L60 were not covered by tests
}

func (g *ProviderGitHub) Claims(ctx context.Context, exchange *oauth2.Token, query url.Values) (*Claims, error) {
Expand Down
4 changes: 2 additions & 2 deletions selfservice/strategy/oidc/provider_github_app.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,8 @@ func (g *ProviderGitHubApp) OAuth2(ctx context.Context) (*oauth2.Config, error)
return g.oauth2(ctx), nil
}

func (g *ProviderGitHubApp) AuthCodeURLOptions(r ider) []oauth2.AuthCodeOption {
return []oauth2.AuthCodeOption{}
func (g *ProviderGitHubApp) AuthCodeURLOptions(r ider) ([]oauth2.AuthCodeOption, error) {
return []oauth2.AuthCodeOption{}, nil

Check warning on line 57 in selfservice/strategy/oidc/provider_github_app.go

View check run for this annotation

Codecov / codecov/patch

selfservice/strategy/oidc/provider_github_app.go#L56-L57

Added lines #L56 - L57 were not covered by tests
}

func (g *ProviderGitHubApp) Claims(ctx context.Context, exchange *oauth2.Token, query url.Values) (*Claims, error) {
Expand Down
9 changes: 6 additions & 3 deletions selfservice/strategy/oidc/provider_google.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,15 +58,18 @@ func (g *ProviderGoogle) OAuth2(ctx context.Context) (*oauth2.Config, error) {
return g.oauth2ConfigFromEndpoint(ctx, endpoint), nil
}

func (g *ProviderGoogle) AuthCodeURLOptions(r ider) []oauth2.AuthCodeOption {
func (g *ProviderGoogle) AuthCodeURLOptions(r ider) ([]oauth2.AuthCodeOption, error) {
scope := g.config.Scope
options := g.ProviderGenericOIDC.AuthCodeURLOptions(r)
options, err := g.ProviderGenericOIDC.AuthCodeURLOptions(r)
if err != nil {
return nil, err

Check warning on line 65 in selfservice/strategy/oidc/provider_google.go

View check run for this annotation

Codecov / codecov/patch

selfservice/strategy/oidc/provider_google.go#L65

Added line #L65 was not covered by tests
}

if stringslice.Has(scope, gooidc.ScopeOfflineAccess) {
options = append(options, oauth2.AccessTypeOffline)
}

return options
return options, nil
}

var _ IDTokenVerifier = new(ProviderGoogle)
Expand Down
3 changes: 2 additions & 1 deletion selfservice/strategy/oidc/provider_google_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,8 @@ func TestProviderGoogle_AccessType(t *testing.T) {
ID: x.NewUUID(),
}

options := p.AuthCodeURLOptions(r)
options, err := p.AuthCodeURLOptions(r)
require.NoError(t, err)
assert.Contains(t, options, oauth2.AccessTypeOffline)
}

Expand Down
4 changes: 2 additions & 2 deletions selfservice/strategy/oidc/provider_lark.go
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,6 @@ func (g *ProviderLark) Claims(ctx context.Context, exchange *oauth2.Token, query
}, nil
}

func (pl *ProviderLark) AuthCodeURLOptions(r ider) []oauth2.AuthCodeOption {
return []oauth2.AuthCodeOption{}
func (pl *ProviderLark) AuthCodeURLOptions(r ider) ([]oauth2.AuthCodeOption, error) {
return []oauth2.AuthCodeOption{}, nil

Check warning on line 116 in selfservice/strategy/oidc/provider_lark.go

View check run for this annotation

Codecov / codecov/patch

selfservice/strategy/oidc/provider_lark.go#L115-L116

Added lines #L115 - L116 were not covered by tests
}
4 changes: 2 additions & 2 deletions selfservice/strategy/oidc/provider_linkedin.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,8 +96,8 @@ func (l *ProviderLinkedIn) OAuth2(ctx context.Context) (*oauth2.Config, error) {
return l.oauth2(ctx), nil
}

func (l *ProviderLinkedIn) AuthCodeURLOptions(r ider) []oauth2.AuthCodeOption {
return []oauth2.AuthCodeOption{}
func (l *ProviderLinkedIn) AuthCodeURLOptions(r ider) ([]oauth2.AuthCodeOption, error) {
return []oauth2.AuthCodeOption{}, nil

Check warning on line 100 in selfservice/strategy/oidc/provider_linkedin.go

View check run for this annotation

Codecov / codecov/patch

selfservice/strategy/oidc/provider_linkedin.go#L99-L100

Added lines #L99 - L100 were not covered by tests
}

func (l *ProviderLinkedIn) fetch(ctx context.Context, client *retryablehttp.Client, url string, result interface{}) (err error) {
Expand Down
6 changes: 3 additions & 3 deletions selfservice/strategy/oidc/provider_patreon.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,15 +68,15 @@ func (d *ProviderPatreon) OAuth2(ctx context.Context) (*oauth2.Config, error) {
return d.oauth2(ctx), nil
}

func (d *ProviderPatreon) AuthCodeURLOptions(r ider) []oauth2.AuthCodeOption {
func (d *ProviderPatreon) AuthCodeURLOptions(r ider) ([]oauth2.AuthCodeOption, error) {

Check warning on line 71 in selfservice/strategy/oidc/provider_patreon.go

View check run for this annotation

Codecov / codecov/patch

selfservice/strategy/oidc/provider_patreon.go#L71

Added line #L71 was not covered by tests
if isForced(r) {
return []oauth2.AuthCodeOption{
oauth2.SetAuthURLParam("prompt", "consent"),
}
}, nil

Check warning on line 75 in selfservice/strategy/oidc/provider_patreon.go

View check run for this annotation

Codecov / codecov/patch

selfservice/strategy/oidc/provider_patreon.go#L75

Added line #L75 was not covered by tests
}
return []oauth2.AuthCodeOption{
oauth2.SetAuthURLParam("prompt", "none"),
}
}, nil

Check warning on line 79 in selfservice/strategy/oidc/provider_patreon.go

View check run for this annotation

Codecov / codecov/patch

selfservice/strategy/oidc/provider_patreon.go#L79

Added line #L79 was not covered by tests
}

func (d *ProviderPatreon) Claims(ctx context.Context, exchange *oauth2.Token, query url.Values) (*Claims, error) {
Expand Down
4 changes: 2 additions & 2 deletions selfservice/strategy/oidc/provider_slack.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,8 @@ func (d *ProviderSlack) OAuth2(ctx context.Context) (*oauth2.Config, error) {
return d.oauth2(ctx), nil
}

func (d *ProviderSlack) AuthCodeURLOptions(r ider) []oauth2.AuthCodeOption {
return []oauth2.AuthCodeOption{}
func (d *ProviderSlack) AuthCodeURLOptions(r ider) ([]oauth2.AuthCodeOption, error) {
return []oauth2.AuthCodeOption{}, nil

Check warning on line 61 in selfservice/strategy/oidc/provider_slack.go

View check run for this annotation

Codecov / codecov/patch

selfservice/strategy/oidc/provider_slack.go#L60-L61

Added lines #L60 - L61 were not covered by tests
}

func (d *ProviderSlack) Claims(ctx context.Context, exchange *oauth2.Token, query url.Values) (*Claims, error) {
Expand Down
4 changes: 2 additions & 2 deletions selfservice/strategy/oidc/provider_spotify.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,8 @@ func (g *ProviderSpotify) OAuth2(ctx context.Context) (*oauth2.Config, error) {
return g.oauth2(ctx), nil
}

func (g *ProviderSpotify) AuthCodeURLOptions(r ider) []oauth2.AuthCodeOption {
return []oauth2.AuthCodeOption{}
func (g *ProviderSpotify) AuthCodeURLOptions(r ider) ([]oauth2.AuthCodeOption, error) {
return []oauth2.AuthCodeOption{}, nil

Check warning on line 60 in selfservice/strategy/oidc/provider_spotify.go

View check run for this annotation

Codecov / codecov/patch

selfservice/strategy/oidc/provider_spotify.go#L59-L60

Added lines #L59 - L60 were not covered by tests
}

func (g *ProviderSpotify) Claims(ctx context.Context, exchange *oauth2.Token, query url.Values) (*Claims, error) {
Expand Down
4 changes: 2 additions & 2 deletions selfservice/strategy/oidc/provider_vk.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,8 @@ func (g *ProviderVK) oauth2(ctx context.Context) *oauth2.Config {
}
}

func (g *ProviderVK) AuthCodeURLOptions(r ider) []oauth2.AuthCodeOption {
return []oauth2.AuthCodeOption{}
func (g *ProviderVK) AuthCodeURLOptions(r ider) ([]oauth2.AuthCodeOption, error) {
return []oauth2.AuthCodeOption{}, nil

Check warning on line 55 in selfservice/strategy/oidc/provider_vk.go

View check run for this annotation

Codecov / codecov/patch

selfservice/strategy/oidc/provider_vk.go#L54-L55

Added lines #L54 - L55 were not covered by tests
}

func (g *ProviderVK) OAuth2(ctx context.Context) (*oauth2.Config, error) {
Expand Down
4 changes: 2 additions & 2 deletions selfservice/strategy/oidc/provider_yandex.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,8 @@ func (g *ProviderYandex) oauth2(ctx context.Context) *oauth2.Config {
}
}

func (g *ProviderYandex) AuthCodeURLOptions(r ider) []oauth2.AuthCodeOption {
return []oauth2.AuthCodeOption{}
func (g *ProviderYandex) AuthCodeURLOptions(r ider) ([]oauth2.AuthCodeOption, error) {
return []oauth2.AuthCodeOption{}, nil

Check warning on line 53 in selfservice/strategy/oidc/provider_yandex.go

View check run for this annotation

Codecov / codecov/patch

selfservice/strategy/oidc/provider_yandex.go#L52-L53

Added lines #L52 - L53 were not covered by tests
}

func (g *ProviderYandex) OAuth2(ctx context.Context) (*oauth2.Config, error) {
Expand Down
6 changes: 5 additions & 1 deletion selfservice/strategy/oidc/strategy_login.go
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,11 @@ func (s *Strategy) Login(w http.ResponseWriter, r *http.Request, f *login.Flow,
return nil, err
}

codeURL := c.AuthCodeURL(state.String(), append(UpstreamParameters(provider, up), provider.AuthCodeURLOptions(req)...)...)
options, err := provider.AuthCodeURLOptions(req)
if err != nil {
return nil, s.handleError(w, r, f, pid, nil, err)

Check warning on line 281 in selfservice/strategy/oidc/strategy_login.go

View check run for this annotation

Codecov / codecov/patch

selfservice/strategy/oidc/strategy_login.go#L281

Added line #L281 was not covered by tests
}
codeURL := c.AuthCodeURL(state.String(), append(UpstreamParameters(provider, up), options...)...)
if x.IsJSONRequest(r) {
s.d.Writer().WriteError(w, r, flow.NewBrowserLocationChangeRequiredError(codeURL))
} else {
Expand Down
6 changes: 5 additions & 1 deletion selfservice/strategy/oidc/strategy_registration.go
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,11 @@ func (s *Strategy) Register(w http.ResponseWriter, r *http.Request, f *registrat
return err
}

codeURL := c.AuthCodeURL(state.String(), append(UpstreamParameters(provider, up), provider.AuthCodeURLOptions(req)...)...)
options, err := provider.AuthCodeURLOptions(req)
if err != nil {
return s.handleError(w, r, f, pid, nil, err)

Check warning on line 245 in selfservice/strategy/oidc/strategy_registration.go

View check run for this annotation

Codecov / codecov/patch

selfservice/strategy/oidc/strategy_registration.go#L245

Added line #L245 was not covered by tests
}
codeURL := c.AuthCodeURL(state.String(), append(UpstreamParameters(provider, up), options...)...)
if x.IsJSONRequest(r) {
s.d.Writer().WriteError(w, r, flow.NewBrowserLocationChangeRequiredError(codeURL))
} else {
Expand Down
6 changes: 5 additions & 1 deletion selfservice/strategy/oidc/strategy_settings.go
Original file line number Diff line number Diff line change
Expand Up @@ -379,7 +379,11 @@ func (s *Strategy) initLinkProvider(w http.ResponseWriter, r *http.Request, ctxU
return err
}

codeURL := c.AuthCodeURL(state, append(UpstreamParameters(provider, up), provider.AuthCodeURLOptions(req)...)...)
options, err := provider.AuthCodeURLOptions(req)
if err != nil {
return s.handleSettingsError(w, r, ctxUpdate, p, err)

Check warning on line 384 in selfservice/strategy/oidc/strategy_settings.go

View check run for this annotation

Codecov / codecov/patch

selfservice/strategy/oidc/strategy_settings.go#L384

Added line #L384 was not covered by tests
}
codeURL := c.AuthCodeURL(state, append(UpstreamParameters(provider, up), options...)...)
if x.IsJSONRequest(r) {
s.d.Writer().WriteError(w, r, flow.NewBrowserLocationChangeRequiredError(codeURL))
} else {
Expand Down

0 comments on commit 9bdd544

Please sign in to comment.