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

This commit is contained in:
upstream-mirror
2026-09-15 21:19:12 +05:00
commit c60cc7ca75
8092 changed files with 394160 additions and 0 deletions

17
test/schema/README.md Normal file
View File

@@ -0,0 +1,17 @@
# Schema Tests
This test works by validating cases of the payload against a schema.
To add a case, place a file in the `${schemaName}.schema.test.${success|failure}` folder.
A success case should validate, a failure case should throw a validation error.
## Handling of "$ref"
To allow testing definitions on their own, and reduce the size of individual cases,
every `"$ref"` in the schema will be replaced with `"const"` before validation.
This means that a case only has to define the pointer as a string. Example:
```yaml
default_browser_return_url: "#/definitions/defaultReturnTo"
hooks:
- "#/definitions/selfServiceSessionRevokerHook"
```

View File

@@ -0,0 +1,18 @@
userinfo:
given_name:
essential: true
someInvalidProperty: 'invalid' # Invalid property
nickname: null
email:
essential: InvalidValueForEssential
email_verified:
essentials: true # key typo
picture: null
http://example/info/claims/groups: null
id_token:
auth_time:
essential: true
acr:
values: ['urn:mace:incommon:iap:silver']
sub:
value: '248289761001'

View File

@@ -0,0 +1,5 @@
valid:
email:
body:
plaintext: "https://some-url"
subject: "https://some-url"

View File

@@ -0,0 +1,4 @@
invalid:
another-courier:
valid:
email:

View File

@@ -0,0 +1,4 @@
body:
plaintext: "http://call-something"
html: "malformed uri"
subject: "something"

View File

@@ -0,0 +1,5 @@
sms:
request_config:
url: "malformed uri"
method: POST
body: "malformed uri"

View File

@@ -0,0 +1,81 @@
selfservice:
strategies:
password:
enabled: 0
oidc:
enabled: 0
config:
providers:
- foo
logout:
redirect_to: 0
profile:
lifespan: 10
login:
lifespan: 10
before: foo
after: foo
registration:
lifespan: 10
before:
- foo
after: foo
dsn: foo
courier:
template_override_path: foo
smtp:
connection_uri: 0
from_address: 0
message_retries: invalid-value
serve:
admin:
host: 0
port: foo
public:
host: 0
port: foo
urls:
self:
public: 1
admin: 1
mfa_ui: 1
login_ui: 1
settings_ui: 1
default_return_to: 1
registration_ui: 1
error_ui: 1
allowed_return_urls:
- 1
- 1
log:
level: 1
format: 1
identity:
traits:
default_schema_id: 1123
schemas:
- id: 1
url: 1
secrets:
session:
- 1
hashers:
argon2:
memory: foo
iterations: foo
parallelism: foo
salt_length: foo
key_length: foo

View File

@@ -0,0 +1 @@
version: x1.0.0

View File

@@ -0,0 +1,20 @@
selfservice:
default_browser_return_url: "#/definitions/defaultReturnTo"
dsn: foo
identity:
schemas:
- id: default
url: https://example.com
courier:
template_override_path: foo
smtp:
connection_uri: smtps://foo:bar@my-mailserver:1234/
from_address: no-reply@ory.kratos.sh
templates:
recovery: "#/definitions/courierTemplates"
verification:
valid:
email: "#/definitions/emailCourierTemplate"

View File

@@ -0,0 +1,12 @@
selfservice:
default_browser_return_url: "#/definitions/defaultReturnTo"
flows:
recovery:
enabled: true
dsn: foo
identity:
schemas:
- id: default
url: https://example.com

View File

@@ -0,0 +1,12 @@
selfservice:
default_browser_return_url: "#/definitions/defaultReturnTo"
flows:
verification:
enabled: true
dsn: foo
identity:
schemas:
- id: default
url: https://example.com

View File

@@ -0,0 +1,11 @@
id: 1
provider: unknown
client_id: 1
client_secret: 1
issuer_url: not an URL
auth_url: not an URL
token_url: not an URL
mapper_url: not an URL
scope:
- 1
microsoft_tenant: 1

View File

@@ -0,0 +1,6 @@
id: foo
provider: github
client_id: asdf
client_secret: asdf
mapper_url: file://./mapper_file
apple_private_key_id: org

View File

@@ -0,0 +1,10 @@
id: foo
provider: apple
client_id: foo
team_id: foo
private_key: foo
mapper_url: https://example.com
scope:
- foo
- bar
requested_claims: "#/definitions/OIDCClaims"

View File

@@ -0,0 +1,6 @@
id: foo
provider: github
client_id: asdf
client_secret: asdf
mapper_url: file://./mapper_file
private_key: org

View File

@@ -0,0 +1,10 @@
id: foo
provider: apple
client_id: foo
apple_team_id: foo
apple_private_key_id: foo
mapper_url: https://example.com
scope:
- foo
- bar
requested_claims: "#/definitions/OIDCClaims"

View File

@@ -0,0 +1,6 @@
id: foo
provider: github
client_id: asdf
client_secret: asdf
mapper_url: file://./mapper_file
team_id: org

View File

@@ -0,0 +1,10 @@
id: foo
provider: apple
client_id: foo
apple_private_key_id: foo
apple_private_key: foo
mapper_url: https://example.com
scope:
- foo
- bar
requested_claims: "#/definitions/OIDCClaims"

View File

@@ -0,0 +1,6 @@
id: foo
provider: github
client_id: asdf
client_secret: asdf
mapper_url: file://./mapper_file
microsoft_tenant: org

View File

@@ -0,0 +1,5 @@
id: foo
provider: microsoft
client_id: asdf
client_secret: asdf
mapper_url: file://./mapper_file

View File

@@ -0,0 +1,18 @@
userinfo:
given_name:
essential: true
nickname: null
email:
essential: true
email_verified:
essential: true
picture: null
http://example/info/claims/groups: null
id_token:
auth_time:
essential: true
acr:
values: ['urn:mace:incommon:iap:silver']
sub:
essential: true
value: 248289761001

View File

@@ -0,0 +1,4 @@
invalid:
email: "#/definitions/emailCourierTemplate"
valid:
email: "#/definitions/emailCourierTemplate"

View File

@@ -0,0 +1 @@
https://my-app.com/dashboard

View File

@@ -0,0 +1,4 @@
body:
plaintext: "base64://"
html: "base64://"
subject: "http://"

View File

@@ -0,0 +1 @@
subject: "http://"

View File

@@ -0,0 +1,3 @@
body:
plaintext: "base64://"
html: "base64://"

View File

@@ -0,0 +1,19 @@
selfservice:
default_browser_return_url: "#/definitions/defaultReturnTo"
dsn: foo
identity:
schemas:
- id: default
url: https://example.com
courier:
message_retries: 50
smtp:
connection_uri: smtps://foo:bar@my-mailserver:1234/
from_address: no-reply@ory.kratos.sh
channels:
- id: sms
type: http
request_config: "#/definitions/httpRequestConfig"

View File

@@ -0,0 +1,18 @@
selfservice:
default_browser_return_url: "#/definitions/defaultReturnTo"
dsn: foo
identity:
schemas:
- id: default
url: https://example.com
courier:
template_override_path: foo
smtp:
connection_uri: smtps://foo:bar@my-mailserver:1234/
from_address: no-reply@ory.kratos.sh
templates:
recovery: "#/definitions/courierTemplates"
verification: "#/definitions/courierTemplates"

View File

@@ -0,0 +1,109 @@
selfservice:
default_browser_return_url: "#/definitions/defaultReturnTo"
allowed_return_urls:
- https://foo.bar
- /dashboard
flows:
settings:
ui_url: /settings
lifespan: 1h5s
privileged_session_max_age: 1h
after: "#/definitions/selfServiceAfterSettings"
logout:
after:
default_browser_return_url: "#/definitions/defaultReturnTo"
registration:
ui_url: /registration
lifespan: 1h
after: "#/definitions/selfServiceAfterRegistration"
login:
ui_url: /login
lifespan: 1h
after: "#/definitions/selfServiceAfterLogin"
verification:
enabled: true
ui_url: /verification
lifespan: 1h
after: "#/definitions/selfServiceAfterVerification"
recovery:
enabled: true
ui_url: /recovery
lifespan: 1h
after: "#/definitions/selfServiceAfterRecovery"
error:
ui_url: /error
methods:
profile:
enabled: true
link:
enabled: true
password:
enabled: true
totp:
enabled: true
config:
issuer: "foobar"
oidc:
enabled: true
config:
providers:
- "#/definitions/selfServiceOIDCProvider"
dsn: foo
courier:
template_override_path: foo
smtp:
connection_uri: smtps://foo:bar@my-mailserver:1234/
from_address: no-reply@ory.kratos.sh
serve:
admin:
host: foo
port: 4434
public:
host: foo
port: 4433
log:
level: trace
format: json
identity:
default_schema_id: foo
schemas:
- id: foo
url: https://example.com
secrets:
default:
- default secret with a lot of chars
cookie:
- cookie secret with a lot of chars
cipher:
- secret-thirty-two-character-long
ciphers:
algorithm: xchacha20-poly1305
hashers:
argon2:
memory: 128MB
iterations: 1
parallelism: 1
salt_length: 16
key_length: 16
dedicated_memory: 1GB
expected_deviation: 500ms
expected_duration: 500ms
version: v1.0.0

View File

@@ -0,0 +1,17 @@
serve:
public:
base_url: "#/definitions/baseUrl"
selfservice:
default_browser_return_url: "#/definitions/defaultReturnTo"
dsn: foo
identity:
schemas:
- id: default
url: https://example.com
session:
cookie:
domain: foobar

View File

@@ -0,0 +1,9 @@
selfservice:
default_browser_return_url: "#/definitions/defaultReturnTo"
dsn: foo
identity:
schemas:
- id: default
url: https://example.com

View File

@@ -0,0 +1,2 @@
default_browser_return_url: "#/definitions/defaultReturnTo"
hooks: "#/definitions/selfServiceAfterDefaultLoginMethodHooks"

View File

@@ -0,0 +1,2 @@
- "#/definitions/selfServiceSessionRevokerHook"
- "#/definitions/selfServiceRequireVerifiedAddressHook"

View File

@@ -0,0 +1,4 @@
default_browser_return_url: "#/definitions/defaultReturnTo"
password: "#/definitions/selfServiceAfterDefaultLoginMethod"
webauthn: "#/definitions/selfServiceAfterDefaultLoginMethod"
oidc: "#/definitions/selfServiceAfterOIDCLoginMethod"

View File

@@ -0,0 +1,3 @@
default_browser_return_url: "#/definitions/defaultReturnTo"
hooks:
- "#/definitions/selfServiceSessionRevokerHook"

View File

@@ -0,0 +1,4 @@
default_browser_return_url: "#/definitions/defaultReturnTo"
password: "#/definitions/selfServiceAfterRegistrationMethod"
webauthn: "#/definitions/selfServiceAfterRegistrationMethod"
oidc: "#/definitions/selfServiceAfterRegistrationMethod"

View File

@@ -0,0 +1,3 @@
default_browser_return_url: "#/definitions/defaultReturnTo"
hooks:
- "#/definitions/selfServiceSessionIssuerHook"

View File

@@ -0,0 +1,3 @@
default_browser_return_url: "#/definitions/defaultReturnTo"
password: "#/definitions/selfServiceAfterSettingsAuthMethod"
profile: "#/definitions/selfServiceAfterSettingsProfileMethod"

View File

@@ -0,0 +1,4 @@
default_browser_return_url: "#/definitions/defaultReturnTo"
hooks:
- "#/definitions/selfServiceWebHook"
- "#/definitions/selfServiceSessionRevokerHook"

View File

@@ -0,0 +1,3 @@
default_browser_return_url: "#/definitions/defaultReturnTo"
hooks:
- "#/definitions/selfServiceWebHook"

View File

@@ -0,0 +1,11 @@
id: foo
provider: apple
client_id: foo
apple_team_id: foo
apple_private_key_id: foo
apple_private_key: foo
mapper_url: https://example.com
scope:
- foo
- bar
requested_claims: "#/definitions/OIDCClaims"

View File

@@ -0,0 +1,12 @@
id: foo
provider: github
client_id: foo
client_secret: foo
issuer_url: https://example.com
auth_url: https://example.com
token_url: https://example.com
mapper_url: https://example.com
scope:
- foo
- bar
requested_claims: "#/definitions/OIDCClaims"

View File

@@ -0,0 +1,13 @@
id: foo
provider: microsoft
client_id: foo
client_secret: foo
issuer_url: https://example.com
auth_url: https://example.com
token_url: https://example.com
mapper_url: https://example.com
scope:
- foo
- bar
microsoft_tenant: org
requested_claims: "#/definitions/OIDCClaims"

View File

@@ -0,0 +1,5 @@
id: foo
provider: github
client_id: foo
client_secret: foo
mapper_url: https://example.com

View File

@@ -0,0 +1 @@
hook: revoke_active_sessions

View File

@@ -0,0 +1,7 @@
hook: web_hook
config:
url: https://foo/bar
method: POST
body: base64://asdf
response:
ignore: false

View File

@@ -0,0 +1,5 @@
type: api_key
config:
name: foo
value: bar
in: header

View File

@@ -0,0 +1,4 @@
type: basic_auth
config:
user: foo
password: bar

153
test/schema/schema_test.go Normal file
View File

@@ -0,0 +1,153 @@
// Copyright © 2023 Ory Corp
// SPDX-License-Identifier: Apache-2.0
package schema
import (
"bytes"
"context"
"fmt"
"io"
"os"
"path/filepath"
"strings"
"testing"
"github.com/pkg/errors"
"github.com/ghodss/yaml"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/tidwall/gjson"
"github.com/ory/jsonschema/v3"
_ "github.com/ory/jsonschema/v3/fileloader"
)
type schema struct {
name string
raw string
s *jsonschema.Schema
}
type schemas []schema
type result int
const (
success result = iota
failure
)
func (r result) String() string {
return []string{"success", "failure"}[r]
}
func (s schema) validate(t *testing.T, path string) error {
t.Helper()
if s.s == nil {
compiler := jsonschema.NewCompiler()
if err := compiler.AddResource(s.name, strings.NewReader(s.raw)); err != nil {
return errors.WithStack(err)
}
sx, err := compiler.Compile(context.Background(), s.name)
if err != nil {
return errors.WithStack(err)
}
s.s = sx
}
var doc io.Reader
y, err := os.ReadFile(path) // #nosec G304 test code
if err != nil {
return errors.WithStack(err)
}
j, err := yaml.YAMLToJSON(y)
if err != nil {
return errors.WithStack(err)
}
doc = bytes.NewBuffer(j)
if err := s.s.Validate(doc); err != nil {
return errors.Errorf("there were validation errors: %s", err)
}
return nil
}
func (ss *schemas) getByName(n string) (*schema, error) {
for _, s := range *ss {
if s.name == n {
return &s, nil
}
}
return nil, errors.Errorf("could not find schema with name %s", n)
}
func TestSchemas(t *testing.T) {
t.Run("test embedx/config.schema.json", SchemaTestRunner("../../embedx", "config"))
}
func SchemaTestRunner(spath string, sname string) func(*testing.T) {
return func(t *testing.T) {
sb, err := os.ReadFile(fmt.Sprintf("%s/%s.schema.json", spath, sname))
require.NoError(t, err)
// To test refs independently and reduce test case size we replace every "$ref" with "const".
// That way refs will not be resolved but we still make sure that they are pointing to the right definition.
// Changing a definition will result in just changing test cases for that definition.
s := strings.ReplaceAll(string(sb), `"$ref":`, `"const":`)
schemas := schemas{{
name: "root",
raw: s,
}}
def := gjson.Get(s, "definitions")
if def.Exists() {
require.True(t, def.IsObject())
def.ForEach(func(key, value gjson.Result) bool {
require.Equal(t, gjson.String, key.Type)
schemas = append(schemas, schema{
name: key.String(),
raw: value.Raw,
})
return true
})
}
RunCases(t, schemas, fmt.Sprintf("./fixtures/%s.schema.test.success", sname), success)
RunCases(t, schemas, fmt.Sprintf("./fixtures/%s.schema.test.failure", sname), failure)
}
}
func RunCases(t *testing.T, ss schemas, dir string, expected result) {
err := filepath.Walk(dir, func(path string, info os.FileInfo, err error) error {
require.NoError(t, err)
if info.IsDir() {
return nil
}
parts := strings.Split(info.Name(), ".")
require.Equal(t, 3, len(parts))
sName, tc := parts[0], parts[1]
s, err := ss.getByName(sName)
require.NoError(t, err)
t.Run(fmt.Sprintf("case=schema %s test case %s expects %s", sName, tc, expected), func(t *testing.T) {
err := s.validate(t, path)
if expected == success {
assert.NoError(t, err, "path: %s", path)
} else {
assert.Error(t, err, "path: %s", path)
}
})
return nil
})
require.NoError(t, err)
}