From 00cf11c071344103c603c078f07196401d091780 Mon Sep 17 00:00:00 2001 From: hackerman <3372410+aeneasr@users.noreply.github.com> Date: Thu, 12 Oct 2023 17:01:24 +0200 Subject: [PATCH] feat: eventually consistency API controls (#3558) Adds a feature used in Ory Network which enables trading faster reads for slightly stale data. This feature depends on Cockroach functionality and configuration, and is not possible for MySQL or PostgreSQL. --- Makefile | 1 + driver/config/config.go | 7 + embedx/config.schema.json | 16 ++ go.mod | 58 +++--- go.sum | 141 +++++++------- identity/handler.go | 5 + identity/handler_test.go | 9 + identity/pool.go | 5 +- identity/test/pool.go | 53 +++++- internal/client-go/.openapi-generator/FILES | 2 + internal/client-go/README.md | 1 + internal/client-go/api_identity.go | 8 + .../model_consistency_request_parameters.go | 115 ++++++++++++ internal/httpclient/.openapi-generator/FILES | 2 + internal/httpclient/README.md | 1 + internal/httpclient/api_identity.go | 8 + .../model_consistency_request_parameters.go | 115 ++++++++++++ .../sql/identity/persister_identity.go | 177 ++++++++++-------- persistence/sql/persister_test.go | 6 +- spec/api.json | 30 +++ spec/swagger.json | 28 +++ 21 files changed, 599 insertions(+), 189 deletions(-) create mode 100644 internal/client-go/model_consistency_request_parameters.go create mode 100644 internal/httpclient/model_consistency_request_parameters.go diff --git a/Makefile b/Makefile index 20416370f26e..1b8572d3cfe0 100644 --- a/Makefile +++ b/Makefile @@ -97,6 +97,7 @@ sdk: .bin/swagger .bin/ory node_modules swagger generate spec -m -o spec/swagger.json \ -c github.com/ory/kratos \ -c github.com/ory/x/healthx \ + -c github.com/ory/x/crdbx \ -c github.com/ory/x/openapix ory dev swagger sanitize ./spec/swagger.json swagger validate ./spec/swagger.json diff --git a/driver/config/config.go b/driver/config/config.go index 6d5aa68d8900..950152f6d088 100644 --- a/driver/config/config.go +++ b/driver/config/config.go @@ -18,6 +18,8 @@ import ( "testing" "time" + "github.com/ory/x/crdbx" + "github.com/go-webauthn/webauthn/protocol" "github.com/go-webauthn/webauthn/webauthn" "github.com/gofrs/uuid" @@ -186,6 +188,7 @@ const ( ViperKeyOAuth2ProviderOverrideReturnTo = "oauth2_provider.override_return_to" ViperKeyClientHTTPNoPrivateIPRanges = "clients.http.disallow_private_ip_ranges" ViperKeyClientHTTPPrivateIPExceptionURLs = "clients.http.private_ip_exception_urls" + ViperKeyPreviewDefaultReadConsistencyLevel = "preview.default_read_consistency_level" ViperKeyVersion = "version" ) @@ -1488,3 +1491,7 @@ func (p *Config) TokenizeTemplate(ctx context.Context, key string) (_ *SessionTo return &result, nil } + +func (p *Config) DefaultConsistencyLevel(ctx context.Context) crdbx.ConsistencyLevel { + return crdbx.ConsistencyLevelFromString(p.GetProvider(ctx).String(ViperKeyPreviewDefaultReadConsistencyLevel)) +} diff --git a/embedx/config.schema.json b/embedx/config.schema.json index 2992a7d3ddda..53c5c4b288a3 100644 --- a/embedx/config.schema.json +++ b/embedx/config.schema.json @@ -2179,6 +2179,22 @@ }, "additionalProperties": false }, + "preview": { + "title": "Configure Preview Features", + "type": "object", + "properties": { + "default_read_consistency_level": { + "type": "string", + "title": "Default Read Consistency Level", + "description": "The default consistency level to use when reading from the database. Defaults to `strong` to not break existing API contracts. Only set this to `eventual` if you can accept that other read APIs will suddenly return eventually consistent results. It is only effective in Ory Network.", + "enum": [ + "strong", + "eventual" + ], + "default": "strong" + } + } + }, "serve": { "type": "object", "properties": { diff --git a/go.mod b/go.mod index d40791136ea9..a40fc7783f43 100644 --- a/go.mod +++ b/go.mod @@ -16,7 +16,7 @@ replace ( ) require ( - github.com/Masterminds/sprig/v3 v3.2.2 + github.com/Masterminds/sprig/v3 v3.2.3 github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0 github.com/avast/retry-go/v3 v3.1.1 github.com/bradleyjkemp/cupaloy/v2 v2.8.0 @@ -32,9 +32,9 @@ require ( github.com/ghodss/yaml v1.0.0 github.com/go-crypt/crypt v0.2.9 github.com/go-errors/errors v1.0.1 - github.com/go-openapi/strfmt v0.21.3 + github.com/go-openapi/strfmt v0.21.7 github.com/go-playground/validator/v10 v10.4.1 - github.com/go-swagger/go-swagger v0.30.3 + github.com/go-swagger/go-swagger v0.30.5 github.com/go-webauthn/webauthn v0.8.4 github.com/gobuffalo/fizz v1.14.4 github.com/gobuffalo/httptest v1.5.2 @@ -49,7 +49,7 @@ require ( github.com/google/go-jsonnet v0.19.0 github.com/gorilla/sessions v1.2.1 github.com/gtank/cryptopasta v0.0.0-20170601214702-1f550f6f2f69 - github.com/hashicorp/consul/api v1.18.0 + github.com/hashicorp/consul/api v1.20.0 github.com/hashicorp/go-retryablehttp v0.7.2 github.com/hashicorp/golang-lru v0.5.4 github.com/imdario/mergo v0.3.13 @@ -77,7 +77,7 @@ require ( github.com/ory/jsonschema/v3 v3.0.8 github.com/ory/mail/v3 v3.0.0 github.com/ory/nosurf v1.2.7 - github.com/ory/x v0.0.591 + github.com/ory/x v0.0.595 github.com/peterhellberg/link v1.2.0 github.com/phayes/freeport v0.0.0-20180830031419-95f893ade6f2 github.com/pkg/errors v0.9.1 @@ -96,13 +96,13 @@ require ( github.com/urfave/negroni v1.0.0 github.com/zmb3/spotify/v2 v2.0.0 go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.36.4 - go.opentelemetry.io/otel v1.11.1 - go.opentelemetry.io/otel/trace v1.11.1 + go.opentelemetry.io/otel v1.14.0 + go.opentelemetry.io/otel/trace v1.14.0 golang.org/x/crypto v0.12.0 golang.org/x/exp v0.0.0-20220303212507-bbda1eaf7a17 golang.org/x/net v0.14.0 golang.org/x/oauth2 v0.11.0 - golang.org/x/sync v0.1.0 + golang.org/x/sync v0.2.0 golang.org/x/text v0.12.0 golang.org/x/tools/cmd/cover v0.1.0-deprecated google.golang.org/grpc v1.55.0 @@ -112,14 +112,14 @@ require ( github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect github.com/Masterminds/goutils v1.1.1 // indirect github.com/Masterminds/semver v1.5.0 // indirect - github.com/Masterminds/semver/v3 v3.1.1 // indirect + github.com/Masterminds/semver/v3 v3.2.0 // indirect github.com/Microsoft/go-winio v0.6.0 // indirect github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 // indirect github.com/a8m/envsubst v1.3.0 // indirect github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 // indirect github.com/alecthomas/units v0.0.0-20210208195552-ff826a37aa15 // indirect github.com/armon/go-metrics v0.4.0 // indirect - github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d // indirect + github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect github.com/avast/retry-go/v4 v4.3.0 // indirect github.com/aymerick/douceur v0.2.0 // indirect github.com/beorn7/perks v1.0.1 // indirect @@ -150,15 +150,15 @@ require ( github.com/go-logr/logr v1.2.3 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-openapi/analysis v0.21.4 // indirect - github.com/go-openapi/errors v0.20.3 // indirect + github.com/go-openapi/errors v0.20.4 // indirect github.com/go-openapi/inflect v0.19.0 // indirect - github.com/go-openapi/jsonpointer v0.19.5 // indirect - github.com/go-openapi/jsonreference v0.20.0 // indirect + github.com/go-openapi/jsonpointer v0.19.6 // indirect + github.com/go-openapi/jsonreference v0.20.2 // indirect github.com/go-openapi/loads v0.21.2 // indirect - github.com/go-openapi/runtime v0.24.2 // indirect - github.com/go-openapi/spec v0.20.7 // indirect - github.com/go-openapi/swag v0.22.3 // indirect - github.com/go-openapi/validate v0.22.0 // indirect + github.com/go-openapi/runtime v0.26.0 // indirect + github.com/go-openapi/spec v0.20.9 // indirect + github.com/go-openapi/swag v0.22.4 // indirect + github.com/go-openapi/validate v0.22.1 // indirect github.com/go-playground/locales v0.13.0 // indirect github.com/go-playground/universal-translator v0.17.0 // indirect github.com/go-sql-driver/mysql v1.7.0 // indirect @@ -199,7 +199,7 @@ require ( github.com/hashicorp/go-rootcerts v1.0.2 // indirect github.com/hashicorp/hcl v1.0.0 // indirect github.com/hashicorp/serf v0.10.1 // indirect - github.com/huandu/xstrings v1.3.2 // indirect + github.com/huandu/xstrings v1.3.3 // indirect github.com/ian-kent/envconf v0.0.0-20141026121121-c19809918c02 // indirect github.com/ian-kent/go-log v0.0.0-20160113211217-5731446c36ab // indirect github.com/ian-kent/goose v0.0.0-20141221090059-c3541ea826ad // indirect @@ -224,7 +224,7 @@ require ( github.com/knadh/koanf/parsers/yaml v0.1.0 // indirect github.com/knadh/koanf/providers/posflag v0.1.0 // indirect github.com/knadh/koanf/v2 v2.0.1 // indirect - github.com/kr/pretty v0.3.0 // indirect + github.com/kr/pretty v0.3.1 // indirect github.com/kr/text v0.2.0 // indirect github.com/leodido/go-urn v1.2.0 // indirect github.com/lestrrat-go/backoff/v2 v2.0.8 // indirect @@ -260,7 +260,7 @@ require ( github.com/opencontainers/runc v1.1.5 // indirect github.com/openzipkin/zipkin-go v0.4.1 // indirect github.com/pelletier/go-toml v1.9.5 // indirect - github.com/pelletier/go-toml/v2 v2.0.7 // indirect + github.com/pelletier/go-toml/v2 v2.0.8 // indirect github.com/philhofer/fwd v1.1.2 // indirect github.com/pkg/profile v1.7.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect @@ -280,9 +280,9 @@ require ( github.com/sourcegraph/annotate v0.0.0-20160123013949-f4cad6c6324d // indirect github.com/sourcegraph/syntaxhighlight v0.0.0-20170531221838-bd320f5d308e // indirect github.com/spf13/afero v1.9.5 // indirect - github.com/spf13/cast v1.5.0 // indirect + github.com/spf13/cast v1.5.1 // indirect github.com/spf13/jwalterweatherman v1.1.0 // indirect - github.com/spf13/viper v1.15.0 // indirect + github.com/spf13/viper v1.16.0 // indirect github.com/subosito/gotenv v1.4.2 // indirect github.com/t-k/fluent-logger-golang v1.0.0 // indirect github.com/tidwall/match v1.1.1 // indirect @@ -296,23 +296,23 @@ require ( github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect github.com/xeipuuv/gojsonschema v1.2.0 // indirect github.com/xtgo/uuid v0.0.0-20140804021211-a0b114877d4c // indirect - go.mongodb.org/mongo-driver v1.10.3 // indirect + go.mongodb.org/mongo-driver v1.11.3 // indirect go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.36.4 // indirect go.opentelemetry.io/contrib/propagators/b3 v1.11.1 // indirect go.opentelemetry.io/contrib/propagators/jaeger v1.11.1 // indirect go.opentelemetry.io/contrib/samplers/jaegerremote v0.5.2 // indirect go.opentelemetry.io/otel/exporters/jaeger v1.11.1 // indirect - go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.11.1 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.9.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.9.0 // indirect - go.opentelemetry.io/otel/exporters/zipkin v1.11.1 // indirect + go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.14.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.14.0 // indirect; / indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.14.0 // indirect; / indirect + go.opentelemetry.io/otel/exporters/zipkin v1.14.0 // indirect; / indirect go.opentelemetry.io/otel/metric v0.33.0 // indirect - go.opentelemetry.io/otel/sdk v1.11.1 // indirect + go.opentelemetry.io/otel/sdk v1.14.0 // indirect go.opentelemetry.io/proto/otlp v0.19.0 // indirect golang.org/x/mod v0.10.0 // indirect golang.org/x/sys v0.11.0 // indirect golang.org/x/term v0.11.0 // indirect - golang.org/x/tools v0.7.0 // indirect + golang.org/x/tools v0.9.3 // indirect golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect google.golang.org/appengine v1.6.7 // indirect google.golang.org/genproto v0.0.0-20230530153820-e85fd2cbaebc // indirect diff --git a/go.sum b/go.sum index 3c3a6cbe2ef7..a65848ab35af 100644 --- a/go.sum +++ b/go.sum @@ -45,10 +45,11 @@ github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJ github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU= github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww= github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y= -github.com/Masterminds/semver/v3 v3.1.1 h1:hLg3sBzpNErnxhQtUy/mmLR2I9foDujNK030IGemrRc= github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs= -github.com/Masterminds/sprig/v3 v3.2.2 h1:17jRggJu518dr3QaafizSXOjKYp94wKfABxUmyxvxX8= -github.com/Masterminds/sprig/v3 v3.2.2/go.mod h1:UoaO7Yp8KlPnJIYWTFkMaqPUYKTfGFPhxNuwnnxkKlk= +github.com/Masterminds/semver/v3 v3.2.0 h1:3MEsd0SM6jqZojhjLWWeBY+Kcjy9i6MQAeY7YgDP83g= +github.com/Masterminds/semver/v3 v3.2.0/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ= +github.com/Masterminds/sprig/v3 v3.2.3 h1:eL2fZNezLomi0uOLqjQoN6BfsDD+fyLtgbJMAj9n6YA= +github.com/Masterminds/sprig/v3 v3.2.3/go.mod h1:rXcFaZ2zZbLRJv/xSysmlgIM1u11eBaRMhvYXJNkGuM= github.com/Microsoft/go-winio v0.6.0 h1:slsWYD/zyx7lCXoZVlvQrj0hPTM1HI4+v1sIda2yDvg= github.com/Microsoft/go-winio v0.6.0/go.mod h1:cTAf44im0RAYeL23bpB+fzCyDH2MJiz2BO69KH/soAE= github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 h1:TngWCqHvy9oXAN6lEVMRuU21PR1EtLVZJmdB18Gu3Rw= @@ -78,8 +79,8 @@ github.com/armon/go-metrics v0.4.0/go.mod h1:E6amYzXo6aW1tqzoZGT755KkbgrJsSdpwZ+ github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= github.com/asaskevich/govalidator v0.0.0-20200907205600-7a23bdc65eef/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= -github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d h1:Byv0BzEl3/e6D5CLfI0j/7hiIEtvGVFPCZ7Ei2oq8iQ= -github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= +github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3dyBCFEj5IhUbnKptjxatkF07cF2ak3yi77so= +github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= github.com/avast/retry-go/v3 v3.1.1 h1:49Scxf4v8PmiQ/nY0aY3p0hDueqSmc7++cBbtiDGu2g= github.com/avast/retry-go/v3 v3.1.1/go.mod h1:6cXRK369RpzFL3UQGqIUp9Q7GDrams+KsYWrfNA1/nQ= github.com/avast/retry-go/v4 v4.3.0 h1:cqI48aXx0BExKoM7XPklDpoHAg7/srPPLAfWG5z62jo= @@ -204,7 +205,7 @@ github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSw github.com/felixge/httpsnoop v1.0.3 h1:s/nj+GCswXYzN5v2DpNMuMQYe+0DDwt5WVCU6CWBdXk= github.com/felixge/httpsnoop v1.0.3/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k= -github.com/frankban/quicktest v1.14.3 h1:FJKSZTDHjyhriyC81FLQ0LY93eSai0ZyR/ZIkd3ZUKE= +github.com/frankban/quicktest v1.14.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0XL9UY= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= @@ -242,38 +243,40 @@ github.com/go-openapi/analysis v0.21.4/go.mod h1:4zQ35W4neeZTqh3ol0rv/O8JBbka9Qy github.com/go-openapi/errors v0.19.8/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M= github.com/go-openapi/errors v0.19.9/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M= github.com/go-openapi/errors v0.20.2/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M= -github.com/go-openapi/errors v0.20.3 h1:rz6kiC84sqNQoqrtulzaL/VERgkoCyB6WdEkc2ujzUc= -github.com/go-openapi/errors v0.20.3/go.mod h1:Z3FlZ4I8jEGxjUK+bugx3on2mIAk4txuAOhlsB1FSgk= +github.com/go-openapi/errors v0.20.4 h1:unTcVm6PispJsMECE3zWgvG4xTiKda1LIR5rCRWLG6M= +github.com/go-openapi/errors v0.20.4/go.mod h1:Z3FlZ4I8jEGxjUK+bugx3on2mIAk4txuAOhlsB1FSgk= github.com/go-openapi/inflect v0.19.0 h1:9jCH9scKIbHeV9m12SmPilScz6krDxKRasNNSNPXu/4= github.com/go-openapi/inflect v0.19.0/go.mod h1:lHpZVlpIQqLyKwJ4N+YSc9hchQy/i12fJykb83CRBH4= github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= -github.com/go-openapi/jsonpointer v0.19.5 h1:gZr+CIYByUqjcgeLXnQu2gHYQC9o73G2XUeOFYEICuY= github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= +github.com/go-openapi/jsonpointer v0.19.6 h1:eCs3fxoIi3Wh6vtgmLTOjdhSpiqphQ+DaPn38N2ZdrE= +github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs= github.com/go-openapi/jsonreference v0.19.6/go.mod h1:diGHMEHg2IqXZGKxqyvWdfWU/aim5Dprw5bqpKkTvns= -github.com/go-openapi/jsonreference v0.20.0 h1:MYlu0sBgChmCfJxxUKZ8g1cPWFOB37YSZqewK7OKeyA= github.com/go-openapi/jsonreference v0.20.0/go.mod h1:Ag74Ico3lPc+zR+qjn4XBUmXymS4zJbYVCZmcgkasdo= +github.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2KvnJRumpMGbE= +github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k= github.com/go-openapi/loads v0.21.1/go.mod h1:/DtAMXXneXFjbQMGEtbamCZb+4x7eGwkvZCvBmwUG+g= github.com/go-openapi/loads v0.21.2 h1:r2a/xFIYeZ4Qd2TnGpWDIQNcP80dIaZgf704za8enro= github.com/go-openapi/loads v0.21.2/go.mod h1:Jq58Os6SSGz0rzh62ptiu8Z31I+OTHqmULx5e/gJbNw= -github.com/go-openapi/runtime v0.24.2 h1:yX9HMGQbz32M87ECaAhGpJjBmErO3QLcgdZj9BzGx7c= -github.com/go-openapi/runtime v0.24.2/go.mod h1:AKurw9fNre+h3ELZfk6ILsfvPN+bvvlaU/M9q/r9hpk= +github.com/go-openapi/runtime v0.26.0 h1:HYOFtG00FM1UvqrcxbEJg/SwvDRvYLQKGhw2zaQjTcc= +github.com/go-openapi/runtime v0.26.0/go.mod h1:QgRGeZwrUcSHdeh4Ka9Glvo0ug1LC5WyE+EV88plZrQ= github.com/go-openapi/spec v0.20.4/go.mod h1:faYFR1CvsJZ0mNsmsphTMSoRrNV3TEDoAM7FOEWeq8I= github.com/go-openapi/spec v0.20.6/go.mod h1:2OpW+JddWPrpXSCIX8eOx7lZ5iyuWj3RYR6VaaBKcWA= -github.com/go-openapi/spec v0.20.7 h1:1Rlu/ZrOCCob0n+JKKJAWhNWMPW8bOZRg8FJaY+0SKI= -github.com/go-openapi/spec v0.20.7/go.mod h1:2OpW+JddWPrpXSCIX8eOx7lZ5iyuWj3RYR6VaaBKcWA= +github.com/go-openapi/spec v0.20.9 h1:xnlYNQAwKd2VQRRfwTEI0DcK+2cbuvI/0c7jx3gA8/8= +github.com/go-openapi/spec v0.20.9/go.mod h1:2OpW+JddWPrpXSCIX8eOx7lZ5iyuWj3RYR6VaaBKcWA= github.com/go-openapi/strfmt v0.21.0/go.mod h1:ZRQ409bWMj+SOgXofQAGTIo2Ebu72Gs+WaRADcS5iNg= github.com/go-openapi/strfmt v0.21.1/go.mod h1:I/XVKeLc5+MM5oPNN7P6urMOpuLXEcNrCX/rPGuWb0k= -github.com/go-openapi/strfmt v0.21.2/go.mod h1:I/XVKeLc5+MM5oPNN7P6urMOpuLXEcNrCX/rPGuWb0k= -github.com/go-openapi/strfmt v0.21.3 h1:xwhj5X6CjXEZZHMWy1zKJxvW9AfHC9pkyUjLvHtKG7o= github.com/go-openapi/strfmt v0.21.3/go.mod h1:k+RzNO0Da+k3FrrynSNN8F7n/peCmQQqbbXjtDfvmGg= +github.com/go-openapi/strfmt v0.21.7 h1:rspiXgNWgeUzhjo1YU01do6qsahtJNByjLVbPLNHb8k= +github.com/go-openapi/strfmt v0.21.7/go.mod h1:adeGTkxE44sPyLk0JV235VQAO/ZXUr8KAzYjclFs3ew= github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= github.com/go-openapi/swag v0.19.15/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ= github.com/go-openapi/swag v0.21.1/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ= -github.com/go-openapi/swag v0.22.3 h1:yMBqmnQ0gyZvEb/+KzuWZOXgllrXT4SADYbvDaXHv/g= github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= -github.com/go-openapi/validate v0.21.0/go.mod h1:rjnrwK57VJ7A8xqfpAOEKRH8yQSGUriMu5/zuPSQ1hg= -github.com/go-openapi/validate v0.22.0 h1:b0QecH6VslW/TxtpKgzpO1SNG7GU2FsaqKdP1E2T50Y= -github.com/go-openapi/validate v0.22.0/go.mod h1:rjnrwK57VJ7A8xqfpAOEKRH8yQSGUriMu5/zuPSQ1hg= +github.com/go-openapi/swag v0.22.4 h1:QLMzNJnMGPRNDCbySlcj1x01tzU8/9LTTL9hZZZogBU= +github.com/go-openapi/swag v0.22.4/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= +github.com/go-openapi/validate v0.22.1 h1:G+c2ub6q47kfX1sOBLwIQwzBVt8qmOAARyo/9Fqs9NU= +github.com/go-openapi/validate v0.22.1/go.mod h1:rjnrwK57VJ7A8xqfpAOEKRH8yQSGUriMu5/zuPSQ1hg= github.com/go-playground/assert/v2 v2.0.1 h1:MsBgLAaY856+nPRTKrp3/OZK38U/wa0CcBYNjji3q3A= github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q= @@ -285,9 +288,8 @@ github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn github.com/go-sql-driver/mysql v1.7.2-0.20231005084435-37980127edfb h1:R5sscofA9Cyd0h2DNMbR8BHYVKj1ZTOgUah1PoU4OVU= github.com/go-sql-driver/mysql v1.7.2-0.20231005084435-37980127edfb/go.mod h1:6gYm/zDt3ahdnMVTPeT/LfoBFsws1qZm5yI6FmVjB14= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= -github.com/go-stack/stack v1.8.1/go.mod h1:dcoOX6HbPZSZptuspn9bctJ+N/CnF5gGygcUP3XYfe4= -github.com/go-swagger/go-swagger v0.30.3 h1:HuzvdMRed/9Q8vmzVcfNBQByZVtT79DNZxZ18OprdoI= -github.com/go-swagger/go-swagger v0.30.3/go.mod h1:neDPes8r8PCz2JPvHRDj8BTULLh4VJUt7n6MpQqxhHM= +github.com/go-swagger/go-swagger v0.30.5 h1:SQ2+xSonWjjoEMOV5tcOnZJVlfyUfCBhGQGArS1b9+U= +github.com/go-swagger/go-swagger v0.30.5/go.mod h1:cWUhSyCNqV7J1wkkxfr5QmbcnCewetCdvEXqgPvbc/Q= github.com/go-swagger/scan-repo-boundary v0.0.0-20180623220736-973b3573c013 h1:l9rI6sNaZgNC0LnF3MiE+qTmyBA/tZAg1rtyrGbUMK0= github.com/go-test/deep v1.0.4 h1:u2CU3YKy9I2pmu9pX0eq50wCgjfGIt539SqR7FbHiho= github.com/go-test/deep v1.0.4/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= @@ -421,7 +423,6 @@ github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/go-github/v27 v27.0.1 h1:sSMFSShNn4VnqCqs+qhab6TS3uQc+uVR6TD1bW6MavM= github.com/google/go-github/v27 v27.0.1/go.mod h1:/0Gr8pJ55COkmv+S/yPKCczSkUPIM/LnFyubufRNIS0= @@ -486,18 +487,15 @@ github.com/grpc-ecosystem/grpc-gateway/v2 v2.12.0 h1:kr3j8iIMR4ywO/O0rvksXaJvauG github.com/grpc-ecosystem/grpc-gateway/v2 v2.12.0/go.mod h1:ummNFgdgLhhX7aIiy35vVmQNS0rWXknfPE0qe6fmFXg= github.com/gtank/cryptopasta v0.0.0-20170601214702-1f550f6f2f69 h1:7xsUJsB2NrdcttQPa7JLEaGzvdbk7KvfrjgHZXOQRo0= github.com/gtank/cryptopasta v0.0.0-20170601214702-1f550f6f2f69/go.mod h1:YLEMZOtU+AZ7dhN9T/IpGhXVGly2bvkJQ+zxj3WeVQo= -github.com/hashicorp/consul/api v1.18.0 h1:R7PPNzTCeN6VuQNDwwhZWJvzCtGSrNpJqfb22h3yH9g= -github.com/hashicorp/consul/api v1.18.0/go.mod h1:owRRGJ9M5xReDC5nfT8FTJrNAPbT4NM6p/k+d03q2v4= -github.com/hashicorp/consul/sdk v0.13.0 h1:lce3nFlpv8humJL8rNrrGHYSKc3q+Kxfeg3Ii1m6ZWU= -github.com/hashicorp/consul/sdk v0.13.0/go.mod h1:0hs/l5fOVhJy/VdcoaNqUSi2AUs95eF5WKtv+EYIQqE= +github.com/hashicorp/consul/api v1.20.0 h1:9IHTjNVSZ7MIwjlW3N3a7iGiykCMDpxZu8jsxFJh0yc= +github.com/hashicorp/consul/api v1.20.0/go.mod h1:nR64eD44KQ59Of/ECwt2vUmIK2DKsDzAwTmwmLl8Wpo= +github.com/hashicorp/consul/sdk v0.13.1 h1:EygWVWWMczTzXGpO93awkHFzfUka6hLYJ0qhETd+6lY= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= -github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ= github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= github.com/hashicorp/go-hclog v0.9.2/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ= -github.com/hashicorp/go-hclog v0.12.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= github.com/hashicorp/go-hclog v1.2.0 h1:La19f8d7WIlm4ogzNHB0JGqs5AUDAZ2UfCY4sJXcJdM= github.com/hashicorp/go-hclog v1.2.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= @@ -515,14 +513,11 @@ github.com/hashicorp/go-rootcerts v1.0.2 h1:jzhAVGtqPKbwpyCPELlgNWhE1znq+qwJtW5O github.com/hashicorp/go-rootcerts v1.0.2/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8= github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= github.com/hashicorp/go-sockaddr v1.0.2 h1:ztczhD1jLxIRjVejw8gFomI1BQZOe2WoVOu0SyteCQc= -github.com/hashicorp/go-sockaddr v1.0.2/go.mod h1:rB4wwRAUzs07qva3c5SdrY/NEtAUjGlgmH/UkBUC97A= github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= -github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8= github.com/hashicorp/go-version v1.2.1 h1:zEfKbn2+PDgroKdiOzqiE8rsmLqU2uwi5PB5pBJ3TkI= -github.com/hashicorp/go-version v1.2.1/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc= @@ -536,9 +531,8 @@ github.com/hashicorp/memberlist v0.5.0/go.mod h1:yvyXLpo0QaGE59Y7hDTsTzDD25JYBZ4 github.com/hashicorp/serf v0.10.1 h1:Z1H2J60yRKvfDYAOZLd2MU0ND4AH/WDz7xYHDWQsIPY= github.com/hashicorp/serf v0.10.1/go.mod h1:yL2t6BqATOLGc5HF7qbFkTfXoPIY0WZdWHfEvMqbG+4= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= -github.com/huandu/xstrings v1.3.1/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= -github.com/huandu/xstrings v1.3.2 h1:L18LIDzqlW6xN2rEkpdV8+oL/IXWJ1APd+vsdYy4Wdw= -github.com/huandu/xstrings v1.3.2/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= +github.com/huandu/xstrings v1.3.3 h1:/Gcsuc1x8JVbJ9/rlye4xZnVAbEkGauT8lbebqcQws4= +github.com/huandu/xstrings v1.3.3/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= github.com/ian-kent/envconf v0.0.0-20141026121121-c19809918c02 h1:dU8zq210pt1b71X8xh9GOxC7uBHNtQ9BYC+Lb6SA/mA= github.com/ian-kent/envconf v0.0.0-20141026121121-c19809918c02/go.mod h1:1m5fo3aKG2moYtGHC4I2nFkXmG97+vCeaEIWC+mXTSI= github.com/ian-kent/go-log v0.0.0-20160113211217-5731446c36ab h1:OgrFrYWlVzY7Tc8rq7Y4ErlKo28igc70gbfJGTVWTJk= @@ -672,10 +666,10 @@ github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxv github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= -github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= @@ -768,18 +762,15 @@ github.com/miekg/dns v1.1.41 h1:WMszZWJG0XmzbK9FEmzH2TVcqYzFesusSIB41b8KHxY= github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI= github.com/mikefarah/yq/v4 v4.19.1 h1:QrZCqjOBZ918aOZIfl/IwnHBv104SPfarhgO5MGd2W4= github.com/mikefarah/yq/v4 v4.19.1/go.mod h1:krTElh9V1fv3Cw7+21S8El/W/vn3f2buOOcJ4VyjsFY= -github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= github.com/mitchellh/cli v1.1.0/go.mod h1:xcISNoH86gajksDmfB23e/pu+B+GeFRMYmoHXxx3xhI= github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw= github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw= github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s= github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= -github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo= github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.3.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= -github.com/mitchellh/mapstructure v1.4.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= @@ -823,7 +814,6 @@ github.com/opencontainers/runc v1.1.5 h1:L44KXEpKmfWDcS02aeGm8QNTFXTo2D+8MYGDIJ/ github.com/opencontainers/runc v1.1.5/go.mod h1:1J5XiS+vdZ3wCyZybsuxXZWGrgSr8fFJHLXuG2PsnNg= github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opencontainers/selinux v1.10.0/go.mod h1:2i0OySw99QjzBBQByd1Gr9gSjvuho1lHsJxIJ3gGbJI= -github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc= github.com/openzipkin/zipkin-go v0.4.1 h1:kNd/ST2yLLWhaWrkgchya40TJabe8Hioj9udfPcEO5A= github.com/openzipkin/zipkin-go v0.4.1/go.mod h1:qY0VqDSN1pOBN94dBc6w2GJlWLiovAyg7Qt6/I9HecM= github.com/ory/analytics-go/v5 v5.0.1 h1:LX8T5B9FN8KZXOtxgN+R3I4THRRVB6+28IKgKBpXmAM= @@ -847,16 +837,16 @@ github.com/ory/nosurf v1.2.7 h1:YrHrbSensQyU6r6HT/V5+HPdVEgrOTMJiLoJABSBOp4= github.com/ory/nosurf v1.2.7/go.mod h1:d4L3ZBa7Amv55bqxCBtCs63wSlyaiCkWVl4vKf3OUxA= github.com/ory/sessions v1.2.2-0.20220110165800-b09c17334dc2 h1:zm6sDvHy/U9XrGpixwHiuAwpp0Ock6khSVHkrv6lQQU= github.com/ory/sessions v1.2.2-0.20220110165800-b09c17334dc2/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/zI+bUmuGM= -github.com/ory/x v0.0.591 h1:a3hyQZIwokuRCeoPzMxbewY/y6C6r1NgX4Jn3csVZv0= -github.com/ory/x v0.0.591/go.mod h1:ksLBEd6iW6czGpE6eNA0gCIxO1FFeqIxCZgsgwNrzMM= +github.com/ory/x v0.0.595 h1:oh2/wLyyQ6hMaFblj9u0EGzrR5tEOmnp+2as+XkER9g= +github.com/ory/x v0.0.595/go.mod h1:ksLBEd6iW6czGpE6eNA0gCIxO1FFeqIxCZgsgwNrzMM= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pascaldekloe/goe v0.1.0 h1:cBOtyMzM9HTpWjXfbbunk26uA6nG3a8n06Wieeh0MwY= github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pelletier/go-toml v1.7.0/go.mod h1:vwGMzjaWMwyfHwgIBhI2YUM4fB6nL6lVAvS1LBMMhTE= github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8= github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= -github.com/pelletier/go-toml/v2 v2.0.7 h1:muncTPStnKRos5dpVKULv2FVd4bMOhNePj9CjgDb8Us= -github.com/pelletier/go-toml/v2 v2.0.7/go.mod h1:eumQOmlWiOPt5WriQQqoM5y18pDHwha2N+QD+EUNTek= +github.com/pelletier/go-toml/v2 v2.0.8 h1:0ctb6s9mE31h0/lhu+J6OPmVeDxJn+kYnJc2jZR9tGQ= +github.com/pelletier/go-toml/v2 v2.0.8/go.mod h1:vuYfssBdrU2XDZ9bYydBu6t+6a6PYNcZljzZR9VXg+4= github.com/peterhellberg/link v1.2.0 h1:UA5pg3Gp/E0F2WdX7GERiNrPQrM1K6CVJUUWfHa4t6c= github.com/peterhellberg/link v1.2.0/go.mod h1:gYfAh+oJgQu2SrZHg5hROVRQe1ICoK0/HHJTcE0edxc= github.com/phayes/freeport v0.0.0-20180830031419-95f893ade6f2 h1:JhzVVoYvbOACxoUmOs6V/G4D5nPVUW73rKvXxP4XUJc= @@ -930,7 +920,6 @@ github.com/rs/zerolog v1.15.0/go.mod h1:xYTKnLHcpfU2225ny5qZjxnj9NvkumZYjJHlAThC github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= -github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/samber/lo v1.37.0 h1:XjVcB8g6tgUp8rsPsJ2CvhClfImrpL04YpQHXeHPhRw= github.com/samber/lo v1.37.0/go.mod h1:9vaz2O4o8oOnK23pd2TrXufcbdbJIa3b6cstBWKpopA= github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= @@ -978,8 +967,8 @@ github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasO github.com/spf13/afero v1.9.5 h1:stMpOSZFs//0Lv29HduCmli3GUfpFoF3Y1Q/aXj/wVM= github.com/spf13/afero v1.9.5/go.mod h1:UBogFpq8E9Hx+xc5CNTTEpTnuHVmXDwZcZcE1eb/UhQ= github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= -github.com/spf13/cast v1.5.0 h1:rj3WzYc11XZaIZMPKmwP96zkFEnnAmV8s6XbB2aY32w= -github.com/spf13/cast v1.5.0/go.mod h1:SpXXQ5YoyJw6s3/6cMTQuxvgRl3PCJiyaX9p6b155UU= +github.com/spf13/cast v1.5.1 h1:R+kOtfhWQE6TVQzY+4D7wJLBgkdVasCEFxSUBYBYIlA= +github.com/spf13/cast v1.5.1/go.mod h1:b9PdjNptOpzXr7Rq1q9gJML/2cdGQAo69NKzQ10KN48= github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= github.com/spf13/cobra v1.6.1/go.mod h1:IOw/AERYS7UzyrGinqmz6HLUo219MORXGxhbaJUqzrY= github.com/spf13/cobra v1.7.0 h1:hyqWnYt1ZQShIddO5kBpj3vu05/++x6tJ6dg8EC572I= @@ -989,8 +978,8 @@ github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0 github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= -github.com/spf13/viper v1.15.0 h1:js3yy885G8xwJa6iOISGFwd+qlUo5AvyXb7CiihdtiU= -github.com/spf13/viper v1.15.0/go.mod h1:fFcTBJxvhhzSJiZy8n+PeW6t8l+KeT/uTARa0jHOQLA= +github.com/spf13/viper v1.16.0 h1:rGGH0XDZhdUOryiDWjmIvUSWpbNqisK8Wk0Vyefw8hc= +github.com/spf13/viper v1.16.0/go.mod h1:yg78JgCJcbrQOvV9YLXgkLaZqUidkY9K+Dd1FofRzQg= github.com/sqs/goreturns v0.0.0-20181028201513-538ac6014518 h1:iD+PFTQwKEmbwSdwfvP5ld2WEI/g7qbdhmHJ2ASfYGs= github.com/sqs/goreturns v0.0.0-20181028201513-538ac6014518/go.mod h1:CKI4AZ4XmGV240rTHfO0hfE83S6/a3/Q1siZJ/vXf7A= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= @@ -1008,6 +997,7 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/subosito/gotenv v1.4.2 h1:X1TuBLAMDFbaTAChgCBLu3DU3UPyELpnF2jjJ2cz/S8= @@ -1068,10 +1058,9 @@ github.com/zmb3/spotify/v2 v2.0.0 h1:NHW9btztNZTrJ0+3yMNyfY5qcu1ck9s36wwzc7zrCic github.com/zmb3/spotify/v2 v2.0.0/go.mod h1:+LVh9CafHu7SedyqYmEf12Rd01dIVlEL845yNhksW0E= go.mongodb.org/mongo-driver v1.7.3/go.mod h1:NqaYOwnXWr5Pm7AOpO5QFxKJ503nbMse/R79oO62zWg= go.mongodb.org/mongo-driver v1.7.5/go.mod h1:VXEWRZ6URJIkUq2SCAyapmhH0ZLRBP+FT4xhp5Zvxng= -go.mongodb.org/mongo-driver v1.8.3/go.mod h1:0sQWfOeY63QTntERDJJ/0SuKK0T1uVSgKCuAROlKEPY= go.mongodb.org/mongo-driver v1.10.0/go.mod h1:wsihk0Kdgv8Kqu1Anit4sfK+22vSFbUrAVEYRhCXrA8= -go.mongodb.org/mongo-driver v1.10.3 h1:XDQEvmh6z1EUsXuIkXE9TaVeqHw6SwS1uf93jFs0HBA= -go.mongodb.org/mongo-driver v1.10.3/go.mod h1:z4XpeoU6w+9Vht+jAFyLgVrD+jGSQQe0+CBWFHNiHt8= +go.mongodb.org/mongo-driver v1.11.3 h1:Ql6K6qYHEzB6xvu4+AU0BoRoqf9vFPcc4o7MUIdPW8Y= +go.mongodb.org/mongo-driver v1.11.3/go.mod h1:PTSz5yu21bkT/wXpkS7WR5f0ddqw5quethTUn9WM+2g= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= @@ -1088,24 +1077,24 @@ go.opentelemetry.io/contrib/propagators/jaeger v1.11.1 h1:Gw+P9NQzw4bjNGZXsoDhww go.opentelemetry.io/contrib/propagators/jaeger v1.11.1/go.mod h1:dP/N3ZFADH8azBcZfGXEFNBXpEmPTXYcNj9rkw1+2Oc= go.opentelemetry.io/contrib/samplers/jaegerremote v0.5.2 h1:Izp9RqrioK/y7J/RXy2c7zd83iKQ4N3td3AMNKNzHiI= go.opentelemetry.io/contrib/samplers/jaegerremote v0.5.2/go.mod h1:Z0aRlRERn9v/3J2K+ATa6ffKyb8/i+/My/gTzFr3dII= -go.opentelemetry.io/otel v1.11.1 h1:4WLLAmcfkmDk2ukNXJyq3/kiz/3UzCaYq6PskJsaou4= -go.opentelemetry.io/otel v1.11.1/go.mod h1:1nNhXBbWSD0nsL38H6btgnFN2k4i0sNLHNNMZMSbUGE= +go.opentelemetry.io/otel v1.14.0 h1:/79Huy8wbf5DnIPhemGB+zEPVwnN6fuQybr/SRXa6hM= +go.opentelemetry.io/otel v1.14.0/go.mod h1:o4buv+dJzx8rohcUeRmWUZhqupFvzWis188WlggnNeU= go.opentelemetry.io/otel/exporters/jaeger v1.11.1 h1:F9Io8lqWdGyIbY3/SOGki34LX/l+7OL0gXNxjqwcbuQ= go.opentelemetry.io/otel/exporters/jaeger v1.11.1/go.mod h1:lRa2w3bQ4R4QN6zYsDgy7tEezgoKEu7Ow2g35Y75+KI= -go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.11.1 h1:X2GndnMCsUPh6CiY2a+frAbNsXaPLbB0soHRYhAZ5Ig= -go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.11.1/go.mod h1:i8vjiSzbiUC7wOQplijSXMYUpNM93DtlS5CbUT+C6oQ= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.9.0 h1:NN90Cuna0CnBg8YNu1Q0V35i2E8LDByFOwHRCq/ZP9I= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.9.0/go.mod h1:0EsCXjZAiiZGnLdEUXM9YjCKuuLZMYyglh2QDXcYKVA= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.9.0 h1:FAF9l8Wjxi9Ad2k/vLTfHZyzXYX72C62wBGpV3G6AIo= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.9.0/go.mod h1:smUdtylgc0YQiUr2PuifS4hBXhAS5xtR6WQhxP1wiNA= -go.opentelemetry.io/otel/exporters/zipkin v1.11.1 h1:JlJ3/oQoyqlrPDCfsSVFcHgGeHvZq+hr1VPWtiYCXTo= -go.opentelemetry.io/otel/exporters/zipkin v1.11.1/go.mod h1:T4S6aVwIS1+MHA+dJHCcPROtZe6ORwnv5vMKPRapsFw= +go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.14.0 h1:/fXHZHGvro6MVqV34fJzDhi7sHGpX3Ej/Qjmfn003ho= +go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.14.0/go.mod h1:UFG7EBMRdXyFstOwH028U0sVf+AvukSGhF0g8+dmNG8= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.14.0 h1:TKf2uAs2ueguzLaxOCBXNpHxfO/aC7PAdDsSH0IbeRQ= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.14.0/go.mod h1:HrbCVv40OOLTABmOn1ZWty6CHXkU8DK/Urc43tHug70= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.14.0 h1:3jAYbRHQAqzLjd9I4tzxwJ8Pk/N6AqBcF6m1ZHrxG94= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.14.0/go.mod h1:+N7zNjIJv4K+DeX67XXET0P+eIciESgaFDBqh+ZJFS4= +go.opentelemetry.io/otel/exporters/zipkin v1.14.0 h1:reEVE1upBF9tcujgvSqLJS0SrI7JQPaTKP4s4rymnSs= +go.opentelemetry.io/otel/exporters/zipkin v1.14.0/go.mod h1:RcjvOAcvhzcufQP8aHmzRw1gE9g/VEZufDdo2w+s4sk= go.opentelemetry.io/otel/metric v0.33.0 h1:xQAyl7uGEYvrLAiV/09iTJlp1pZnQ9Wl793qbVvED1E= go.opentelemetry.io/otel/metric v0.33.0/go.mod h1:QlTYc+EnYNq/M2mNk1qDDMRLpqCOj2f/r5c7Fd5FYaI= -go.opentelemetry.io/otel/sdk v1.11.1 h1:F7KmQgoHljhUuJyA+9BiU+EkJfyX5nVVF4wyzWZpKxs= -go.opentelemetry.io/otel/sdk v1.11.1/go.mod h1:/l3FE4SupHJ12TduVjUkZtlfFqDCQJlOlithYrdktys= -go.opentelemetry.io/otel/trace v1.11.1 h1:ofxdnzsNrGBYXbP7t7zpUK281+go5rF7dvdIZXF8gdQ= -go.opentelemetry.io/otel/trace v1.11.1/go.mod h1:f/Q9G7vzk5u91PhbmKbg1Qn0rzH1LJ4vbPHFGkTPtOk= +go.opentelemetry.io/otel/sdk v1.14.0 h1:PDCppFRDq8A1jL9v6KMI6dYesaq+DFcDZvjsoGvxGzY= +go.opentelemetry.io/otel/sdk v1.14.0/go.mod h1:bwIC5TjrNG6QDCHNWvW4HLHtUQ4I+VQDsnjhvyZCALM= +go.opentelemetry.io/otel/trace v1.14.0 h1:wp2Mmvj41tDsyAJXiWDWpfNsOiIyd38fy85pyKcFq/M= +go.opentelemetry.io/otel/trace v1.14.0/go.mod h1:8avnQLK+CG77yNLUae4ea2JDQ6iT+gozhnZjy/rw9G8= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= go.opentelemetry.io/proto/otlp v0.19.0 h1:IVN6GR+mhC4s5yfcTbmzHYODqvWAp3ZedA2SJPI1Nnw= go.opentelemetry.io/proto/otlp v0.19.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U= @@ -1134,10 +1123,8 @@ golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3 golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200323165209-0ec3e9974c59/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20200414173820-0848c9571904/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201203163018-be400aefbc4c/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= -golang.org/x/crypto v0.0.0-20201216223049-8b5274cf687f/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= @@ -1147,6 +1134,7 @@ golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5y golang.org/x/crypto v0.0.0-20220517005047-85d78b3ac167/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0= golang.org/x/crypto v0.12.0 h1:tFM/ta59kqch6LlvYnPa0yx5a83cL2nHflFhYKvv9Yk= golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw= @@ -1235,12 +1223,12 @@ golang.org/x/net v0.0.0-20210421230115-4e50805a0758/go.mod h1:72T/g9IO56b78aLF+1 golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20211216030914-fe4d6282115f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.0.0-20220826154423-83b083e8dc8b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= golang.org/x/net v0.0.0-20221002022538-bcab6841153b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= +golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= golang.org/x/net v0.3.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= @@ -1275,8 +1263,9 @@ golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220929204114-8fcdb60fdcc0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.2.0 h1:PUR+T4wwASmuSTYdKjYHI5TD22Wy5ogLU5qZCOLxBrI= +golang.org/x/sync v0.2.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -1353,7 +1342,6 @@ golang.org/x/sys v0.0.0-20211116061358-0a5406a5449c/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220406163625-3f8b81556e12/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220513210249-45d2b4557a2a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -1363,6 +1351,7 @@ golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20221010170243-090e33056c14/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -1375,6 +1364,7 @@ golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9sn golang.org/x/term v0.0.0-20210317153231-de623e64d2a6/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.0.0-20220722155259-a9ba230a4035/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= @@ -1389,6 +1379,7 @@ golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= @@ -1464,8 +1455,8 @@ golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.4.0/go.mod h1:UE5sM2OK9E/d67R0ANs2xJizIymRP5gJU295PvKXxjQ= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.7.0 h1:W4OVu8VVOaIO0yzWMNdepAulS7YfoS3Zabrm8DOXXU4= -golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s= +golang.org/x/tools v0.9.3 h1:Gn1I8+64MsuTb/HpH+LmQtNas23LhUVr3rYZ0eKuaMM= +golang.org/x/tools v0.9.3/go.mod h1:owI94Op576fPu3cIGQeHs3joujW/2Oc6MtlxbF5dfNc= golang.org/x/tools/cmd/cover v0.1.0-deprecated h1:Rwy+mWYz6loAF+LnG1jHG/JWMHRMMC2/1XX3Ejkx9lA= golang.org/x/tools/cmd/cover v0.1.0-deprecated/go.mod h1:hMDiIvlpN1NoVgmjLjUJE9tMHyxHjFX7RuQ+rW12mSA= golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/identity/handler.go b/identity/handler.go index ce1a9f927ce0..5c82f27b9164 100644 --- a/identity/handler.go +++ b/identity/handler.go @@ -11,7 +11,9 @@ import ( "strings" "time" + "github.com/ory/x/crdbx" "github.com/ory/x/pagination/keysetpagination" + "github.com/ory/x/pagination/migrationpagination" "github.com/ory/x/pagination/pagepagination" "github.com/ory/x/sqlcon" @@ -152,6 +154,8 @@ type listIdentitiesParameters struct { // required: false // in: query CredentialsIdentifierSimilar string `json:"preview_credentials_identifier_similar"` + + crdbx.ConsistencyRequestParameters } // swagger:route GET /admin/identities identity listIdentities @@ -178,6 +182,7 @@ func (h *Handler) list(w http.ResponseWriter, r *http.Request, _ httprouter.Para Expand: ExpandDefault, CredentialsIdentifier: r.URL.Query().Get("credentials_identifier"), CredentialsIdentifierSimilar: r.URL.Query().Get("preview_credentials_identifier_similar"), + ConsistencyLevel: crdbx.ConsistencyLevelFromRequest(r), } ) if params.CredentialsIdentifier != "" && params.CredentialsIdentifierSimilar != "" { diff --git a/identity/handler_test.go b/identity/handler_test.go index 5da5bf076b68..78f7cfe505d2 100644 --- a/identity/handler_test.go +++ b/identity/handler_test.go @@ -1267,6 +1267,15 @@ func TestHandler(t *testing.T) { } }) + t.Run("case=should list all identities with eventual consistency", func(t *testing.T) { + for name, ts := range map[string]*httptest.Server{"public": publicTS, "admin": adminTS} { + t.Run("endpoint="+name, func(t *testing.T) { + res := get(t, ts, "/identities?consistency=eventual", http.StatusOK) + assert.EqualValues(t, "baz", res.Get(`#(traits.bar=="baz").traits.bar`).String(), "%s", res.Raw) + }) + } + }) + t.Run("case=should not be able to update an identity that does not exist yet", func(t *testing.T) { for name, ts := range map[string]*httptest.Server{"public": publicTS, "admin": adminTS} { t.Run("endpoint="+name, func(t *testing.T) { diff --git a/identity/pool.go b/identity/pool.go index 61665f056abd..e0d14637f29a 100644 --- a/identity/pool.go +++ b/identity/pool.go @@ -6,6 +6,8 @@ package identity import ( "context" + "github.com/ory/x/crdbx" + "github.com/ory/kratos/x" "github.com/ory/x/pagination/keysetpagination" "github.com/ory/x/sqlxx" @@ -20,7 +22,8 @@ type ( CredentialsIdentifierSimilar string KeySetPagination []keysetpagination.Option // DEPRECATED - PagePagination *x.Page + PagePagination *x.Page + ConsistencyLevel crdbx.ConsistencyLevel } Pool interface { diff --git a/identity/test/pool.go b/identity/test/pool.go index b51a88f242ca..85cafd3d369f 100644 --- a/identity/test/pool.go +++ b/identity/test/pool.go @@ -13,6 +13,8 @@ import ( "testing" "time" + "github.com/ory/x/crdbx" + "github.com/bxcodec/faker/v3" "github.com/gofrs/uuid" "github.com/stretchr/testify/assert" @@ -34,7 +36,7 @@ import ( "github.com/ory/x/urlx" ) -func TestPool(ctx context.Context, conf *config.Config, p persistence.Persister, m *identity.Manager) func(t *testing.T) { +func TestPool(ctx context.Context, conf *config.Config, p persistence.Persister, m *identity.Manager, dbname string) func(t *testing.T) { return func(t *testing.T) { exampleServerURL := urlx.ParseOrPanic("http://example.com") conf.MustSet(ctx, config.ViperKeyPublicBaseURL, exampleServerURL.String()) @@ -654,6 +656,55 @@ func TestPool(ctx context.Context, conf *config.Config, p persistence.Persister, require.NoError(t, err) assert.Len(t, is, 0) }) + + t.Run("eventually consistent", func(t *testing.T) { + if dbname != "cockroach" { + t.Skipf("Test only works with cockroachdb") + return + } + + id := x.NewUUID().String() + another := oidcIdentity("", id) + require.NoError(t, p.CreateIdentity(ctx, another)) + createdIDs = append(createdIDs, another.ID) + + is, _, err := p.ListIdentities(ctx, identity.ListIdentityParameters{ + Expand: identity.ExpandDefault, + KeySetPagination: []keysetpagination.Option{keysetpagination.WithSize(25)}, + ConsistencyLevel: crdbx.ConsistencyLevelStrong, + }) + require.NoError(t, err) + require.Len(t, is, len(createdIDs)) + + var results []identity.Identity + // It takes about 4.8 seconds to replicate the data. + for i := 0; i < 8; i++ { + time.Sleep(time.Second) + + // The error here is explicitly ignored because the table / schema might not yet be replicated. + // This can lead to "ERROR: cached plan must not change result type (SQLSTATE 0A000)" whih is caused + // because the prepared query exist but the schema is not yet replicated. + is, _, _ := p.ListIdentities(ctx, identity.ListIdentityParameters{ + Expand: identity.ExpandEverything, + KeySetPagination: []keysetpagination.Option{keysetpagination.WithSize(25)}, + ConsistencyLevel: crdbx.ConsistencyLevelEventual, + }) + + if len(is) == len(createdIDs) { + results = is + } + } + require.NotZero(t, len(results)) + require.Len(t, results, len(createdIDs), "Could not find all identities after 8 seconds") + + var found bool + for _, i := range results { + if i.ID == another.ID { + found = true + } + } + require.True(t, found, id, "Unable to find created identity in eventually consistent results.") + }) }) t.Run("case=find identity by its credentials identifier", func(t *testing.T) { diff --git a/internal/client-go/.openapi-generator/FILES b/internal/client-go/.openapi-generator/FILES index 908e0021b70e..24a832963dac 100644 --- a/internal/client-go/.openapi-generator/FILES +++ b/internal/client-go/.openapi-generator/FILES @@ -11,6 +11,7 @@ client.go configuration.go docs/AuthenticatorAssuranceLevel.md docs/BatchPatchIdentitiesResponse.md +docs/ConsistencyRequestParameters.md docs/ContinueWith.md docs/ContinueWithSetOrySessionToken.md docs/ContinueWithVerificationUi.md @@ -128,6 +129,7 @@ go.mod go.sum model_authenticator_assurance_level.go model_batch_patch_identities_response.go +model_consistency_request_parameters.go model_continue_with.go model_continue_with_set_ory_session_token.go model_continue_with_verification_ui.go diff --git a/internal/client-go/README.md b/internal/client-go/README.md index 17418c7742f8..171764a11a5b 100644 --- a/internal/client-go/README.md +++ b/internal/client-go/README.md @@ -138,6 +138,7 @@ Class | Method | HTTP request | Description - [AuthenticatorAssuranceLevel](docs/AuthenticatorAssuranceLevel.md) - [BatchPatchIdentitiesResponse](docs/BatchPatchIdentitiesResponse.md) + - [ConsistencyRequestParameters](docs/ConsistencyRequestParameters.md) - [ContinueWith](docs/ContinueWith.md) - [ContinueWithSetOrySessionToken](docs/ContinueWithSetOrySessionToken.md) - [ContinueWithVerificationUi](docs/ContinueWithVerificationUi.md) diff --git a/internal/client-go/api_identity.go b/internal/client-go/api_identity.go index 93dcc20dddd1..ae406e98fae0 100644 --- a/internal/client-go/api_identity.go +++ b/internal/client-go/api_identity.go @@ -2051,6 +2051,7 @@ type IdentityApiApiListIdentitiesRequest struct { page *int64 pageSize *int64 pageToken *string + consistency *string credentialsIdentifier *string previewCredentialsIdentifierSimilar *string } @@ -2071,6 +2072,10 @@ func (r IdentityApiApiListIdentitiesRequest) PageToken(pageToken string) Identit r.pageToken = &pageToken return r } +func (r IdentityApiApiListIdentitiesRequest) Consistency(consistency string) IdentityApiApiListIdentitiesRequest { + r.consistency = &consistency + return r +} func (r IdentityApiApiListIdentitiesRequest) CredentialsIdentifier(credentialsIdentifier string) IdentityApiApiListIdentitiesRequest { r.credentialsIdentifier = &credentialsIdentifier return r @@ -2134,6 +2139,9 @@ func (a *IdentityApiService) ListIdentitiesExecute(r IdentityApiApiListIdentitie if r.pageToken != nil { localVarQueryParams.Add("page_token", parameterToString(*r.pageToken, "")) } + if r.consistency != nil { + localVarQueryParams.Add("consistency", parameterToString(*r.consistency, "")) + } if r.credentialsIdentifier != nil { localVarQueryParams.Add("credentials_identifier", parameterToString(*r.credentialsIdentifier, "")) } diff --git a/internal/client-go/model_consistency_request_parameters.go b/internal/client-go/model_consistency_request_parameters.go new file mode 100644 index 000000000000..6c48a4d6bb47 --- /dev/null +++ b/internal/client-go/model_consistency_request_parameters.go @@ -0,0 +1,115 @@ +/* + * Ory Identities API + * + * This is the API specification for Ory Identities with features such as registration, login, recovery, account verification, profile settings, password reset, identity management, session management, email and sms delivery, and more. + * + * API version: + * Contact: office@ory.sh + */ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. + +package client + +import ( + "encoding/json" +) + +// ConsistencyRequestParameters Control API consistency guarantees +type ConsistencyRequestParameters struct { + // Read Consistency Level (preview) The read consistency level determines the consistency guarantee for reads: strong (slow): The read is guaranteed to return the most recent data committed at the start of the read. eventual (very fast): The result will return data that is about 4.8 seconds old. The default consistency guarantee can be changed in the Ory Network Console or using the Ory CLI with `ory patch project --replace '/previews/default_read_consistency_level=\"strong\"'`. Setting the default consistency level to `eventual` may cause regressions in the future as we add consistency controls to more APIs. Currently, the following APIs will be affected by this setting: `GET /admin/identities` This feature is in preview and only available in Ory Network. ConsistencyLevelUnset ConsistencyLevelUnset is the unset / default consistency level. strong ConsistencyLevelStrong ConsistencyLevelStrong is the strong consistency level. eventual ConsistencyLevelEventual ConsistencyLevelEventual is the eventual consistency level using follower read timestamps. + Consistency *string `json:"consistency,omitempty"` +} + +// NewConsistencyRequestParameters instantiates a new ConsistencyRequestParameters object +// This constructor will assign default values to properties that have it defined, +// and makes sure properties required by API are set, but the set of arguments +// will change when the set of required properties is changed +func NewConsistencyRequestParameters() *ConsistencyRequestParameters { + this := ConsistencyRequestParameters{} + return &this +} + +// NewConsistencyRequestParametersWithDefaults instantiates a new ConsistencyRequestParameters object +// This constructor will only assign default values to properties that have it defined, +// but it doesn't guarantee that properties required by API are set +func NewConsistencyRequestParametersWithDefaults() *ConsistencyRequestParameters { + this := ConsistencyRequestParameters{} + return &this +} + +// GetConsistency returns the Consistency field value if set, zero value otherwise. +func (o *ConsistencyRequestParameters) GetConsistency() string { + if o == nil || o.Consistency == nil { + var ret string + return ret + } + return *o.Consistency +} + +// GetConsistencyOk returns a tuple with the Consistency field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *ConsistencyRequestParameters) GetConsistencyOk() (*string, bool) { + if o == nil || o.Consistency == nil { + return nil, false + } + return o.Consistency, true +} + +// HasConsistency returns a boolean if a field has been set. +func (o *ConsistencyRequestParameters) HasConsistency() bool { + if o != nil && o.Consistency != nil { + return true + } + + return false +} + +// SetConsistency gets a reference to the given string and assigns it to the Consistency field. +func (o *ConsistencyRequestParameters) SetConsistency(v string) { + o.Consistency = &v +} + +func (o ConsistencyRequestParameters) MarshalJSON() ([]byte, error) { + toSerialize := map[string]interface{}{} + if o.Consistency != nil { + toSerialize["consistency"] = o.Consistency + } + return json.Marshal(toSerialize) +} + +type NullableConsistencyRequestParameters struct { + value *ConsistencyRequestParameters + isSet bool +} + +func (v NullableConsistencyRequestParameters) Get() *ConsistencyRequestParameters { + return v.value +} + +func (v *NullableConsistencyRequestParameters) Set(val *ConsistencyRequestParameters) { + v.value = val + v.isSet = true +} + +func (v NullableConsistencyRequestParameters) IsSet() bool { + return v.isSet +} + +func (v *NullableConsistencyRequestParameters) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableConsistencyRequestParameters(val *ConsistencyRequestParameters) *NullableConsistencyRequestParameters { + return &NullableConsistencyRequestParameters{value: val, isSet: true} +} + +func (v NullableConsistencyRequestParameters) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableConsistencyRequestParameters) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} diff --git a/internal/httpclient/.openapi-generator/FILES b/internal/httpclient/.openapi-generator/FILES index 908e0021b70e..24a832963dac 100644 --- a/internal/httpclient/.openapi-generator/FILES +++ b/internal/httpclient/.openapi-generator/FILES @@ -11,6 +11,7 @@ client.go configuration.go docs/AuthenticatorAssuranceLevel.md docs/BatchPatchIdentitiesResponse.md +docs/ConsistencyRequestParameters.md docs/ContinueWith.md docs/ContinueWithSetOrySessionToken.md docs/ContinueWithVerificationUi.md @@ -128,6 +129,7 @@ go.mod go.sum model_authenticator_assurance_level.go model_batch_patch_identities_response.go +model_consistency_request_parameters.go model_continue_with.go model_continue_with_set_ory_session_token.go model_continue_with_verification_ui.go diff --git a/internal/httpclient/README.md b/internal/httpclient/README.md index 17418c7742f8..171764a11a5b 100644 --- a/internal/httpclient/README.md +++ b/internal/httpclient/README.md @@ -138,6 +138,7 @@ Class | Method | HTTP request | Description - [AuthenticatorAssuranceLevel](docs/AuthenticatorAssuranceLevel.md) - [BatchPatchIdentitiesResponse](docs/BatchPatchIdentitiesResponse.md) + - [ConsistencyRequestParameters](docs/ConsistencyRequestParameters.md) - [ContinueWith](docs/ContinueWith.md) - [ContinueWithSetOrySessionToken](docs/ContinueWithSetOrySessionToken.md) - [ContinueWithVerificationUi](docs/ContinueWithVerificationUi.md) diff --git a/internal/httpclient/api_identity.go b/internal/httpclient/api_identity.go index 93dcc20dddd1..ae406e98fae0 100644 --- a/internal/httpclient/api_identity.go +++ b/internal/httpclient/api_identity.go @@ -2051,6 +2051,7 @@ type IdentityApiApiListIdentitiesRequest struct { page *int64 pageSize *int64 pageToken *string + consistency *string credentialsIdentifier *string previewCredentialsIdentifierSimilar *string } @@ -2071,6 +2072,10 @@ func (r IdentityApiApiListIdentitiesRequest) PageToken(pageToken string) Identit r.pageToken = &pageToken return r } +func (r IdentityApiApiListIdentitiesRequest) Consistency(consistency string) IdentityApiApiListIdentitiesRequest { + r.consistency = &consistency + return r +} func (r IdentityApiApiListIdentitiesRequest) CredentialsIdentifier(credentialsIdentifier string) IdentityApiApiListIdentitiesRequest { r.credentialsIdentifier = &credentialsIdentifier return r @@ -2134,6 +2139,9 @@ func (a *IdentityApiService) ListIdentitiesExecute(r IdentityApiApiListIdentitie if r.pageToken != nil { localVarQueryParams.Add("page_token", parameterToString(*r.pageToken, "")) } + if r.consistency != nil { + localVarQueryParams.Add("consistency", parameterToString(*r.consistency, "")) + } if r.credentialsIdentifier != nil { localVarQueryParams.Add("credentials_identifier", parameterToString(*r.credentialsIdentifier, "")) } diff --git a/internal/httpclient/model_consistency_request_parameters.go b/internal/httpclient/model_consistency_request_parameters.go new file mode 100644 index 000000000000..6c48a4d6bb47 --- /dev/null +++ b/internal/httpclient/model_consistency_request_parameters.go @@ -0,0 +1,115 @@ +/* + * Ory Identities API + * + * This is the API specification for Ory Identities with features such as registration, login, recovery, account verification, profile settings, password reset, identity management, session management, email and sms delivery, and more. + * + * API version: + * Contact: office@ory.sh + */ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. + +package client + +import ( + "encoding/json" +) + +// ConsistencyRequestParameters Control API consistency guarantees +type ConsistencyRequestParameters struct { + // Read Consistency Level (preview) The read consistency level determines the consistency guarantee for reads: strong (slow): The read is guaranteed to return the most recent data committed at the start of the read. eventual (very fast): The result will return data that is about 4.8 seconds old. The default consistency guarantee can be changed in the Ory Network Console or using the Ory CLI with `ory patch project --replace '/previews/default_read_consistency_level=\"strong\"'`. Setting the default consistency level to `eventual` may cause regressions in the future as we add consistency controls to more APIs. Currently, the following APIs will be affected by this setting: `GET /admin/identities` This feature is in preview and only available in Ory Network. ConsistencyLevelUnset ConsistencyLevelUnset is the unset / default consistency level. strong ConsistencyLevelStrong ConsistencyLevelStrong is the strong consistency level. eventual ConsistencyLevelEventual ConsistencyLevelEventual is the eventual consistency level using follower read timestamps. + Consistency *string `json:"consistency,omitempty"` +} + +// NewConsistencyRequestParameters instantiates a new ConsistencyRequestParameters object +// This constructor will assign default values to properties that have it defined, +// and makes sure properties required by API are set, but the set of arguments +// will change when the set of required properties is changed +func NewConsistencyRequestParameters() *ConsistencyRequestParameters { + this := ConsistencyRequestParameters{} + return &this +} + +// NewConsistencyRequestParametersWithDefaults instantiates a new ConsistencyRequestParameters object +// This constructor will only assign default values to properties that have it defined, +// but it doesn't guarantee that properties required by API are set +func NewConsistencyRequestParametersWithDefaults() *ConsistencyRequestParameters { + this := ConsistencyRequestParameters{} + return &this +} + +// GetConsistency returns the Consistency field value if set, zero value otherwise. +func (o *ConsistencyRequestParameters) GetConsistency() string { + if o == nil || o.Consistency == nil { + var ret string + return ret + } + return *o.Consistency +} + +// GetConsistencyOk returns a tuple with the Consistency field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *ConsistencyRequestParameters) GetConsistencyOk() (*string, bool) { + if o == nil || o.Consistency == nil { + return nil, false + } + return o.Consistency, true +} + +// HasConsistency returns a boolean if a field has been set. +func (o *ConsistencyRequestParameters) HasConsistency() bool { + if o != nil && o.Consistency != nil { + return true + } + + return false +} + +// SetConsistency gets a reference to the given string and assigns it to the Consistency field. +func (o *ConsistencyRequestParameters) SetConsistency(v string) { + o.Consistency = &v +} + +func (o ConsistencyRequestParameters) MarshalJSON() ([]byte, error) { + toSerialize := map[string]interface{}{} + if o.Consistency != nil { + toSerialize["consistency"] = o.Consistency + } + return json.Marshal(toSerialize) +} + +type NullableConsistencyRequestParameters struct { + value *ConsistencyRequestParameters + isSet bool +} + +func (v NullableConsistencyRequestParameters) Get() *ConsistencyRequestParameters { + return v.value +} + +func (v *NullableConsistencyRequestParameters) Set(val *ConsistencyRequestParameters) { + v.value = val + v.isSet = true +} + +func (v NullableConsistencyRequestParameters) IsSet() bool { + return v.isSet +} + +func (v *NullableConsistencyRequestParameters) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableConsistencyRequestParameters(val *ConsistencyRequestParameters) *NullableConsistencyRequestParameters { + return &NullableConsistencyRequestParameters{value: val, isSet: true} +} + +func (v NullableConsistencyRequestParameters) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableConsistencyRequestParameters) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} diff --git a/persistence/sql/identity/persister_identity.go b/persistence/sql/identity/persister_identity.go index fadac678951f..2d457fa42985 100644 --- a/persistence/sql/identity/persister_identity.go +++ b/persistence/sql/identity/persister_identity.go @@ -12,6 +12,8 @@ import ( "sync" "time" + "github.com/ory/x/crdbx" + "github.com/gobuffalo/pop/v6" "github.com/gofrs/uuid" "github.com/pkg/errors" @@ -675,50 +677,60 @@ func (p *IdentityPersister) ListIdentities(ctx context.Context, params identity. attribute.String("network.id", p.NetworkID(ctx).String()))...)) defer otelx.End(span, &err) - is := make([]identity.Identity, 0) - - con := p.GetConnection(ctx) nid := p.NetworkID(ctx) + var is []identity.Identity - joins := "" - wheres := "identities.nid = ? AND identities.id > ?" - args := []any{nid, paginator.Token().Encode()} - limit := fmt.Sprintf("LIMIT %d", paginator.Size()+1) - if params.PagePagination != nil { - wheres = "identities.nid = ?" - args = []any{nid} - paginator := pop.NewPaginator(params.PagePagination.Page+1, params.PagePagination.ItemsPerPage) - limit = fmt.Sprintf("LIMIT %d OFFSET %d", paginator.PerPage, paginator.Offset) - } - identifier := params.CredentialsIdentifier - identifierOperator := "=" - if identifier == "" && params.CredentialsIdentifierSimilar != "" { - identifier = params.CredentialsIdentifierSimilar - identifierOperator = "%" - switch con.Dialect.Name() { - case "postgres", "cockroach": - default: - identifier = "%" + identifier + "%" - identifierOperator = "LIKE" - } - } - - if len(identifier) > 0 { - // When filtering by credentials identifier, we most likely are looking for a username or email. It is therefore - // important to normalize the identifier before querying the database. - identifier = NormalizeIdentifier(identity.CredentialsTypePassword, identifier) - - joins = ` + if err = p.Transaction(ctx, func(ctx context.Context, con *pop.Connection) error { + is = make([]identity.Identity, 0) // Make sure we reset this to 0 in case of retries. + nextPage = nil + + if err := crdbx.SetTransactionReadOnly(con); err != nil { + return err + } + + if err := crdbx.SetTransactionConsistency(con, params.ConsistencyLevel, p.r.Config().DefaultConsistencyLevel(ctx)); err != nil { + return err + } + + joins := "" + wheres := "identities.nid = ? AND identities.id > ?" + args := []any{nid, paginator.Token().Encode()} + limit := fmt.Sprintf("LIMIT %d", paginator.Size()+1) + if params.PagePagination != nil { + wheres = "identities.nid = ?" + args = []any{nid} + paginator := pop.NewPaginator(params.PagePagination.Page+1, params.PagePagination.ItemsPerPage) + limit = fmt.Sprintf("LIMIT %d OFFSET %d", paginator.PerPage, paginator.Offset) + } + identifier := params.CredentialsIdentifier + identifierOperator := "=" + if identifier == "" && params.CredentialsIdentifierSimilar != "" { + identifier = params.CredentialsIdentifierSimilar + identifierOperator = "%" + switch con.Dialect.Name() { + case "postgres", "cockroach": + default: + identifier = "%" + identifier + "%" + identifierOperator = "LIKE" + } + } + + if len(identifier) > 0 { + // When filtering by credentials identifier, we most likely are looking for a username or email. It is therefore + // important to normalize the identifier before querying the database. + identifier = NormalizeIdentifier(identity.CredentialsTypePassword, identifier) + + joins = ` INNER JOIN identity_credentials ic ON ic.identity_id = identities.id INNER JOIN identity_credential_types ict ON ict.id = ic.identity_credential_type_id INNER JOIN identity_credential_identifiers ici ON ici.identity_credential_id = ic.id` - wheres += fmt.Sprintf(` + wheres += fmt.Sprintf(` AND (ic.nid = ? AND ici.nid = ? AND ici.identifier %s ?) AND ict.name IN (?, ?)`, identifierOperator) - args = append(args, nid, nid, identifier, identity.CredentialsTypeWebAuthn, identity.CredentialsTypePassword) - } + args = append(args, nid, nid, identifier, identity.CredentialsTypeWebAuthn, identity.CredentialsTypePassword) + } - query := fmt.Sprintf(` + query := fmt.Sprintf(` SELECT DISTINCT identities.* FROM identities AS identities %s @@ -726,56 +738,61 @@ func (p *IdentityPersister) ListIdentities(ctx context.Context, params identity. %s ORDER BY identities.id ASC %s`, - joins, wheres, limit) + joins, wheres, limit) - if err := con.RawQuery(query, args...).All(&is); err != nil { - return nil, nil, sqlcon.HandleError(err) - } - - if params.PagePagination == nil { - is, nextPage = keysetpagination.Result(is, paginator) - } + if err := con.RawQuery(query, args...).All(&is); err != nil { + return sqlcon.HandleError(err) + } - if len(is) == 0 { - return is, nextPage, nil - } + if params.PagePagination == nil { + is, nextPage = keysetpagination.Result(is, paginator) + } - identitiesByID := make(map[uuid.UUID]*identity.Identity, len(is)) - identityIDs := make([]any, len(is)) - for k := range is { - identitiesByID[is[k].ID] = &is[k] - identityIDs[k] = is[k].ID - } + if len(is) == 0 { + return nil + } - for _, e := range params.Expand { - switch e { - case identity.ExpandFieldCredentials: - creds, err := QueryForCredentials(con, - Where{"identity_credentials.nid = ?", []any{nid}}, - Where{"identity_credentials.identity_id IN (?)", identityIDs}) - if err != nil { - return nil, nil, err - } - for k := range is { - is[k].Credentials = creds[is[k].ID] - } - case identity.ExpandFieldVerifiableAddresses: - addrs := make([]identity.VerifiableAddress, 0) - if err := con.Where("nid = ?", nid).Where("identity_id IN (?)", identityIDs).Order("id").All(&addrs); err != nil { - return nil, nil, sqlcon.HandleError(err) - } - for _, addr := range addrs { - identitiesByID[addr.IdentityID].VerifiableAddresses = append(identitiesByID[addr.IdentityID].VerifiableAddresses, addr) - } - case identity.ExpandFieldRecoveryAddresses: - addrs := make([]identity.RecoveryAddress, 0) - if err := con.Where("nid = ?", nid).Where("identity_id IN (?)", identityIDs).Order("id").All(&addrs); err != nil { - return nil, nil, sqlcon.HandleError(err) - } - for _, addr := range addrs { - identitiesByID[addr.IdentityID].RecoveryAddresses = append(identitiesByID[addr.IdentityID].RecoveryAddresses, addr) + identitiesByID := make(map[uuid.UUID]*identity.Identity, len(is)) + identityIDs := make([]any, len(is)) + for k := range is { + identitiesByID[is[k].ID] = &is[k] + identityIDs[k] = is[k].ID + } + + for _, e := range params.Expand { + switch e { + case identity.ExpandFieldCredentials: + creds, err := QueryForCredentials(con, + Where{"identity_credentials.nid = ?", []any{nid}}, + Where{"identity_credentials.identity_id IN (?)", identityIDs}) + if err != nil { + return err + } + for k := range is { + is[k].Credentials = creds[is[k].ID] + } + case identity.ExpandFieldVerifiableAddresses: + addrs := make([]identity.VerifiableAddress, 0) + if err := con.Where("nid = ?", nid).Where("identity_id IN (?)", identityIDs).Order("id").All(&addrs); err != nil { + return sqlcon.HandleError(err) + } + for _, addr := range addrs { + identitiesByID[addr.IdentityID].VerifiableAddresses = append(identitiesByID[addr.IdentityID].VerifiableAddresses, addr) + } + case identity.ExpandFieldRecoveryAddresses: + addrs := make([]identity.RecoveryAddress, 0) + if err := con.Where("nid = ?", nid).Where("identity_id IN (?)", identityIDs).Order("id").All(&addrs); err != nil { + return sqlcon.HandleError(err) + } + for _, addr := range addrs { + identitiesByID[addr.IdentityID].RecoveryAddresses = append(identitiesByID[addr.IdentityID].RecoveryAddresses, addr) + } } } + + return nil + }); err != nil { + return nil, nil, err } schemaCache := map[string]string{} diff --git a/persistence/sql/persister_test.go b/persistence/sql/persister_test.go index 548df5268cc7..088c7cb13e19 100644 --- a/persistence/sql/persister_test.go +++ b/persistence/sql/persister_test.go @@ -104,8 +104,8 @@ func createCleanDatabases(t testing.TB) map[string]*driver.RegistryDefault { var l sync.Mutex if !testing.Short() { funcs := map[string]func(t testing.TB) string{ - "postgres": dockertest.RunTestPostgreSQL, - "mysql": dockertest.RunTestMySQL, + //"postgres": dockertest.RunTestPostgreSQL, + //"mysql": dockertest.RunTestMySQL, "cockroach": dockertest.NewLocalTestCRDBServer, } @@ -220,7 +220,7 @@ func TestPersister(t *testing.T) { t.Run("contract=identity.TestPool", func(t *testing.T) { pop.SetLogger(pl(t)) - identity.TestPool(ctx, conf, p, reg.IdentityManager())(t) + identity.TestPool(ctx, conf, p, reg.IdentityManager(), name)(t) }) t.Run("contract=registration.TestFlowPersister", func(t *testing.T) { pop.SetLogger(pl(t)) diff --git a/spec/api.json b/spec/api.json index 24b8c33a63f6..e7f7e6360031 100644 --- a/spec/api.json +++ b/spec/api.json @@ -457,6 +457,22 @@ }, "type": "object" }, + "consistencyRequestParameters": { + "description": "Control API consistency guarantees", + "properties": { + "consistency": { + "description": "Read Consistency Level (preview)\n\nThe read consistency level determines the consistency guarantee for reads:\n\nstrong (slow): The read is guaranteed to return the most recent data committed at the start of the read.\neventual (very fast): The result will return data that is about 4.8 seconds old.\n\nThe default consistency guarantee can be changed in the Ory Network Console or using the Ory CLI with\n`ory patch project --replace '/previews/default_read_consistency_level=\"strong\"'`.\n\nSetting the default consistency level to `eventual` may cause regressions in the future as we add consistency\ncontrols to more APIs. Currently, the following APIs will be affected by this setting:\n\n`GET /admin/identities`\n\nThis feature is in preview and only available in Ory Network.\n ConsistencyLevelUnset ConsistencyLevelUnset is the unset / default consistency level.\nstrong ConsistencyLevelStrong ConsistencyLevelStrong is the strong consistency level.\neventual ConsistencyLevelEventual ConsistencyLevelEventual is the eventual consistency level using follower read timestamps.", + "enum": [ + "", + "strong", + "eventual" + ], + "type": "string", + "x-go-enum-desc": " ConsistencyLevelUnset ConsistencyLevelUnset is the unset / default consistency level.\nstrong ConsistencyLevelStrong ConsistencyLevelStrong is the strong consistency level.\neventual ConsistencyLevelEventual ConsistencyLevelEventual is the eventual consistency level using follower read timestamps." + } + }, + "type": "object" + }, "continueWith": { "discriminator": { "mapping": { @@ -3459,6 +3475,20 @@ "type": "string" } }, + { + "description": "Read Consistency Level (preview)\n\nThe read consistency level determines the consistency guarantee for reads:\n\nstrong (slow): The read is guaranteed to return the most recent data committed at the start of the read.\neventual (very fast): The result will return data that is about 4.8 seconds old.\n\nThe default consistency guarantee can be changed in the Ory Network Console or using the Ory CLI with\n`ory patch project --replace '/previews/default_read_consistency_level=\"strong\"'`.\n\nSetting the default consistency level to `eventual` may cause regressions in the future as we add consistency\ncontrols to more APIs. Currently, the following APIs will be affected by this setting:\n\n`GET /admin/identities`\n\nThis feature is in preview and only available in Ory Network.\n ConsistencyLevelUnset ConsistencyLevelUnset is the unset / default consistency level.\nstrong ConsistencyLevelStrong ConsistencyLevelStrong is the strong consistency level.\neventual ConsistencyLevelEventual ConsistencyLevelEventual is the eventual consistency level using follower read timestamps.", + "in": "query", + "name": "consistency", + "schema": { + "enum": [ + "", + "strong", + "eventual" + ], + "type": "string" + }, + "x-go-enum-desc": " ConsistencyLevelUnset ConsistencyLevelUnset is the unset / default consistency level.\nstrong ConsistencyLevelStrong ConsistencyLevelStrong is the strong consistency level.\neventual ConsistencyLevelEventual ConsistencyLevelEventual is the eventual consistency level using follower read timestamps." + }, { "description": "CredentialsIdentifier is the identifier (username, email) of the credentials to look up using exact match.\nOnly one of CredentialsIdentifier and CredentialsIdentifierSimilar can be used.", "in": "query", diff --git a/spec/swagger.json b/spec/swagger.json index a2e5e859f712..a61ca10e51b4 100755 --- a/spec/swagger.json +++ b/spec/swagger.json @@ -220,6 +220,18 @@ "name": "page_token", "in": "query" }, + { + "enum": [ + "", + "strong", + "eventual" + ], + "type": "string", + "x-go-enum-desc": " ConsistencyLevelUnset ConsistencyLevelUnset is the unset / default consistency level.\nstrong ConsistencyLevelStrong ConsistencyLevelStrong is the strong consistency level.\neventual ConsistencyLevelEventual ConsistencyLevelEventual is the eventual consistency level using follower read timestamps.", + "description": "Read Consistency Level (preview)\n\nThe read consistency level determines the consistency guarantee for reads:\n\nstrong (slow): The read is guaranteed to return the most recent data committed at the start of the read.\neventual (very fast): The result will return data that is about 4.8 seconds old.\n\nThe default consistency guarantee can be changed in the Ory Network Console or using the Ory CLI with\n`ory patch project --replace '/previews/default_read_consistency_level=\"strong\"'`.\n\nSetting the default consistency level to `eventual` may cause regressions in the future as we add consistency\ncontrols to more APIs. Currently, the following APIs will be affected by this setting:\n\n`GET /admin/identities`\n\nThis feature is in preview and only available in Ory Network.\n ConsistencyLevelUnset ConsistencyLevelUnset is the unset / default consistency level.\nstrong ConsistencyLevelStrong ConsistencyLevelStrong is the strong consistency level.\neventual ConsistencyLevelEventual ConsistencyLevelEventual is the eventual consistency level using follower read timestamps.", + "name": "consistency", + "in": "query" + }, { "type": "string", "description": "CredentialsIdentifier is the identifier (username, email) of the credentials to look up using exact match.\nOnly one of CredentialsIdentifier and CredentialsIdentifierSimilar can be used.", @@ -3538,6 +3550,22 @@ } } }, + "consistencyRequestParameters": { + "description": "Control API consistency guarantees", + "type": "object", + "properties": { + "consistency": { + "description": "Read Consistency Level (preview)\n\nThe read consistency level determines the consistency guarantee for reads:\n\nstrong (slow): The read is guaranteed to return the most recent data committed at the start of the read.\neventual (very fast): The result will return data that is about 4.8 seconds old.\n\nThe default consistency guarantee can be changed in the Ory Network Console or using the Ory CLI with\n`ory patch project --replace '/previews/default_read_consistency_level=\"strong\"'`.\n\nSetting the default consistency level to `eventual` may cause regressions in the future as we add consistency\ncontrols to more APIs. Currently, the following APIs will be affected by this setting:\n\n`GET /admin/identities`\n\nThis feature is in preview and only available in Ory Network.\n ConsistencyLevelUnset ConsistencyLevelUnset is the unset / default consistency level.\nstrong ConsistencyLevelStrong ConsistencyLevelStrong is the strong consistency level.\neventual ConsistencyLevelEventual ConsistencyLevelEventual is the eventual consistency level using follower read timestamps.", + "type": "string", + "enum": [ + "", + "strong", + "eventual" + ], + "x-go-enum-desc": " ConsistencyLevelUnset ConsistencyLevelUnset is the unset / default consistency level.\nstrong ConsistencyLevelStrong ConsistencyLevelStrong is the strong consistency level.\neventual ConsistencyLevelEventual ConsistencyLevelEventual is the eventual consistency level using follower read timestamps." + } + } + }, "continueWith": { }, "continueWithSetOrySessionToken": {