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:
224
selfservice/strategy/password/op_helpers_test.go
Normal file
224
selfservice/strategy/password/op_helpers_test.go
Normal file
@@ -0,0 +1,224 @@
|
||||
// Copyright © 2023 Ory Corp
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package password_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"strconv"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/gofrs/uuid"
|
||||
"github.com/phayes/freeport"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"golang.org/x/oauth2"
|
||||
|
||||
"github.com/moby/moby/api/types/container"
|
||||
"github.com/moby/moby/api/types/network"
|
||||
|
||||
dockertest "github.com/ory/dockertest/v4"
|
||||
hydraclientgo "github.com/ory/hydra-client-go/v2"
|
||||
"github.com/ory/kratos/pkg/testhelpers"
|
||||
"github.com/ory/x/urlx"
|
||||
)
|
||||
|
||||
type clientAppConfig struct {
|
||||
client *oauth2.Config
|
||||
expectToken bool
|
||||
state *clientAppState
|
||||
}
|
||||
|
||||
type clientAppState struct {
|
||||
visits int64
|
||||
tokens int64
|
||||
}
|
||||
|
||||
type callTrace string
|
||||
|
||||
const (
|
||||
RegistrationUI callTrace = "registration-ui"
|
||||
RegistrationWithOAuth2LoginChallenge callTrace = "registration-with-oauth2-login-challenge"
|
||||
RegistrationWithFlowID callTrace = "registration-with-flow-id"
|
||||
LoginUI callTrace = "login-ui"
|
||||
LoginWithOAuth2LoginChallenge callTrace = "login-with-oauth2-login-challenge"
|
||||
LoginWithFlowID callTrace = "login-with-flow-id"
|
||||
Consent callTrace = "consent"
|
||||
ConsentWithChallenge callTrace = "consent-with-challenge"
|
||||
ConsentAccept callTrace = "consent-accept"
|
||||
ConsentSkip callTrace = "consent-skip"
|
||||
ConsentClientSkip callTrace = "consent-client-skip"
|
||||
CodeExchange callTrace = "code-exchange"
|
||||
CodeExchangeWithToken callTrace = "code-exchange-with-token"
|
||||
)
|
||||
|
||||
type testContextKey string
|
||||
|
||||
const (
|
||||
TestUIConfig testContextKey = "test-ui-config"
|
||||
TestOAuthClientState testContextKey = "test-oauth-client-state"
|
||||
)
|
||||
|
||||
type testConfig struct {
|
||||
identifier string
|
||||
password string
|
||||
browserClient *http.Client
|
||||
kratosPublicTS *httptest.Server
|
||||
clientAppTS *httptest.Server
|
||||
hydraAdminClient hydraclientgo.OAuth2API
|
||||
consentRemember bool
|
||||
requestedScope []string
|
||||
callTrace *[]callTrace
|
||||
}
|
||||
|
||||
func createHydraOAuth2ApiClient(url string) hydraclientgo.OAuth2API {
|
||||
configuration := hydraclientgo.NewConfiguration()
|
||||
configuration.Host = urlx.ParseOrPanic(url).Host
|
||||
configuration.Servers = hydraclientgo.ServerConfigurations{{URL: url}}
|
||||
|
||||
return hydraclientgo.NewAPIClient(configuration).OAuth2API
|
||||
}
|
||||
|
||||
func createOAuth2Client(t *testing.T, ctx context.Context, hydraAdmin hydraclientgo.OAuth2API, redirectURIs []string, scope string, skipConsent bool) string {
|
||||
t.Helper()
|
||||
|
||||
clientName := "kratos-hydra-integration-test-client-1"
|
||||
tokenEndpointAuthMethod := "client_secret_post"
|
||||
clientSecret := "client-secret"
|
||||
|
||||
c, r, err := hydraAdmin.CreateOAuth2Client(ctx).OAuth2Client(
|
||||
hydraclientgo.OAuth2Client{
|
||||
ClientName: &clientName,
|
||||
RedirectUris: redirectURIs,
|
||||
Scope: &scope,
|
||||
TokenEndpointAuthMethod: &tokenEndpointAuthMethod,
|
||||
ClientSecret: &clientSecret,
|
||||
SkipConsent: &skipConsent,
|
||||
},
|
||||
).Execute()
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, r.StatusCode, http.StatusCreated)
|
||||
return *c.ClientId
|
||||
}
|
||||
|
||||
func makeAuthCodeURL(t *testing.T, c *oauth2.Config, requestedClaims string, isForced bool) string {
|
||||
t.Helper()
|
||||
|
||||
var options []oauth2.AuthCodeOption
|
||||
|
||||
if isForced {
|
||||
options = append(options, oauth2.SetAuthURLParam("prompt", "login"))
|
||||
}
|
||||
if requestedClaims != "" {
|
||||
options = append(options, oauth2.SetAuthURLParam("claims", requestedClaims))
|
||||
}
|
||||
|
||||
state := fmt.Sprintf("%x", uuid.Must(uuid.NewV4()))
|
||||
return c.AuthCodeURL(state, options...)
|
||||
}
|
||||
|
||||
func newHydra(t *testing.T, loginUI string, consentUI string) (hydraAdmin string, hydraPublic string) {
|
||||
pool := dockertest.NewPoolT(t, "")
|
||||
|
||||
// The public host port must be known before the container starts because it
|
||||
// is part of URLS_SELF_ISSUER. freeport releases the port before Docker binds
|
||||
// it, so another process can grab it in between — retry on that race.
|
||||
var hydraResource dockertest.ClosableResource
|
||||
ctx := t.Context()
|
||||
require.EventuallyWithT(t, func(t *assert.CollectT) {
|
||||
publicPort, err := freeport.GetFreePort()
|
||||
require.NoError(t, err)
|
||||
|
||||
hydraResource, err = pool.Run(ctx, "oryd/hydra",
|
||||
// Keep tag in sync with the version in ci.yaml
|
||||
dockertest.WithTag("v2.2.0"),
|
||||
dockertest.WithoutReuse(),
|
||||
dockertest.WithEnv([]string{
|
||||
"DSN=memory",
|
||||
fmt.Sprintf("URLS_SELF_ISSUER=http://127.0.0.1:%d/", publicPort),
|
||||
"URLS_LOGIN=" + loginUI,
|
||||
"URLS_CONSENT=" + consentUI,
|
||||
"LOG_LEAK_SENSITIVE_VALUES=true",
|
||||
"SECRETS_SYSTEM=someverylongsecretthatis32byteslong",
|
||||
}),
|
||||
dockertest.WithCmd([]string{"serve", "all", "--dev"}),
|
||||
dockertest.WithContainerConfig(func(cc *container.Config) {
|
||||
cc.ExposedPorts = network.PortSet{
|
||||
network.MustParsePort("4444/tcp"): struct{}{},
|
||||
network.MustParsePort("4445/tcp"): struct{}{},
|
||||
}
|
||||
}),
|
||||
dockertest.WithHostConfig(func(hc *container.HostConfig) {
|
||||
hc.PortBindings = network.PortMap{
|
||||
network.MustParsePort("4444/tcp"): {{HostPort: strconv.Itoa(publicPort)}},
|
||||
network.MustParsePort("4445/tcp"): {{HostPort: ""}},
|
||||
}
|
||||
}),
|
||||
)
|
||||
require.NoError(t, err)
|
||||
}, 2*time.Minute, 100*time.Millisecond)
|
||||
hydraResource.Cleanup(t)
|
||||
require.NotEmpty(t, hydraResource.GetPort("4444/tcp"), "%+v", hydraResource.Container().NetworkSettings.Ports)
|
||||
require.NotEmpty(t, hydraResource.GetPort("4445/tcp"), "%+v", hydraResource.Container)
|
||||
|
||||
hydraPublic = "http://127.0.0.1:" + hydraResource.GetPort("4444/tcp")
|
||||
hydraAdmin = "http://127.0.0.1:" + hydraResource.GetPort("4445/tcp")
|
||||
|
||||
go func() {
|
||||
stdout, stderr, err := hydraResource.Logs(context.Background())
|
||||
if err == nil {
|
||||
if stdout != "" {
|
||||
t.Logf("[hydra stdout]:\n%s\n", stdout)
|
||||
}
|
||||
if stderr != "" {
|
||||
t.Logf("[hydra stderr]:\n%s\n", stderr)
|
||||
}
|
||||
}
|
||||
}()
|
||||
client := testhelpers.NewTestClient(t)
|
||||
require.EventuallyWithT(t, func(t *assert.CollectT) {
|
||||
res, err := client.Get(hydraPublic + "/health/ready")
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, 200, res.StatusCode)
|
||||
|
||||
res, err = client.Get(hydraAdmin + "/health/ready")
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, 200, res.StatusCode)
|
||||
}, 30*time.Second, time.Second)
|
||||
|
||||
t.Logf("Ory Hydra running at: %s %s", hydraPublic, hydraAdmin)
|
||||
|
||||
return hydraAdmin, hydraPublic
|
||||
}
|
||||
|
||||
type TestLogWriter struct {
|
||||
streamName string
|
||||
*testing.T
|
||||
}
|
||||
|
||||
func (t TestLogWriter) Write(p []byte) (int, error) {
|
||||
t.Logf("[%d bytes @ %s]:\n\n%s\n", len(p), t.streamName, string(p))
|
||||
return len(p), nil
|
||||
}
|
||||
|
||||
func doOAuthFlow(t *testing.T, ctx context.Context, oauthClient *oauth2.Config, browserClient *http.Client) {
|
||||
t.Helper()
|
||||
|
||||
authCodeURL := makeAuthCodeURL(t, oauthClient, "", false)
|
||||
req, err := http.NewRequestWithContext(ctx, http.MethodGet, authCodeURL, nil)
|
||||
require.NoError(t, err)
|
||||
res, err := browserClient.Do(req)
|
||||
require.NoError(t, err)
|
||||
|
||||
body, err := io.ReadAll(res.Body)
|
||||
require.NoError(t, err)
|
||||
|
||||
require.NoError(t, res.Body.Close())
|
||||
require.Equal(t, "", string(body))
|
||||
require.Equal(t, http.StatusOK, res.StatusCode)
|
||||
}
|
||||
Reference in New Issue
Block a user