summaryrefslogtreecommitdiff
path: root/vendor/github.com/authzed/spicedb/pkg/tuple/strings.go
diff options
context:
space:
mode:
authormo khan <mo@mokhan.ca>2025-07-24 17:58:01 -0600
committermo khan <mo@mokhan.ca>2025-07-24 17:58:01 -0600
commit72296119fc9755774719f8f625ad03e0e0ec457a (patch)
treeed236ddee12a20fb55b7cfecf13f62d3a000dcb5 /vendor/github.com/authzed/spicedb/pkg/tuple/strings.go
parenta920a8cfe415858bb2777371a77018599ffed23f (diff)
parenteaa1bd3b8e12934aed06413d75e7482ac58d805a (diff)
Merge branch 'the-spice-must-flow' into 'main'
Add SpiceDB Authorization See merge request gitlab-org/software-supply-chain-security/authorization/sparkled!19
Diffstat (limited to 'vendor/github.com/authzed/spicedb/pkg/tuple/strings.go')
-rw-r--r--vendor/github.com/authzed/spicedb/pkg/tuple/strings.go165
1 files changed, 165 insertions, 0 deletions
diff --git a/vendor/github.com/authzed/spicedb/pkg/tuple/strings.go b/vendor/github.com/authzed/spicedb/pkg/tuple/strings.go
new file mode 100644
index 0000000..7b5a378
--- /dev/null
+++ b/vendor/github.com/authzed/spicedb/pkg/tuple/strings.go
@@ -0,0 +1,165 @@
+package tuple
+
+import (
+ "sort"
+ "strings"
+ "time"
+
+ "google.golang.org/protobuf/encoding/protojson"
+ "google.golang.org/protobuf/types/known/structpb"
+
+ core "github.com/authzed/spicedb/pkg/proto/core/v1"
+ "github.com/authzed/spicedb/pkg/spiceerrors"
+)
+
+var expirationFormat = time.RFC3339Nano
+
+// JoinRelRef joins the namespace and relation together into the same
+// format as `StringRR()`.
+func JoinRelRef(namespace, relation string) string { return namespace + "#" + relation }
+
+// MustSplitRelRef splits a string produced by `JoinRelRef()` and panics if
+// it fails.
+func MustSplitRelRef(relRef string) (namespace, relation string) {
+ var ok bool
+ namespace, relation, ok = strings.Cut(relRef, "#")
+ if !ok {
+ panic("improperly formatted relation reference")
+ }
+ return
+}
+
+// StringRR converts a RR object to a string.
+func StringRR(rr RelationReference) string {
+ return JoinRelRef(rr.ObjectType, rr.Relation)
+}
+
+// StringONR converts an ONR object to a string.
+func StringONR(onr ObjectAndRelation) string {
+ return StringONRStrings(onr.ObjectType, onr.ObjectID, onr.Relation)
+}
+
+func StringCoreRR(rr *core.RelationReference) string {
+ if rr == nil {
+ return ""
+ }
+
+ return JoinRelRef(rr.Namespace, rr.Relation)
+}
+
+// StringCoreONR converts a core ONR object to a string.
+func StringCoreONR(onr *core.ObjectAndRelation) string {
+ if onr == nil {
+ return ""
+ }
+
+ return StringONRStrings(onr.Namespace, onr.ObjectId, onr.Relation)
+}
+
+// StringONRStrings converts ONR strings to a string.
+func StringONRStrings(namespace, objectID, relation string) string {
+ if relation == Ellipsis {
+ return JoinObjectRef(namespace, objectID)
+ }
+ return JoinRelRef(JoinObjectRef(namespace, objectID), relation)
+}
+
+// StringsONRs converts ONR objects to a string slice, sorted.
+func StringsONRs(onrs []ObjectAndRelation) []string {
+ onrstrings := make([]string, 0, len(onrs))
+ for _, onr := range onrs {
+ onrstrings = append(onrstrings, StringONR(onr))
+ }
+
+ sort.Strings(onrstrings)
+ return onrstrings
+}
+
+// MustString converts a relationship to a string.
+func MustString(rel Relationship) string {
+ tplString, err := String(rel)
+ if err != nil {
+ panic(err)
+ }
+ return tplString
+}
+
+// String converts a relationship to a string.
+func String(rel Relationship) (string, error) {
+ spiceerrors.DebugAssert(rel.ValidateNotEmpty, "relationship must not be empty")
+
+ caveatString, err := StringCaveat(rel.OptionalCaveat)
+ if err != nil {
+ return "", err
+ }
+
+ expirationString, err := StringExpiration(rel.OptionalExpiration)
+ if err != nil {
+ return "", err
+ }
+
+ return StringONR(rel.Resource) + "@" + StringONR(rel.Subject) + caveatString + expirationString, nil
+}
+
+func StringExpiration(expiration *time.Time) (string, error) {
+ if expiration == nil {
+ return "", nil
+ }
+
+ return "[expiration:" + expiration.Format(expirationFormat) + "]", nil
+}
+
+// StringWithoutCaveatOrExpiration converts a relationship to a string, without its caveat or expiration included.
+func StringWithoutCaveatOrExpiration(rel Relationship) string {
+ spiceerrors.DebugAssert(rel.ValidateNotEmpty, "relationship must not be empty")
+
+ return StringONR(rel.Resource) + "@" + StringONR(rel.Subject)
+}
+
+func MustStringCaveat(caveat *core.ContextualizedCaveat) string {
+ caveatString, err := StringCaveat(caveat)
+ if err != nil {
+ panic(err)
+ }
+ return caveatString
+}
+
+// StringCaveat converts a contextualized caveat to a string. If the caveat is nil or empty, returns empty string.
+func StringCaveat(caveat *core.ContextualizedCaveat) (string, error) {
+ if caveat == nil || caveat.CaveatName == "" {
+ return "", nil
+ }
+
+ contextString, err := StringCaveatContext(caveat.Context)
+ if err != nil {
+ return "", err
+ }
+
+ if len(contextString) > 0 {
+ contextString = ":" + contextString
+ }
+
+ return "[" + caveat.CaveatName + contextString + "]", nil
+}
+
+// StringCaveatContext converts the context of a caveat to a string. If the context is nil or empty, returns an empty string.
+func StringCaveatContext(context *structpb.Struct) (string, error) {
+ if context == nil || len(context.Fields) == 0 {
+ return "", nil
+ }
+
+ contextBytes, err := protojson.MarshalOptions{
+ Multiline: false,
+ Indent: "",
+ }.Marshal(context)
+ if err != nil {
+ return "", err
+ }
+ return string(contextBytes), nil
+}
+
+// JoinObjectRef joins the namespace and the objectId together into the standard
+// format.
+//
+// This function assumes that the provided values have already been validated.
+func JoinObjectRef(namespace, objectID string) string { return namespace + ":" + objectID }