Skip to content

Commit

Permalink
feat: allow checking permissions for a specific principal (#417)
Browse files Browse the repository at this point in the history
Signed-off-by: Kush Sharma <[email protected]>
  • Loading branch information
kushsharma authored Nov 19, 2023
1 parent 3887194 commit 3a7d05c
Show file tree
Hide file tree
Showing 48 changed files with 4,327 additions and 1,614 deletions.
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
.DEFAULT_GOAL := build
PROTON_COMMIT := "c8354c9ed17b6810711d8df8a601d972af7d09f5"
PROTON_COMMIT := "63e49ee6dede0b10379fece8b56fd92784d5d3d4"

ui:
@echo " > generating ui build"
Expand Down
59 changes: 59 additions & 0 deletions core/serviceuser/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ type RelationService interface {
Create(ctx context.Context, rel relation.Relation) (relation.Relation, error)
Delete(ctx context.Context, rel relation.Relation) error
LookupSubjects(ctx context.Context, rel relation.Relation) ([]string, error)
CheckPermission(ctx context.Context, rel relation.Relation) (bool, error)
}

type Service struct {
Expand Down Expand Up @@ -280,3 +281,61 @@ func (s Service) GetByToken(ctx context.Context, token string) (ServiceUser, err
}
return s.repo.GetByID(ctx, cred.ServiceUserID)
}

// IsSudo checks platform permissions.
// Platform permissions are:
// - superuser
// - check
func (s Service) IsSudo(ctx context.Context, id string, permissionName string) (bool, error) {
return s.relService.CheckPermission(ctx, relation.Relation{
Subject: relation.Subject{
ID: id,
Namespace: schema.ServiceUserPrincipal,
},
Object: relation.Object{
ID: schema.PlatformID,
Namespace: schema.PlatformNamespace,
},
RelationName: permissionName,
})
}

// Sudo add platform permissions to user
func (s Service) Sudo(ctx context.Context, id string, relationName string) error {
currentUser, err := s.Get(ctx, id)
if err != nil {
return err
}

// check if already su
permissionName := ""
switch relationName {
case schema.MemberRelationName:
permissionName = schema.PlatformCheckPermission
case schema.AdminRelationName:
permissionName = schema.PlatformSudoPermission
}
if permissionName == "" {
return fmt.Errorf("invalid relation name, possible options are: %s, %s", schema.MemberRelationName, schema.AdminRelationName)
}

if ok, err := s.IsSudo(ctx, currentUser.ID, permissionName); err != nil {
return err
} else if ok {
return nil
}

// mark su
_, err = s.relService.Create(ctx, relation.Relation{
Object: relation.Object{
ID: schema.PlatformID,
Namespace: schema.PlatformNamespace,
},
Subject: relation.Subject{
ID: currentUser.ID,
Namespace: schema.ServiceUserPrincipal,
},
RelationName: relationName,
})
return err
}
31 changes: 24 additions & 7 deletions core/user/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package user

import (
"context"
"fmt"
"net/mail"
"strings"
"time"
Expand Down Expand Up @@ -225,7 +226,8 @@ func (s Service) ListByGroup(ctx context.Context, groupID string, roleFilter str
return s.repository.GetByIDs(ctx, userIDs)
}

func (s Service) Sudo(ctx context.Context, id string) error {
// Sudo add platform permissions to user
func (s Service) Sudo(ctx context.Context, id string, relationName string) error {
currentUser, err := s.GetByID(ctx, id)
if errors.Is(err, ErrNotExist) {
if isValidEmail(id) {
Expand All @@ -247,7 +249,18 @@ func (s Service) Sudo(ctx context.Context, id string) error {
}

// check if already su
if ok, err := s.IsSudo(ctx, currentUser.ID); err != nil {
permissionName := ""
switch relationName {
case schema.MemberRelationName:
permissionName = schema.PlatformCheckPermission
case schema.AdminRelationName:
permissionName = schema.PlatformSudoPermission
}
if permissionName == "" {
return fmt.Errorf("invalid relation name, possible options are: %s, %s", schema.MemberRelationName, schema.AdminRelationName)
}

if ok, err := s.IsSudo(ctx, currentUser.ID, permissionName); err != nil {
return err
} else if ok {
return nil
Expand All @@ -263,20 +276,24 @@ func (s Service) Sudo(ctx context.Context, id string) error {
ID: currentUser.ID,
Namespace: schema.UserPrincipal,
},
RelationName: schema.AdminRelationName,
RelationName: relationName,
})
return err
}

func (s Service) IsSudo(ctx context.Context, id string) (bool, error) {
status, err := s.IsSudos(ctx, []string{id})
// IsSudo checks platform permissions.
// Platform permissions are:
// - superuser
// - check
func (s Service) IsSudo(ctx context.Context, id string, permissionName string) (bool, error) {
status, err := s.IsSudos(ctx, []string{id}, permissionName)
if err != nil {
return false, err
}
return len(status) > 0, nil
}

func (s Service) IsSudos(ctx context.Context, ids []string) ([]relation.Relation, error) {
func (s Service) IsSudos(ctx context.Context, ids []string, permissionName string) ([]relation.Relation, error) {
relations := utils.Map(ids, func(id string) relation.Relation {
return relation.Relation{
Subject: relation.Subject{
Expand All @@ -287,7 +304,7 @@ func (s Service) IsSudos(ctx context.Context, ids []string) ([]relation.Relation
ID: schema.PlatformID,
Namespace: schema.PlatformNamespace,
},
RelationName: schema.SudoPermission,
RelationName: permissionName,
}
})
statusForIDs, err := s.relationService.BatchCheckPermission(ctx, relations)
Expand Down
Loading

0 comments on commit 3a7d05c

Please sign in to comment.