diff options
Diffstat (limited to 'vendor/github.com/authzed/spicedb/pkg/tuple/structs.go')
| -rw-r--r-- | vendor/github.com/authzed/spicedb/pkg/tuple/structs.go | 219 |
1 files changed, 219 insertions, 0 deletions
diff --git a/vendor/github.com/authzed/spicedb/pkg/tuple/structs.go b/vendor/github.com/authzed/spicedb/pkg/tuple/structs.go new file mode 100644 index 0000000..e6cd256 --- /dev/null +++ b/vendor/github.com/authzed/spicedb/pkg/tuple/structs.go @@ -0,0 +1,219 @@ +package tuple + +import ( + "errors" + "fmt" + "time" + + "google.golang.org/protobuf/types/known/timestamppb" + + core "github.com/authzed/spicedb/pkg/proto/core/v1" + "github.com/authzed/spicedb/pkg/spiceerrors" +) + +const ( + // Ellipsis is the Ellipsis relation in v0 style subjects. + Ellipsis = "..." + + // PublicWildcard is the wildcard value for subject object IDs that indicates public access + // for the subject type. + PublicWildcard = "*" +) + +// ObjectAndRelation represents an object and its relation. +type ObjectAndRelation struct { + ObjectID string + ObjectType string + Relation string +} + +const onrStructSize = 48 /* size of the struct itself */ + +func (onr ObjectAndRelation) SizeVT() int { + return len(onr.ObjectID) + len(onr.ObjectType) + len(onr.Relation) + onrStructSize +} + +// WithRelation returns a copy of the object and relation with the given relation. +func (onr ObjectAndRelation) WithRelation(relation string) ObjectAndRelation { + onr.Relation = relation + return onr +} + +// RelationReference returns a RelationReference for the object and relation. +func (onr ObjectAndRelation) RelationReference() RelationReference { + return RelationReference{ + ObjectType: onr.ObjectType, + Relation: onr.Relation, + } +} + +// ToCoreONR converts the ObjectAndRelation to a core.ObjectAndRelation. +func (onr ObjectAndRelation) ToCoreONR() *core.ObjectAndRelation { + return &core.ObjectAndRelation{ + Namespace: onr.ObjectType, + ObjectId: onr.ObjectID, + Relation: onr.Relation, + } +} + +func (onr ObjectAndRelation) String() string { + return fmt.Sprintf("%s:%s#%s", onr.ObjectType, onr.ObjectID, onr.Relation) +} + +// RelationshipReference represents a reference to a relationship, i.e. those portions +// of a relationship that are not the integrity or caveat and thus form the unique +// identifier of the relationship. +type RelationshipReference struct { + Resource ObjectAndRelation + Subject ObjectAndRelation +} + +// Relationship represents a relationship between two objects. +type Relationship struct { + OptionalCaveat *core.ContextualizedCaveat + OptionalExpiration *time.Time + OptionalIntegrity *core.RelationshipIntegrity + + RelationshipReference +} + +// ToCoreTuple converts the Relationship to a core.RelationTuple. +func (r Relationship) ToCoreTuple() *core.RelationTuple { + var expirationTime *timestamppb.Timestamp + if r.OptionalExpiration != nil { + expirationTime = timestamppb.New(*r.OptionalExpiration) + } + + return &core.RelationTuple{ + ResourceAndRelation: r.Resource.ToCoreONR(), + Subject: r.Subject.ToCoreONR(), + Caveat: r.OptionalCaveat, + Integrity: r.OptionalIntegrity, + OptionalExpirationTime: expirationTime, + } +} + +const relStructSize = 120 /* size of the struct itself */ + +func (r Relationship) SizeVT() int { + size := r.Resource.SizeVT() + r.Subject.SizeVT() + relStructSize + if r.OptionalCaveat != nil { + size += r.OptionalCaveat.SizeVT() + } + return size +} + +// ValidateNotEmpty returns true if the relationship is not empty. +func (r Relationship) ValidateNotEmpty() bool { + return r.Resource.ObjectType != "" && r.Resource.ObjectID != "" && r.Subject.ObjectType != "" && r.Subject.ObjectID != "" && r.Resource.Relation != "" && r.Subject.Relation != "" +} + +// Validate returns an error if the relationship is invalid. +func (r Relationship) Validate() error { + if !r.ValidateNotEmpty() { + return errors.New("object and relation must not be empty") + } + + if r.RelationshipReference.Resource.ObjectID == PublicWildcard { + return errors.New("invalid resource id") + } + + return nil +} + +// WithoutIntegrity returns a copy of the relationship without its integrity. +func (r Relationship) WithoutIntegrity() Relationship { + r.OptionalIntegrity = nil + return r +} + +// WithCaveat returns a copy of the relationship with the given caveat. +func (r Relationship) WithCaveat(caveat *core.ContextualizedCaveat) Relationship { + r.OptionalCaveat = caveat + return r +} + +// UpdateOperation represents the type of update to a relationship. +type UpdateOperation int + +const ( + UpdateOperationTouch UpdateOperation = iota + UpdateOperationCreate + UpdateOperationDelete +) + +// RelationshipUpdate represents an update to a relationship. +type RelationshipUpdate struct { + Relationship Relationship + Operation UpdateOperation +} + +func (ru RelationshipUpdate) OperationString() string { + switch ru.Operation { + case UpdateOperationTouch: + return "TOUCH" + case UpdateOperationCreate: + return "CREATE" + case UpdateOperationDelete: + return "DELETE" + default: + return "unknown" + } +} + +func (ru RelationshipUpdate) DebugString() string { + return fmt.Sprintf("%s(%s)", ru.OperationString(), StringWithoutCaveatOrExpiration(ru.Relationship)) +} + +// RelationReference represents a reference to a relation. +type RelationReference struct { + ObjectType string + Relation string +} + +// ToCoreRR converts the RelationReference to a core.RelationReference. +func (rr RelationReference) ToCoreRR() *core.RelationReference { + return &core.RelationReference{ + Namespace: rr.ObjectType, + Relation: rr.Relation, + } +} + +func (rr RelationReference) RefString() string { + return JoinRelRef(rr.ObjectType, rr.Relation) +} + +func (rr RelationReference) String() string { + return rr.RefString() +} + +// ONR creates an ObjectAndRelation. +func ONR(namespace, objectID, relation string) ObjectAndRelation { + spiceerrors.DebugAssert(func() bool { + return namespace != "" && objectID != "" && relation != "" + }, "invalid ONR: %s %s %s", namespace, objectID, relation) + + return ObjectAndRelation{ + ObjectType: namespace, + ObjectID: objectID, + Relation: relation, + } +} + +// ONRRef creates an ObjectAndRelation reference. +func ONRRef(namespace, objectID, relation string) *ObjectAndRelation { + onr := ONR(namespace, objectID, relation) + return &onr +} + +// RR creates a RelationReference. +func RR(namespace, relation string) RelationReference { + spiceerrors.DebugAssert(func() bool { + return namespace != "" && relation != "" + }, "invalid RR: %s %s", namespace, relation) + + return RelationReference{ + ObjectType: namespace, + Relation: relation, + } +} |
