diff --git a/changelog/unreleased/user-share-indicators.md b/changelog/unreleased/user-share-indicators.md
new file mode 100644
index 0000000000..949906deae
--- /dev/null
+++ b/changelog/unreleased/user-share-indicators.md
@@ -0,0 +1,3 @@
+Enhancement: Make user share indicators read from the share provider service
+
+https://github.com/cs3org/reva/pull/2946
\ No newline at end of file
diff --git a/internal/http/services/owncloud/ocdav/propfind.go b/internal/http/services/owncloud/ocdav/propfind.go
index 7fd60c19cc..0fce4905ac 100644
--- a/internal/http/services/owncloud/ocdav/propfind.go
+++ b/internal/http/services/owncloud/ocdav/propfind.go
@@ -35,6 +35,7 @@ import (
userv1beta1 "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1"
rpc "github.com/cs3org/go-cs3apis/cs3/rpc/v1beta1"
+ collaboration "github.com/cs3org/go-cs3apis/cs3/sharing/collaboration/v1beta1"
link "github.com/cs3org/go-cs3apis/cs3/sharing/link/v1beta1"
provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1"
"github.com/cs3org/reva/internal/grpc/services/storageprovider"
@@ -43,6 +44,7 @@ import (
ctxpkg "github.com/cs3org/reva/pkg/ctx"
"github.com/cs3org/reva/pkg/errtypes"
"github.com/cs3org/reva/pkg/publicshare"
+ "github.com/cs3org/reva/pkg/share"
rtrace "github.com/cs3org/reva/pkg/trace"
"github.com/cs3org/reva/pkg/utils"
"github.com/cs3org/reva/pkg/utils/resourceid"
@@ -146,9 +148,11 @@ func (s *svc) propfindResponse(ctx context.Context, w http.ResponseWriter, r *ht
ctx, span := rtrace.Provider.Tracer("ocdav").Start(ctx, "propfind_response")
defer span.End()
- filters := make([]*link.ListPublicSharesRequest_Filter, 0, len(resourceInfos))
+ linkFilters := make([]*link.ListPublicSharesRequest_Filter, 0, len(resourceInfos))
+ shareFilters := make([]*collaboration.Filter, 0, len(resourceInfos))
for i := range resourceInfos {
- filters = append(filters, publicshare.ResourceIDFilter(resourceInfos[i].Id))
+ linkFilters = append(linkFilters, publicshare.ResourceIDFilter(resourceInfos[i].Id))
+ shareFilters = append(shareFilters, share.ResourceIDFilter(resourceInfos[i].Id))
}
client, err := s.getClient()
@@ -159,18 +163,30 @@ func (s *svc) propfindResponse(ctx context.Context, w http.ResponseWriter, r *ht
}
var linkshares map[string]struct{}
- listResp, err := client.ListPublicShares(ctx, &link.ListPublicSharesRequest{Filters: filters})
+ listResp, err := client.ListPublicShares(ctx, &link.ListPublicSharesRequest{Filters: linkFilters})
if err == nil {
linkshares = make(map[string]struct{}, len(listResp.Share))
for i := range listResp.Share {
- linkshares[listResp.Share[i].ResourceId.OpaqueId] = struct{}{}
+ linkshares[resourceid.OwnCloudResourceIDWrap(listResp.Share[i].ResourceId)] = struct{}{}
}
} else {
log.Error().Err(err).Msg("propfindResponse: couldn't list public shares")
span.SetStatus(codes.Error, err.Error())
}
- propRes, err := s.multistatusResponse(ctx, &pf, resourceInfos, namespace, linkshares)
+ var usershares map[string]struct{}
+ listSharesResp, err := client.ListShares(ctx, &collaboration.ListSharesRequest{Filters: shareFilters})
+ if err == nil {
+ usershares = make(map[string]struct{}, len(listSharesResp.Shares))
+ for i := range listSharesResp.Shares {
+ usershares[resourceid.OwnCloudResourceIDWrap(listSharesResp.Shares[i].ResourceId)] = struct{}{}
+ }
+ } else {
+ log.Error().Err(err).Msg("propfindResponse: couldn't list user shares")
+ span.SetStatus(codes.Error, err.Error())
+ }
+
+ propRes, err := s.multistatusResponse(ctx, &pf, resourceInfos, namespace, usershares, linkshares)
if err != nil {
log.Error().Err(err).Msg("error formatting propfind")
w.WriteHeader(http.StatusInternalServerError)
@@ -431,10 +447,10 @@ func readPropfind(r io.Reader) (pf propfindXML, status int, err error) {
return pf, 0, nil
}
-func (s *svc) multistatusResponse(ctx context.Context, pf *propfindXML, mds []*provider.ResourceInfo, ns string, linkshares map[string]struct{}) (string, error) {
+func (s *svc) multistatusResponse(ctx context.Context, pf *propfindXML, mds []*provider.ResourceInfo, ns string, usershares, linkshares map[string]struct{}) (string, error) {
responses := make([]*responseXML, 0, len(mds))
for i := range mds {
- res, err := s.mdToPropResponse(ctx, pf, mds[i], ns, linkshares)
+ res, err := s.mdToPropResponse(ctx, pf, mds[i], ns, usershares, linkshares)
if err != nil {
return "", err
}
@@ -486,8 +502,8 @@ func (s *svc) newPropRaw(key, val string) *propertyXML {
// mdToPropResponse converts the CS3 metadata into a webdav PropResponse
// ns is the CS3 namespace that needs to be removed from the CS3 path before
// prefixing it with the baseURI
-func (s *svc) mdToPropResponse(ctx context.Context, pf *propfindXML, md *provider.ResourceInfo, ns string, linkshares map[string]struct{}) (*responseXML, error) {
- sublog := appctx.GetLogger(ctx).With().Interface("md", md).Str("ns", ns).Logger()
+func (s *svc) mdToPropResponse(ctx context.Context, pf *propfindXML, md *provider.ResourceInfo, ns string, usershares, linkshares map[string]struct{}) (*responseXML, error) {
+ sublog := appctx.GetLogger(ctx).With().Str("ns", ns).Logger()
md.Path = strings.TrimPrefix(md.Path, ns)
baseURI := ctx.Value(ctxKeyBaseURI).(string)
@@ -804,6 +820,10 @@ func (s *svc) mdToPropResponse(ctx context.Context, pf *propfindXML, md *provide
types.WriteString("")
types.WriteString(amdv)
types.WriteString("")
+ } else if md.Id != nil {
+ if _, ok := usershares[resourceid.OwnCloudResourceIDWrap(md.Id)]; ok {
+ types.WriteString("0")
+ }
}
if md.Id != nil {
diff --git a/internal/http/services/owncloud/ocdav/publicfile.go b/internal/http/services/owncloud/ocdav/publicfile.go
index b7a62d8bc7..d5b6c54c9a 100644
--- a/internal/http/services/owncloud/ocdav/publicfile.go
+++ b/internal/http/services/owncloud/ocdav/publicfile.go
@@ -179,7 +179,7 @@ func (s *svc) handlePropfindOnToken(w http.ResponseWriter, r *http.Request, ns s
}
infos := s.getPublicFileInfos(onContainer, depth == "0", tokenStatInfo)
- propRes, err := s.multistatusResponse(ctx, &pf, infos, ns, nil)
+ propRes, err := s.multistatusResponse(ctx, &pf, infos, ns, nil, nil)
if err != nil {
sublog.Error().Err(err).Msg("error formatting propfind")
w.WriteHeader(http.StatusInternalServerError)
diff --git a/internal/http/services/owncloud/ocdav/report.go b/internal/http/services/owncloud/ocdav/report.go
index 39729be770..da921905af 100644
--- a/internal/http/services/owncloud/ocdav/report.go
+++ b/internal/http/services/owncloud/ocdav/report.go
@@ -122,7 +122,7 @@ func (s *svc) doFilterFiles(w http.ResponseWriter, r *http.Request, ff *reportFi
infos = append(infos, statRes.Info)
}
- responsesXML, err := s.multistatusResponse(ctx, &propfindXML{Prop: ff.Prop}, infos, namespace, nil)
+ responsesXML, err := s.multistatusResponse(ctx, &propfindXML{Prop: ff.Prop}, infos, namespace, nil, nil)
if err != nil {
log.Error().Err(err).Msg("error formatting propfind")
w.WriteHeader(http.StatusInternalServerError)
diff --git a/internal/http/services/owncloud/ocdav/versions.go b/internal/http/services/owncloud/ocdav/versions.go
index 75467dd39e..b1f3db1eae 100644
--- a/internal/http/services/owncloud/ocdav/versions.go
+++ b/internal/http/services/owncloud/ocdav/versions.go
@@ -165,7 +165,7 @@ func (h *VersionsHandler) doListVersions(w http.ResponseWriter, r *http.Request,
infos = append(infos, vi)
}
- propRes, err := s.multistatusResponse(ctx, &pf, infos, "", nil)
+ propRes, err := s.multistatusResponse(ctx, &pf, infos, "", nil, nil)
if err != nil {
sublog.Error().Err(err).Msg("error formatting propfind")
w.WriteHeader(http.StatusInternalServerError)
diff --git a/pkg/cbox/publicshare/sql/sql.go b/pkg/cbox/publicshare/sql/sql.go
index b086426dfe..d3d94f8516 100644
--- a/pkg/cbox/publicshare/sql/sql.go
+++ b/pkg/cbox/publicshare/sql/sql.go
@@ -32,6 +32,7 @@ import (
"golang.org/x/crypto/bcrypt"
user "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1"
+ rpc "github.com/cs3org/go-cs3apis/cs3/rpc/v1beta1"
link "github.com/cs3org/go-cs3apis/cs3/sharing/link/v1beta1"
provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1"
typespb "github.com/cs3org/go-cs3apis/cs3/types/v1beta1"
@@ -39,12 +40,20 @@ import (
"github.com/cs3org/reva/pkg/errtypes"
"github.com/cs3org/reva/pkg/publicshare"
"github.com/cs3org/reva/pkg/publicshare/manager/registry"
+ "github.com/cs3org/reva/pkg/rgrpc/todo/pool"
+ "github.com/cs3org/reva/pkg/sharedconf"
"github.com/cs3org/reva/pkg/utils"
"github.com/mitchellh/mapstructure"
"github.com/pkg/errors"
)
-const publicShareType = 3
+const (
+ publicShareType = 3
+
+ projectInstancesPrefix = "newproject"
+ projectSpaceGroupsPrefix = "cernbox-project-"
+ projectSpaceAdminGroupsSuffix = "-admins"
+)
func init() {
registry.Register("sql", New)
@@ -59,6 +68,7 @@ type config struct {
DbHost string `mapstructure:"db_host"`
DbPort int `mapstructure:"db_port"`
DbName string `mapstructure:"db_name"`
+ GatewaySvc string `mapstructure:"gatewaysvc"`
}
type manager struct {
@@ -73,6 +83,8 @@ func (c *config) init() {
if c.JanitorRunInterval == 0 {
c.JanitorRunInterval = 3600
}
+
+ c.GatewaySvc = sharedconf.GetGatewaySVC(c.GatewaySvc)
}
func (m *manager) startJanitorRun() {
@@ -309,35 +321,53 @@ func (m *manager) GetPublicShare(ctx context.Context, u *user.User, ref *link.Pu
}
func (m *manager) ListPublicShares(ctx context.Context, u *user.User, filters []*link.ListPublicSharesRequest_Filter, md *provider.ResourceInfo, sign bool) ([]*link.PublicShare, error) {
- uid := conversions.FormatUserID(u.Id)
- query := "select coalesce(uid_owner, '') as uid_owner, coalesce(uid_initiator, '') as uid_initiator, coalesce(share_with, '') as share_with, coalesce(fileid_prefix, '') as fileid_prefix, coalesce(item_source, '') as item_source, coalesce(item_type, '') as item_type, coalesce(token,'') as token, coalesce(expiration, '') as expiration, coalesce(share_name, '') as share_name, id, stime, permissions FROM oc_share WHERE (orphan = 0 or orphan IS NULL) AND (uid_owner=? or uid_initiator=?) AND (share_type=?)"
- var filterQuery string
- params := []interface{}{uid, uid, publicShareType}
-
- for i, f := range filters {
+ query := "select coalesce(uid_owner, '') as uid_owner, coalesce(uid_initiator, '') as uid_initiator, coalesce(share_with, '') as share_with, coalesce(fileid_prefix, '') as fileid_prefix, coalesce(item_source, '') as item_source, coalesce(item_type, '') as item_type, coalesce(token,'') as token, coalesce(expiration, '') as expiration, coalesce(share_name, '') as share_name, id, stime, permissions FROM oc_share WHERE (orphan = 0 or orphan IS NULL) AND (share_type=?)"
+ var resourceFilters, ownerFilters, creatorFilters string
+ var resourceParams, ownerParams, creatorParams []interface{}
+ params := []interface{}{publicShareType}
+ for _, f := range filters {
switch f.Type {
case link.ListPublicSharesRequest_Filter_TYPE_RESOURCE_ID:
- filterQuery += "(fileid_prefix=? AND item_source=?)"
- if i != len(filters)-1 {
- filterQuery += " AND "
+ if len(resourceFilters) != 0 {
+ resourceFilters += " OR "
}
- params = append(params, f.GetResourceId().StorageId, f.GetResourceId().OpaqueId)
+ resourceFilters += "(fileid_prefix=? AND item_source=?)"
+ resourceParams = append(resourceParams, f.GetResourceId().StorageId, f.GetResourceId().OpaqueId)
case link.ListPublicSharesRequest_Filter_TYPE_OWNER:
- filterQuery += "(uid_owner=?)"
- if i != len(filters)-1 {
- filterQuery += " AND "
+ if len(ownerFilters) != 0 {
+ ownerFilters += " OR "
}
- params = append(params, conversions.FormatUserID(f.GetOwner()))
+ ownerFilters += "(uid_owner=?)"
+ ownerParams = append(ownerParams, conversions.FormatUserID(f.GetOwner()))
case link.ListPublicSharesRequest_Filter_TYPE_CREATOR:
- filterQuery += "(uid_initiator=?)"
- if i != len(filters)-1 {
- filterQuery += " AND "
+ if len(creatorFilters) != 0 {
+ creatorFilters += " OR "
}
- params = append(params, conversions.FormatUserID(f.GetCreator()))
+ creatorFilters += "(uid_initiator=?)"
+ creatorParams = append(creatorParams, conversions.FormatUserID(f.GetCreator()))
}
}
- if filterQuery != "" {
- query = fmt.Sprintf("%s AND (%s)", query, filterQuery)
+
+ if resourceFilters != "" {
+ query = fmt.Sprintf("%s AND (%s)", query, resourceFilters)
+ params = append(params, resourceParams...)
+ }
+ if ownerFilters != "" {
+ query = fmt.Sprintf("%s AND (%s)", query, ownerFilters)
+ params = append(params, ownerParams...)
+ }
+ if creatorFilters != "" {
+ query = fmt.Sprintf("%s AND (%s)", query, creatorFilters)
+ params = append(params, creatorParams...)
+ }
+
+ uidOwnersQuery, uidOwnersParams, err := m.uidOwnerFilters(ctx, u, filters)
+ if err != nil {
+ return nil, err
+ }
+ params = append(params, uidOwnersParams...)
+ if uidOwnersQuery != "" {
+ query = fmt.Sprintf("%s AND (%s)", query, uidOwnersQuery)
}
rows, err := m.db.Query(query, params...)
@@ -466,6 +496,57 @@ func expired(s *link.PublicShare) bool {
return false
}
+func (m *manager) uidOwnerFilters(ctx context.Context, u *user.User, filters []*link.ListPublicSharesRequest_Filter) (string, []interface{}, error) {
+ uid := conversions.FormatUserID(u.Id)
+
+ query := "uid_owner=? or uid_initiator=?"
+ params := []interface{}{uid, uid}
+
+ client, err := pool.GetGatewayServiceClient(pool.Endpoint(m.c.GatewaySvc))
+ if err != nil {
+ return "", nil, err
+ }
+
+ for _, f := range filters {
+ if f.Type == link.ListPublicSharesRequest_Filter_TYPE_RESOURCE_ID {
+ // For shares inside project spaces, if the user is an admin, we try to list all shares created by other admins
+ if strings.HasPrefix(f.GetResourceId().GetStorageId(), projectInstancesPrefix) {
+ res, err := client.Stat(ctx, &provider.StatRequest{Ref: &provider.Reference{ResourceId: f.GetResourceId()}})
+ if err != nil || res.Status.Code != rpc.Code_CODE_OK {
+ continue
+ }
+
+ // The path will look like /eos/project/c/cernbox, we need to extract the project name
+ parts := strings.SplitN(res.Info.Path, "/", 6)
+ if len(parts) < 5 {
+ continue
+ }
+
+ adminGroup := projectSpaceGroupsPrefix + parts[4] + projectSpaceAdminGroupsSuffix
+ for _, g := range u.Groups {
+ if g == adminGroup {
+ // User belongs to the admin group, list all shares for the resource
+
+ // TODO: this only works if shares for a single project are requested.
+ // If shares for multiple projects are requested, then we're not checking if the
+ // user is an admin for all of those. We can append the query ` or uid_owner=?`
+ // for all the project owners, which works fine for new reva
+ // but won't work for revaold since there, we store the uid of the share creator as uid_owner.
+ // For this to work across the two versions, this change would have to be made in revaold
+ // but it won't be straightforward as there, the storage provider doesn't return the
+ // resource owners.
+ query = ""
+ params = []interface{}{}
+ break
+ }
+ }
+ }
+ }
+ }
+
+ return query, params, nil
+}
+
func hashPassword(password string, cost int) (string, error) {
bytes, err := bcrypt.GenerateFromPassword([]byte(password), cost)
return "1|" + string(bytes), err
diff --git a/pkg/cbox/share/sql/sql.go b/pkg/cbox/share/sql/sql.go
index c7bd3caa69..c3ecd8e730 100644
--- a/pkg/cbox/share/sql/sql.go
+++ b/pkg/cbox/share/sql/sql.go
@@ -27,14 +27,17 @@ import (
"strings"
"time"
+ rpc "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"
conversions "github.com/cs3org/reva/pkg/cbox/utils"
ctxpkg "github.com/cs3org/reva/pkg/ctx"
"github.com/cs3org/reva/pkg/errtypes"
+ "github.com/cs3org/reva/pkg/rgrpc/todo/pool"
"github.com/cs3org/reva/pkg/share"
"github.com/cs3org/reva/pkg/share/manager/registry"
+ "github.com/cs3org/reva/pkg/sharedconf"
"github.com/cs3org/reva/pkg/utils"
"github.com/mitchellh/mapstructure"
"github.com/pkg/errors"
@@ -47,6 +50,10 @@ import (
const (
shareTypeUser = 0
shareTypeGroup = 1
+
+ projectInstancesPrefix = "newproject"
+ projectSpaceGroupsPrefix = "cernbox-project-"
+ projectSpaceAdminGroupsSuffix = "-admins"
)
func init() {
@@ -59,6 +66,7 @@ type config struct {
DbHost string `mapstructure:"db_host"`
DbPort int `mapstructure:"db_port"`
DbName string `mapstructure:"db_name"`
+ GatewaySvc string `mapstructure:"gatewaysvc"`
}
type mgr struct {
@@ -90,6 +98,7 @@ func parseConfig(m map[string]interface{}) (*config, error) {
if err := mapstructure.Decode(m, c); err != nil {
return nil, err
}
+ c.GatewaySvc = sharedconf.GetGatewaySVC(c.GatewaySvc)
return c, nil
}
@@ -281,20 +290,15 @@ func (m *mgr) UpdateShare(ctx context.Context, ref *collaboration.ShareReference
}
func (m *mgr) ListShares(ctx context.Context, filters []*collaboration.Filter) ([]*collaboration.Share, error) {
- uid := conversions.FormatUserID(ctxpkg.ContextMustGetUser(ctx).Id)
query := `select coalesce(uid_owner, '') as uid_owner, coalesce(uid_initiator, '') as uid_initiator, coalesce(share_with, '') as share_with,
coalesce(fileid_prefix, '') as fileid_prefix, coalesce(item_source, '') as item_source, coalesce(item_type, '') as item_type,
id, stime, permissions, share_type
- FROM oc_share
- WHERE (orphan = 0 or orphan IS NULL) AND (uid_owner=? or uid_initiator=?)`
- params := []interface{}{uid, uid}
+ FROM oc_share WHERE (orphan = 0 or orphan IS NULL) AND (share_type=? OR share_type=?)`
+ params := []interface{}{shareTypeUser, shareTypeGroup}
- if len(filters) == 0 {
- query += " AND (share_type=? OR share_type=?)"
- params = append(params, shareTypeUser)
- params = append(params, shareTypeGroup)
- } else {
- filterQuery, filterParams, err := translateFilters(filters)
+ groupedFilters := share.GroupFiltersByType(filters)
+ if len(groupedFilters) > 0 {
+ filterQuery, filterParams, err := translateFilters(groupedFilters)
if err != nil {
return nil, err
}
@@ -304,6 +308,15 @@ func (m *mgr) ListShares(ctx context.Context, filters []*collaboration.Filter) (
}
}
+ uidOwnersQuery, uidOwnersParams, err := m.uidOwnerFilters(ctx, groupedFilters)
+ if err != nil {
+ return nil, err
+ }
+ params = append(params, uidOwnersParams...)
+ if uidOwnersQuery != "" {
+ query = fmt.Sprintf("%s AND (%s)", query, uidOwnersQuery)
+ }
+
rows, err := m.db.Query(query, params...)
if err != nil {
return nil, err
@@ -346,7 +359,8 @@ func (m *mgr) ListReceivedShares(ctx context.Context, filters []*collaboration.F
query += " AND (share_with=? AND share_type = 0)"
}
- filterQuery, filterParams, err := translateFilters(filters)
+ groupedFilters := share.GroupFiltersByType(filters)
+ filterQuery, filterParams, err := translateFilters(groupedFilters)
if err != nil {
return nil, err
}
@@ -497,6 +511,58 @@ func (m *mgr) UpdateReceivedShare(ctx context.Context, share *collaboration.Rece
return rs, nil
}
+func (m *mgr) uidOwnerFilters(ctx context.Context, filters map[collaboration.Filter_Type][]*collaboration.Filter) (string, []interface{}, error) {
+ user := ctxpkg.ContextMustGetUser(ctx)
+ uid := conversions.FormatUserID(user.Id)
+
+ query := "uid_owner=? or uid_initiator=?"
+ params := []interface{}{uid, uid}
+
+ client, err := pool.GetGatewayServiceClient(pool.Endpoint(m.c.GatewaySvc))
+ if err != nil {
+ return "", nil, err
+ }
+
+ if resourceFilters, ok := filters[collaboration.Filter_TYPE_RESOURCE_ID]; ok {
+ for _, f := range resourceFilters {
+ // For shares inside project spaces, if the user is an admin, we try to list all shares created by other admins
+ if strings.HasPrefix(f.GetResourceId().GetStorageId(), projectInstancesPrefix) {
+ res, err := client.Stat(ctx, &provider.StatRequest{Ref: &provider.Reference{ResourceId: f.GetResourceId()}})
+ if err != nil || res.Status.Code != rpc.Code_CODE_OK {
+ continue
+ }
+
+ // The path will look like /eos/project/c/cernbox, we need to extract the project name
+ parts := strings.SplitN(res.Info.Path, "/", 6)
+ if len(parts) < 5 {
+ continue
+ }
+
+ adminGroup := projectSpaceGroupsPrefix + parts[4] + projectSpaceAdminGroupsSuffix
+ for _, g := range user.Groups {
+ if g == adminGroup {
+ // User belongs to the admin group, list all shares for the resource
+
+ // TODO: this only works if shares for a single project are requested.
+ // If shares for multiple projects are requested, then we're not checking if the
+ // user is an admin for all of those. We can append the query ` or uid_owner=?`
+ // for all the project owners, which works fine for new reva
+ // but won't work for revaold since there, we store the uid of the share creator as uid_owner.
+ // For this to work across the two versions, this change would have to be made in revaold
+ // but it won't be straightforward as there, the storage provider doesn't return the
+ // resource owners.
+ query = ""
+ params = []interface{}{}
+ break
+ }
+ }
+ }
+ }
+ }
+
+ return query, params, nil
+}
+
func granteeTypeToShareType(granteeType provider.GranteeType) int {
switch granteeType {
case provider.GranteeType_GRANTEE_TYPE_USER:
@@ -508,38 +574,37 @@ func granteeTypeToShareType(granteeType provider.GranteeType) int {
}
// translateFilters translates the filters to sql queries
-func translateFilters(filters []*collaboration.Filter) (string, []interface{}, error) {
+func translateFilters(filters map[collaboration.Filter_Type][]*collaboration.Filter) (string, []interface{}, error) {
var (
filterQuery string
params []interface{}
)
- groupedFilters := share.GroupFiltersByType(filters)
// If multiple filters of the same type are passed to this function, they need to be combined with the `OR` operator.
// That is why the filters got grouped by type.
// For every given filter type, iterate over the filters and if there are more than one combine them.
// Combine the different filter types using `AND`
var filterCounter = 0
- for filterType, filters := range groupedFilters {
+ for filterType, currFilters := range filters {
switch filterType {
case collaboration.Filter_TYPE_RESOURCE_ID:
filterQuery += "("
- for i, f := range filters {
+ for i, f := range currFilters {
filterQuery += "(fileid_prefix =? AND item_source=?)"
params = append(params, f.GetResourceId().StorageId, f.GetResourceId().OpaqueId)
- if i != len(filters)-1 {
+ if i != len(currFilters)-1 {
filterQuery += " OR "
}
}
filterQuery += ")"
case collaboration.Filter_TYPE_GRANTEE_TYPE:
filterQuery += "("
- for i, f := range filters {
+ for i, f := range currFilters {
filterQuery += "share_type=?"
params = append(params, granteeTypeToShareType(f.GetGranteeType()))
- if i != len(filters)-1 {
+ if i != len(currFilters)-1 {
filterQuery += " OR "
}
}
@@ -550,7 +615,7 @@ func translateFilters(filters []*collaboration.Filter) (string, []interface{}, e
default:
return "", nil, fmt.Errorf("filter type is not supported")
}
- if filterCounter != len(groupedFilters)-1 {
+ if filterCounter != len(filters)-1 {
filterQuery += " AND "
}
filterCounter++