graph

package
v1.5.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 16, 2024 License: Apache-2.0 Imports: 34 Imported by: 0

Documentation

Overview

Package graph contains code related to evaluation of authorization models through graph traversals.

Package graph is a generated GoMock package.

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrResolutionDepthExceeded = errors.New("resolution depth exceeded")
)

Functions

func CheckRequestCacheKey added in v1.5.0

func CheckRequestCacheKey(req *ResolveCheckRequest) (string, error)

CheckRequestCacheKey converts the ResolveCheckRequest into a canonical cache key that can be used for Check resolution cache key lookups in a stable way.

For one store and model ID, the same tuple provided with the same contextual tuples and context should produce the same cache key. Contextual tuple order and context parameter order is ignored, only the contents are compared.

func ContextWithResolutionDepth added in v0.2.5

func ContextWithResolutionDepth(parent context.Context, depth uint32) context.Context

ContextWithResolutionDepth attaches the provided graph resolution depth to the parent context.

func NewLayeredCheckResolver added in v1.5.0

func NewLayeredCheckResolver(
	localResolverOpts []LocalCheckerOption,
	cacheEnabled bool,
	cachedResolverOpts []CachedCheckResolverOpt,
) (CheckResolver, CheckResolverCloser)

NewLayeredCheckResolver constructs a CheckResolver that is composed of various CheckResolver layers. Specifically, it constructs a CheckResolver with the following composition:

CycleDetectionCheckResolver  <-----|
	CachedCheckResolver              |
		LocalChecker                   |
			CycleDetectionCheckResolver -|

The returned CheckResolverCloser should be used to close all resolvers involved in the composition after you are done with the CheckResolver.

func ResolutionDepthFromContext added in v0.2.5

func ResolutionDepthFromContext(ctx context.Context) (uint32, bool)

ResolutionDepthFromContext returns the current graph resolution depth from the provided context (if any).

Types

type CachedCheckResolver added in v1.3.1

type CachedCheckResolver struct {
	// contains filtered or unexported fields
}

CachedCheckResolver attempts to resolve check sub-problems via prior computations before delegating the request to some underlying CheckResolver.

func NewCachedCheckResolver added in v1.3.1

func NewCachedCheckResolver(opts ...CachedCheckResolverOpt) *CachedCheckResolver

NewCachedCheckResolver constructs a CheckResolver that delegates Check resolution to the provided delegate, but before delegating the query to the delegate a cache-key lookup is made to see if the Check sub-problem has already recently been computed. If the Check sub-problem is in the cache, then the response is returned immediately and no re-computation is necessary. NOTE: the ResolveCheck's resolution data will be set as the default values as we actually did no database lookup

func (*CachedCheckResolver) Close added in v1.3.1

func (c *CachedCheckResolver) Close()

Close will deallocate resource allocated by the CachedCheckResolver It will not deallocate cache if it has been passed in from WithExistingCache

func (*CachedCheckResolver) GetDelegate added in v1.5.1

func (c *CachedCheckResolver) GetDelegate() CheckResolver

GetDelegate returns this CachedCheckResolver's dispatch delegate.

func (*CachedCheckResolver) ResolveCheck added in v1.3.1

func (*CachedCheckResolver) SetDelegate added in v1.5.0

func (c *CachedCheckResolver) SetDelegate(delegate CheckResolver)

SetDelegate sets this CachedCheckResolver's dispatch delegate.

type CachedCheckResolverOpt added in v1.3.1

type CachedCheckResolverOpt func(*CachedCheckResolver)

CachedCheckResolverOpt defines an option that can be used to change the behavior of cachedCheckResolver instance.

func WithCacheTTL added in v1.3.1

func WithCacheTTL(ttl time.Duration) CachedCheckResolverOpt

WithCacheTTL sets the TTL (as a duration) for any single Check cache key value.

func WithExistingCache added in v1.3.1

func WithExistingCache(cache *ccache.Cache[*ResolveCheckResponse]) CachedCheckResolverOpt

WithExistingCache sets the cache to the specified cache. Note that the original cache will not be stopped as it may still be used by others. It is up to the caller to check whether the original cache should be stopped.

func WithLogger added in v1.3.1

func WithLogger(logger logger.Logger) CachedCheckResolverOpt

WithLogger sets the logger for the cached check resolver

func WithMaxCacheSize added in v1.3.1

func WithMaxCacheSize(size int64) CachedCheckResolverOpt

WithMaxCacheSize sets the maximum size of the Check resolution cache. After this maximum size is met, then cache keys will start being evicted with an LRU policy.

type CheckFuncReducer added in v0.3.5

type CheckFuncReducer func(ctx context.Context, concurrencyLimit uint32, handlers ...CheckHandlerFunc) (*ResolveCheckResponse, error)

CheckFuncReducer defines a function that combines or reduces one or more CheckHandlerFunc into a single CheckResponse with a maximum limit on the number of concurrent evaluations that can be in flight at any given time.

type CheckHandlerFunc added in v0.3.5

type CheckHandlerFunc func(ctx context.Context) (*ResolveCheckResponse, error)

CheckHandlerFunc defines a function that evaluates a CheckResponse or returns an error otherwise.

type CheckResolver added in v0.3.5

type CheckResolver interface {
	// ResolveCheck resolves a node (a single subproblem) out of a tree of problems.
	// If the depth of the tree has gotten too large, resolution is aborted and an error must be returned.
	//
	// It is expected that callers pass in, contextually:
	// - a [[storage.RelationshipTupleReader]] using [[storage.ContextWithRelationshipTupleReader]]. This is by design because this method is called by
	// [[server.Check]], but each time it is called there are invariants that must be met that relate
	// to the concurrency of the underlying RelationshipTupleReader as well as contextual tuples per
	// parent request.
	// - a [[Typesystem]]. Some implementations may panic if this isn't set.
	//
	// ResolveCheck is a recursive function. The first call to this function must be the "parent" problem to solve,
	// and recursive calls solve the child subproblems (which may be overlapping).
	//
	// Implementations must pass along the request in full, with all its fields,
	// and it must set the response in full, including the metadata, with any updates necessary.
	//
	// The return values may be nil and an error, or non-nil and an error.
	ResolveCheck(ctx context.Context, req *ResolveCheckRequest) (*ResolveCheckResponse, error)

	// Close releases resources. It must be called after the CheckResolver is done processing all requests.
	Close()
}

func NewLocalCheckerWithCycleDetection added in v1.5.0

func NewLocalCheckerWithCycleDetection(opts ...LocalCheckerOption) CheckResolver

NewLocalCheckerWithCycleDetection constructs a LocalChecker wrapped with a [CycleDetectionCheckResolver] which can be used to evaluate a Check request locally with cycle detection enabled.

type CheckResolverCloser added in v1.5.0

type CheckResolverCloser func()

type CycleDetectionCheckResolver added in v1.5.0

type CycleDetectionCheckResolver struct {
	// contains filtered or unexported fields
}

func NewCycleDetectionCheckResolver added in v1.5.0

func NewCycleDetectionCheckResolver() *CycleDetectionCheckResolver

func (*CycleDetectionCheckResolver) Close added in v1.5.0

func (*CycleDetectionCheckResolver) Close()

Close implements CheckResolver.

func (*CycleDetectionCheckResolver) GetDelegate added in v1.5.1

func (c *CycleDetectionCheckResolver) GetDelegate() CheckResolver

func (*CycleDetectionCheckResolver) ResolveCheck added in v1.5.0

ResolveCheck implements CheckResolver.

func (*CycleDetectionCheckResolver) SetDelegate added in v1.5.0

func (c *CycleDetectionCheckResolver) SetDelegate(delegate CheckResolver)

type DispatchThrottlingCheckResolver added in v1.5.1

type DispatchThrottlingCheckResolver struct {
	// contains filtered or unexported fields
}

DispatchThrottlingCheckResolver will prioritize requests with fewer dispatches over requests with more dispatches. Initially, request's dispatches will not be throttled and will be processed immediately. When the number of request dispatches is above the Threshold, the dispatches are placed in the throttling queue. One item form the throttling queue will be processed ticker. This allows a check / list objects request to be gradually throttled.

func NewDispatchThrottlingCheckResolver added in v1.5.1

func NewDispatchThrottlingCheckResolver(
	config DispatchThrottlingCheckResolverConfig) *DispatchThrottlingCheckResolver

func (*DispatchThrottlingCheckResolver) Close added in v1.5.1

func (*DispatchThrottlingCheckResolver) GetDelegate added in v1.5.1

func (*DispatchThrottlingCheckResolver) ResolveCheck added in v1.5.1

func (*DispatchThrottlingCheckResolver) SetDelegate added in v1.5.1

func (r *DispatchThrottlingCheckResolver) SetDelegate(delegate CheckResolver)

type DispatchThrottlingCheckResolverConfig added in v1.5.1

type DispatchThrottlingCheckResolverConfig struct {
	Frequency time.Duration
	Threshold uint32
}

DispatchThrottlingCheckResolverConfig encapsulates configuration for dispatch throttling check resolver

type EdgeCondition added in v1.3.2

type EdgeCondition int

type LocalChecker added in v0.3.5

type LocalChecker struct {
	// contains filtered or unexported fields
}

func NewLocalChecker added in v0.3.5

func NewLocalChecker(opts ...LocalCheckerOption) *LocalChecker

NewLocalChecker constructs a LocalChecker that can be used to evaluate a Check request locally.

The constructed LocalChecker is not wrapped with cycle detection. Developers wanting a LocalChecker without other wrapped layers (e.g caching and others) are encouraged to use [NewLocalCheckerWithCycleDetection] instead.

func (*LocalChecker) Close added in v1.3.1

func (c *LocalChecker) Close()

Close is a noop

func (*LocalChecker) GetDelegate added in v1.5.1

func (c *LocalChecker) GetDelegate() CheckResolver

GetDelegate sets this LocalChecker's dispatch delegate.

func (*LocalChecker) ResolveCheck added in v0.3.5

func (c *LocalChecker) ResolveCheck(
	ctx context.Context,
	req *ResolveCheckRequest,
) (*ResolveCheckResponse, error)

ResolveCheck implements [[CheckResolver.ResolveCheck]]. If the typesystem isn't set in the context, it will panic.

func (*LocalChecker) SetDelegate added in v1.3.1

func (c *LocalChecker) SetDelegate(delegate CheckResolver)

SetDelegate sets this LocalChecker's dispatch delegate.

type LocalCheckerOption added in v1.3.0

type LocalCheckerOption func(d *LocalChecker)

func WithMaxConcurrentReads added in v1.3.0

func WithMaxConcurrentReads(limit uint32) LocalCheckerOption

WithMaxConcurrentReads see server.WithMaxConcurrentReadsForCheck

func WithResolveNodeBreadthLimit added in v1.3.0

func WithResolveNodeBreadthLimit(limit uint32) LocalCheckerOption

WithResolveNodeBreadthLimit see server.WithResolveNodeBreadthLimit

type MockCheckResolver added in v1.3.1

type MockCheckResolver struct {
	// contains filtered or unexported fields
}

MockCheckResolver is a mock of CheckResolver interface.

func NewMockCheckResolver added in v1.3.1

func NewMockCheckResolver(ctrl *gomock.Controller) *MockCheckResolver

NewMockCheckResolver creates a new mock instance.

func (*MockCheckResolver) Close added in v1.3.1

func (m *MockCheckResolver) Close()

Close mocks base method.

func (*MockCheckResolver) EXPECT added in v1.3.1

EXPECT returns an object that allows the caller to indicate expected use.

func (*MockCheckResolver) ResolveCheck added in v1.3.1

ResolveCheck mocks base method.

type MockCheckResolverMockRecorder added in v1.3.1

type MockCheckResolverMockRecorder struct {
	// contains filtered or unexported fields
}

MockCheckResolverMockRecorder is the mock recorder for MockCheckResolver.

func (*MockCheckResolverMockRecorder) Close added in v1.3.1

Close indicates an expected call of Close.

func (*MockCheckResolverMockRecorder) ResolveCheck added in v1.3.1

func (mr *MockCheckResolverMockRecorder) ResolveCheck(ctx, req any) *gomock.Call

ResolveCheck indicates an expected call of ResolveCheck.

type RelationshipEdge added in v1.3.2

type RelationshipEdge struct {
	Type RelationshipEdgeType

	// The edge is directed towards this node, which can be like group:*, or group, or group:member
	TargetReference *openfgav1.RelationReference

	// If the type is TupleToUsersetEdge, this defines the TTU condition
	TuplesetRelation string

	TargetReferenceInvolvesIntersectionOrExclusion bool
}

RelationshipEdge represents a possible relationship between some source object reference and a target user reference. The possibility is realized depending on the tuples and on the edge's type.

func (RelationshipEdge) String added in v1.3.2

func (r RelationshipEdge) String() string

type RelationshipEdgeType added in v1.3.2

type RelationshipEdgeType int
const (
	// DirectEdge defines a direct connection between a source object reference
	// and some target user reference.
	DirectEdge RelationshipEdgeType = iota
	// TupleToUsersetEdge defines a connection between a source object reference
	// and some target user reference that is co-dependent upon the lookup of a third object reference.
	TupleToUsersetEdge
	// ComputedUsersetEdge defines a direct connection between a source object reference
	// and some target user reference. The difference with DirectEdge is that DirectEdge will involve
	// a read of tuples and this one will not.
	ComputedUsersetEdge
)

func (RelationshipEdgeType) String added in v1.3.2

func (r RelationshipEdgeType) String() string

type RelationshipGraph added in v1.3.2

type RelationshipGraph struct {
	// contains filtered or unexported fields
}

RelationshipGraph represents a graph of relationships and the connectivity between object and relation references within the graph through direct or indirect relationships.

func New added in v1.3.2

func New(typesystem *typesystem.TypeSystem) *RelationshipGraph

New returns a RelationshipGraph from an authorization model. The RelationshipGraph should be used to introspect what kind of relationships between object types can exist. To visualize this graph, use https://github.com/jon-whit/openfga-graphviz-gen

func (*RelationshipGraph) GetPrunedRelationshipEdges added in v1.3.2

func (g *RelationshipGraph) GetPrunedRelationshipEdges(target *openfgav1.RelationReference, source *openfgav1.RelationReference) ([]*RelationshipEdge, error)

GetPrunedRelationshipEdges finds all paths from a source to a target and then returns all the edges at distance 0 or 1 of the source in those paths. If the edges from the source to the target pass through a relationship involving intersection or exclusion (directly or indirectly), then GetPrunedRelationshipEdges will just return the first-most edge involved in that rewrite.

Consider the following model:

type user type document

relations
  define allowed: [user]
  define viewer: [user] and allowed

The pruned relationship edges from the 'user' type to 'document#viewer' returns only the edge from 'user' to 'document#viewer' and with a 'RequiresFurtherEvalCondition'. This is because when evaluating relationships involving intersection or exclusion we choose to only evaluate one operand of the rewrite rule, and for each result found we call Check on the result to evaluate the sub-condition on the 'and allowed' bit.

func (*RelationshipGraph) GetRelationshipEdges added in v1.3.2

func (g *RelationshipGraph) GetRelationshipEdges(target *openfgav1.RelationReference, source *openfgav1.RelationReference) ([]*RelationshipEdge, error)

GetRelationshipEdges finds all paths from a source to a target and then returns all the edges at distance 0 or 1 of the source in those paths.

type ResolveCheckRequest added in v0.3.5

type ResolveCheckRequest struct {
	StoreID              string
	AuthorizationModelID string
	TupleKey             *openfgav1.TupleKey
	ContextualTuples     []*openfgav1.TupleKey
	Context              *structpb.Struct
	RequestMetadata      *ResolveCheckRequestMetadata
	VisitedPaths         map[string]struct{}
}

func (*ResolveCheckRequest) GetAuthorizationModelID added in v0.3.5

func (r *ResolveCheckRequest) GetAuthorizationModelID() string

func (*ResolveCheckRequest) GetContext added in v1.3.8

func (r *ResolveCheckRequest) GetContext() *structpb.Struct

func (*ResolveCheckRequest) GetContextualTuples added in v0.3.5

func (r *ResolveCheckRequest) GetContextualTuples() []*openfgav1.TupleKey

func (*ResolveCheckRequest) GetRequestMetadata added in v1.5.1

func (r *ResolveCheckRequest) GetRequestMetadata() *ResolveCheckRequestMetadata

func (*ResolveCheckRequest) GetStoreID added in v0.3.5

func (r *ResolveCheckRequest) GetStoreID() string

func (*ResolveCheckRequest) GetTupleKey added in v0.3.5

func (r *ResolveCheckRequest) GetTupleKey() *openfgav1.TupleKey

type ResolveCheckRequestMetadata added in v1.5.1

type ResolveCheckRequestMetadata struct {
	// Thinking of a Check as a tree of evaluations,
	// Depth is the current level in the tree in the current path that we are exploring.
	// When we jump one level, we decrement 1. If it hits 0, we throw ErrResolutionDepthExceeded.
	Depth uint32

	// Number of calls to ReadUserTuple + ReadUsersetTuples + Read accumulated so far, before this request is solved.
	DatastoreQueryCount uint32

	// DispatchCounter is the address to a shared counter that keeps track of how many calls to ResolveCheck we had to do
	// to solve the root/parent problem.
	// The contents of this counter will be written by concurrent goroutines.
	// After the root problem has been solved, this value can be read.
	DispatchCounter *atomic.Uint32
}

func NewCheckRequestMetadata added in v1.5.1

func NewCheckRequestMetadata(maxDepth uint32) *ResolveCheckRequestMetadata

type ResolveCheckResponse added in v0.3.5

type ResolveCheckResponse struct {
	Allowed            bool
	ResolutionMetadata *ResolveCheckResponseMetadata
}

func CloneResolveCheckResponse added in v1.5.3

func CloneResolveCheckResponse(r *ResolveCheckResponse) *ResolveCheckResponse

CloneResolveCheckResponse clones the provided ResolveCheckResponse.

If 'r' defines a nil ResolutionMetadata then this function returns an empty value struct for the resolution metadata instead of nil.

func (*ResolveCheckResponse) GetAllowed added in v1.3.1

func (r *ResolveCheckResponse) GetAllowed() bool

func (*ResolveCheckResponse) GetCycleDetected added in v1.5.3

func (r *ResolveCheckResponse) GetCycleDetected() bool

func (*ResolveCheckResponse) GetResolutionMetadata added in v1.3.1

func (r *ResolveCheckResponse) GetResolutionMetadata() *ResolveCheckResponseMetadata

type ResolveCheckResponseMetadata added in v1.5.1

type ResolveCheckResponseMetadata struct {
	// Number of calls to ReadUserTuple + ReadUsersetTuples + Read accumulated after this request is solved.
	// Thinking of a Check as a tree of evaluations,
	// If the solution is "allowed=true", one path was found. This is the value in the leaf node of that path, plus the sum of the paths that were
	// evaluated and potentially discarded
	// If the solution is "allowed=false", no paths were found. This is the sum of all the reads in all the paths that had to be evaluated
	DatastoreQueryCount uint32

	// Indicates if the ResolveCheck subproblem that was evaluated involved
	// a cycle in the evaluation.
	CycleDetected bool
}

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL