Skip to content

Commit 5a71705

Browse files
committed
feat: role filter while listing organization users
- raystack/proton#371 - a list of role name/ids are accepted as inputs, it can't be used when `with_roles` is toggled on. Signed-off-by: Kush Sharma <thekushsharma@gmail.com>
1 parent 6b4d111 commit 5a71705

File tree

10 files changed

+6531
-5696
lines changed

10 files changed

+6531
-5696
lines changed

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ TAG := $(shell git rev-list --tags --max-count=1)
44
VERSION := $(shell git describe --tags ${TAG})
55
.PHONY: build check fmt lint test test-race vet test-cover-html help install proto ui compose-up-dev
66
.DEFAULT_GOAL := build
7-
PROTON_COMMIT := "145667ee53b037d636c09df0a529c351069132dc"
7+
PROTON_COMMIT := "60baa540e80479049ed36a8defc149cb9776a132"
88

99
ui:
1010
@echo " > generating ui build"

core/policy/filter.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ type Filter struct {
55
ProjectID string
66
GroupID string
77
RoleID string
8+
RoleIDs []string
89

910
PrincipalType string
1011
PrincipalID string

internal/api/v1beta1/org.go

Lines changed: 67 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ package v1beta1
33
import (
44
"context"
55

6+
"github.com/raystack/frontier/core/policy"
7+
68
"github.com/raystack/frontier/core/authenticate"
79

810
"go.uber.org/zap"
@@ -246,6 +248,10 @@ func (h Handler) ListOrganizationAdmins(ctx context.Context, request *frontierv1
246248
}
247249

248250
func (h Handler) ListOrganizationUsers(ctx context.Context, request *frontierv1beta1.ListOrganizationUsersRequest) (*frontierv1beta1.ListOrganizationUsersResponse, error) {
251+
if len(request.GetRoleFilters()) > 0 && request.GetWithRoles() {
252+
return nil, status.Errorf(codes.InvalidArgument, "cannot use role filters and with_roles together")
253+
}
254+
249255
logger := grpczap.Extract(ctx)
250256
orgResp, err := h.orgService.Get(ctx, request.GetId())
251257
if err != nil {
@@ -259,9 +265,67 @@ func (h Handler) ListOrganizationUsers(ctx context.Context, request *frontierv1b
259265
}
260266
}
261267

262-
users, err := h.userService.ListByOrg(ctx, orgResp.ID, request.GetPermissionFilter())
263-
if err != nil {
264-
return nil, err
268+
var users []user.User
269+
var rolePairPBs []*frontierv1beta1.ListOrganizationUsersResponse_RolePair
270+
271+
if len(request.GetRoleFilters()) > 0 {
272+
// convert role names to ids if needed
273+
roleIDs := request.GetRoleFilters()
274+
for i, roleFilter := range request.GetRoleFilters() {
275+
if !utils.IsValidUUID(roleFilter) {
276+
role, err := h.roleService.Get(ctx, roleFilter)
277+
if err != nil {
278+
return nil, err
279+
}
280+
roleIDs[i] = role.ID
281+
}
282+
}
283+
284+
// need to fetch users with roles assigned to them
285+
policies, err := h.policyService.List(ctx, policy.Filter{
286+
OrgID: request.GetId(),
287+
PrincipalType: schema.UserPrincipal,
288+
ResourceType: schema.OrganizationNamespace,
289+
RoleIDs: roleIDs,
290+
})
291+
if err != nil {
292+
return nil, err
293+
}
294+
users = utils.Filter(utils.Map(policies, func(pol policy.Policy) user.User {
295+
u, _ := h.userService.GetByID(ctx, pol.PrincipalID)
296+
return u
297+
}), func(u user.User) bool {
298+
return u.ID != ""
299+
})
300+
} else {
301+
// list all users
302+
users, err = h.userService.ListByOrg(ctx, orgResp.ID, request.GetPermissionFilter())
303+
if err != nil {
304+
return nil, err
305+
}
306+
if request.GetWithRoles() {
307+
for _, user := range users {
308+
roles, err := h.policyService.ListRoles(ctx, schema.UserPrincipal, user.ID, schema.OrganizationNamespace, request.GetId())
309+
if err != nil {
310+
return nil, err
311+
}
312+
313+
rolesPb := utils.Filter(utils.Map(roles, func(role role.Role) *frontierv1beta1.Role {
314+
pb, err := transformRoleToPB(role)
315+
if err != nil {
316+
logger.Error("failed to transform role for group", zap.Error(err))
317+
return nil
318+
}
319+
return &pb
320+
}), func(role *frontierv1beta1.Role) bool {
321+
return role != nil
322+
})
323+
rolePairPBs = append(rolePairPBs, &frontierv1beta1.ListOrganizationUsersResponse_RolePair{
324+
UserId: user.ID,
325+
Roles: rolesPb,
326+
})
327+
}
328+
}
265329
}
266330

267331
var usersPB []*frontierv1beta1.User
@@ -270,35 +334,8 @@ func (h Handler) ListOrganizationUsers(ctx context.Context, request *frontierv1b
270334
if err != nil {
271335
return nil, err
272336
}
273-
274337
usersPB = append(usersPB, u)
275338
}
276-
277-
var rolePairPBs []*frontierv1beta1.ListOrganizationUsersResponse_RolePair
278-
if request.GetWithRoles() {
279-
for _, user := range users {
280-
roles, err := h.policyService.ListRoles(ctx, schema.UserPrincipal, user.ID, schema.OrganizationNamespace, request.GetId())
281-
if err != nil {
282-
return nil, err
283-
}
284-
285-
rolesPb := utils.Filter(utils.Map(roles, func(role role.Role) *frontierv1beta1.Role {
286-
pb, err := transformRoleToPB(role)
287-
if err != nil {
288-
logger.Error("failed to transform role for group", zap.Error(err))
289-
return nil
290-
}
291-
return &pb
292-
}), func(role *frontierv1beta1.Role) bool {
293-
return role != nil
294-
})
295-
rolePairPBs = append(rolePairPBs, &frontierv1beta1.ListOrganizationUsersResponse_RolePair{
296-
UserId: user.ID,
297-
Roles: rolesPb,
298-
})
299-
}
300-
}
301-
302339
return &frontierv1beta1.ListOrganizationUsersResponse{
303340
Users: usersPB,
304341
RolePairs: rolePairPBs,

internal/store/postgres/policy_repository.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,11 @@ func applyListFilter(stmt *goqu.SelectDataset, flt policy.Filter) *goqu.SelectDa
118118
"role_id": flt.RoleID,
119119
})
120120
}
121+
if len(flt.RoleIDs) > 0 {
122+
stmt = stmt.Where(goqu.Ex{
123+
"role_id": flt.RoleIDs,
124+
})
125+
}
121126
return stmt
122127
}
123128

0 commit comments

Comments
 (0)