diff --git a/x/exp/schema/resolved/resolve.go b/x/exp/schema/resolved/resolve.go index 82e9af2f..3b92eb78 100644 --- a/x/exp/schema/resolved/resolve.go +++ b/x/exp/schema/resolved/resolve.go @@ -49,9 +49,8 @@ type AppliesTo struct { // Action is a resolved action definition. type Action struct { - Name types.String + Entity types.Entity Annotations Annotations - Parents []types.EntityUID AppliesTo *AppliesTo } @@ -307,13 +306,17 @@ func (r *resolverState) resolveActions(nsName types.Path, actions ast.Actions, r for name, action := range actions { actionTypeName := qualifyActionType(nsName) uid := types.NewEntityUID(actionTypeName, types.String(name)) + var parents []types.EntityUID + for _, ref := range action.Parents { + parents = append(parents, resolveActionParentRef(nsName, ref)) + } resolved := Action{ - Name: name, + Entity: types.Entity{ + UID: uid, + Parents: types.NewEntityUIDSet(parents...), + }, Annotations: Annotations(action.Annotations), } - for _, ref := range action.Parents { - resolved.Parents = append(resolved.Parents, resolveActionParentRef(nsName, ref)) - } if action.AppliesTo != nil { at := &AppliesTo{} for _, p := range action.AppliesTo.Principals { @@ -523,7 +526,7 @@ func (r *resolverState) validateActionMembership(result *Schema) error { // Validate references and detect cycles for uid, action := range result.Actions { - for _, parent := range action.Parents { + for parent := range action.Entity.Parents.All() { if !actionUIDs[parent] { return fmt.Errorf("action %s: undefined parent action %s", uid, parent) } @@ -542,7 +545,7 @@ func (r *resolverState) validateActionMembership(result *Schema) error { } visited[uid] = 1 action := result.Actions[uid] - for _, parent := range action.Parents { + for parent := range action.Entity.Parents.All() { if err := visit(parent); err != nil { return err } diff --git a/x/exp/schema/resolved/resolve_test.go b/x/exp/schema/resolved/resolve_test.go index 3cb35e6f..b180c387 100644 --- a/x/exp/schema/resolved/resolve_test.go +++ b/x/exp/schema/resolved/resolve_test.go @@ -356,7 +356,7 @@ func TestResolveActionParents(t *testing.T) { testutil.OK(t, err) uid := types.NewEntityUID("Action", "view") view := result.Actions[uid] - testutil.Equals(t, view.Parents, []types.EntityUID{types.NewEntityUID("Action", "readOnly")}) + testutil.Equals(t, view.Entity.Parents, types.NewEntityUIDSet(types.NewEntityUID("Action", "readOnly"))) } func TestResolveActionCycle(t *testing.T) { @@ -482,7 +482,7 @@ func TestResolveActionQualifiedParent(t *testing.T) { testutil.OK(t, err) uid := types.NewEntityUID("NS::Action", "view") view := result.Actions[uid] - testutil.Equals(t, view.Parents, []types.EntityUID{types.NewEntityUID("NS::Action", "readOnly")}) + testutil.Equals(t, view.Entity.Parents, types.NewEntityUIDSet(types.NewEntityUID("NS::Action", "readOnly"))) } func TestResolveActionContextNull(t *testing.T) { diff --git a/x/exp/schema/schema_test.go b/x/exp/schema/schema_test.go index 7bfb1b5f..5f743ff3 100644 --- a/x/exp/schema/schema_test.go +++ b/x/exp/schema/schema_test.go @@ -556,7 +556,7 @@ var wantResolved = &resolved.Schema{ }, Actions: map[types.EntityUID]resolved.Action{ types.NewEntityUID("Action", "audit"): { - Name: "audit", + Entity: types.Entity{UID: types.NewEntityUID("Action", "audit"), Parents: types.NewEntityUIDSet()}, AppliesTo: &resolved.AppliesTo{ Principals: []types.EntityType{"Admin"}, Resources: []types.EntityType{"MyApp::Document", "System"}, @@ -564,7 +564,7 @@ var wantResolved = &resolved.Schema{ }, }, types.NewEntityUID("MyApp::Action", "edit"): { - Name: "edit", + Entity: types.Entity{UID: types.NewEntityUID("MyApp::Action", "edit"), Parents: types.NewEntityUIDSet()}, Annotations: resolved.Annotations{"doc": "View or edit document"}, AppliesTo: &resolved.AppliesTo{ Principals: []types.EntityType{"MyApp::User"}, @@ -576,7 +576,7 @@ var wantResolved = &resolved.Schema{ }, }, types.NewEntityUID("MyApp::Action", "manage"): { - Name: "manage", + Entity: types.Entity{UID: types.NewEntityUID("MyApp::Action", "manage"), Parents: types.NewEntityUIDSet()}, AppliesTo: &resolved.AppliesTo{ Principals: []types.EntityType{"MyApp::User"}, Resources: []types.EntityType{"MyApp::Document", "MyApp::Group"}, @@ -584,7 +584,7 @@ var wantResolved = &resolved.Schema{ }, }, types.NewEntityUID("MyApp::Action", "view"): { - Name: "view", + Entity: types.Entity{UID: types.NewEntityUID("MyApp::Action", "view"), Parents: types.NewEntityUIDSet()}, Annotations: resolved.Annotations{"doc": "View or edit document"}, AppliesTo: &resolved.AppliesTo{ Principals: []types.EntityType{"MyApp::User"},