Skip to content

Commit

Permalink
Merge pull request #4244 from kobergj/ListReceivedSharesByServiceAcco…
Browse files Browse the repository at this point in the history
…unts

Allow listing received Shares by service accounts
  • Loading branch information
kobergj committed Oct 11, 2023
2 parents 5da9c00 + 79d8713 commit b16ab92
Show file tree
Hide file tree
Showing 15 changed files with 129 additions and 44 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
Enhancement: Allow listing reveived shares by service accounts

Similar to UpdateReceivedShare we now pass a forUser parameter to list received shares when using service accounts

https://github.com/cs3org/reva/pull/4244
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,10 @@ func (s *service) ListReceivedShares(ctx context.Context, req *collaboration.Lis
if !foundExclude {
req.Filters = append(req.Filters, &collaboration.Filter{Type: collaboration.Filter_TYPE_EXCLUDE_DENIALS})
}
shares, err := s.sm.ListReceivedShares(ctx, req.Filters) // TODO(labkode): check what to update

var uid userpb.UserId
_ = utils.ReadJSONFromOpaque(req.Opaque, "userid", &uid)
shares, err := s.sm.ListReceivedShares(ctx, req.Filters, &uid) // TODO(labkode): check what to update
if err != nil {
return &collaboration.ListReceivedSharesResponse{
Status: status.NewInternal(ctx, "error listing received shares"),
Expand Down
2 changes: 1 addition & 1 deletion pkg/cbox/share/sql/sql.go
Original file line number Diff line number Diff line change
Expand Up @@ -323,7 +323,7 @@ func (m *mgr) ListShares(ctx context.Context, filters []*collaboration.Filter) (
}

// we list the shares that are targeted to the user in context or to the user groups.
func (m *mgr) ListReceivedShares(ctx context.Context, filters []*collaboration.Filter) ([]*collaboration.ReceivedShare, error) {
func (m *mgr) ListReceivedShares(ctx context.Context, filters []*collaboration.Filter, _ *userpb.UserId) ([]*collaboration.ReceivedShare, error) {
user := ctxpkg.ContextMustGetUser(ctx)
uid := conversions.FormatUserID(user.Id)

Expand Down
15 changes: 12 additions & 3 deletions pkg/share/manager/cs3/cs3.go
Original file line number Diff line number Diff line change
Expand Up @@ -519,7 +519,7 @@ func (m *Manager) UpdateShare(ctx context.Context, ref *collaboration.ShareRefer
}

// ListReceivedShares returns the list of shares the user has access to.
func (m *Manager) ListReceivedShares(ctx context.Context, filters []*collaboration.Filter) ([]*collaboration.ReceivedShare, error) {
func (m *Manager) ListReceivedShares(ctx context.Context, filters []*collaboration.Filter, forUser *userpb.UserId) ([]*collaboration.ReceivedShare, error) {
if err := m.initialize(); err != nil {
return nil, err
}
Expand All @@ -529,11 +529,20 @@ func (m *Manager) ListReceivedShares(ctx context.Context, filters []*collaborati
return nil, errtypes.UserRequired("error getting user from context")
}

uid, groups := user.GetId(), user.GetGroups()
if user.GetId().GetType() == userpb.UserType_USER_TYPE_SERVICE {
u, err := utils.GetUser(forUser, m.gatewayClient)
if err != nil {
return nil, errtypes.BadRequest("user not found")
}
uid = forUser
groups = u.GetGroups()
}
result := []*collaboration.ReceivedShare{}

ids, err := granteeToIndex(&provider.Grantee{
Type: provider.GranteeType_GRANTEE_TYPE_USER,
Id: &provider.Grantee_UserId{UserId: user.Id},
Id: &provider.Grantee_UserId{UserId: uid},
})
if err != nil {
return nil, err
Expand All @@ -544,7 +553,7 @@ func (m *Manager) ListReceivedShares(ctx context.Context, filters []*collaborati
if err != nil {
return nil, err
}
for _, group := range user.Groups {
for _, group := range groups {
index, err := granteeToIndex(&provider.Grantee{
Type: provider.GranteeType_GRANTEE_TYPE_GROUP,
Id: &provider.Grantee_GroupId{GroupId: &groupv1beta1.GroupId{OpaqueId: group}},
Expand Down
10 changes: 5 additions & 5 deletions pkg/share/manager/cs3/cs3_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -463,7 +463,7 @@ var _ = Describe("Manager", func() {
})

It("list the user shares", func() {
rshares, err := m.ListReceivedShares(granteeCtx, []*collaboration.Filter{})
rshares, err := m.ListReceivedShares(granteeCtx, []*collaboration.Filter{}, nil)
Expect(err).ToNot(HaveOccurred())
Expect(rshares).ToNot(BeNil())
Expect(len(rshares)).To(Equal(1))
Expand Down Expand Up @@ -493,7 +493,7 @@ var _ = Describe("Manager", func() {
})

It("list the group share", func() {
rshares, err := m.ListReceivedShares(granteeCtx, []*collaboration.Filter{})
rshares, err := m.ListReceivedShares(granteeCtx, []*collaboration.Filter{}, nil)
Expect(err).ToNot(HaveOccurred())
Expect(rshares).ToNot(BeNil())
Expect(len(rshares)).To(Equal(1))
Expand Down Expand Up @@ -531,7 +531,7 @@ var _ = Describe("Manager", func() {
})

It("list the user and shares", func() {
rshares, err := m.ListReceivedShares(granteeCtx, []*collaboration.Filter{})
rshares, err := m.ListReceivedShares(granteeCtx, []*collaboration.Filter{}, nil)
Expect(err).ToNot(HaveOccurred())
Expect(rshares).ToNot(BeNil())
Expect(len(rshares)).To(Equal(2))
Expand All @@ -545,7 +545,7 @@ var _ = Describe("Manager", func() {
GranteeType: provider.GranteeType_GRANTEE_TYPE_USER,
},
},
})
}, nil)
Expect(err).ToNot(HaveOccurred())
Expect(rshares).ToNot(BeNil())
Expect(len(rshares)).To(Equal(1))
Expand All @@ -560,7 +560,7 @@ var _ = Describe("Manager", func() {
GranteeType: provider.GranteeType_GRANTEE_TYPE_GROUP,
},
},
})
}, nil)
Expect(err).ToNot(HaveOccurred())
Expect(rshares).ToNot(BeNil())
Expect(len(rshares)).To(Equal(1))
Expand Down
13 changes: 12 additions & 1 deletion pkg/share/manager/json/json.go
Original file line number Diff line number Diff line change
Expand Up @@ -475,11 +475,22 @@ func (m *mgr) ListShares(ctx context.Context, filters []*collaboration.Filter) (
}

// we list the shares that are targeted to the user in context or to the user groups.
func (m *mgr) ListReceivedShares(ctx context.Context, filters []*collaboration.Filter) ([]*collaboration.ReceivedShare, error) {
func (m *mgr) ListReceivedShares(ctx context.Context, filters []*collaboration.Filter, forUser *userv1beta1.UserId) ([]*collaboration.ReceivedShare, error) {
m.Lock()
defer m.Unlock()

user := ctxpkg.ContextMustGetUser(ctx)
if user.GetId().GetType() == userv1beta1.UserType_USER_TYPE_SERVICE {
gwc, err := pool.GetGatewayServiceClient(m.c.GatewayAddr)
if err != nil {
return nil, errors.Wrap(err, "failed to list shares")
}
u, err := utils.GetUser(forUser, gwc)
if err != nil {
return nil, errtypes.BadRequest("user not found")
}
user = u
}
mem := make(map[string]int)
var rss []*collaboration.ReceivedShare
for _, s := range m.model.Shares {
Expand Down
9 changes: 8 additions & 1 deletion pkg/share/manager/jsoncs3/jsoncs3.go
Original file line number Diff line number Diff line change
Expand Up @@ -759,7 +759,7 @@ func (m *Manager) listCreatedShares(ctx context.Context, user *userv1beta1.User,
}

// ListReceivedShares returns the list of shares the user has access to.
func (m *Manager) ListReceivedShares(ctx context.Context, filters []*collaboration.Filter) ([]*collaboration.ReceivedShare, error) {
func (m *Manager) ListReceivedShares(ctx context.Context, filters []*collaboration.Filter, forUser *userv1beta1.UserId) ([]*collaboration.ReceivedShare, error) {
ctx, span := appctx.GetTracerProvider(ctx).Tracer(tracerName).Start(ctx, "ListReceivedShares")
defer span.End()

Expand All @@ -768,6 +768,13 @@ func (m *Manager) ListReceivedShares(ctx context.Context, filters []*collaborati
}

user := ctxpkg.ContextMustGetUser(ctx)
if user.GetId().GetType() == userv1beta1.UserType_USER_TYPE_SERVICE {
u, err := utils.GetUser(forUser, m.gateway)
if err != nil {
return nil, errtypes.BadRequest("user not found")
}
user = u
}

ssids := map[string]*receivedsharecache.Space{}

Expand Down
20 changes: 10 additions & 10 deletions pkg/share/manager/jsoncs3/jsoncs3_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -715,15 +715,15 @@ var _ = Describe("Jsoncs3", func() {

Describe("ListReceivedShares", func() {
It("lists the received shares", func() {
received, err := m.ListReceivedShares(granteeCtx, []*collaboration.Filter{})
received, err := m.ListReceivedShares(granteeCtx, []*collaboration.Filter{}, nil)
Expect(err).ToNot(HaveOccurred())
Expect(len(received)).To(Equal(1))
Expect(received[0].Share.ResourceId).To(Equal(sharedResource.Id))
Expect(received[0].State).To(Equal(collaboration.ShareState_SHARE_STATE_PENDING))
})

It("syncronizes the provider cache before listing", func() {
received, err := m.ListReceivedShares(granteeCtx, []*collaboration.Filter{})
received, err := m.ListReceivedShares(granteeCtx, []*collaboration.Filter{}, nil)
Expect(err).ToNot(HaveOccurred())
Expect(len(received)).To(Equal(1))
Expect(received[0].Share.Permissions.Permissions.InitiateFileUpload).To(BeFalse())
Expand All @@ -743,7 +743,7 @@ var _ = Describe("Jsoncs3", func() {
cache.Shares[share.Id.OpaqueId].Permissions.Permissions.InitiateFileUpload = false

cache.Etag = "reset1" // trigger reload
received, err = m.ListReceivedShares(granteeCtx, []*collaboration.Filter{})
received, err = m.ListReceivedShares(granteeCtx, []*collaboration.Filter{}, nil)
Expect(err).ToNot(HaveOccurred())
Expect(len(received)).To(Equal(1))
Expect(received[0].Share.Permissions.Permissions.InitiateFileUpload).To(BeTrue())
Expand All @@ -753,7 +753,7 @@ var _ = Describe("Jsoncs3", func() {
m, err := jsoncs3.New(storage, nil, 0, nil, 0) // Reset in-memory cache
Expect(err).ToNot(HaveOccurred())

received, err := m.ListReceivedShares(granteeCtx, []*collaboration.Filter{})
received, err := m.ListReceivedShares(granteeCtx, []*collaboration.Filter{}, nil)
Expect(err).ToNot(HaveOccurred())
Expect(len(received)).To(Equal(1))
})
Expand All @@ -762,7 +762,7 @@ var _ = Describe("Jsoncs3", func() {
share2, err := m.Share(ctx, sharedResource2, grant)
Expect(err).ToNot(HaveOccurred())

received, err := m.ListReceivedShares(granteeCtx, []*collaboration.Filter{})
received, err := m.ListReceivedShares(granteeCtx, []*collaboration.Filter{}, nil)
Expect(err).ToNot(HaveOccurred())
Expect(len(received)).To(Equal(2))

Expand All @@ -773,7 +773,7 @@ var _ = Describe("Jsoncs3", func() {
ResourceId: sharedResource.Id,
},
},
})
}, nil)
Expect(err).ToNot(HaveOccurred())
Expect(len(received)).To(Equal(1))
Expect(received[0].Share.ResourceId).To(Equal(sharedResource.Id))
Expand All @@ -787,7 +787,7 @@ var _ = Describe("Jsoncs3", func() {
ResourceId: sharedResource2.Id,
},
},
})
}, nil)
Expect(err).ToNot(HaveOccurred())
Expect(len(received)).To(Equal(1))
Expect(received[0].Share.ResourceId).To(Equal(sharedResource2.Id))
Expand All @@ -807,7 +807,7 @@ var _ = Describe("Jsoncs3", func() {
})

It("lists the group share", func() {
received, err := m.ListReceivedShares(granteeCtx, []*collaboration.Filter{})
received, err := m.ListReceivedShares(granteeCtx, []*collaboration.Filter{}, nil)
Expect(err).ToNot(HaveOccurred())
Expect(len(received)).To(Equal(2))
ids := []string{}
Expand All @@ -821,7 +821,7 @@ var _ = Describe("Jsoncs3", func() {
m, err := jsoncs3.New(storage, nil, 0, nil, 0) // Reset in-memory cache
Expect(err).ToNot(HaveOccurred())

received, err := m.ListReceivedShares(granteeCtx, []*collaboration.Filter{})
received, err := m.ListReceivedShares(granteeCtx, []*collaboration.Filter{}, nil)
Expect(err).ToNot(HaveOccurred())
Expect(len(received)).To(Equal(2))
ids := []string{}
Expand All @@ -843,7 +843,7 @@ var _ = Describe("Jsoncs3", func() {
_, err = m.UpdateReceivedShare(granteeCtx, rs, &fieldmaskpb.FieldMask{Paths: []string{"state"}}, nil)
Expect(err).ToNot(HaveOccurred())

received, err := m.ListReceivedShares(granteeCtx, []*collaboration.Filter{})
received, err := m.ListReceivedShares(granteeCtx, []*collaboration.Filter{}, nil)
Expect(err).ToNot(HaveOccurred())
Expect(len(received)).To(Equal(2))
})
Expand Down
7 changes: 6 additions & 1 deletion pkg/share/manager/memory/memory.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ package memory

import (
"context"
"errors"
"fmt"
"sync"
"sync/atomic"
Expand Down Expand Up @@ -282,11 +283,15 @@ func (m *manager) ListShares(ctx context.Context, filters []*collaboration.Filte
}

// we list the shares that are targeted to the user in context or to the user groups.
func (m *manager) ListReceivedShares(ctx context.Context, filters []*collaboration.Filter) ([]*collaboration.ReceivedShare, error) {
func (m *manager) ListReceivedShares(ctx context.Context, filters []*collaboration.Filter, forUser *userv1beta1.UserId) ([]*collaboration.ReceivedShare, error) {
var rss []*collaboration.ReceivedShare
m.lock.Lock()
defer m.lock.Unlock()
user := ctxpkg.ContextMustGetUser(ctx)
if user.GetId().GetType() == userv1beta1.UserType_USER_TYPE_SERVICE {
// TODO: gateway missing!
return nil, errors.New("can't use inmem share manager and service accounts")
}
for _, s := range m.shares {
if share.IsCreatedByUser(s, user) || !share.IsGrantedToUser(s, user) {
// omit shares created by the user or shares the user can't access
Expand Down
11 changes: 11 additions & 0 deletions pkg/share/manager/owncloudsql/conversions.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import (
conversions "github.com/cs3org/reva/v2/internal/http/services/owncloud/ocs/conversions"
"github.com/cs3org/reva/v2/pkg/rgrpc/status"
"github.com/cs3org/reva/v2/pkg/rgrpc/todo/pool"
"github.com/cs3org/reva/v2/pkg/utils"
"github.com/jellydator/ttlcache/v2"
)

Expand Down Expand Up @@ -62,6 +63,7 @@ type DBShare struct {
type UserConverter interface {
UserNameToUserID(ctx context.Context, username string) (*userpb.UserId, error)
UserIDToUserName(ctx context.Context, userid *userpb.UserId) (string, error)
GetUser(userid *userpb.UserId) (*userpb.User, error)
}

// GatewayUserConverter converts usernames and ids using the gateway
Expand Down Expand Up @@ -139,6 +141,15 @@ func (c *GatewayUserConverter) UserNameToUserID(ctx context.Context, username st
return getUserResponse.User.Id, nil
}

// GetUser gets the user
func (c *GatewayUserConverter) GetUser(userid *userpb.UserId) (*userpb.User, error) {
gwc, err := pool.GetGatewayServiceClient(c.gwAddr)
if err != nil {
return nil, err
}
return utils.GetUser(userid, gwc)
}

func (m *mgr) formatGrantee(ctx context.Context, g *provider.Grantee) (int, string, error) {
var granteeType int
var formattedID string
Expand Down
26 changes: 26 additions & 0 deletions pkg/share/manager/owncloudsql/mocks/UserConverter.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 8 additions & 1 deletion pkg/share/manager/owncloudsql/owncloudsql.go
Original file line number Diff line number Diff line change
Expand Up @@ -336,8 +336,15 @@ func (m *mgr) ListShares(ctx context.Context, filters []*collaboration.Filter) (
}

// we list the shares that are targeted to the user in context or to the user groups.
func (m *mgr) ListReceivedShares(ctx context.Context, filters []*collaboration.Filter) ([]*collaboration.ReceivedShare, error) {
func (m *mgr) ListReceivedShares(ctx context.Context, filters []*collaboration.Filter, forUser *userpb.UserId) ([]*collaboration.ReceivedShare, error) {
user := ctxpkg.ContextMustGetUser(ctx)
if user.GetId().GetType() == userpb.UserType_USER_TYPE_SERVICE {
u, err := m.userConverter.GetUser(forUser)
if err != nil {
return nil, errtypes.BadRequest("user not found")
}
user = u
}
uid := user.Username

params := []interface{}{uid, uid, uid}
Expand Down

0 comments on commit b16ab92

Please sign in to comment.