Skip to content

Commit

Permalink
feat: add permission filter list user resources (#94)
Browse files Browse the repository at this point in the history
  • Loading branch information
FemiNoviaLina authored Sep 23, 2024
1 parent dd036a8 commit 8d2b133
Show file tree
Hide file tree
Showing 9 changed files with 821 additions and 697 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ GOVERSION := $(shell go version | cut -d ' ' -f 3 | cut -d '.' -f 2)

.PHONY: build check fmt lint test test-race vet test-cover-html help install proto
.DEFAULT_GOAL := build
PROTON_COMMIT := "cca99f3519d6ad94953d75083445ae5e7af00e71"
PROTON_COMMIT := "c94a2e1ead95fffc206141373f99a0bf1deca9d3"

install:
@echo "Clean up imports..."
Expand Down
35 changes: 20 additions & 15 deletions core/resource/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -403,13 +403,13 @@ func (s Service) BulkCheckAuthz(ctx context.Context, resources []Resource, actio
return s.relationService.BulkCheckPermission(ctx, relations, actions)
}

func (s Service) ListUserResourcesByType(ctx context.Context, userID string, resourceType string) (ResourcePermissions, error) {
func (s Service) ListUserResourcesByType(ctx context.Context, userID string, resourceType string, permissions []string) (ResourcePermissions, error) {
user, err := s.userService.Get(ctx, userID)
if err != nil {
return ResourcePermissions{}, err
}

res, err := s.listUserResources(ctx, resourceType, user)
res, err := s.listUserResources(ctx, resourceType, user, permissions)
if err != nil {
switch status.Code(err) {
case codes.FailedPrecondition:
Expand All @@ -423,7 +423,7 @@ func (s Service) ListUserResourcesByType(ctx context.Context, userID string, res
return res, nil
}

func (s Service) ListAllUserResources(ctx context.Context, userID string, resourceTypes []string) (map[string]ResourcePermissions, error) {
func (s Service) ListAllUserResources(ctx context.Context, userID string, resourceTypes []string, permissions []string) (map[string]ResourcePermissions, error) {
user, err := s.userService.Get(ctx, userID)
if err != nil {
return map[string]ResourcePermissions{}, err
Expand All @@ -446,7 +446,7 @@ func (s Service) ListAllUserResources(ctx context.Context, userID string, resour
result := make(map[string]ResourcePermissions)
for _, res := range resourceTypes {
if _, ok := result[res]; !ok {
list, err := s.listUserResources(ctx, res, user)
list, err := s.listUserResources(ctx, res, user, permissions)
if err != nil {
switch status.Code(err) {
case codes.FailedPrecondition:
Expand All @@ -465,21 +465,26 @@ func (s Service) ListAllUserResources(ctx context.Context, userID string, resour
return result, nil
}

func (s Service) listUserResources(ctx context.Context, resourceType string, user user.User) (ResourcePermissions, error) {
policies, err := s.policyService.List(ctx, policy.Filters{NamespaceID: resourceType})
if err != nil {
return ResourcePermissions{}, err
func (s Service) listUserResources(ctx context.Context, resourceType string, user user.User, permissions []string) (ResourcePermissions, error) {
if len(permissions) == 0 {
policies, err := s.policyService.List(ctx, policy.Filters{NamespaceID: resourceType})
if err != nil {
return ResourcePermissions{}, err
}

for _, p := range policies {
permissions = append(permissions, strings.Split(p.ActionID, ".")[0])
}
}

resPermissionsMap := make(ResourcePermissions)
actMap := make(map[string]bool)
for _, policy := range policies {
action := strings.Split(policy.ActionID, ".")[0]
if _, ok := actMap[action]; ok {
for _, p := range permissions {
if _, ok := actMap[p]; ok {
continue
}
actMap[action] = true
resources, err := s.relationService.LookupResources(ctx, resourceType, action, userNamespace, user.ID)
actMap[p] = true
resources, err := s.relationService.LookupResources(ctx, resourceType, p, userNamespace, user.ID)
if err != nil {
// continue if permission under a namespace is not found
// https://github.com/authzed/spicedb/blob/main/internal/dispatch/graph/errors.go#L73
Expand All @@ -492,9 +497,9 @@ func (s Service) listUserResources(ctx context.Context, resourceType string, use

for _, r := range resources {
if _, ok := resPermissionsMap[r]; !ok {
resPermissionsMap[r] = []string{action}
resPermissionsMap[r] = []string{p}
} else {
resPermissionsMap[r] = append(resPermissionsMap[r], action)
resPermissionsMap[r] = append(resPermissionsMap[r], p)
}
}
}
Expand Down
60 changes: 31 additions & 29 deletions internal/api/v1beta1/mocks/resource_service.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 4 additions & 4 deletions internal/api/v1beta1/resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ type ResourceService interface {
Update(ctx context.Context, id string, resource resource.Resource) (resource.Resource, error)
CheckAuthz(ctx context.Context, resource resource.Resource, action action.Action) (bool, error)
BulkCheckAuthz(ctx context.Context, resources []resource.Resource, actions []action.Action) ([]relation.Permission, error)
ListUserResourcesByType(ctx context.Context, userID string, resourceType string) (resource.ResourcePermissions, error)
ListAllUserResources(ctx context.Context, userID string, resourceTypes []string) (map[string]resource.ResourcePermissions, error)
ListUserResourcesByType(ctx context.Context, userID string, resourceType string, permissions []string) (resource.ResourcePermissions, error)
ListAllUserResources(ctx context.Context, userID string, resourceTypes []string, permissions []string) (map[string]resource.ResourcePermissions, error)
}

var grpcResourceNotFoundErr = status.Errorf(codes.NotFound, "resource doesn't exist")
Expand Down Expand Up @@ -227,7 +227,7 @@ func (h Handler) UpdateResource(ctx context.Context, request *shieldv1beta1.Upda

func (h Handler) ListAllUserResources(ctx context.Context, request *shieldv1beta1.ListAllUserResourcesRequest) (*shieldv1beta1.ListAllUserResourcesResponse, error) {
logger := grpczap.Extract(ctx)
resources, err := h.resourceService.ListAllUserResources(ctx, request.UserId, request.Types)
resources, err := h.resourceService.ListAllUserResources(ctx, request.UserId, request.Types, request.Permissions)
if err != nil {
logger.Error(err.Error())
switch {
Expand Down Expand Up @@ -269,7 +269,7 @@ func (h Handler) ListAllUserResources(ctx context.Context, request *shieldv1beta
func (h Handler) ListUserResourcesByType(ctx context.Context, request *shieldv1beta1.ListUserResourcesByTypeRequest) (*shieldv1beta1.ListUserResourcesByTypeResponse, error) {
logger := grpczap.Extract(ctx)

resources, err := h.resourceService.ListUserResourcesByType(ctx, request.UserId, fmt.Sprintf("%s/%s", request.Namespace, request.Type))
resources, err := h.resourceService.ListUserResourcesByType(ctx, request.UserId, fmt.Sprintf("%s/%s", request.Namespace, request.Type), request.Permissions)
if err != nil {
logger.Error(err.Error())
switch {
Expand Down
Loading

0 comments on commit 8d2b133

Please sign in to comment.