Skip to content

Commit

Permalink
Restrict the paths where share creation is allowed (#2267)
Browse files Browse the repository at this point in the history
  • Loading branch information
ishank011 authored Nov 17, 2021
1 parent e10bce6 commit d621c9d
Show file tree
Hide file tree
Showing 4 changed files with 83 additions and 18 deletions.
7 changes: 7 additions & 0 deletions changelog/unreleased/share-creation-paths.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
Enhancement: Restrict the paths where share creation is allowed

This PR limits share creation to certain specified paths. These can be useful
when users have access to global spaces and virtual views but these should not
be sharable.

https://github.com/cs3org/reva/pull/2267
43 changes: 37 additions & 6 deletions internal/grpc/services/publicshareprovider/publicshareprovider.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ package publicshareprovider

import (
"context"
"regexp"

link "github.com/cs3org/go-cs3apis/cs3/sharing/link/v1beta1"
provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1"
Expand All @@ -40,8 +41,9 @@ func init() {
}

type config struct {
Driver string `mapstructure:"driver"`
Drivers map[string]map[string]interface{} `mapstructure:"drivers"`
Driver string `mapstructure:"driver"`
Drivers map[string]map[string]interface{} `mapstructure:"drivers"`
AllowedPathsForShares []string `mapstructure:"allowed_paths_for_shares"`
}

func (c *config) init() {
Expand All @@ -51,8 +53,9 @@ func (c *config) init() {
}

type service struct {
conf *config
sm publicshare.Manager
conf *config
sm publicshare.Manager
allowedPathsForShares []*regexp.Regexp
}

func getShareManager(c *config) (publicshare.Manager, error) {
Expand Down Expand Up @@ -98,18 +101,46 @@ func New(m map[string]interface{}, ss *grpc.Server) (rgrpc.Service, error) {
return nil, err
}

allowedPathsForShares := make([]*regexp.Regexp, 0, len(c.AllowedPathsForShares))
for _, s := range c.AllowedPathsForShares {
regex, err := regexp.Compile(s)
if err != nil {
return nil, err
}
allowedPathsForShares = append(allowedPathsForShares, regex)
}

service := &service{
conf: c,
sm: sm,
conf: c,
sm: sm,
allowedPathsForShares: allowedPathsForShares,
}

return service, nil
}

func (s *service) isPathAllowed(path string) bool {
if len(s.allowedPathsForShares) == 0 {
return true
}
for _, reg := range s.allowedPathsForShares {
if reg.MatchString(path) {
return true
}
}
return false
}

func (s *service) CreatePublicShare(ctx context.Context, req *link.CreatePublicShareRequest) (*link.CreatePublicShareResponse, error) {
log := appctx.GetLogger(ctx)
log.Info().Str("publicshareprovider", "create").Msg("create public share")

if !s.isPathAllowed(req.ResourceInfo.Path) {
return &link.CreatePublicShareResponse{
Status: status.NewInvalidArg(ctx, "share creation is not allowed for the specified path"),
}, nil
}

u, ok := ctxpkg.ContextGetUser(ctx)
if !ok {
log.Error().Msg("error getting user from context")
Expand Down
44 changes: 38 additions & 6 deletions internal/grpc/services/usershareprovider/usershareprovider.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ package usershareprovider

import (
"context"
"regexp"

userpb "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1"
collaboration "github.com/cs3org/go-cs3apis/cs3/sharing/collaboration/v1beta1"
Expand All @@ -41,8 +42,9 @@ func init() {
}

type config struct {
Driver string `mapstructure:"driver"`
Drivers map[string]map[string]interface{} `mapstructure:"drivers"`
Driver string `mapstructure:"driver"`
Drivers map[string]map[string]interface{} `mapstructure:"drivers"`
AllowedPathsForShares []string `mapstructure:"allowed_paths_for_shares"`
}

func (c *config) init() {
Expand All @@ -52,8 +54,9 @@ func (c *config) init() {
}

type service struct {
conf *config
sm share.Manager
conf *config
sm share.Manager
allowedPathsForShares []*regexp.Regexp
}

func getShareManager(c *config) (share.Manager, error) {
Expand Down Expand Up @@ -100,21 +103,50 @@ func New(m map[string]interface{}, ss *grpc.Server) (rgrpc.Service, error) {
return nil, err
}

allowedPathsForShares := make([]*regexp.Regexp, 0, len(c.AllowedPathsForShares))
for _, s := range c.AllowedPathsForShares {
regex, err := regexp.Compile(s)
if err != nil {
return nil, err
}
allowedPathsForShares = append(allowedPathsForShares, regex)
}

service := &service{
conf: c,
sm: sm,
conf: c,
sm: sm,
allowedPathsForShares: allowedPathsForShares,
}

return service, nil
}

func (s *service) isPathAllowed(path string) bool {
if len(s.allowedPathsForShares) == 0 {
return true
}
for _, reg := range s.allowedPathsForShares {
if reg.MatchString(path) {
return true
}
}
return false
}

func (s *service) CreateShare(ctx context.Context, req *collaboration.CreateShareRequest) (*collaboration.CreateShareResponse, error) {
u := ctxpkg.ContextMustGetUser(ctx)
if req.Grant.Grantee.Type == provider.GranteeType_GRANTEE_TYPE_USER && req.Grant.Grantee.GetUserId().Idp == "" {
// use logged in user Idp as default.
g := &userpb.UserId{OpaqueId: req.Grant.Grantee.GetUserId().OpaqueId, Idp: u.Id.Idp, Type: userpb.UserType_USER_TYPE_PRIMARY}
req.Grant.Grantee.Id = &provider.Grantee_UserId{UserId: g}
}

if !s.isPathAllowed(req.ResourceInfo.Path) {
return &collaboration.CreateShareResponse{
Status: status.NewInvalidArg(ctx, "share creation is not allowed for the specified path"),
}, nil
}

share, err := s.sm.Share(ctx, req.ResourceInfo, req.Grant)
if err != nil {
return &collaboration.CreateShareResponse{
Expand Down
7 changes: 1 addition & 6 deletions pkg/utils/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -104,12 +104,7 @@ func ResolvePath(path string) (string, error) {
path = filepath.Join(homeDir, path[2:])
}

path, err = filepath.Abs(path)
if err != nil {
return "", err
}

return path, nil
return filepath.Abs(path)
}

// RandString is a helper to create tokens.
Expand Down

0 comments on commit d621c9d

Please sign in to comment.