From 4dbd126cef63b8f8551526072fe1e131719bf68c Mon Sep 17 00:00:00 2001 From: "Jose I. Paris" Date: Mon, 21 Jul 2025 14:28:55 +0200 Subject: [PATCH 1/2] viewers can list org memberships Signed-off-by: Jose I. Paris --- app/controlplane/pkg/authz/authz.go | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/app/controlplane/pkg/authz/authz.go b/app/controlplane/pkg/authz/authz.go index 16682b9b5..d651978d0 100644 --- a/app/controlplane/pkg/authz/authz.go +++ b/app/controlplane/pkg/authz/authz.go @@ -158,8 +158,10 @@ var ( PolicyWorkflowDelete = &Policy{ResourceWorkflow, ActionDelete} // Projects PolicyProjectCreate = &Policy{ResourceProject, ActionCreate} + // User Membership - PolicyOrganizationRead = &Policy{Organization, ActionRead} + PolicyOrganizationRead = &Policy{Organization, ActionRead} + PolicyOrganizationListMemberships = &Policy{OrganizationMemberships, ActionList} // Group Memberships PolicyGroupListPendingInvitations = &Policy{ResourceGroup, ActionList} @@ -215,6 +217,9 @@ var RolesMap = map[Role][]*Policy{ PolicyWorkflowRead, // Organization PolicyOrganizationRead, + + // List organization memberships + PolicyOrganizationListMemberships, }, // RoleAdmin is an org-scoped role that provides super admin privileges (it's the higher role) RoleAdmin: { @@ -385,6 +390,10 @@ var ServerOperationsMap = map[string][]*Policy{ // since all the permissions here are in the context of an organization // Create new organization "/controlplane.v1.OrganizationService/Create": {}, + + // List global memberships + "/controlplane.v1.OrganizationService/ListMemberships": {PolicyOrganizationListMemberships}, + // NOTE: this is about listing my own memberships, not about listing all the memberships in the organization "/controlplane.v1.UserService/ListMemberships": {}, // Set the current organization for the current user From d908cfe32cb006d10af3f0693af53333640264c2 Mon Sep 17 00:00:00 2001 From: "Jose I. Paris" Date: Mon, 21 Jul 2025 14:41:18 +0200 Subject: [PATCH 2/2] allow viewers to list group memberships Signed-off-by: Jose I. Paris --- app/controlplane/internal/service/group.go | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/app/controlplane/internal/service/group.go b/app/controlplane/internal/service/group.go index 02a78c35b..16fa43af0 100644 --- a/app/controlplane/internal/service/group.go +++ b/app/controlplane/internal/service/group.go @@ -236,8 +236,14 @@ func (g *GroupService) ListMembers(ctx context.Context, req *pb.GroupServiceList return nil, err } - if err := g.userHasPermissionToListGroupMember(ctx, currentOrg.ID, req.GetGroupReference()); err != nil { - return nil, err + orgRole := usercontext.CurrentAuthzSubject(ctx) + + // Viewers can see group memberships + // TODO: replace this with enforcer check once group_memberships and memberships are merged + if authz.Role(orgRole) != authz.RoleViewer { + if err := g.userHasPermissionToListGroupMember(ctx, currentOrg.ID, req.GetGroupReference()); err != nil { + return nil, err + } } currentUser, err := requireCurrentUser(ctx)