From 0b446f245d101ef35e407c395b9ad3260b678e64 Mon Sep 17 00:00:00 2001 From: Ronen Hilewicz Date: Sat, 13 Jul 2024 14:55:11 -0400 Subject: [PATCH] Fix inversion of negation permissions --- graph/check_test.yaml | 6 ++++++ model/inverse.go | 16 ++++++++++++++++ model/types.go | 3 +++ 3 files changed, 25 insertions(+) diff --git a/graph/check_test.yaml b/graph/check_test.yaml index 89577b9..d576f02 100644 --- a/graph/check_test.yaml +++ b/graph/check_test.yaml @@ -62,6 +62,12 @@ types: can_share: can_write & parent->can_share can_invite: parent->can_read - viewer + # viewer can be user or group but owner can only be user + negation_type_subset: viewer - owner + + # viewer can be user or group but owner can only be user + intersection_type_subset: viewer & owner + cycle: relations: parent: cycle diff --git a/model/inverse.go b/model/inverse.go index 6050511..8a56e52 100644 --- a/model/inverse.go +++ b/model/inverse.go @@ -55,6 +55,22 @@ func (i *inverter) invert() *Model { } } + for _, o := range i.im.Objects { + for _, p := range o.Permissions { + if !p.IsExclusion() { + continue + } + + if p.Exclusion.Exclude == nil { + // It is possible for the 'Exclude' term to be empty in in inverted model if the object type + // cannot have the relation/permission being excluded. + // In this case, the exclusion permission becomes a single-term union. + p.Union = PermissionTerms{p.Exclusion.Include} + p.Exclusion = nil + } + } + } + return i.im } diff --git a/model/types.go b/model/types.go index 2e10dbd..7bd22eb 100644 --- a/model/types.go +++ b/model/types.go @@ -227,6 +227,9 @@ type PermissionTerm struct { } func (pr *PermissionTerm) String() string { + if pr == nil { + return "" + } s := string(pr.RelOrPerm) if pr.Base != "" { s = string(pr.Base) + "->" + s