Skip to content

Commit

Permalink
Merge pull request #4335 from micbar/sharing-ng-links
Browse files Browse the repository at this point in the history
Sharing ng preparation and bugfix
  • Loading branch information
micbar authored Nov 14, 2023
2 parents e258a7c + 3d7572e commit 7f1549f
Show file tree
Hide file tree
Showing 5 changed files with 157 additions and 0 deletions.
5 changes: 5 additions & 0 deletions changelog/unreleased/fix-shares-cleanup-config.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
Bugfix: Fix public shares cleanup config

The public shares cleanup for expired shares was not configurable via ocis.

https://github.com/cs3org/reva/pull/4335/
6 changes: 6 additions & 0 deletions changelog/unreleased/new-permission-helper-function.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
Enhancement: Add sufficient permissions check function

We added a helper function to check for sufficient CS3 resource permissions.

https://github.com/cs3org/reva/pull/4335/
https://github.com/owncloud/ocis/issues/6993
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import (
rpc "github.com/cs3org/go-cs3apis/cs3/rpc/v1beta1"
link "github.com/cs3org/go-cs3apis/cs3/sharing/link/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 All @@ -44,6 +45,7 @@ type config struct {
Driver string `mapstructure:"driver"`
Drivers map[string]map[string]interface{} `mapstructure:"drivers"`
AllowedPathsForShares []string `mapstructure:"allowed_paths_for_shares"`
EnableExpiredSharesCleanup bool `mapstructure:"enable_expired_shares_cleanup"`
WriteableShareMustHavePassword bool `mapstructure:"writeable_share_must_have_password"`
}

Expand Down Expand Up @@ -136,6 +138,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
31 changes: 31 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,33 @@ 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 {
if existing == nil || requested == nil {
return false
}
// empty permissions represent a denial
if grants.PermissionsEqual(requested, &provider.ResourcePermissions{}) {
return existing.DenyGrant
}
requestedPermissionsType := reflect.TypeOf(provider.ResourcePermissions{})
numFields := requestedPermissionsType.NumField()
requestedPermissionsValues := reflect.ValueOf(requested)
existingPermissionsValues := reflect.ValueOf(existing)

for i := 0; i < numFields; i++ {
permissionName := requestedPermissionsType.Field(i).Name
// filter out irrelevant fields
if strings.Contains(permissionName, "XXX") {
continue
}
existingPermission := reflect.Indirect(existingPermissionsValues).FieldByName(permissionName).Bool()
requestedPermission := requestedPermissionsValues.Elem().Field(i).Bool()
// every requested permission needs to exist for the creator
if requestedPermission && !existingPermission {
return false
}
}
return true
}
107 changes: 107 additions & 0 deletions pkg/conversions/role_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
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: nil,
Requested: nil,
Sufficient: false,
},
{
Existing: RoleFromName("editor", true).CS3ResourcePermissions(),
Requested: nil,
Sufficient: false,
},
{
Existing: nil,
Requested: RoleFromName("viewer", true).CS3ResourcePermissions(),
Sufficient: false,
},
{
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 7f1549f

Please sign in to comment.