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:
165
selfservice/flow/error_test.go
Normal file
165
selfservice/flow/error_test.go
Normal file
@@ -0,0 +1,165 @@
|
||||
// Copyright © 2023 Ory Corp
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package flow
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"testing"
|
||||
|
||||
"github.com/gofrs/uuid"
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/ory/kratos/identity"
|
||||
"github.com/ory/kratos/schema"
|
||||
"github.com/ory/kratos/text"
|
||||
"github.com/ory/kratos/ui/container"
|
||||
"github.com/ory/kratos/ui/node"
|
||||
"github.com/ory/kratos/x"
|
||||
"github.com/ory/x/httpx"
|
||||
"github.com/ory/x/logrusx"
|
||||
"github.com/ory/x/otelx"
|
||||
)
|
||||
|
||||
type testCSRFTokenGenerator struct{}
|
||||
|
||||
func (t *testCSRFTokenGenerator) GenerateCSRFToken(_ *http.Request) string {
|
||||
return "csrf_token_value"
|
||||
}
|
||||
|
||||
// testFlow is a minimalistic flow implementation to satisfy interface and is used only in tests.
|
||||
type testFlow struct {
|
||||
// ID represents the flow's unique ID.
|
||||
//
|
||||
// required: true
|
||||
ID uuid.UUID `json:"id" faker:"-" db:"id" rw:"r"`
|
||||
|
||||
// Type represents the flow's type which can be either "api" or "browser", depending on the flow interaction.
|
||||
//
|
||||
// required: true
|
||||
Type Type `json:"type" db:"type" faker:"flow_type"`
|
||||
|
||||
// RequestURL is the initial URL that was requested from Ory Kratos. It can be used
|
||||
// to forward information contained in the URL's path or query for example.
|
||||
//
|
||||
// required: true
|
||||
RequestURL string `json:"request_url" db:"request_url"`
|
||||
|
||||
// UI contains data which must be shown in the user interface.
|
||||
//
|
||||
// required: true
|
||||
UI *container.Container `json:"ui" db:"ui"`
|
||||
|
||||
// Flow State
|
||||
//
|
||||
// The state represents the state of the verification flow.
|
||||
//
|
||||
// - choose_method: ask the user to choose a method (e.g. recover account via email)
|
||||
// - sent_email: the email has been sent to the user
|
||||
// - passed_challenge: the request was successful and the recovery challenge was passed.
|
||||
//
|
||||
// required: true
|
||||
State State `json:"state" db:"state"`
|
||||
}
|
||||
|
||||
func (t *testFlow) GetID() uuid.UUID {
|
||||
return t.ID
|
||||
}
|
||||
|
||||
func (t *testFlow) GetType() Type {
|
||||
return t.Type
|
||||
}
|
||||
|
||||
func (t *testFlow) GetRequestURL() string {
|
||||
return t.RequestURL
|
||||
}
|
||||
|
||||
func (t *testFlow) AppendTo(url *url.URL) *url.URL {
|
||||
return AppendFlowTo(url, t.ID)
|
||||
}
|
||||
|
||||
func (t *testFlow) GetUI() *container.Container {
|
||||
return t.UI
|
||||
}
|
||||
|
||||
func (t *testFlow) GetState() State {
|
||||
return t.State
|
||||
}
|
||||
|
||||
func (t *testFlow) GetFlowName() FlowName {
|
||||
return FlowName("test")
|
||||
}
|
||||
|
||||
func (t *testFlow) SetState(state State) {
|
||||
t.State = state
|
||||
}
|
||||
|
||||
func (t *testFlow) GetTransientPayload() json.RawMessage {
|
||||
return nil
|
||||
}
|
||||
|
||||
func newTestFlow(r *http.Request, flowType Type) Flow {
|
||||
id := x.NewUUID()
|
||||
requestURL := x.RequestURL(r).String()
|
||||
ui := &container.Container{
|
||||
Method: "POST",
|
||||
Action: "/test",
|
||||
}
|
||||
|
||||
ui.Nodes.Append(node.NewInputField("traits.username", nil, node.PasswordGroup, node.InputAttributeTypeText, node.WithRequiredInputAttribute))
|
||||
ui.Nodes.Append(node.NewInputField("traits.password", nil, node.PasswordGroup, node.InputAttributeTypePassword, node.WithRequiredInputAttribute))
|
||||
|
||||
return &testFlow{
|
||||
ID: id,
|
||||
UI: ui,
|
||||
RequestURL: requestURL,
|
||||
Type: flowType,
|
||||
}
|
||||
}
|
||||
|
||||
func prepareTraits(username, password string) identity.Traits {
|
||||
payload := struct {
|
||||
Username string `json:"username"`
|
||||
Password string `json:"password"`
|
||||
}{username, password}
|
||||
|
||||
data, _ := json.Marshal(payload)
|
||||
return data
|
||||
}
|
||||
|
||||
func TestHandleHookError(t *testing.T) {
|
||||
r := &http.Request{URL: &url.URL{RawQuery: ""}}
|
||||
logger := logrusx.New("kratos", "test", logrusx.ForceLevel(logrus.FatalLevel))
|
||||
l := &x.BasicRegistry{L: logger, C: httpx.NewResilientClient(), T: otelx.NewNoop()}
|
||||
csrf := testCSRFTokenGenerator{}
|
||||
f := newTestFlow(r, TypeBrowser)
|
||||
tr := prepareTraits("foo", "bar")
|
||||
|
||||
t.Run("case=fill_in_traits", func(t *testing.T) {
|
||||
ve := schema.NewValidationListError([]*schema.ValidationError{schema.NewHookValidationError("traits.username", "invalid username", text.Messages{})})
|
||||
|
||||
err := HandleHookError(nil, r, f, tr, node.PasswordGroup, ve, l, &csrf)
|
||||
assert.ErrorIs(t, err, ve)
|
||||
if assert.NotEmpty(t, f.GetUI()) {
|
||||
ui := f.GetUI()
|
||||
assert.Len(t, ui.Nodes, 3)
|
||||
assert.ElementsMatch(t, ui.Nodes,
|
||||
node.Nodes{
|
||||
&node.Node{Type: node.Input, Group: node.PasswordGroup, Attributes: &node.InputAttributes{Name: "traits.username", Type: node.InputAttributeTypeText, FieldValue: "foo", Required: true}, Meta: &node.Meta{}},
|
||||
&node.Node{Type: node.Input, Group: node.PasswordGroup, Attributes: &node.InputAttributes{Name: "traits.password", Type: node.InputAttributeTypePassword, FieldValue: "bar", Required: true}, Meta: &node.Meta{}},
|
||||
&node.Node{Type: node.Input, Group: node.DefaultGroup, Attributes: &node.InputAttributes{Name: "csrf_token", Type: node.InputAttributeTypeHidden, FieldValue: "csrf_token_value", Required: true}},
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("case=unmarshal_fail", func(t *testing.T) {
|
||||
ve := schema.NewValidationListError([]*schema.ValidationError{schema.NewHookValidationError("traits.username", "invalid username", text.Messages{})})
|
||||
|
||||
err := HandleHookError(nil, r, f, []byte("garbage"), node.PasswordGroup, ve, l, &csrf)
|
||||
var jsonErr *json.SyntaxError
|
||||
assert.ErrorAs(t, err, &jsonErr)
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user