snapshot of https://github.com/ory/kratos.git (master, 2026-09-15; blobs > 131072B omitted)
Some checks failed
CI / Run tests and lints (push) Failing after 29s
CI / Build CLI docs (push) Has been skipped
CI / Run Playwright end-to-end tests (mysql) (push) Failing after 3s
CI / Run Playwright end-to-end tests (postgres) (push) Failing after 2s
CI / Run Playwright end-to-end tests (sqlite) (push) Failing after 3s
CodeQL / Analyze (go) (push) Failing after 4s
CodeQL / Analyze (javascript) (push) Failing after 3s
Docker Image Scanners / scanners (push) Failing after 4s
Synchronize Issue Labels / Synchronize Issue Labels (push) Has been skipped
CI / Run end-to-end tests (postgres) (push) Failing after 19s
CI / Run end-to-end tests (sqlite) (push) Failing after 2s
CI / Run Playwright end-to-end tests (cockroach) (push) Failing after 2s
CI / Draft newsletter (push) Has been skipped
CI / Generate release (push) Has been skipped
CI / Pending approval Slack notification (push) Has been skipped
CI / Send newsletter (push) Has been skipped
Some checks failed
CI / Run tests and lints (push) Failing after 29s
CI / Build CLI docs (push) Has been skipped
CI / Run Playwright end-to-end tests (mysql) (push) Failing after 3s
CI / Run Playwright end-to-end tests (postgres) (push) Failing after 2s
CI / Run Playwright end-to-end tests (sqlite) (push) Failing after 3s
CodeQL / Analyze (go) (push) Failing after 4s
CodeQL / Analyze (javascript) (push) Failing after 3s
Docker Image Scanners / scanners (push) Failing after 4s
Synchronize Issue Labels / Synchronize Issue Labels (push) Has been skipped
CI / Run end-to-end tests (postgres) (push) Failing after 19s
CI / Run end-to-end tests (sqlite) (push) Failing after 2s
CI / Run Playwright end-to-end tests (cockroach) (push) Failing after 2s
CI / Draft newsletter (push) Has been skipped
CI / Generate release (push) Has been skipped
CI / Pending approval Slack notification (push) Has been skipped
CI / Send newsletter (push) Has been skipped
This commit is contained in:
176
selfservice/strategy/oidc/provider_test.go
Normal file
176
selfservice/strategy/oidc/provider_test.go
Normal file
@@ -0,0 +1,176 @@
|
||||
// Copyright © 2023 Ory Corp
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package oidc
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"golang.org/x/oauth2"
|
||||
)
|
||||
|
||||
func TestClaimsValidate(t *testing.T) {
|
||||
require.Error(t, new(Claims).Validate())
|
||||
require.Error(t, (&Claims{Issuer: "not-empty"}).Validate())
|
||||
require.Error(t, (&Claims{Issuer: "not-empty"}).Validate())
|
||||
require.Error(t, (&Claims{Subject: "not-empty"}).Validate())
|
||||
require.Error(t, (&Claims{Subject: "not-empty"}).Validate())
|
||||
require.NoError(t, (&Claims{Issuer: "not-empty", Subject: "not-empty"}).Validate())
|
||||
}
|
||||
|
||||
type TestProvider struct {
|
||||
*ProviderGenericOIDC
|
||||
}
|
||||
|
||||
func NewTestProvider(c *Configuration, reg Dependencies) Provider {
|
||||
return &TestProvider{
|
||||
ProviderGenericOIDC: NewProviderGenericOIDC(c, reg).(*ProviderGenericOIDC),
|
||||
}
|
||||
}
|
||||
|
||||
func RegisterTestProvider(t *testing.T, id string) {
|
||||
supportedProviders[id] = func(c *Configuration, reg Dependencies) Provider {
|
||||
return NewTestProvider(c, reg)
|
||||
}
|
||||
t.Cleanup(func() {
|
||||
delete(supportedProviders, id)
|
||||
})
|
||||
}
|
||||
|
||||
var _ IDTokenVerifier = new(TestProvider)
|
||||
|
||||
func (t *TestProvider) Verify(_ context.Context, token string) (*Claims, error) {
|
||||
if token == "error" {
|
||||
return nil, fmt.Errorf("stub error")
|
||||
}
|
||||
c := Claims{}
|
||||
if err := json.Unmarshal([]byte(token), &c); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &c, nil
|
||||
}
|
||||
|
||||
// SetUserInfoURL allows overriding the userinfo URL for testing purposes.
|
||||
func (p *ProviderUAEPass) SetUserInfoURL(t *testing.T, url string) {
|
||||
t.Helper()
|
||||
p.userinfoURL = url
|
||||
}
|
||||
|
||||
// upstreamParam reports whether the option list produced by
|
||||
// UpstreamParameters contains a given upstream parameter, and its value.
|
||||
// The options are applied through a real oauth2.Config.AuthCodeURL so the
|
||||
// test observes exactly what is sent to the upstream provider.
|
||||
func upstreamParam(t *testing.T, opts []oauth2.AuthCodeOption, key string) (string, bool) {
|
||||
t.Helper()
|
||||
conf := &oauth2.Config{
|
||||
ClientID: "client",
|
||||
Endpoint: oauth2.Endpoint{AuthURL: "https://idp.example.com/auth"},
|
||||
}
|
||||
authURL, err := url.Parse(conf.AuthCodeURL("state", opts...))
|
||||
require.NoError(t, err)
|
||||
q := authURL.Query()
|
||||
if !q.Has(key) {
|
||||
return "", false
|
||||
}
|
||||
return q.Get(key), true
|
||||
}
|
||||
|
||||
func TestUpstreamParameters(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
upstream := map[string]string{
|
||||
"login_hint": "victim@example.com",
|
||||
"hd": "example.com",
|
||||
"prompt": "select_account",
|
||||
"auth_type": "reauthenticate",
|
||||
"acr_values": "urn:example:acr",
|
||||
"unknown": "dropped",
|
||||
}
|
||||
|
||||
opts := UpstreamParameters(upstream)
|
||||
|
||||
t.Run("case=login_hint is never forwarded", func(t *testing.T) {
|
||||
// A caller-supplied login_hint cannot be trusted and can steer
|
||||
// account/tenant/client selection on some IdPs, enabling a client-swap
|
||||
// attack (HackerOne #3239672, ory-corp/cloud#8955).
|
||||
_, ok := upstreamParam(t, opts, "login_hint")
|
||||
assert.False(t, ok, "login_hint must not be forwarded")
|
||||
})
|
||||
|
||||
t.Run("case=other allowed parameters are forwarded", func(t *testing.T) {
|
||||
for key, want := range map[string]string{
|
||||
"hd": "example.com",
|
||||
"prompt": "select_account",
|
||||
"auth_type": "reauthenticate",
|
||||
"acr_values": "urn:example:acr",
|
||||
} {
|
||||
got, ok := upstreamParam(t, opts, key)
|
||||
assert.True(t, ok, "%s must be forwarded", key)
|
||||
assert.Equal(t, want, got)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("case=unknown parameters are dropped", func(t *testing.T) {
|
||||
_, ok := upstreamParam(t, opts, "unknown")
|
||||
assert.False(t, ok, "unknown parameters must not be forwarded")
|
||||
})
|
||||
}
|
||||
|
||||
func TestLocale(t *testing.T) {
|
||||
// test json unmarshal
|
||||
for _, tc := range []struct {
|
||||
name string
|
||||
json string
|
||||
expected string
|
||||
assertErr assert.ErrorAssertionFunc
|
||||
}{{
|
||||
name: "empty",
|
||||
json: `{}`,
|
||||
expected: "",
|
||||
}, {
|
||||
name: "empty string locale",
|
||||
json: `{"locale":""}`,
|
||||
expected: "",
|
||||
}, {
|
||||
name: "invalid string locale",
|
||||
json: `{"locale":"""}`,
|
||||
assertErr: assert.Error,
|
||||
}, {
|
||||
name: "string locale",
|
||||
json: `{"locale":"en-US"}`,
|
||||
expected: "en-US",
|
||||
}, {
|
||||
name: "linkedin locale",
|
||||
json: `{"locale":{"country":"US","language":"en","ignore":"me"}}`,
|
||||
expected: "en-US",
|
||||
}, {
|
||||
name: "missing country linkedin locale",
|
||||
json: `{"locale":{"language":"en"}}`,
|
||||
expected: "en",
|
||||
}, {
|
||||
name: "missing language linkedin locale",
|
||||
json: `{"locale":{"country":"US"}}`,
|
||||
expected: "US",
|
||||
}, {
|
||||
name: "invalid linkedin locale",
|
||||
json: `{"locale":{"invalid":"me"}}`,
|
||||
expected: "",
|
||||
}} {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
var c Claims
|
||||
err := json.Unmarshal([]byte(tc.json), &c)
|
||||
if tc.assertErr != nil {
|
||||
tc.assertErr(t, err)
|
||||
return
|
||||
}
|
||||
require.NoError(t, err)
|
||||
assert.EqualValues(t, tc.expected, c.Locale)
|
||||
})
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user