zanzibar

package
v0.0.0-...-5b87a2c Latest Latest
Warning

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

Go to latest
Published: Jan 22, 2024 License: Apache-2.0 Imports: 10 Imported by: 0

Documentation

Index

Constants

View Source
const (
	TupleFilterWildcardUserName        = "*"
	TupleFilterWildcardUserSetRelation = "*"
)

Variables

View Source
var ErrCouldNotCastType = errors.New("could not cast object to correct type")

Functions

func IsUserSet

func IsUserSet(n Node) bool

func NodeValid

func NodeValid(n Node) bool

func PrintTuples

func PrintTuples(tuples Tuples) string

func ReconcileApply

func ReconcileApply(ctx context.Context, s TupleStore, node Node, desiredTuples []Tuple) error

func ReconcileCompute

func ReconcileCompute(ctx context.Context, s TupleStore, node Node, desiredTuples []Tuple) ([]Tuple, []Tuple, error)

Reconcile computes a reconcile for all tuples related to the given node. Old tuples are deleted, new tuples added, and existing tuples not touched. The first tuple slice returned are the tuples that should be added, the second for tuples to be deleted. Use ReconcileApply for applying them at the same time. TODO: This would reconcile almost all tuples twice, once from the "user side" and once from the "object side" How do we specify what side is the "authorative" or "producing" side to respect? TODO: Move this to the generic Zanzibar library as we won't depend on specific stuff in OpenFGA.

Types

type AuthorizationSchema

type AuthorizationSchema struct {
	Types []TypeRelation
}

type Checker

type Checker interface {
	// CheckOne performs one check request for the given tuple.
	// The checker is bound to a given authorization schema.
	// Contextual tuples are added to all individual check requests.
	CheckOne(ctx context.Context, tuple Tuple, contextualTuples []Tuple) (bool, error)
}

type ConditionFunc

type ConditionFunc func(obj any) bool

type DifferenceUserset

type DifferenceUserset struct {
	Base     EvaluatedUserset
	Subtract EvaluatedUserset
}

type EvaluatedUserset

type EvaluatedUserset struct {
	// Set operations
	Union        []EvaluatedUserset
	Intersection []EvaluatedUserset
	Difference   *DifferenceUserset

	// Relation points to a relation being "inherited" (Computed Userset)
	Relation       string
	TupleToUserset *TupleToUserset
}

EvaluatedUserset specifies a set of mutually exclusive options TODO: Add validation and "empty" functions

type IDExprFunc

type IDExprFunc func(obj any) (string, error)

func CastIDExpr

func CastIDExpr[T any](f func(obj T) (string, error)) IDExprFunc

type IncomingRelation

type IncomingRelation struct {
	UserType        string
	UserSetRelation string
	Relation        string

	UserIDExpr UserIDExprFunc
	Condition  ConditionFunc

	EscapeID bool
}

type MockTupleStore

type MockTupleStore struct {
	mock.Mock
}

MockTupleStore is an autogenerated mock type for the TupleStore type

func NewMockTupleStore

func NewMockTupleStore(t interface {
	mock.TestingT
	Cleanup(func())
}) *MockTupleStore

NewMockTupleStore creates a new instance of MockTupleStore. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. The first argument is typically a *testing.T value.

func (*MockTupleStore) EXPECT

func (*MockTupleStore) ReadTuples

func (_m *MockTupleStore) ReadTuples(ctx context.Context, filter TupleFilter) ([]Tuple, error)

ReadTuples provides a mock function with given fields: ctx, filter

func (*MockTupleStore) WriteTuples

func (_m *MockTupleStore) WriteTuples(ctx context.Context, writes []Tuple, deletes []Tuple) error

WriteTuples provides a mock function with given fields: ctx, writes, deletes

type MockTupleStore_Expecter

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

func (*MockTupleStore_Expecter) ReadTuples

func (_e *MockTupleStore_Expecter) ReadTuples(ctx interface{}, filter interface{}) *MockTupleStore_ReadTuples_Call

ReadTuples is a helper method to define mock.On call

  • ctx context.Context
  • filter TupleFilter

func (*MockTupleStore_Expecter) WriteTuples

func (_e *MockTupleStore_Expecter) WriteTuples(ctx interface{}, writes interface{}, deletes interface{}) *MockTupleStore_WriteTuples_Call

WriteTuples is a helper method to define mock.On call

  • ctx context.Context
  • writes []Tuple
  • deletes []Tuple

type MockTupleStore_ReadTuples_Call

type MockTupleStore_ReadTuples_Call struct {
	*mock.Call
}

MockTupleStore_ReadTuples_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ReadTuples'

func (*MockTupleStore_ReadTuples_Call) Return

func (*MockTupleStore_ReadTuples_Call) Run

func (*MockTupleStore_ReadTuples_Call) RunAndReturn

type MockTupleStore_WriteTuples_Call

type MockTupleStore_WriteTuples_Call struct {
	*mock.Call
}

MockTupleStore_WriteTuples_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WriteTuples'

func (*MockTupleStore_WriteTuples_Call) Return

func (*MockTupleStore_WriteTuples_Call) Run

func (_c *MockTupleStore_WriteTuples_Call) Run(run func(ctx context.Context, writes []Tuple, deletes []Tuple)) *MockTupleStore_WriteTuples_Call

func (*MockTupleStore_WriteTuples_Call) RunAndReturn

type Node

type Node interface {
	// NodeType specifies the node type name.
	NodeType() string
	// NodeName specifies the name of the node of NodeType type.
	// Any two nodes with the same NodeType and NodeName are considered
	// equal. Two nodes of distinct types with the same name are not equal.
	// TODO: Talk about ID and Type only instead?
	NodeName() string

	// WithUserSet transforms the node into a userset query.
	// As UserSet also embeds Node, calling WithUserSet on a
	// UserSet overwrites the previous UserSetRelation.
	WithUserSet(userSetRelation string) UserSet
	WithRelation(relation string) RelatedNode
}

Node points to only exactly one node. The node has a type and name. The node can be transformed into a user set, meaning it becomes a query which matches all users related to the given node (with type NodeType() and name NodeName()) through UserSetRelation(). The Node can be related to one or multiple other nodes producing tuples, through providing a relation.

func NewNode

func NewNode(nodeType, nodeName string) Node

type Nodes

type Nodes interface {
	// GetNodes return the underlying slice of nodes.
	GetNodes() []Node
	WithRelation(relation string) RelatedNodes
	// WithUserSet maps all nodes to UserSets using the
	// the Node WithUserSet function.
	WithUserSet(userSetRelation string) UserSets
}

Nodes represents one or more nodes that can be related to other nodes through a relation.

func NewNodes

func NewNodes(n ...Node) Nodes

type ObjectIDExprFunc

type ObjectIDExprFunc func(obj any, relation string) ([]string, error)

func CastOutgoing

func CastOutgoing[T any](f func(obj T, relation string) ([]string, error)) ObjectIDExprFunc

type OutgoingRelation

type OutgoingRelation struct {
	ObjectType      string
	UserSetRelation string
	Relations       []string

	ObjectIDExpr ObjectIDExprFunc
	Condition    ConditionFunc

	EscapeID bool
}

type RelatedNode

type RelatedNode interface {
	RelatedNodes
	ToOne(object Node) Tuple
}

RelatedNode represents exactly one user node and a relation, which can be related with the given one or multiple object nodes to produce tuples.

It is invalid to provide any UserSet nodes as objects, however, no errors are produced, but UserSetRelation() is ignored. Any invalid nodes where either NodeType or NodeName are empty are ignored.

type RelatedNodes

type RelatedNodes interface {
	To(objects ...Node) []Tuple
}

RelatedNodes contains one or multiple user or userset nodes, and a relation, which can be related with the given objects nodes to produce tuples.

It is invalid to provide any UserSet nodes as objects, however, no errors are produced, but UserSetRelation() is ignored. Any invalid nodes where either NodeType or NodeName are empty are ignored.

type Tuple

type Tuple struct {
	// User might be casted to UserSet, too
	// User might be nil if the tuple is empty
	User     Node
	Relation string
	Object   Node
}

func GenerateTuplesFor

func GenerateTuplesFor(tr TypeRelation, obj any) ([]Tuple, error)

func NewTuple

func NewTuple(userType, userName, relation, objectType, objectName string) Tuple

func NewUserSetTuple

func NewUserSetTuple(userType, userName, userSetRelation, relation, objectType, objectName string) Tuple

func (Tuple) GetUserSet

func (t Tuple) GetUserSet() (us UserSet, hasUserSet bool)

func (Tuple) GetUserSetRelation

func (t Tuple) GetUserSetRelation() string

GetUserSetRelation gets t.User.UserSetRelation() if t.User is an UserSet, otherwise returns an empty string.

func (Tuple) Valid

func (t Tuple) Valid() bool

type TupleFilter

type TupleFilter struct {
	// UserType filter matches all tuples with the given user type.
	UserType string
	// UserName filter matches all tuples with the given user type and name.
	// If UserName is set, UserType is mandatory. If UserName is empty,
	// _any_ user is returned. If UserName is TupleFilterWildcardUserName,
	// tuples which apply simultaneously to _all_ users are returned.
	UserName string
	// UserSetRelation matches all tuples with the given user type and name,
	// together with the given userset relation as the user. For example,
	// UserType=group, UserName=foo, UserSetRelation=members matches all tuples
	// where all group members of group foo are matched.
	// If UserSetRelation=TupleFilterWildcardUserSetRelation, then a union of all
	// tuples from all possible userset relations are returned.
	// If this is set, UserName and UserType are mandatory. However, UserName cannot
	// be TupleFilterWildcardUserName when UserSetRelation is non-empty.
	UserSetRelation string

	// Relation filter matches tuples only with the given relation.
	// If empty, tuples with any relation are returned.
	Relation string

	// ObjectType filter matches all tuples with the given object type.
	ObjectType string
	// ObjectName filter matches all tuples with the given object type and name.
	// If ObjectName is set, ObjectType is mandatory. If ObjectName is empty,
	// all tuples of the given type with any name is returned. As object nodes
	// cannot be usersets, there is no functionality related to usersets supported.
	ObjectName string
}

TupleFilter contains predicates which filter tuples in the TupleStore. If all predicates are empty, all tuples in the store are returned.

func (TupleFilter) Validate

func (tf TupleFilter) Validate() error

type TupleStore

type TupleStore interface {
	// ReadTuples reads all tuples from the store matching the following predicates:
	// - if tuple.User is set, then the
	ReadTuples(ctx context.Context, filter TupleFilter) ([]Tuple, error)
	// WriteTuples TODO
	WriteTuples(ctx context.Context, writes, deletes []Tuple) error
	// GetAuthorizationSchema gets the current authorization schema
	// TODO: Should this be a no-op without ctx and errors?
	GetAuthorizationSchema(ctx context.Context) (*AuthorizationSchema, error)
}

TupleStore is a store bound to a specific authorization model (TODO: can the model change over time?) and set of tuples.

type TupleToUserset

type TupleToUserset struct {
	// The relation being referenced in the foreign type
	ReferencedRelation string
	// The relation in the main type pointing to the foreign type
	FromRelation string
}

type Tuples

type Tuples []Tuple

Tuples is a typed Tuples slice that supports sorting using sort.Sort

func (Tuples) AssertEqualsWanted

func (t Tuples) AssertEqualsWanted(wanted Tuples, tt *testing.T, testName string)

func (Tuples) Equals

func (t Tuples) Equals(other Tuples) bool

func (Tuples) Len

func (t Tuples) Len() int

Len is part of sort.Interface.

func (Tuples) Less

func (t Tuples) Less(i, j int) bool

Less is part of sort.Interface.

func (Tuples) Swap

func (t Tuples) Swap(i, j int)

Swap is part of sort.Interface.

type TypeRelation

type TypeRelation struct {
	TypeName string
	IDExpr   IDExprFunc
	EscapeID bool

	Condition ConditionFunc

	Outgoing []OutgoingRelation
	Incoming []IncomingRelation

	EvaluatedUsersets map[string]EvaluatedUserset
}

func (*TypeRelation) GetID

func (tr *TypeRelation) GetID(obj any) (string, error)

TODO: Make this for all other places too Maybe call EscapeID QueryEscapeID

type UserIDExprFunc

type UserIDExprFunc func(obj any) ([]string, error)

func CastIncoming

func CastIncoming[T any](f func(obj T) ([]string, error)) UserIDExprFunc

type UserSet

type UserSet interface {
	Node
	UserSetRelation() string
}

UserSet points to all nodes related as users in tuples where AbstractNode is the object, and NodeSetRelation is the relation.

func ToUserSet

func ToUserSet(n Node) (us UserSet, ok bool)

type UserSets

type UserSets interface {
	GetUserSets() []UserSet
	WithRelation(relation string) RelatedNodes
}

UserSets represents a set of usersets that can be related to other nodes through a relation.

Jump to

Keyboard shortcuts

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