Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Restrict the paths where share creation is allowed #2267

Merged
merged 1 commit into from
Nov 17, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
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