Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: role filter while listing organization users #810

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ TAG := $(shell git rev-list --tags --max-count=1)
VERSION := $(shell git describe --tags ${TAG})
.PHONY: build check fmt lint test test-race vet test-cover-html help install proto ui compose-up-dev
.DEFAULT_GOAL := build
PROTON_COMMIT := "145667ee53b037d636c09df0a529c351069132dc"
PROTON_COMMIT := "60baa540e80479049ed36a8defc149cb9776a132"

ui:
@echo " > generating ui build"
Expand Down
1 change: 1 addition & 0 deletions core/policy/filter.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ type Filter struct {
ProjectID string
GroupID string
RoleID string
RoleIDs []string

PrincipalType string
PrincipalID string
Expand Down
97 changes: 67 additions & 30 deletions internal/api/v1beta1/org.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ package v1beta1
import (
"context"

"github.com/raystack/frontier/core/policy"

"github.com/raystack/frontier/core/authenticate"

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

func (h Handler) ListOrganizationUsers(ctx context.Context, request *frontierv1beta1.ListOrganizationUsersRequest) (*frontierv1beta1.ListOrganizationUsersResponse, error) {
if len(request.GetRoleFilters()) > 0 && request.GetWithRoles() {
return nil, status.Errorf(codes.InvalidArgument, "cannot use role filters and with_roles together")
}

logger := grpczap.Extract(ctx)
orgResp, err := h.orgService.Get(ctx, request.GetId())
if err != nil {
Expand All @@ -259,9 +265,67 @@ func (h Handler) ListOrganizationUsers(ctx context.Context, request *frontierv1b
}
}

users, err := h.userService.ListByOrg(ctx, orgResp.ID, request.GetPermissionFilter())
if err != nil {
return nil, err
var users []user.User
var rolePairPBs []*frontierv1beta1.ListOrganizationUsersResponse_RolePair

if len(request.GetRoleFilters()) > 0 {
// convert role names to ids if needed
kushsharma marked this conversation as resolved.
Show resolved Hide resolved
roleIDs := request.GetRoleFilters()
for i, roleFilter := range request.GetRoleFilters() {
if !utils.IsValidUUID(roleFilter) {
role, err := h.roleService.Get(ctx, roleFilter)
if err != nil {
return nil, err
}
roleIDs[i] = role.ID
}
}

// need to fetch users with roles assigned to them
policies, err := h.policyService.List(ctx, policy.Filter{
OrgID: request.GetId(),
PrincipalType: schema.UserPrincipal,
ResourceType: schema.OrganizationNamespace,
RoleIDs: roleIDs,
})
if err != nil {
return nil, err
}
users = utils.Filter(utils.Map(policies, func(pol policy.Policy) user.User {
u, _ := h.userService.GetByID(ctx, pol.PrincipalID)
return u
}), func(u user.User) bool {
return u.ID != ""
})
} else {
// list all users
users, err = h.userService.ListByOrg(ctx, orgResp.ID, request.GetPermissionFilter())
if err != nil {
return nil, err
}
if request.GetWithRoles() {
for _, user := range users {
roles, err := h.policyService.ListRoles(ctx, schema.UserPrincipal, user.ID, schema.OrganizationNamespace, request.GetId())
if err != nil {
return nil, err
}

rolesPb := utils.Filter(utils.Map(roles, func(role role.Role) *frontierv1beta1.Role {
pb, err := transformRoleToPB(role)
if err != nil {
logger.Error("failed to transform role for group", zap.Error(err))
return nil
}
return &pb
}), func(role *frontierv1beta1.Role) bool {
return role != nil
})
rolePairPBs = append(rolePairPBs, &frontierv1beta1.ListOrganizationUsersResponse_RolePair{
UserId: user.ID,
Roles: rolesPb,
})
}
}
}

var usersPB []*frontierv1beta1.User
Expand All @@ -270,35 +334,8 @@ func (h Handler) ListOrganizationUsers(ctx context.Context, request *frontierv1b
if err != nil {
return nil, err
}

usersPB = append(usersPB, u)
}

var rolePairPBs []*frontierv1beta1.ListOrganizationUsersResponse_RolePair
if request.GetWithRoles() {
for _, user := range users {
roles, err := h.policyService.ListRoles(ctx, schema.UserPrincipal, user.ID, schema.OrganizationNamespace, request.GetId())
if err != nil {
return nil, err
}

rolesPb := utils.Filter(utils.Map(roles, func(role role.Role) *frontierv1beta1.Role {
pb, err := transformRoleToPB(role)
if err != nil {
logger.Error("failed to transform role for group", zap.Error(err))
return nil
}
return &pb
}), func(role *frontierv1beta1.Role) bool {
return role != nil
})
rolePairPBs = append(rolePairPBs, &frontierv1beta1.ListOrganizationUsersResponse_RolePair{
UserId: user.ID,
Roles: rolesPb,
})
}
}

return &frontierv1beta1.ListOrganizationUsersResponse{
Users: usersPB,
RolePairs: rolePairPBs,
Expand Down
5 changes: 5 additions & 0 deletions internal/store/postgres/policy_repository.go
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,11 @@ func applyListFilter(stmt *goqu.SelectDataset, flt policy.Filter) *goqu.SelectDa
"role_id": flt.RoleID,
})
}
if len(flt.RoleIDs) > 0 {
stmt = stmt.Where(goqu.Ex{
"role_id": flt.RoleIDs,
})
}
return stmt
}

Expand Down
Loading