snapshot of https://github.com/ory/keto.git (master, 2026-09-16; blobs > 131072B omitted)
Some checks failed
CI / Run lints and checks (push) Failing after 47s
CI / Run tests (push) Failing after 1s
CI / Run race tests (push) Failing after 5s
CI / Build CLI docs (push) Has been skipped
CI / Run buf actions (push) Failing after 5s
CodeQL / Analyze (go) (push) Failing after 3s
CodeQL / Analyze (javascript) (push) Failing after 2s
Docker Image Scanners / scanners (push) Failing after 3s
Format / format (push) Failing after 3s
Synchronize Issue Labels / Synchronize Issue Labels (push) Has been skipped
CI / Generate release (push) Has been skipped
CI / Draft newsletter (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-16 01:08:34 +05:00
commit 9456a4e922
2560 changed files with 120911 additions and 0 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,65 @@
[
{
"Title": "",
"Description": "",
"Examples": null,
"Name": "providers",
"Default": null,
"Type": [],
"TypeHint": 5,
"Format": "",
"Pattern": null,
"Enum": null,
"Constant": null,
"ReadOnly": false,
"MinLength": -1,
"MaxLength": -1,
"Required": false,
"Minimum": null,
"Maximum": null,
"MultipleOf": null,
"CustomProperties": null
},
{
"Title": "",
"Description": "",
"Examples": null,
"Name": "providers.#",
"Default": null,
"Type": {},
"TypeHint": 5,
"Format": "",
"Pattern": null,
"Enum": null,
"Constant": null,
"ReadOnly": false,
"MinLength": -1,
"MaxLength": -1,
"Required": false,
"Minimum": null,
"Maximum": null,
"MultipleOf": null,
"CustomProperties": null
},
{
"Title": "",
"Description": "",
"Examples": null,
"Name": "providers.#.id",
"Default": null,
"Type": "",
"TypeHint": 1,
"Format": "",
"Pattern": null,
"Enum": null,
"Constant": null,
"ReadOnly": false,
"MinLength": -1,
"MaxLength": -1,
"Required": false,
"Minimum": null,
"Maximum": null,
"MultipleOf": null,
"CustomProperties": null
}
]

View File

@@ -0,0 +1,23 @@
[
{
"Title": "",
"Description": "",
"Examples": null,
"Name": "dsn",
"Default": null,
"Type": "",
"TypeHint": 1,
"Format": "",
"Pattern": null,
"Enum": null,
"Constant": null,
"ReadOnly": false,
"MinLength": -1,
"MaxLength": -1,
"Required": true,
"Minimum": null,
"Maximum": null,
"MultipleOf": null,
"CustomProperties": null
}
]

View File

@@ -0,0 +1,305 @@
[
{
"Title": "OpenID Connect and OAuth2 Providers",
"Description": "A list and configuration of OAuth2 and OpenID Connect providers ORY Kratos should integrate with.",
"Examples": null,
"Name": "providers",
"Default": null,
"Type": [],
"TypeHint": 5,
"Format": "",
"Pattern": null,
"Enum": null,
"Constant": null,
"ReadOnly": false,
"MinLength": -1,
"MaxLength": -1,
"Required": false,
"Minimum": null,
"Maximum": null,
"MultipleOf": null,
"CustomProperties": null
},
{
"Title": "",
"Description": "",
"Examples": null,
"Name": "providers.#",
"Default": null,
"Type": {},
"TypeHint": 5,
"Format": "",
"Pattern": null,
"Enum": null,
"Constant": null,
"ReadOnly": false,
"MinLength": -1,
"MaxLength": -1,
"Required": false,
"Minimum": null,
"Maximum": null,
"MultipleOf": null,
"CustomProperties": null
},
{
"Title": "",
"Description": "",
"Examples": [
"https://accounts.google.com/o/oauth2/v2/auth"
],
"Name": "providers.#.auth_url",
"Default": null,
"Type": "",
"TypeHint": 1,
"Format": "uri",
"Pattern": null,
"Enum": null,
"Constant": null,
"ReadOnly": false,
"MinLength": -1,
"MaxLength": -1,
"Required": false,
"Minimum": null,
"Maximum": null,
"MultipleOf": null,
"CustomProperties": null
},
{
"Title": "",
"Description": "",
"Examples": null,
"Name": "providers.#.client_id",
"Default": null,
"Type": "",
"TypeHint": 1,
"Format": "",
"Pattern": null,
"Enum": null,
"Constant": null,
"ReadOnly": false,
"MinLength": -1,
"MaxLength": -1,
"Required": false,
"Minimum": null,
"Maximum": null,
"MultipleOf": null,
"CustomProperties": null
},
{
"Title": "",
"Description": "",
"Examples": null,
"Name": "providers.#.client_secret",
"Default": null,
"Type": "",
"TypeHint": 1,
"Format": "",
"Pattern": null,
"Enum": null,
"Constant": null,
"ReadOnly": false,
"MinLength": -1,
"MaxLength": -1,
"Required": false,
"Minimum": null,
"Maximum": null,
"MultipleOf": null,
"CustomProperties": null
},
{
"Title": "",
"Description": "",
"Examples": [
"google"
],
"Name": "providers.#.id",
"Default": null,
"Type": "",
"TypeHint": 1,
"Format": "",
"Pattern": null,
"Enum": null,
"Constant": null,
"ReadOnly": false,
"MinLength": -1,
"MaxLength": -1,
"Required": false,
"Minimum": null,
"Maximum": null,
"MultipleOf": null,
"CustomProperties": null
},
{
"Title": "",
"Description": "",
"Examples": [
"https://accounts.google.com"
],
"Name": "providers.#.issuer_url",
"Default": null,
"Type": "",
"TypeHint": 1,
"Format": "uri",
"Pattern": null,
"Enum": null,
"Constant": null,
"ReadOnly": false,
"MinLength": -1,
"MaxLength": -1,
"Required": false,
"Minimum": null,
"Maximum": null,
"MultipleOf": null,
"CustomProperties": null
},
{
"Title": "Jsonnet Mapper URL",
"Description": "The URL where the jsonnet source is located for mapping the provider's data to ORY Kratos data.",
"Examples": [
"file://path/to/oidc.jsonnet",
"https://foo.bar.com/path/to/oidc.jsonnet",
"base64://bG9jYWwgc3ViamVjdCA9I..."
],
"Name": "providers.#.mapper_url",
"Default": null,
"Type": "",
"TypeHint": 1,
"Format": "uri",
"Pattern": null,
"Enum": null,
"Constant": null,
"ReadOnly": false,
"MinLength": -1,
"MaxLength": -1,
"Required": false,
"Minimum": null,
"Maximum": null,
"MultipleOf": null,
"CustomProperties": null
},
{
"Title": "Provider",
"Description": "Can be one of github, gitlab, generic, google, microsoft, discord.",
"Examples": [
"google"
],
"Name": "providers.#.provider",
"Default": null,
"Type": "",
"TypeHint": 1,
"Format": "",
"Pattern": null,
"Enum": [
"github",
"gitlab",
"generic",
"google",
"microsoft",
"discord"
],
"Constant": null,
"ReadOnly": false,
"MinLength": -1,
"MaxLength": -1,
"Required": false,
"Minimum": null,
"Maximum": null,
"MultipleOf": null,
"CustomProperties": null
},
{
"Title": "",
"Description": "",
"Examples": null,
"Name": "providers.#.scope",
"Default": null,
"Type": [],
"TypeHint": 8,
"Format": "",
"Pattern": null,
"Enum": null,
"Constant": null,
"ReadOnly": false,
"MinLength": -1,
"MaxLength": -1,
"Required": false,
"Minimum": null,
"Maximum": null,
"MultipleOf": null,
"CustomProperties": null
},
{
"Title": "",
"Description": "",
"Examples": [
"offline_access",
"profile"
],
"Name": "providers.#.scope.#",
"Default": null,
"Type": "",
"TypeHint": 1,
"Format": "",
"Pattern": null,
"Enum": null,
"Constant": null,
"ReadOnly": false,
"MinLength": -1,
"MaxLength": -1,
"Required": false,
"Minimum": null,
"Maximum": null,
"MultipleOf": null,
"CustomProperties": null
},
{
"Title": "Azure AD Tenant",
"Description": "The Azure AD Tenant to use for authentication.",
"Examples": [
"common",
"organizations",
"consumers",
"8eaef023-2b34-4da1-9baa-8bc8c9d6a490",
"contoso.onmicrosoft.com"
],
"Name": "providers.#.tenant",
"Default": null,
"Type": "",
"TypeHint": 1,
"Format": "",
"Pattern": null,
"Enum": null,
"Constant": null,
"ReadOnly": false,
"MinLength": -1,
"MaxLength": -1,
"Required": false,
"Minimum": null,
"Maximum": null,
"MultipleOf": null,
"CustomProperties": null
},
{
"Title": "",
"Description": "",
"Examples": [
"https://www.googleapis.com/oauth2/v4/token"
],
"Name": "providers.#.token_url",
"Default": null,
"Type": "",
"TypeHint": 1,
"Format": "uri",
"Pattern": null,
"Enum": null,
"Constant": null,
"ReadOnly": false,
"MinLength": -1,
"MaxLength": -1,
"Required": false,
"Minimum": null,
"Maximum": null,
"MultipleOf": null,
"CustomProperties": null
}
]

View File

@@ -0,0 +1,86 @@
[
{
"Title": "",
"Description": "",
"Examples": null,
"Name": "bar",
"Default": "asdf",
"Type": false,
"TypeHint": 4,
"Format": "",
"Pattern": null,
"Enum": null,
"Constant": null,
"ReadOnly": true,
"MinLength": -1,
"MaxLength": -1,
"Required": false,
"Minimum": null,
"Maximum": null,
"MultipleOf": null,
"CustomProperties": null
},
{
"Title": "",
"Description": "",
"Examples": null,
"Name": "foo",
"Default": false,
"Type": false,
"TypeHint": 4,
"Format": "",
"Pattern": null,
"Enum": null,
"Constant": null,
"ReadOnly": false,
"MinLength": -1,
"MaxLength": -1,
"Required": false,
"Minimum": null,
"Maximum": null,
"MultipleOf": null,
"CustomProperties": null
},
{
"Title": "",
"Description": "",
"Examples": null,
"Name": "list",
"Default": null,
"Type": [],
"TypeHint": 8,
"Format": "",
"Pattern": null,
"Enum": null,
"Constant": null,
"ReadOnly": false,
"MinLength": -1,
"MaxLength": -1,
"Required": false,
"Minimum": null,
"Maximum": null,
"MultipleOf": null,
"CustomProperties": null
},
{
"Title": "",
"Description": "",
"Examples": null,
"Name": "list.#",
"Default": null,
"Type": "",
"TypeHint": 1,
"Format": "",
"Pattern": null,
"Enum": null,
"Constant": null,
"ReadOnly": false,
"MinLength": -1,
"MaxLength": -1,
"Required": false,
"Minimum": null,
"Maximum": null,
"MultipleOf": null,
"CustomProperties": null
}
]

View File

@@ -0,0 +1,86 @@
[
{
"Title": "",
"Description": "",
"Examples": null,
"Name": "bar",
"Default": "asdf",
"Type": false,
"TypeHint": 4,
"Format": "",
"Pattern": null,
"Enum": null,
"Constant": null,
"ReadOnly": true,
"MinLength": -1,
"MaxLength": -1,
"Required": false,
"Minimum": null,
"Maximum": null,
"MultipleOf": null,
"CustomProperties": null
},
{
"Title": "",
"Description": "",
"Examples": null,
"Name": "foo",
"Default": false,
"Type": false,
"TypeHint": 4,
"Format": "",
"Pattern": null,
"Enum": null,
"Constant": null,
"ReadOnly": false,
"MinLength": -1,
"MaxLength": -1,
"Required": false,
"Minimum": null,
"Maximum": null,
"MultipleOf": null,
"CustomProperties": null
},
{
"Title": "",
"Description": "",
"Examples": null,
"Name": "list",
"Default": null,
"Type": [],
"TypeHint": 8,
"Format": "",
"Pattern": null,
"Enum": null,
"Constant": null,
"ReadOnly": false,
"MinLength": -1,
"MaxLength": -1,
"Required": false,
"Minimum": null,
"Maximum": null,
"MultipleOf": null,
"CustomProperties": null
},
{
"Title": "",
"Description": "",
"Examples": null,
"Name": "list.#",
"Default": null,
"Type": "",
"TypeHint": 1,
"Format": "",
"Pattern": null,
"Enum": null,
"Constant": null,
"ReadOnly": false,
"MinLength": -1,
"MaxLength": -1,
"Required": false,
"Minimum": null,
"Maximum": null,
"MultipleOf": null,
"CustomProperties": null
}
]

View File

@@ -0,0 +1,46 @@
[
{
"Title": "",
"Description": "",
"Examples": null,
"Name": "bar",
"Default": null,
"Type": "",
"TypeHint": 1,
"Format": "",
"Pattern": null,
"Enum": null,
"Constant": null,
"ReadOnly": false,
"MinLength": -1,
"MaxLength": -1,
"Required": false,
"Minimum": null,
"Maximum": null,
"MultipleOf": null,
"CustomProperties": {
"foobar": "bar"
}
},
{
"Title": "",
"Description": "",
"Examples": null,
"Name": "foo",
"Default": null,
"Type": false,
"TypeHint": 4,
"Format": "",
"Pattern": null,
"Enum": null,
"Constant": null,
"ReadOnly": false,
"MinLength": -1,
"MaxLength": -1,
"Required": true,
"Minimum": null,
"Maximum": null,
"MultipleOf": null,
"CustomProperties": null
}
]

View File

@@ -0,0 +1,44 @@
[
{
"Title": "",
"Description": "",
"Examples": null,
"Name": "bar",
"Default": null,
"Type": [],
"TypeHint": 8,
"Format": "",
"Pattern": null,
"Enum": null,
"Constant": null,
"ReadOnly": false,
"MinLength": -1,
"MaxLength": -1,
"Required": false,
"Minimum": null,
"Maximum": null,
"MultipleOf": null,
"CustomProperties": null
},
{
"Title": "",
"Description": "",
"Examples": null,
"Name": "bar.#",
"Default": null,
"Type": "",
"TypeHint": 1,
"Format": "",
"Pattern": null,
"Enum": null,
"Constant": null,
"ReadOnly": false,
"MinLength": -1,
"MaxLength": -1,
"Required": false,
"Minimum": null,
"Maximum": null,
"MultipleOf": null,
"CustomProperties": null
}
]

View File

@@ -0,0 +1,65 @@
[
{
"Title": "",
"Description": "",
"Examples": null,
"Name": "baz",
"Default": null,
"Type": [],
"TypeHint": 5,
"Format": "",
"Pattern": null,
"Enum": null,
"Constant": null,
"ReadOnly": false,
"MinLength": -1,
"MaxLength": -1,
"Required": false,
"Minimum": null,
"Maximum": null,
"MultipleOf": null,
"CustomProperties": null
},
{
"Title": "",
"Description": "",
"Examples": null,
"Name": "baz.#",
"Default": null,
"Type": [],
"TypeHint": 8,
"Format": "",
"Pattern": null,
"Enum": null,
"Constant": null,
"ReadOnly": false,
"MinLength": -1,
"MaxLength": -1,
"Required": false,
"Minimum": null,
"Maximum": null,
"MultipleOf": null,
"CustomProperties": null
},
{
"Title": "",
"Description": "",
"Examples": null,
"Name": "baz.#.#",
"Default": null,
"Type": "",
"TypeHint": 1,
"Format": "",
"Pattern": null,
"Enum": null,
"Constant": null,
"ReadOnly": false,
"MinLength": -1,
"MaxLength": -1,
"Required": false,
"Minimum": null,
"Maximum": null,
"MultipleOf": null,
"CustomProperties": null
}
]

View File

@@ -0,0 +1,65 @@
[
{
"Title": "",
"Description": "",
"Examples": null,
"Name": "baz",
"Default": null,
"Type": [],
"TypeHint": 5,
"Format": "",
"Pattern": null,
"Enum": null,
"Constant": null,
"ReadOnly": false,
"MinLength": -1,
"MaxLength": -1,
"Required": false,
"Minimum": null,
"Maximum": null,
"MultipleOf": null,
"CustomProperties": null
},
{
"Title": "",
"Description": "",
"Examples": null,
"Name": "baz.#",
"Default": null,
"Type": {},
"TypeHint": 5,
"Format": "",
"Pattern": null,
"Enum": null,
"Constant": null,
"ReadOnly": false,
"MinLength": -1,
"MaxLength": -1,
"Required": false,
"Minimum": null,
"Maximum": null,
"MultipleOf": null,
"CustomProperties": null
},
{
"Title": "",
"Description": "",
"Examples": null,
"Name": "baz.#.foo",
"Default": null,
"Type": "",
"TypeHint": 1,
"Format": "",
"Pattern": null,
"Enum": null,
"Constant": null,
"ReadOnly": false,
"MinLength": -1,
"MaxLength": -1,
"Required": false,
"Minimum": null,
"Maximum": null,
"MultipleOf": null,
"CustomProperties": null
}
]

View File

@@ -0,0 +1,233 @@
[
{
"Title": "",
"Description": "",
"Examples": null,
"Name": "bar",
"Default": null,
"Type": {},
"TypeHint": 5,
"Format": "",
"Pattern": null,
"Enum": null,
"Constant": null,
"ReadOnly": false,
"MinLength": -1,
"MaxLength": -1,
"Required": false,
"Minimum": null,
"Maximum": null,
"MultipleOf": null,
"CustomProperties": null
},
{
"Title": "",
"Description": "",
"Examples": null,
"Name": "bar.foo",
"Default": null,
"Type": {},
"TypeHint": 5,
"Format": "",
"Pattern": null,
"Enum": null,
"Constant": null,
"ReadOnly": false,
"MinLength": -1,
"MaxLength": -1,
"Required": false,
"Minimum": null,
"Maximum": null,
"MultipleOf": null,
"CustomProperties": null
},
{
"Title": "",
"Description": "",
"Examples": null,
"Name": "bar.foo.bar",
"Default": null,
"Type": {},
"TypeHint": 5,
"Format": "",
"Pattern": null,
"Enum": null,
"Constant": null,
"ReadOnly": false,
"MinLength": -1,
"MaxLength": -1,
"Required": false,
"Minimum": null,
"Maximum": null,
"MultipleOf": null,
"CustomProperties": null
},
{
"Title": "",
"Description": "",
"Examples": null,
"Name": "bar.foo.bar.foo",
"Default": null,
"Type": {},
"TypeHint": 5,
"Format": "",
"Pattern": null,
"Enum": null,
"Constant": null,
"ReadOnly": false,
"MinLength": -1,
"MaxLength": -1,
"Required": false,
"Minimum": null,
"Maximum": null,
"MultipleOf": null,
"CustomProperties": null
},
{
"Title": "",
"Description": "",
"Examples": null,
"Name": "bar.foo.bar.foo.bar",
"Default": null,
"Type": {},
"TypeHint": 5,
"Format": "",
"Pattern": null,
"Enum": null,
"Constant": null,
"ReadOnly": false,
"MinLength": -1,
"MaxLength": -1,
"Required": false,
"Minimum": null,
"Maximum": null,
"MultipleOf": null,
"CustomProperties": null
},
{
"Title": "",
"Description": "",
"Examples": null,
"Name": "bar.foo.bar.foo.bar.foo",
"Default": null,
"Type": {},
"TypeHint": 5,
"Format": "",
"Pattern": null,
"Enum": null,
"Constant": null,
"ReadOnly": false,
"MinLength": -1,
"MaxLength": -1,
"Required": false,
"Minimum": null,
"Maximum": null,
"MultipleOf": null,
"CustomProperties": null
},
{
"Title": "",
"Description": "",
"Examples": null,
"Name": "bar.foo.bar.foo.bar.foos",
"Default": null,
"Type": "",
"TypeHint": 1,
"Format": "",
"Pattern": null,
"Enum": null,
"Constant": null,
"ReadOnly": false,
"MinLength": 1,
"MaxLength": 10,
"Required": false,
"Minimum": null,
"Maximum": null,
"MultipleOf": null,
"CustomProperties": null
},
{
"Title": "",
"Description": "",
"Examples": null,
"Name": "bar.foo.bar.foo.bars",
"Default": null,
"Type": "",
"TypeHint": 1,
"Format": "email",
"Pattern": ".*",
"Enum": null,
"Constant": null,
"ReadOnly": false,
"MinLength": -1,
"MaxLength": -1,
"Required": true,
"Minimum": null,
"Maximum": null,
"MultipleOf": null,
"CustomProperties": null
},
{
"Title": "",
"Description": "",
"Examples": null,
"Name": "bar.foo.bar.foos",
"Default": null,
"Type": "",
"TypeHint": 1,
"Format": "",
"Pattern": null,
"Enum": null,
"Constant": null,
"ReadOnly": false,
"MinLength": 1,
"MaxLength": 10,
"Required": false,
"Minimum": null,
"Maximum": null,
"MultipleOf": null,
"CustomProperties": null
},
{
"Title": "",
"Description": "",
"Examples": null,
"Name": "bar.foo.bars",
"Default": null,
"Type": "",
"TypeHint": 1,
"Format": "email",
"Pattern": ".*",
"Enum": null,
"Constant": null,
"ReadOnly": false,
"MinLength": -1,
"MaxLength": -1,
"Required": true,
"Minimum": null,
"Maximum": null,
"MultipleOf": null,
"CustomProperties": null
},
{
"Title": "",
"Description": "",
"Examples": null,
"Name": "bar.foos",
"Default": null,
"Type": "",
"TypeHint": 1,
"Format": "",
"Pattern": null,
"Enum": null,
"Constant": null,
"ReadOnly": false,
"MinLength": 1,
"MaxLength": 10,
"Required": false,
"Minimum": null,
"Maximum": null,
"MultipleOf": null,
"CustomProperties": null
}
]

120
oryx/jsonschemax/README.md Normal file
View File

@@ -0,0 +1,120 @@
# JSON Schema Helpers
This package contains utilities for working with JSON Schemas.
## Listing all Possible JSON Schema Paths
Using `jsonschemax.ListPaths()` you can get a list of all possible JSON paths in
a JSON Schema.
```go
package main
import (
"bytes"
"fmt"
"github.com/ory/jsonschema/v3"
"github.com/ory/x/jsonschemax"
)
var schema = "..."
func main() {
c := jsonschema.NewCompiler()
_ = c.AddResource("test.json", bytes.NewBufferString(schema))
paths, _ := jsonschemax.ListPaths("test.json", c)
fmt.Printf("%+v", paths)
}
```
All keys are delimited using `.`. Please note that arrays are denoted with `#`
when `ListPathsWithArraysIncluded` is used. For example, the JSON Schema
```json
{
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"providers": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string"
}
}
}
}
}
}
```
Results in paths:
```json
[
{
"Title": "",
"Description": "",
"Examples": null,
"Name": "providers",
"Default": null,
"Type": [],
"TypeHint": 5,
"Format": "",
"Pattern": null,
"Enum": null,
"Constant": null,
"ReadOnly": false,
"MinLength": -1,
"MaxLength": -1,
"Required": false,
"Minimum": null,
"Maximum": null,
"MultipleOf": null,
"CustomProperties": null
},
{
"Title": "",
"Description": "",
"Examples": null,
"Name": "providers.#",
"Default": null,
"Type": {},
"TypeHint": 5,
"Format": "",
"Pattern": null,
"Enum": null,
"Constant": null,
"ReadOnly": false,
"MinLength": -1,
"MaxLength": -1,
"Required": false,
"Minimum": null,
"Maximum": null,
"MultipleOf": null,
"CustomProperties": null
},
{
"Title": "",
"Description": "",
"Examples": null,
"Name": "providers.#.id",
"Default": null,
"Type": "",
"TypeHint": 1,
"Format": "",
"Pattern": null,
"Enum": null,
"Constant": null,
"ReadOnly": false,
"MinLength": -1,
"MaxLength": -1,
"Required": false,
"Minimum": null,
"Maximum": null,
"MultipleOf": null,
"CustomProperties": null
}
]
```

40
oryx/jsonschemax/error.go Normal file
View File

@@ -0,0 +1,40 @@
// Copyright © 2023 Ory Corp
// SPDX-License-Identifier: Apache-2.0
package jsonschemax
import (
"github.com/ory/jsonschema/v3"
)
// ErrorType is the schema error type.
type ErrorType int
const (
// ErrorTypeMissing represents a validation that failed because a value is missing.
ErrorTypeMissing ErrorType = iota + 1
)
// Error represents a schema error.
type Error struct {
// Type is the error type.
Type ErrorType
// DocumentPointer is the JSON Pointer in the document.
DocumentPointer string
// SchemaPointer is the JSON Pointer in the schema.
SchemaPointer string
// DocumentFieldName is a pointer to the document in dot-notation: fo.bar.baz
DocumentFieldName string
}
// NewFromSanthoshError converts github.com/santhosh-tekuri/jsonschema.ValidationError to Error.
func NewFromSanthoshError(validationError jsonschema.ValidationError) *Error {
return &Error{
// DocumentPointer: JSONPointerToDotNotation(validationError.InstancePtr),
// SchemaPointer: JSONPointerToDotNotation(validationError.SchemaPtr),
// DocumentFieldName: JSONPointerToDotNotation(validationError.InstancePtr),
}
}

447
oryx/jsonschemax/keys.go Normal file
View File

@@ -0,0 +1,447 @@
// Copyright © 2023 Ory Corp
// SPDX-License-Identifier: Apache-2.0
package jsonschemax
import (
"bytes"
"context"
"crypto/sha256"
"encoding/json"
"fmt"
"math/big"
"regexp"
"slices"
"sort"
"strings"
"github.com/pkg/errors"
"github.com/ory/jsonschema/v3"
)
type (
byName []Path
PathEnhancer interface {
EnhancePath(Path) map[string]interface{}
}
TypeHint int
)
func (s byName) Len() int { return len(s) }
func (s byName) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
func (s byName) Less(i, j int) bool { return s[i].Name < s[j].Name }
const (
String TypeHint = iota + 1
Float
Int
Bool
JSON
Nil
BoolSlice
StringSlice
IntSlice
FloatSlice
)
// Path represents a JSON Schema Path.
type Path struct {
// Title of the path.
Title string
// Description of the path.
Description string
// Examples of the path.
Examples []interface{}
// Name is the JSON path name.
Name string
// Default is the default value of that path.
Default interface{}
// Type is a prototype (e.g. float64(0)) of the path type.
Type interface{}
TypeHint
// Format is the format of the path if defined
Format string
// Pattern is the pattern of the path if defined
Pattern *regexp.Regexp
// Enum are the allowed enum values
Enum []interface{}
// first element in slice is constant value. note: slice is used to capture nil constant.
Constant []interface{}
// ReadOnly is whether the value is readonly
ReadOnly bool
// -1 if not specified
MinLength int
MaxLength int
// Required if set indicates this field is required.
Required bool
Minimum *big.Float
Maximum *big.Float
MultipleOf *big.Float
CustomProperties map[string]interface{}
}
// ListPathsBytes works like ListPathsWithRecursion but prepares the JSON Schema itself.
func ListPathsBytes(ctx context.Context, raw json.RawMessage, maxRecursion int16) ([]Path, error) {
compiler := jsonschema.NewCompiler()
compiler.ExtractAnnotations = true
id := fmt.Sprintf("%x.json", sha256.Sum256(raw))
if err := compiler.AddResource(id, bytes.NewReader(raw)); err != nil {
return nil, err
}
compiler.ExtractAnnotations = true
return runPathsFromCompiler(ctx, id, compiler, maxRecursion, false)
}
// ListPathsWithRecursion will follow circular references until maxRecursion is reached, without
// returning an error.
func ListPathsWithRecursion(ctx context.Context, ref string, compiler *jsonschema.Compiler, maxRecursion uint8) ([]Path, error) {
return runPathsFromCompiler(ctx, ref, compiler, int16(maxRecursion), false)
}
// ListPaths lists all paths of a JSON Schema. Will return an error
// if circular references are found.
func ListPaths(ctx context.Context, ref string, compiler *jsonschema.Compiler) ([]Path, error) {
return runPathsFromCompiler(ctx, ref, compiler, -1, false)
}
// ListPathsWithArraysIncluded lists all paths of a JSON Schema. Will return an error
// if circular references are found.
// Includes arrays with `#`.
func ListPathsWithArraysIncluded(ctx context.Context, ref string, compiler *jsonschema.Compiler) ([]Path, error) {
return runPathsFromCompiler(ctx, ref, compiler, -1, true)
}
// ListPathsWithInitializedSchema loads the paths from the schema without compiling it.
//
// You MUST ensure that the compiler was using `ExtractAnnotations = true`.
func ListPathsWithInitializedSchema(schema *jsonschema.Schema) ([]Path, error) {
return runPaths(schema, -1, false)
}
// ListPathsWithInitializedSchemaAndArraysIncluded loads the paths from the schema without compiling it.
//
// You MUST ensure that the compiler was using `ExtractAnnotations = true`.
// Includes arrays with `#`.
func ListPathsWithInitializedSchemaAndArraysIncluded(schema *jsonschema.Schema) ([]Path, error) {
return runPaths(schema, -1, true)
}
func runPathsFromCompiler(ctx context.Context, ref string, compiler *jsonschema.Compiler, maxRecursion int16, includeArrays bool) ([]Path, error) {
if compiler == nil {
compiler = jsonschema.NewCompiler()
}
compiler.ExtractAnnotations = true
schema, err := compiler.Compile(ctx, ref)
if err != nil {
return nil, errors.WithStack(err)
}
return runPaths(schema, maxRecursion, includeArrays)
}
func runPaths(schema *jsonschema.Schema, maxRecursion int16, includeArrays bool) ([]Path, error) {
pointers := map[string]bool{}
paths, err := listPaths(schema, nil, nil, pointers, 0, maxRecursion, includeArrays)
if err != nil {
return nil, errors.WithStack(err)
}
sort.Stable(paths)
return makeUnique(paths)
}
func makeUnique(in byName) (byName, error) {
cache := make(map[string]Path)
for _, p := range in {
vc, ok := cache[p.Name]
if !ok {
cache[p.Name] = p
continue
}
if fmt.Sprintf("%T", p.Type) != fmt.Sprintf("%T", p.Type) {
return nil, errors.Errorf("multiple types %+v are not supported for path: %s", []interface{}{p.Type, vc.Type}, p.Name)
}
if vc.Default == nil {
cache[p.Name] = p
}
}
k := 0
out := make([]Path, len(cache))
for _, v := range cache {
out[k] = v
k++
}
paths := byName(out)
sort.Sort(paths)
return paths, nil
}
func appendPointer(in map[string]bool, pointer *jsonschema.Schema) map[string]bool {
out := make(map[string]bool)
for k, v := range in {
out[k] = v
}
out[fmt.Sprintf("%p", pointer)] = true
return out
}
func listPaths(schema *jsonschema.Schema, parent *jsonschema.Schema, parents []string, pointers map[string]bool, currentRecursion int16, maxRecursion int16, includeArrays bool) (byName, error) {
var pathType interface{}
var pathTypeHint TypeHint
var paths []Path
_, isCircular := pointers[fmt.Sprintf("%p", schema)]
if len(schema.Constant) > 0 {
switch schema.Constant[0].(type) {
case float64, json.Number:
pathType = float64(0)
pathTypeHint = Float
case int8, int16, int, int64:
pathType = int64(0)
pathTypeHint = Int
case string:
pathType = ""
pathTypeHint = String
case bool:
pathType = false
pathTypeHint = Bool
default:
pathType = schema.Constant[0]
pathTypeHint = JSON
}
} else if len(schema.Types) == 1 {
switch schema.Types[0] {
case "null":
pathType = nil
pathTypeHint = Nil
case "boolean":
pathType = false
pathTypeHint = Bool
case "number":
pathType = float64(0)
pathTypeHint = Float
case "integer":
pathType = float64(0)
pathTypeHint = Int
case "string":
pathType = ""
pathTypeHint = String
case "array":
pathType = []interface{}{}
if schema.Items != nil {
var itemSchemas []*jsonschema.Schema
switch t := schema.Items.(type) {
case []*jsonschema.Schema:
itemSchemas = t
case *jsonschema.Schema:
itemSchemas = []*jsonschema.Schema{t}
}
var types []string
for _, is := range itemSchemas {
types = append(types, is.Types...)
if is.Ref != nil {
types = append(types, is.Ref.Types...)
}
}
types = slices.Compact(types)
if len(types) == 1 {
switch types[0] {
case "boolean":
pathType = []bool{}
pathTypeHint = BoolSlice
case "number":
pathType = []float64{}
pathTypeHint = FloatSlice
case "integer":
pathType = []float64{}
pathTypeHint = IntSlice
case "string":
pathType = []string{}
pathTypeHint = StringSlice
default:
pathType = []interface{}{}
pathTypeHint = JSON
}
}
}
case "object":
pathType = map[string]interface{}{}
pathTypeHint = JSON
}
} else if len(schema.Types) > 2 {
pathType = nil
pathTypeHint = JSON
}
var def interface{} = schema.Default
if v, ok := def.(json.Number); ok {
def, _ = v.Float64()
}
if (pathType != nil || schema.Default != nil) && len(parents) > 0 {
name := parents[len(parents)-1]
var required bool
if parent != nil {
for _, r := range parent.Required {
if r == name {
required = true
break
}
}
}
path := Path{
Name: strings.Join(parents, "."),
Default: def,
Type: pathType,
TypeHint: pathTypeHint,
Format: schema.Format,
Pattern: schema.Pattern,
Enum: schema.Enum,
Constant: schema.Constant,
MinLength: schema.MinLength,
MaxLength: schema.MaxLength,
Minimum: schema.Minimum,
Maximum: schema.Maximum,
MultipleOf: schema.MultipleOf,
ReadOnly: schema.ReadOnly,
Title: schema.Title,
Description: schema.Description,
Examples: schema.Examples,
Required: required,
}
for _, e := range schema.Extensions {
if enhancer, ok := e.(PathEnhancer); ok {
path.CustomProperties = enhancer.EnhancePath(path)
}
}
paths = append(paths, path)
}
if isCircular {
if maxRecursion == -1 {
return nil, errors.Errorf("detected circular dependency in schema path: %s", strings.Join(parents, "."))
} else if currentRecursion > maxRecursion {
return paths, nil
}
currentRecursion++
}
if schema.Ref != nil {
path, err := listPaths(schema.Ref, schema, parents, appendPointer(pointers, schema), currentRecursion, maxRecursion, includeArrays)
if err != nil {
return nil, err
}
paths = append(paths, path...)
}
if schema.Not != nil {
path, err := listPaths(schema.Not, schema, parents, appendPointer(pointers, schema), currentRecursion, maxRecursion, includeArrays)
if err != nil {
return nil, err
}
paths = append(paths, path...)
}
if schema.If != nil {
path, err := listPaths(schema.If, schema, parents, appendPointer(pointers, schema), currentRecursion, maxRecursion, includeArrays)
if err != nil {
return nil, err
}
paths = append(paths, path...)
}
if schema.Then != nil {
path, err := listPaths(schema.Then, schema, parents, appendPointer(pointers, schema), currentRecursion, maxRecursion, includeArrays)
if err != nil {
return nil, err
}
paths = append(paths, path...)
}
if schema.Else != nil {
path, err := listPaths(schema.Else, schema, parents, appendPointer(pointers, schema), currentRecursion, maxRecursion, includeArrays)
if err != nil {
return nil, err
}
paths = append(paths, path...)
}
for _, sub := range schema.AllOf {
path, err := listPaths(sub, schema, parents, appendPointer(pointers, schema), currentRecursion, maxRecursion, includeArrays)
if err != nil {
return nil, err
}
paths = append(paths, path...)
}
for _, sub := range schema.AnyOf {
path, err := listPaths(sub, schema, parents, appendPointer(pointers, schema), currentRecursion, maxRecursion, includeArrays)
if err != nil {
return nil, err
}
paths = append(paths, path...)
}
for _, sub := range schema.OneOf {
path, err := listPaths(sub, schema, parents, appendPointer(pointers, schema), currentRecursion, maxRecursion, includeArrays)
if err != nil {
return nil, err
}
paths = append(paths, path...)
}
for name, sub := range schema.Properties {
path, err := listPaths(sub, schema, append(parents, name), appendPointer(pointers, schema), currentRecursion, maxRecursion, includeArrays)
if err != nil {
return nil, err
}
paths = append(paths, path...)
}
if schema.Items != nil && includeArrays {
switch t := schema.Items.(type) {
case []*jsonschema.Schema:
for _, sub := range t {
path, err := listPaths(sub, schema, append(parents, "#"), appendPointer(pointers, schema), currentRecursion, maxRecursion, includeArrays)
if err != nil {
return nil, err
}
paths = append(paths, path...)
}
case *jsonschema.Schema:
path, err := listPaths(t, schema, append(parents, "#"), appendPointer(pointers, schema), currentRecursion, maxRecursion, includeArrays)
if err != nil {
return nil, err
}
paths = append(paths, path...)
}
}
return paths, nil
}

View File

@@ -0,0 +1,31 @@
// Copyright © 2023 Ory Corp
// SPDX-License-Identifier: Apache-2.0
package jsonschemax
import (
"net/url"
"strings"
"github.com/pkg/errors"
)
// JSONPointerToDotNotation converts JSON Pointer "#/foo/bar" to dot-notation "foo.bar".
func JSONPointerToDotNotation(pointer string) (string, error) {
if !strings.HasPrefix(pointer, "#/") {
return pointer, errors.Errorf("remote JSON pointers are not supported: %s", pointer)
}
var path []string
for _, item := range strings.Split(strings.TrimPrefix(pointer, "#/"), "/") {
item = strings.Replace(item, "~1", "/", -1)
item = strings.Replace(item, "~0", "~", -1)
item, err := url.PathUnescape(item)
if err != nil {
return "", err
}
path = append(path, strings.ReplaceAll(item, ".", "\\."))
}
return strings.Join(path, "."), nil
}

72
oryx/jsonschemax/print.go Normal file
View File

@@ -0,0 +1,72 @@
// Copyright © 2023 Ory Corp
// SPDX-License-Identifier: Apache-2.0
package jsonschemax
import (
"errors"
"fmt"
"io"
"strings"
"github.com/tidwall/gjson"
"github.com/ory/jsonschema/v3"
)
func FormatValidationErrorForCLI(w io.Writer, conf []byte, err error) {
if err == nil {
return
}
if e := new(jsonschema.ValidationError); errors.As(err, &e) {
_, _ = fmt.Fprintln(w, "The configuration contains values or keys which are invalid:")
pointer, validation := FormatError(e)
if pointer == "#" {
if len(e.Causes) == 0 {
_, _ = fmt.Fprintln(w, "(root)")
_, _ = fmt.Fprintln(w, "^-- "+validation)
_, _ = fmt.Fprintln(w, "")
}
} else {
spaces := make([]string, len(pointer)+3)
_, _ = fmt.Fprintf(w, "%s: %+v", pointer, gjson.GetBytes(conf, pointer).Value())
_, _ = fmt.Fprintln(w, "")
_, _ = fmt.Fprintf(w, "%s^-- %s", strings.Join(spaces, " "), validation)
_, _ = fmt.Fprintln(w, "")
_, _ = fmt.Fprintln(w, "")
}
for _, cause := range e.Causes {
FormatValidationErrorForCLI(w, conf, cause)
}
return
}
}
func FormatError(e *jsonschema.ValidationError) (string, string) {
var (
err error
pointer string
message string
)
pointer = e.InstancePtr
message = e.Message
switch ctx := e.Context.(type) {
case *jsonschema.ValidationErrorContextRequired:
if len(ctx.Missing) > 0 {
message = "one or more required properties are missing"
pointer = ctx.Missing[0]
}
}
// We can ignore the error as it will simply echo the pointer.
pointer, err = JSONPointerToDotNotation(pointer)
if err != nil {
pointer = e.InstancePtr
}
return pointer, message
}

View File

@@ -0,0 +1,3 @@
dsn: memory
items:
- id: 1

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,12 @@
{
"$id": "https://example.com/config.schema.json",
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "config",
"type": "object",
"properties": {
"dsn": {
"type": "string"
}
},
"required": ["dsn"]
}

View File

@@ -0,0 +1,7 @@
{
"serve": {
"admin": {
"port": 1
}
}
}

View File

@@ -0,0 +1,105 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"providers": {
"title": "OpenID Connect and OAuth2 Providers",
"description": "A list and configuration of OAuth2 and OpenID Connect providers ORY Kratos should integrate with.",
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string",
"examples": ["google"]
},
"provider": {
"title": "Provider",
"description": "Can be one of github, gitlab, generic, google, microsoft, discord.",
"type": "string",
"enum": [
"github",
"gitlab",
"generic",
"google",
"microsoft",
"discord"
],
"examples": ["google"]
},
"client_id": {
"type": "string"
},
"client_secret": {
"type": "string"
},
"issuer_url": {
"type": "string",
"format": "uri",
"examples": ["https://accounts.google.com"]
},
"auth_url": {
"type": "string",
"format": "uri",
"examples": ["https://accounts.google.com/o/oauth2/v2/auth"]
},
"token_url": {
"type": "string",
"format": "uri",
"examples": ["https://www.googleapis.com/oauth2/v4/token"]
},
"mapper_url": {
"title": "Jsonnet Mapper URL",
"description": "The URL where the jsonnet source is located for mapping the provider's data to ORY Kratos data.",
"type": "string",
"format": "uri",
"examples": [
"file://path/to/oidc.jsonnet",
"https://foo.bar.com/path/to/oidc.jsonnet",
"base64://bG9jYWwgc3ViamVjdCA9I..."
]
},
"scope": {
"type": "array",
"items": {
"type": "string",
"examples": ["offline_access", "profile"]
}
},
"tenant": {
"title": "Azure AD Tenant",
"description": "The Azure AD Tenant to use for authentication.",
"type": "string",
"examples": [
"common",
"organizations",
"consumers",
"8eaef023-2b34-4da1-9baa-8bc8c9d6a490",
"contoso.onmicrosoft.com"
]
}
},
"additionalProperties": false,
"required": [],
"if": {
"properties": {
"provider": {
"const": "microsoft"
}
},
"required": ["provider"]
},
"then": {
"required": ["tenant"]
},
"else": {
"not": {
"properties": {
"tenant": {}
},
"required": ["tenant"]
}
}
}
}
}
}

View File

@@ -0,0 +1,16 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"providers": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string"
}
}
}
}
}
}

View File

@@ -0,0 +1,4 @@
[serve]
[serve.admin]
port = "2"

View File

@@ -0,0 +1,4 @@
# serve controls the configuration for the http(s) daemon
serve:
admin:
port: 3

View File

@@ -0,0 +1,3 @@
serve:
admin:
port: 4