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

View File

@@ -0,0 +1,392 @@
// Copyright © 2023 Ory Corp
// SPDX-License-Identifier: Apache-2.0
package driver
import (
"context"
"io/fs"
"maps"
"net/http"
"sync"
"connectrpc.com/connect"
"github.com/gofrs/uuid"
"github.com/ory/herodot"
"github.com/pkg/errors"
"google.golang.org/grpc/credentials"
"google.golang.org/grpc/health"
"google.golang.org/protobuf/reflect/protoreflect"
"github.com/ory/pop/v6"
"github.com/ory/x/contextx"
"github.com/ory/x/dbal"
"github.com/ory/x/fsx"
"github.com/ory/x/healthx"
"github.com/ory/x/httprouterx"
"github.com/ory/x/httpx"
"github.com/ory/x/logrusx"
"github.com/ory/x/metricsx"
"github.com/ory/x/networkx"
"github.com/ory/x/otelx"
"github.com/ory/x/popx"
rts "github.com/ory/keto/gen/go/ory/keto/relation_tuples/v1alpha2"
"github.com/ory/keto/gen/go/ory/keto/relation_tuples/v1alpha2/relationtuplesconnect"
"github.com/ory/keto/internal/check"
"github.com/ory/keto/internal/check/step"
"github.com/ory/keto/internal/driver/config"
"github.com/ory/keto/internal/expand"
"github.com/ory/keto/internal/persistence"
"github.com/ory/keto/internal/persistence/sql"
"github.com/ory/keto/internal/persistence/sql/migrations/uuidmapping"
"github.com/ory/keto/internal/relationtuple"
"github.com/ory/keto/ketoctx"
)
var (
_ relationtuple.ManagerProvider = (*RegistryDefault)(nil)
_ relationtuple.MapperProvider = (*RegistryDefault)(nil)
_ relationtuple.MappingManagerProvider = (*RegistryDefault)(nil)
_ httpx.WriterProvider = (*RegistryDefault)(nil)
_ logrusx.Provider = (*RegistryDefault)(nil)
_ Registry = (*RegistryDefault)(nil)
_ relationtuplesconnect.VersionServiceHandler = (*RegistryDefault)(nil)
)
type (
RegistryDefault struct {
relationtuplesconnect.UnimplementedVersionServiceHandler
p persistence.Persister
mb *popx.MigrationBox
extraMigrations []fs.FS
l *logrusx.Logger
w herodot.Writer
ce *check.Engine
ck *step.Executor
ee *expand.Engine
c *config.Config
conn *pop.Connection
ctxer contextx.Contextualizer
mapper *relationtuple.Mapper
readOnlyMapper *relationtuple.Mapper
replaceMapperNs func(ctx context.Context) uuid.UUID
replaceShardID func() uuid.UUID
init1, init2 sync.Once
init1err, init2err error
healthH *healthx.Handler
healthServer *health.Server
sqaService *metricsx.Service
tracer *otelx.Tracer
tracerWrapper ketoctx.TracerWrapper
defaultHandlerOptions []connect.HandlerOption
defaultConnectInterceptors []connect.Interceptor
defaultHttpMiddlewares []func(rw http.ResponseWriter, r *http.Request, next http.HandlerFunc)
grpcTransportCredentials credentials.TransportCredentials
defaultMigrationOptions []popx.MigrationBoxOption
healthReadyCheckers healthx.ReadyCheckers
dbOpts []func(details *pop.ConnectionDetails)
}
ReadHandler interface {
Handler
RegisterReadRoutes(r *httprouterx.RouterPublic)
}
WriteHandler interface {
Handler
RegisterWriteRoutes(r *httprouterx.RouterAdmin)
}
OPLSyntaxHandler interface {
Handler
RegisterSyntaxRoutes(r httprouterx.Router)
}
Handler interface {
ProtoFiles() []protoreflect.FileDescriptor
}
)
func (r *RegistryDefault) Mapper() *relationtuple.Mapper {
if r.mapper == nil {
r.mapper = &relationtuple.Mapper{D: r}
}
return r.mapper
}
func (r *RegistryDefault) ReadOnlyMapper() *relationtuple.Mapper {
if r.readOnlyMapper == nil {
r.readOnlyMapper = &relationtuple.Mapper{D: r, ReadOnly: true}
}
return r.readOnlyMapper
}
func (r *RegistryDefault) Contextualizer() contextx.Contextualizer {
return r.ctxer
}
func (r *RegistryDefault) Config(ctx context.Context) *config.Config {
if provider := r.ctxer.Config(ctx, r.c.Source()); provider != r.c.Source() {
return config.New(ctx, r.Logger(), provider)
}
return r.c
}
func (r *RegistryDefault) HealthHandler() *healthx.Handler {
if r.healthH != nil {
return r.healthH
}
h := healthx.ReadyCheckers{
"database": func(req *http.Request) error {
return r.Persister().Connection(req.Context()).Store.PingContext(req.Context())
},
"migrations": func(req *http.Request) error {
mb, err := r.MigrationBox(req.Context())
if err != nil {
return err
}
status, err := mb.Status(req.Context())
if err != nil {
return err
}
if status.HasPending() {
return errors.Errorf("migrations have not yet been fully applied")
}
return nil
},
}
maps.Copy(h, r.healthReadyCheckers) // possibly override default checkers
r.healthH = healthx.NewHandler(r.Writer(), config.Version, h)
return r.healthH
}
func (r *RegistryDefault) HealthServer() *health.Server {
if r.healthServer == nil {
r.healthServer = health.NewServer()
}
return r.healthServer
}
func (r *RegistryDefault) GetVersion(_ context.Context, _ *connect.Request[rts.GetVersionRequest]) (*connect.Response[rts.GetVersionResponse], error) {
return connect.NewResponse(&rts.GetVersionResponse{Version: config.Version}), nil
}
func (r *RegistryDefault) Tracer(ctx context.Context) *otelx.Tracer {
if r.tracer == nil {
// Tracing is initialized only once, so it can not be hot reloaded or context-aware.
t, err := otelx.New("Ory Keto", r.Logger(), r.Config(ctx).TracingConfig())
if err != nil {
r.Logger().WithError(err).Fatalf("Unable to initialize Tracer.")
}
// Wrap the tracer if required
if r.tracerWrapper != nil {
t = r.tracerWrapper(t)
}
r.tracer = t
}
return r.tracer
}
func (r *RegistryDefault) Logger() *logrusx.Logger {
if r.l == nil {
r.l = logrusx.New("Ory Keto", config.Version)
}
return r.l
}
func (r *RegistryDefault) Writer() herodot.Writer {
if r.w == nil {
r.w = herodot.NewJSONWriter(r.Logger())
}
return r.w
}
func (r *RegistryDefault) RelationTupleManager() relationtuple.Manager {
if r.p == nil {
panic("no relation tuple manager, but expected to have one")
}
return r.p
}
func (r *RegistryDefault) MappingManager() relationtuple.MappingManager {
if r.p == nil {
panic("no relation tuple manager, but expected to have one")
}
return r.p
}
func (r *RegistryDefault) Persister() persistence.Persister {
if r.p == nil {
panic("no persister, but expected to have one")
}
return r.p
}
func (r *RegistryDefault) NetworkID(ctx context.Context) uuid.UUID {
if r.p == nil {
panic("no persister, but expected to have one")
}
return r.p.NetworkID(ctx)
}
func (r *RegistryDefault) NewShardID() uuid.UUID {
if r.replaceShardID != nil {
return r.replaceShardID()
}
return uuid.Must(uuid.NewV4())
}
func (r *RegistryDefault) MapperNamespace(ctx context.Context) uuid.UUID {
if r.replaceMapperNs != nil {
return r.replaceMapperNs(ctx)
}
return r.p.NetworkID(ctx)
}
func (r *RegistryDefault) PermissionEngine() *check.Engine {
if r.ce == nil {
r.ce = check.NewEngine(r)
}
return r.ce
}
func (r *RegistryDefault) ExpandEngine() *expand.Engine {
if r.ee == nil {
r.ee = expand.NewEngine(r)
}
return r.ee
}
func (r *RegistryDefault) Checker() check.Checker {
if r.ck == nil {
r.ck = step.NewExecutor(r, step.CallLimitMiddleware())
}
return r.ck
}
func (r *RegistryDefault) MigrationBox(ctx context.Context, opts ...popx.MigrationBoxOption) (*popx.MigrationBox, error) {
if r.mb == nil {
c, err := r.PopConnection(ctx)
if err != nil {
return nil, err
}
namespaces, err := r.Config(ctx).NamespaceManager()
if err != nil {
return nil, err
}
migrationBoxOptions := append(opts,
popx.WithGoMigrations(uuidmapping.Migrations(namespaces)))
migrationBoxOptions = append(migrationBoxOptions, r.defaultMigrationOptions...)
mb, err := popx.NewMigrationBox(
fsx.Merge(append([]fs.FS{sql.Migrations, networkx.Migrations}, r.extraMigrations...)...),
c, r.Logger(),
migrationBoxOptions...,
)
if err != nil {
return nil, err
}
r.mb = mb
}
return r.mb, nil
}
func (r *RegistryDefault) MigrateUp(ctx context.Context) error {
mb, err := r.MigrationBox(ctx)
if err != nil {
return err
}
if err := mb.Up(ctx); err != nil {
return err
}
return r.Init(ctx)
}
func (r *RegistryDefault) MigrateDown(ctx context.Context) error {
mb, err := r.MigrationBox(ctx)
if err != nil {
return err
}
return mb.Down(ctx, -1)
}
func (r *RegistryDefault) DetermineNetwork(ctx context.Context) (*networkx.Network, error) {
c, err := r.PopConnection(ctx)
if err != nil {
return nil, err
}
mb, err := popx.NewMigrationBox(networkx.Migrations, c, r.Logger())
if err != nil {
return nil, err
}
s, err := mb.Status(ctx)
if err != nil {
return nil, err
}
if s.HasPending() {
return nil, errors.WithStack(persistence.ErrNetworkMigrationsMissing)
}
return networkx.Determine(c.WithContext(ctx))
}
func (r *RegistryDefault) InitWithoutNetworkID(ctx context.Context) error {
r.init1.Do(func() {
if dbal.IsMemorySQLite(r.Config(ctx).DSN()) {
mb, err := r.MigrationBox(ctx)
if err != nil {
r.init1err = err
return
}
if err := mb.Up(ctx); err != nil {
r.init1err = err
return
}
}
p, err := sql.NewPersister(ctx, r, uuid.Nil)
if err != nil {
r.init1err = err
return
}
r.p = p
r.initEngines()
})
return r.init1err
}
func (r *RegistryDefault) initEngines() {
_ = r.PermissionEngine()
_ = r.ExpandEngine()
_ = r.Checker()
}
func (r *RegistryDefault) Init(ctx context.Context) (err error) {
r.init2.Do(func() {
if err := r.InitWithoutNetworkID(ctx); err != nil {
r.init2err = err
return
}
network, err := r.DetermineNetwork(ctx)
if err != nil {
r.init2err = err
return
}
r.p.SetNetwork(network.ID)
})
return r.init2err
}