diff --git a/graph/check_test.yaml b/graph/check_test.yaml index d576f02..c8985ae 100644 --- a/graph/check_test.yaml +++ b/graph/check_test.yaml @@ -63,10 +63,12 @@ types: can_invite: parent->can_read - viewer # viewer can be user or group but owner can only be user + union_type_subset: viewer | owner + union_type_subset_arrow: viewer | parent->owner negation_type_subset: viewer - owner - - # viewer can be user or group but owner can only be user + negation_type_subset_arrow: viewer - parent->owner intersection_type_subset: viewer & owner + intersection_type_subset_arrow: viewer & parent->owner cycle: relations: diff --git a/graph/objects.go b/graph/objects.go index 65c0aec..c025a8e 100644 --- a/graph/objects.go +++ b/graph/objects.go @@ -7,6 +7,7 @@ import ( dsc "github.com/aserto-dev/go-directory/aserto/directory/common/v3" dsr "github.com/aserto-dev/go-directory/aserto/directory/reader/v3" "github.com/aserto-dev/go-directory/pkg/derr" + "github.com/rs/zerolog/log" "github.com/samber/lo" ) @@ -25,8 +26,9 @@ func NewObjectSearch(m *model.Model, req *dsr.GetGraphRequest, reader RelationRe // validate the model but skip name validation. To avoid name collisions, the inverted model // uses mangled names that are not valid identifiers. if err := im.Validate(model.SkipNameValidation, model.AllowPermissionInArrowBase); err != nil { + log.Err(err).Interface("req", req).Msg("inverted model is invalid") // TODO: we should persist the inverted model instead of computing it on the fly. - return nil, derr.ErrUnknown.Msg("internal error: unable to search for objects.") + return nil, derr.ErrUnknown.Msg("internal error: unable to search objects.") } iParams := invertGetGraphRequest(im, req) diff --git a/model/inverse.go b/model/inverse.go index 8a56e52..b3916f4 100644 --- a/model/inverse.go +++ b/model/inverse.go @@ -194,7 +194,10 @@ func (ti *termInverter) invertArrow() { itip := ti.inv.irelSub(ti.objName, ti.term.Base) baseRel := ti.obj.Relations[ti.term.Base] - typeRefs := set.NewSet(ti.perm.Types()...) + typeRefs := set.NewSet(ti.term.Types()...) + if typeRefs.IsEmpty() { + typeRefs.Append(ti.perm.Types()...) + } typeRefs.Intersect(ti.typeSet).Each(func(rr RelationRef) bool { iName := InverseRelation(ti.objName, ti.permName, rr.Relation) iPerm := permissionOrNew(ti.inv.im.Objects[rr.Object], iName, ti.kind)