Skip to content

Commit

Permalink
add sufficient permissions check
Browse files Browse the repository at this point in the history
  • Loading branch information
micbar committed Nov 13, 2023
1 parent 7a0869a commit 4315f6b
Show file tree
Hide file tree
Showing 3 changed files with 125 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import (
link "github.com/cs3org/go-cs3apis/cs3/sharing/link/v1beta1"
typesv1beta1 "github.com/cs3org/go-cs3apis/cs3/types/v1beta1"
"github.com/cs3org/reva/v2/pkg/appctx"
"github.com/cs3org/reva/v2/pkg/conversions"
ctxpkg "github.com/cs3org/reva/v2/pkg/ctx"
"github.com/cs3org/reva/v2/pkg/errtypes"
"github.com/cs3org/reva/v2/pkg/publicshare"
Expand Down Expand Up @@ -140,6 +141,12 @@ func (s *service) CreatePublicShare(ctx context.Context, req *link.CreatePublicS
log := appctx.GetLogger(ctx)
log.Info().Str("publicshareprovider", "create").Msg("create public share")

if !conversions.SufficientCS3Permissions(req.GetResourceInfo().GetPermissionSet(), req.GetGrant().GetPermissions().GetPermissions()) {
return &link.CreatePublicShareResponse{
Status: status.NewInvalid(ctx, "insufficient permissions to create that kind of share"),
}, nil
}

if !s.isPathAllowed(req.ResourceInfo.Path) {
return &link.CreatePublicShareResponse{
Status: status.NewInvalid(ctx, "share creation is not allowed for the specified path"),
Expand Down
26 changes: 26 additions & 0 deletions pkg/conversions/role.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ package conversions

import (
"fmt"
"reflect"
"strings"

provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1"
Expand Down Expand Up @@ -508,3 +509,28 @@ func RoleFromResourcePermissions(rp *provider.ResourcePermissions, islink bool)
// TODO what about even more granular cs3 permissions?, eg. only stat
return r
}

// SufficientCS3Permissions returns true if the `existing` permissions contain the `requested` permissions
func SufficientCS3Permissions(existing, requested *provider.ResourcePermissions) bool {
// empty permissions represent a denial
if grants.PermissionsEqual(requested, &provider.ResourcePermissions{}) {
return existing.DenyGrant
}
requestedPermissionsType := reflect.TypeOf(provider.ResourcePermissions{})
numFields := requestedPermissionsType.NumField()
reqestedPermissionsValues := reflect.ValueOf(requested)
existingPermissionsValues := reflect.ValueOf(existing)

for i := 0; i < numFields; i++ {
permissionName := requestedPermissionsType.Field(i).Name
if strings.Contains(permissionName, "XXX") {
continue
}
existingPermission := reflect.Indirect(existingPermissionsValues).FieldByName(permissionName).Bool()
requestedPermission := reqestedPermissionsValues.Elem().Field(i).Bool()
if requestedPermission == true && existingPermission == false {
return false
}
}
return true
}
92 changes: 92 additions & 0 deletions pkg/conversions/role_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
package conversions

import (
"testing"

providerv1beta1 "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1"
"github.com/stretchr/testify/assert"
)

func TestSufficientPermissions(t *testing.T) {
type testData struct {
Existing *providerv1beta1.ResourcePermissions
Requested *providerv1beta1.ResourcePermissions
Sufficient bool
}
table := []testData{
{
Existing: RoleFromName("editor", true).CS3ResourcePermissions(),
Requested: RoleFromName("viewer", true).CS3ResourcePermissions(),
Sufficient: true,
},
{
Existing: RoleFromName("viewer", true).CS3ResourcePermissions(),
Requested: RoleFromName("editor", true).CS3ResourcePermissions(),
Sufficient: false,
},
{
Existing: RoleFromName("spaceviewer", true).CS3ResourcePermissions(),
Requested: RoleFromName("spaceeditor", true).CS3ResourcePermissions(),
Sufficient: false,
},
{
Existing: RoleFromName("manager", true).CS3ResourcePermissions(),
Requested: RoleFromName("spaceeditor", true).CS3ResourcePermissions(),
Sufficient: true,
},
{
Existing: RoleFromName("manager", true).CS3ResourcePermissions(),
Requested: RoleFromName("spaceviewer", true).CS3ResourcePermissions(),
Sufficient: true,
},
{
Existing: RoleFromName("manager", true).CS3ResourcePermissions(),
Requested: RoleFromName("manager", true).CS3ResourcePermissions(),
Sufficient: true,
},
{
Existing: RoleFromName("manager", true).CS3ResourcePermissions(),
Requested: RoleFromName("denied", true).CS3ResourcePermissions(),
Sufficient: true,
},
{
Existing: RoleFromName("spaceeditor", true).CS3ResourcePermissions(),
Requested: RoleFromName("denied", true).CS3ResourcePermissions(),
Sufficient: false,
},
{
Existing: RoleFromName("editor", true).CS3ResourcePermissions(),
Requested: RoleFromName("denied", true).CS3ResourcePermissions(),
Sufficient: false,
},
{
Existing: &providerv1beta1.ResourcePermissions{
// all permissions, used for personal space owners
AddGrant: true,
CreateContainer: true,
Delete: true,
GetPath: true,
GetQuota: true,
InitiateFileDownload: true,
InitiateFileUpload: true,
ListContainer: true,
ListFileVersions: true,
ListGrants: true,
ListRecycle: true,
Move: true,
PurgeRecycle: true,
RemoveGrant: true,
RestoreFileVersion: true,
RestoreRecycleItem: true,
Stat: true,
UpdateGrant: true,
DenyGrant: true,
},
Requested: RoleFromName("denied", true).CS3ResourcePermissions(),
Sufficient: true,
},
}
for _, test := range table {
assert.Equal(t, test.Sufficient, SufficientCS3Permissions(test.Existing, test.Requested))
}
}

0 comments on commit 4315f6b

Please sign in to comment.