Skip to content

Commit

Permalink
enable all space members to see shares
Browse files Browse the repository at this point in the history
  • Loading branch information
David Christofas committed Mar 25, 2022
1 parent 490cdaf commit a11a492
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 4 deletions.
7 changes: 7 additions & 0 deletions changelog/unreleased/spaces-shares.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
Enhancement: Enable space members to list shares inside the space

If there are shared resources in a space then all members are allowed to see those shares.
The json share manager was enhanced to check if the user is allowed to see a share by checking the grants on a resource.

https://github.com/owncloud/ocis/issues/3370
https://github.com/cs3org/reva/pull/2674
Original file line number Diff line number Diff line change
Expand Up @@ -95,11 +95,16 @@ func (h *Handler) addSpaceMember(w http.ResponseWriter, r *http.Request, info *p
return
}

permissions := role.CS3ResourcePermissions()
// All members of a space should be able to list shares inside that space.
// The viewer role doesn't have the ListGrants permission so we set it here.
permissions.ListGrants = true

createShareRes, err := client.CreateShare(ctx, &collaborationv1beta1.CreateShareRequest{
ResourceInfo: info,
Grant: &collaborationv1beta1.ShareGrant{
Permissions: &collaborationv1beta1.SharePermissions{
Permissions: role.CS3ResourcePermissions(),
Permissions: permissions,
},
Grantee: &grantee,
},
Expand Down
44 changes: 41 additions & 3 deletions pkg/share/manager/json/json.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,19 @@ import (
"io/fs"
"io/ioutil"
"os"
"strings"
"sync"
"time"

userv1beta1 "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1"
rpcv1beta1 "github.com/cs3org/go-cs3apis/cs3/rpc/v1beta1"
collaboration "github.com/cs3org/go-cs3apis/cs3/sharing/collaboration/v1beta1"
provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1"
typespb "github.com/cs3org/go-cs3apis/cs3/types/v1beta1"
"github.com/cs3org/reva/v2/pkg/appctx"
ctxpkg "github.com/cs3org/reva/v2/pkg/ctx"
"github.com/cs3org/reva/v2/pkg/errtypes"
"github.com/cs3org/reva/v2/pkg/rgrpc/todo/pool"
"github.com/cs3org/reva/v2/pkg/share"
"github.com/google/uuid"
"github.com/mitchellh/mapstructure"
Expand All @@ -55,6 +59,10 @@ func New(m map[string]interface{}) (share.Manager, error) {
return nil, err
}

if c.GatewayAddr == "" {
return nil, errors.New("share manager config is missing gateway address")
}

c.init()

// load or create file
Expand Down Expand Up @@ -161,7 +169,8 @@ type mgr struct {
}

type config struct {
File string `mapstructure:"file"`
File string `mapstructure:"file"`
GatewayAddr string `mapstructure:"gateway_addr"`
}

func (c *config) init() {
Expand Down Expand Up @@ -335,12 +344,41 @@ func (m *mgr) UpdateShare(ctx context.Context, ref *collaboration.ShareReference
}

func (m *mgr) ListShares(ctx context.Context, filters []*collaboration.Filter) ([]*collaboration.Share, error) {
var ss []*collaboration.Share
m.Lock()
defer m.Unlock()
log := appctx.GetLogger(ctx)
user := ctxpkg.ContextMustGetUser(ctx)

client, err := pool.GetGatewayServiceClient(m.c.GatewayAddr)
if err != nil {
return nil, errors.Wrap(err, "failed to list shares")
}
cache := make(map[string]struct{})
var ss []*collaboration.Share
for _, s := range m.model.Shares {
if share.IsCreatedByUser(s, user) && share.MatchesFilters(s, filters) {
if share.MatchesFilters(s, filters) {
// Only add the share if the share was created by the user or if
// the user has ListGrants permissions on the shared resource.
// The ListGrants check is necessary when a space member wants
// to list shares in a space.
// We are using a cache here so that we don't have to stat a
// resource multiple times.
key := strings.Join([]string{s.ResourceId.StorageId, s.ResourceId.OpaqueId}, "!")
if _, hit := cache[key]; !hit && !share.IsCreatedByUser(s, user) {
sRes, err := client.Stat(ctx, &provider.StatRequest{Ref: &provider.Reference{ResourceId: s.ResourceId}})
if err != nil || sRes.Status.Code != rpcv1beta1.Code_CODE_OK {
log.Error().
Err(err).
Interface("status", sRes.Status).
Interface("resource_id", s.ResourceId).
Msg("ListShares: could not stat resource")
continue
}
if !sRes.Info.PermissionSet.ListGrants {
continue
}
cache[key] = struct{}{}
}
ss = append(ss, s)
}
}
Expand Down

0 comments on commit a11a492

Please sign in to comment.