Skip to content

Commit

Permalink
Merge pull request #4516 from butonic/allow-disabling-resharing
Browse files Browse the repository at this point in the history
allow sharemanager to disable reshares
  • Loading branch information
butonic authored Feb 19, 2024
2 parents f95f5b4 + a82fdb7 commit eee945a
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 3 deletions.
5 changes: 5 additions & 0 deletions changelog/unreleased/allow-disabling-resharing.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
Bugfix: the sharemanager can now reject grants with resharing permissions

When disabling resharing we also need to prevent grants from allowing any grant permissions.

https://github.com/cs3org/reva/pull/4516
26 changes: 24 additions & 2 deletions internal/grpc/services/usershareprovider/usershareprovider.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ type config struct {
Drivers map[string]map[string]interface{} `mapstructure:"drivers"`
GatewayAddr string `mapstructure:"gateway_addr"`
AllowedPathsForShares []string `mapstructure:"allowed_paths_for_shares"`
DisableResharing bool `mapstructure:"disable_resharing"`
}

func (c *config) init() {
Expand All @@ -67,6 +68,7 @@ type service struct {
sm share.Manager
gatewaySelector pool.Selectable[gateway.GatewayAPIClient]
allowedPathsForShares []*regexp.Regexp
disableResharing bool
}

func getShareManager(c *config) (share.Manager, error) {
Expand Down Expand Up @@ -127,15 +129,16 @@ func NewDefault(m map[string]interface{}, ss *grpc.Server) (rgrpc.Service, error
return nil, err
}

return New(gatewaySelector, sm, allowedPathsForShares), nil
return New(gatewaySelector, sm, allowedPathsForShares, c.DisableResharing), nil
}

// New creates a new user share provider svc
func New(gatewaySelector pool.Selectable[gateway.GatewayAPIClient], sm share.Manager, allowedPathsForShares []*regexp.Regexp) rgrpc.Service {
func New(gatewaySelector pool.Selectable[gateway.GatewayAPIClient], sm share.Manager, allowedPathsForShares []*regexp.Regexp, disableResharing bool) rgrpc.Service {
service := &service{
sm: sm,
gatewaySelector: gatewaySelector,
allowedPathsForShares: allowedPathsForShares,
disableResharing: disableResharing,
}

return service
Expand All @@ -157,6 +160,13 @@ func (s *service) CreateShare(ctx context.Context, req *collaboration.CreateShar
log := appctx.GetLogger(ctx)
user := ctxpkg.ContextMustGetUser(ctx)

// when resharing is disabled grants must not allow grant permissions
if s.disableResharing && HasGrantPermissions(req.GetGrant().GetPermissions().GetPermissions()) {
return &collaboration.CreateShareResponse{
Status: status.NewInvalidArg(ctx, "resharing not supported"),
}, nil
}

gatewayClient, err := s.gatewaySelector.Next()
if err != nil {
return nil, err
Expand Down Expand Up @@ -235,6 +245,10 @@ func (s *service) CreateShare(ctx context.Context, req *collaboration.CreateShar
}, nil
}

func HasGrantPermissions(p *provider.ResourcePermissions) bool {
return p.GetAddGrant() || p.GetUpdateGrant() || p.GetRemoveGrant() || p.GetDenyGrant()
}

func (s *service) RemoveShare(ctx context.Context, req *collaboration.RemoveShareRequest) (*collaboration.RemoveShareResponse, error) {
log := appctx.GetLogger(ctx)
user := ctxpkg.ContextMustGetUser(ctx)
Expand Down Expand Up @@ -327,6 +341,14 @@ func (s *service) ListShares(ctx context.Context, req *collaboration.ListSharesR
func (s *service) UpdateShare(ctx context.Context, req *collaboration.UpdateShareRequest) (*collaboration.UpdateShareResponse, error) {
log := appctx.GetLogger(ctx)
user := ctxpkg.ContextMustGetUser(ctx)

// when resharing is disabled grants must not allow grant permissions
if s.disableResharing && HasGrantPermissions(req.GetShare().GetPermissions().GetPermissions()) {
return &collaboration.UpdateShareResponse{
Status: status.NewInvalidArg(ctx, "resharing not supported"),
}, nil
}

gatewayClient, err := s.gatewaySelector.Next()
if err != nil {
return nil, err
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ var _ = Describe("user share provider service", func() {
}
manager.On("GetShare", mock.Anything, mock.Anything).Return(getShareResponse, nil)

rgrpcService := usershareprovider.New(gatewaySelector, manager, []*regexp.Regexp{})
rgrpcService := usershareprovider.New(gatewaySelector, manager, []*regexp.Regexp{}, false)

provider = rgrpcService.(collaborationpb.CollaborationAPIServer)
Expect(provider).ToNot(BeNil())
Expand Down Expand Up @@ -183,6 +183,52 @@ var _ = Describe("user share provider service", func() {
0,
),
)
Context("resharing disabled", func() {
JustBeforeEach(func() {
// disable resharing
rgrpcService := usershareprovider.New(gatewaySelector, manager, []*regexp.Regexp{}, true)

provider = rgrpcService.(collaborationpb.CollaborationAPIServer)
Expect(provider).ToNot(BeNil())

// user has list grants access
statResourceResponse.Info.PermissionSet = &providerpb.ResourcePermissions{
AddGrant: true,
ListGrants: true,
}
})
DescribeTable("rejects shares with any grant changing permissions",
func(
resourceInfoPermissions *providerpb.ResourcePermissions,
grantPermissions *providerpb.ResourcePermissions,
responseCode rpcpb.Code,
expectedCalls int,
) {
manager.On("Share", mock.Anything, mock.Anything, mock.Anything).Return(&collaborationpb.Share{}, nil)

createShareResponse, err := provider.CreateShare(ctx, &collaborationpb.CreateShareRequest{
ResourceInfo: &providerpb.ResourceInfo{
PermissionSet: resourceInfoPermissions,
},
Grant: &collaborationpb.ShareGrant{
Permissions: &collaborationpb.SharePermissions{
Permissions: grantPermissions,
},
},
})

Expect(err).ToNot(HaveOccurred())
Expect(createShareResponse.Status.Code).To(Equal(responseCode))

manager.AssertNumberOfCalls(GinkgoT(), "Share", expectedCalls)
},
Entry("AddGrant", conversions.RoleFromName("manager", true).CS3ResourcePermissions(), &providerpb.ResourcePermissions{AddGrant: true}, rpcpb.Code_CODE_INVALID_ARGUMENT, 0),
Entry("UpdateGrant", conversions.RoleFromName("manager", true).CS3ResourcePermissions(), &providerpb.ResourcePermissions{UpdateGrant: true}, rpcpb.Code_CODE_INVALID_ARGUMENT, 0),
Entry("RemoveGrant", conversions.RoleFromName("manager", true).CS3ResourcePermissions(), &providerpb.ResourcePermissions{RemoveGrant: true}, rpcpb.Code_CODE_INVALID_ARGUMENT, 0),
Entry("DenyGrant", conversions.RoleFromName("manager", true).CS3ResourcePermissions(), &providerpb.ResourcePermissions{DenyGrant: true}, rpcpb.Code_CODE_INVALID_ARGUMENT, 0),
Entry("ListGrants", conversions.RoleFromName("manager", true).CS3ResourcePermissions(), &providerpb.ResourcePermissions{ListGrants: true}, rpcpb.Code_CODE_OK, 1),
)
})
})
Describe("UpdateShare", func() {
It("fails without WriteShare permission in user role", func() {
Expand Down

0 comments on commit eee945a

Please sign in to comment.