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/middleware/nodeid | |
| parent | 44e0d272c040cdc53a98b9f1dc58ae7da67752e6 (diff) | |
feat: connect to spicedb
Diffstat (limited to 'vendor/github.com/authzed/spicedb/pkg/middleware/nodeid')
| -rw-r--r-- | vendor/github.com/authzed/spicedb/pkg/middleware/nodeid/doc.go | 2 | ||||
| -rw-r--r-- | vendor/github.com/authzed/spicedb/pkg/middleware/nodeid/nodeid.go | 102 |
2 files changed, 104 insertions, 0 deletions
diff --git a/vendor/github.com/authzed/spicedb/pkg/middleware/nodeid/doc.go b/vendor/github.com/authzed/spicedb/pkg/middleware/nodeid/doc.go new file mode 100644 index 0000000..571288c --- /dev/null +++ b/vendor/github.com/authzed/spicedb/pkg/middleware/nodeid/doc.go @@ -0,0 +1,2 @@ +// Package nodeid defines middleware to update the context with the Id of the SpiceDB node running the request. +package nodeid diff --git a/vendor/github.com/authzed/spicedb/pkg/middleware/nodeid/nodeid.go b/vendor/github.com/authzed/spicedb/pkg/middleware/nodeid/nodeid.go new file mode 100644 index 0000000..3885036 --- /dev/null +++ b/vendor/github.com/authzed/spicedb/pkg/middleware/nodeid/nodeid.go @@ -0,0 +1,102 @@ +package nodeid + +import ( + "context" + "fmt" + "os" + + "github.com/cespare/xxhash/v2" + middleware "github.com/grpc-ecosystem/go-grpc-middleware/v2" + "github.com/rs/zerolog/log" + "google.golang.org/grpc" +) + +const spiceDBPrefix = "spicedb:" + +type ctxKeyType struct{} + +var nodeIDKey ctxKeyType = struct{}{} + +type nodeIDHandle struct { + nodeID string +} + +var defaultNodeID string + +func init() { + hostname, err := os.Hostname() + if err != nil { + log.Warn().Err(err).Msg("failed to get hostname, using an empty node ID") + return + } + + // Hash the hostname to get the final default node ID. + hasher := xxhash.New() + if _, err := hasher.WriteString(hostname); err != nil { + log.Warn().Err(err).Msg("failed to hash hostname, using an empty node ID") + return + } + + defaultNodeID = spiceDBPrefix + fmt.Sprintf("%x", hasher.Sum(nil)) +} + +// ContextWithHandle adds a placeholder to a context that will later be +// filled by the Node ID. +func ContextWithHandle(ctx context.Context) context.Context { + return context.WithValue(ctx, nodeIDKey, &nodeIDHandle{}) +} + +// FromContext reads the node's ID out of a context.Context. +func FromContext(ctx context.Context) (string, error) { + if c := ctx.Value(nodeIDKey); c != nil { + handle := c.(*nodeIDHandle) + if handle.nodeID != "" { + return handle.nodeID, nil + } + } + + if err := setInContext(ctx, defaultNodeID); err != nil { + return "", err + } + + return defaultNodeID, nil +} + +// setInContext adds a node ID to the given context +func setInContext(ctx context.Context, nodeID string) error { + handle := ctx.Value(nodeIDKey) + if handle == nil { + return nil + } + handle.(*nodeIDHandle).nodeID = nodeID + return nil +} + +// UnaryServerInterceptor returns a new unary server interceptor that adds the +// node ID to the context. If empty, spicedb:$hostname is used. +func UnaryServerInterceptor(nodeID string) grpc.UnaryServerInterceptor { + return func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) { + newCtx := ContextWithHandle(ctx) + if nodeID != "" { + if err := setInContext(newCtx, nodeID); err != nil { + return nil, err + } + } + return handler(newCtx, req) + } +} + +// StreamServerInterceptor returns a new stream server interceptor that adds the +// node ID to the context. If empty, spicedb:$hostname is used. +func StreamServerInterceptor(nodeID string) grpc.StreamServerInterceptor { + return func(srv interface{}, stream grpc.ServerStream, info *grpc.StreamServerInfo, handler grpc.StreamHandler) error { + wrapped := middleware.WrapServerStream(stream) + wrapped.WrappedContext = ContextWithHandle(wrapped.WrappedContext) + if nodeID != "" { + if err := setInContext(wrapped.WrappedContext, nodeID); err != nil { + return err + } + } + return handler(srv, wrapped) + } +} |
