diff options
| author | mo khan <mo@mokhan.ca> | 2025-07-22 17:35:49 -0600 |
|---|---|---|
| committer | mo khan <mo@mokhan.ca> | 2025-07-22 17:35:49 -0600 |
| commit | 20ef0d92694465ac86b550df139e8366a0a2b4fa (patch) | |
| tree | 3f14589e1ce6eb9306a3af31c3a1f9e1af5ed637 /vendor/github.com/authzed/spicedb/pkg/schema/resolver.go | |
| parent | 44e0d272c040cdc53a98b9f1dc58ae7da67752e6 (diff) | |
feat: connect to spicedb
Diffstat (limited to 'vendor/github.com/authzed/spicedb/pkg/schema/resolver.go')
| -rw-r--r-- | vendor/github.com/authzed/spicedb/pkg/schema/resolver.go | 114 |
1 files changed, 114 insertions, 0 deletions
diff --git a/vendor/github.com/authzed/spicedb/pkg/schema/resolver.go b/vendor/github.com/authzed/spicedb/pkg/schema/resolver.go new file mode 100644 index 0000000..4610886 --- /dev/null +++ b/vendor/github.com/authzed/spicedb/pkg/schema/resolver.go @@ -0,0 +1,114 @@ +package schema + +import ( + "context" + "fmt" + "slices" + + "github.com/authzed/spicedb/pkg/datastore" + core "github.com/authzed/spicedb/pkg/proto/core/v1" + "github.com/authzed/spicedb/pkg/schemadsl/compiler" +) + +// Resolver is an interface defined for resolving referenced namespaces and caveats when constructing +// and validating a type system. +type Resolver interface { + // LookupDefinition lookups up a namespace definition, also returning whether it was pre-validated. + LookupDefinition(ctx context.Context, name string) (*core.NamespaceDefinition, bool, error) + + // LookupCaveat lookups up a caveat. + LookupCaveat(ctx context.Context, name string) (*Caveat, error) +} + +// ResolverForDatastoreReader returns a Resolver for a datastore reader. +func ResolverForDatastoreReader(ds datastore.Reader) *DatastoreResolver { + return &DatastoreResolver{ + ds: ds, + } +} + +// PredefinedElements are predefined namespaces and/or caveats to give to a resolver. +type PredefinedElements struct { + Definitions []*core.NamespaceDefinition + Caveats []*Caveat +} + +func (pe PredefinedElements) combineWith(other PredefinedElements) PredefinedElements { + return PredefinedElements{ + Definitions: append(slices.Clone(pe.Definitions), other.Definitions...), + Caveats: append(slices.Clone(pe.Caveats), other.Caveats...), + } +} + +// ResolverForPredefinedDefinitions returns a resolver for predefined namespaces and caveats. +func ResolverForPredefinedDefinitions(predefined PredefinedElements) Resolver { + return &DatastoreResolver{ + predefined: predefined, + } +} + +// ResolverForSchema returns a resolver for a schema. +func ResolverForSchema(schema compiler.CompiledSchema) Resolver { + return ResolverForPredefinedDefinitions( + PredefinedElements{ + Definitions: schema.ObjectDefinitions, + Caveats: schema.CaveatDefinitions, + }, + ) +} + +// DatastoreResolver is a resolver implementation for a datastore, to look up schema stored in the underlying storage. +type DatastoreResolver struct { + ds datastore.Reader + predefined PredefinedElements +} + +// LookupDefinition lookups up a namespace definition, also returning whether it was pre-validated. +func (r *DatastoreResolver) LookupDefinition(ctx context.Context, name string) (*core.NamespaceDefinition, bool, error) { + if len(r.predefined.Definitions) > 0 { + for _, def := range r.predefined.Definitions { + if def.Name == name { + return def, false, nil + } + } + } + + if r.ds == nil { + return nil, false, asTypeError(NewDefinitionNotFoundErr(name)) + } + + ns, _, err := r.ds.ReadNamespaceByName(ctx, name) + return ns, true, err +} + +// WithPredefinedElements adds elements (definitions and caveats) that will be used as a local overlay +// for the datastore, often for validation. +func (r *DatastoreResolver) WithPredefinedElements(predefined PredefinedElements) Resolver { + return &DatastoreResolver{ + ds: r.ds, + predefined: predefined.combineWith(r.predefined), + } +} + +// LookupCaveat lookups up a caveat. +func (r *DatastoreResolver) LookupCaveat(ctx context.Context, name string) (*Caveat, error) { + if len(r.predefined.Caveats) > 0 { + for _, caveat := range r.predefined.Caveats { + if caveat.Name == name { + return caveat, nil + } + } + } + + if r.ds == nil { + return nil, asTypeError(NewCaveatNotFoundErr(name)) + } + + cr, ok := r.ds.(datastore.CaveatReader) + if !ok { + return nil, fmt.Errorf("caveats are not supported on this datastore type") + } + + caveatDef, _, err := cr.ReadCaveatByName(ctx, name) + return caveatDef, err +} |
