From 9f7f54e7ff0d60b1610fa3d7cf5879c8e1420d4c Mon Sep 17 00:00:00 2001 From: Ishank Arora Date: Mon, 8 Nov 2021 12:20:59 +0100 Subject: [PATCH] Fix the permissions response for shared files in the cbox sql driver --- changelog/unreleased/sql-share-file-perm.md | 3 +++ pkg/cbox/share/sql/sql.go | 24 ++++++++++----------- pkg/cbox/utils/conversions.go | 20 ++++++++++------- 3 files changed, 27 insertions(+), 20 deletions(-) create mode 100644 changelog/unreleased/sql-share-file-perm.md diff --git a/changelog/unreleased/sql-share-file-perm.md b/changelog/unreleased/sql-share-file-perm.md new file mode 100644 index 00000000000..1450bedc163 --- /dev/null +++ b/changelog/unreleased/sql-share-file-perm.md @@ -0,0 +1,3 @@ +Bugfix: Fix the permissions response for shared files in the cbox sql driver + +https://github.com/cs3org/reva/pull/2244 \ No newline at end of file diff --git a/pkg/cbox/share/sql/sql.go b/pkg/cbox/share/sql/sql.go index 0987aa711bb..90ea3923631 100644 --- a/pkg/cbox/share/sql/sql.go +++ b/pkg/cbox/share/sql/sql.go @@ -167,8 +167,8 @@ func (m *mgr) Share(ctx context.Context, md *provider.ResourceInfo, g *collabora func (m *mgr) getByID(ctx context.Context, id *collaboration.ShareId) (*collaboration.Share, error) { uid := conversions.FormatUserID(ctxpkg.ContextMustGetUser(ctx).Id) s := conversions.DBShare{ID: id.OpaqueId} - 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, stime, permissions, share_type FROM oc_share WHERE (orphan = 0 or orphan IS NULL) AND id=? AND (uid_owner=? or uid_initiator=?)" - if err := m.db.QueryRow(query, id.OpaqueId, uid, uid).Scan(&s.UIDOwner, &s.UIDInitiator, &s.ShareWith, &s.Prefix, &s.ItemSource, &s.STime, &s.Permissions, &s.ShareType); err != nil { + 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, stime, permissions, share_type FROM oc_share WHERE (orphan = 0 or orphan IS NULL) AND id=? AND (uid_owner=? or uid_initiator=?)" + if err := m.db.QueryRow(query, id.OpaqueId, uid, uid).Scan(&s.UIDOwner, &s.UIDInitiator, &s.ShareWith, &s.Prefix, &s.ItemSource, &s.ItemType, &s.STime, &s.Permissions, &s.ShareType); err != nil { if err == sql.ErrNoRows { return nil, errtypes.NotFound(id.OpaqueId) } @@ -183,8 +183,8 @@ func (m *mgr) getByKey(ctx context.Context, key *collaboration.ShareKey) (*colla s := conversions.DBShare{} shareType, shareWith := conversions.FormatGrantee(key.Grantee) - 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, id, stime, permissions, share_type FROM oc_share WHERE (orphan = 0 or orphan IS NULL) AND uid_owner=? AND fileid_prefix=? AND item_source=? AND share_type=? AND share_with=? AND (uid_owner=? or uid_initiator=?)" - if err := m.db.QueryRow(query, owner, key.ResourceId.StorageId, key.ResourceId.OpaqueId, shareType, shareWith, uid, uid).Scan(&s.UIDOwner, &s.UIDInitiator, &s.ShareWith, &s.Prefix, &s.ItemSource, &s.ID, &s.STime, &s.Permissions, &s.ShareType); err != nil { + 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=? AND fileid_prefix=? AND item_source=? AND share_type=? AND share_with=? AND (uid_owner=? or uid_initiator=?)" + if err := m.db.QueryRow(query, owner, key.ResourceId.StorageId, key.ResourceId.OpaqueId, shareType, shareWith, uid, uid).Scan(&s.UIDOwner, &s.UIDInitiator, &s.ShareWith, &s.Prefix, &s.ItemSource, &s.ItemType, &s.ID, &s.STime, &s.Permissions, &s.ShareType); err != nil { if err == sql.ErrNoRows { return nil, errtypes.NotFound(key.String()) } @@ -283,7 +283,7 @@ 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, id, stime, permissions, share_type + 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} @@ -317,7 +317,7 @@ func (m *mgr) ListShares(ctx context.Context, filters []*collaboration.Filter) ( var s conversions.DBShare shares := []*collaboration.Share{} for rows.Next() { - if err := rows.Scan(&s.UIDOwner, &s.UIDInitiator, &s.ShareWith, &s.Prefix, &s.ItemSource, &s.ID, &s.STime, &s.Permissions, &s.ShareType); err != nil { + if err := rows.Scan(&s.UIDOwner, &s.UIDInitiator, &s.ShareWith, &s.Prefix, &s.ItemSource, &s.ItemType, &s.ID, &s.STime, &s.Permissions, &s.ShareType); err != nil { continue } shares = append(shares, conversions.ConvertToCS3Share(s)) @@ -340,7 +340,7 @@ func (m *mgr) ListReceivedShares(ctx context.Context, filters []*collaboration.F } 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, ts.id, stime, + coalesce(fileid_prefix, '') as fileid_prefix, coalesce(item_source, '') as item_source, coalesce(item_type, '') as item_type, ts.id, stime, permissions, share_type, accepted, coalesce(tr.rejected_by, '') as rejected_by FROM oc_share ts LEFT JOIN oc_share_acl tr ON (ts.id = tr.id AND tr.rejected_by = ?) WHERE (orphan = 0 or orphan IS NULL) AND (uid_owner != ? AND uid_initiator != ?)` @@ -369,7 +369,7 @@ func (m *mgr) ListReceivedShares(ctx context.Context, filters []*collaboration.F var s conversions.DBShare shares := []*collaboration.ReceivedShare{} for rows.Next() { - if err := rows.Scan(&s.UIDOwner, &s.UIDInitiator, &s.ShareWith, &s.Prefix, &s.ItemSource, &s.ID, &s.STime, &s.Permissions, &s.ShareType, &s.State, &s.RejectedBy); err != nil { + if err := rows.Scan(&s.UIDOwner, &s.UIDInitiator, &s.ShareWith, &s.Prefix, &s.ItemSource, &s.ItemType, &s.ID, &s.STime, &s.Permissions, &s.ShareType, &s.State, &s.RejectedBy); err != nil { continue } shares = append(shares, conversions.ConvertToCS3ReceivedShare(s)) @@ -391,13 +391,13 @@ func (m *mgr) getReceivedByID(ctx context.Context, id *collaboration.ShareId) (* } s := conversions.DBShare{ID: id.OpaqueId} - 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, stime, permissions, share_type, accepted, coalesce(tr.rejected_by, '') as rejected_by FROM oc_share ts LEFT JOIN oc_share_acl tr ON (ts.id = tr.id AND tr.rejected_by = ?) WHERE (orphan = 0 or orphan IS NULL) AND ts.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, scoalesce(item_type, '') as item_type, time, permissions, share_type, accepted, coalesce(tr.rejected_by, '') as rejected_by FROM oc_share ts LEFT JOIN oc_share_acl tr ON (ts.id = tr.id AND tr.rejected_by = ?) WHERE (orphan = 0 or orphan IS NULL) AND ts.id=? " if len(user.Groups) > 0 { query += "AND ((share_with=? AND share_type = 0) OR (share_type = 1 AND share_with in (?" + strings.Repeat(",?", len(user.Groups)-1) + ")))" } else { query += "AND (share_with=? AND share_type = 0)" } - if err := m.db.QueryRow(query, params...).Scan(&s.UIDOwner, &s.UIDInitiator, &s.ShareWith, &s.Prefix, &s.ItemSource, &s.STime, &s.Permissions, &s.ShareType, &s.State, &s.RejectedBy); err != nil { + if err := m.db.QueryRow(query, params...).Scan(&s.UIDOwner, &s.UIDInitiator, &s.ShareWith, &s.ItemType, &s.Prefix, &s.ItemSource, &s.STime, &s.Permissions, &s.ShareType, &s.State, &s.RejectedBy); err != nil { if err == sql.ErrNoRows { return nil, errtypes.NotFound(id.OpaqueId) } @@ -417,14 +417,14 @@ func (m *mgr) getReceivedByKey(ctx context.Context, key *collaboration.ShareKey) } s := conversions.DBShare{} - 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, ts.id, stime, permissions, share_type, accepted, coalesce(tr.rejected_by, '') as rejected_by FROM oc_share ts LEFT JOIN oc_share_acl tr ON (ts.id = tr.id AND tr.rejected_by = ?) WHERE (orphan = 0 or orphan IS NULL) AND uid_owner=? AND fileid_prefix=? AND item_source=? AND share_type=? AND share_with=? " + 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, ts.id, stime, permissions, share_type, accepted, coalesce(tr.rejected_by, '') as rejected_by FROM oc_share ts LEFT JOIN oc_share_acl tr ON (ts.id = tr.id AND tr.rejected_by = ?) WHERE (orphan = 0 or orphan IS NULL) AND uid_owner=? AND fileid_prefix=? AND item_source=? AND share_type=? AND share_with=? " if len(user.Groups) > 0 { query += "AND ((share_with=? AND share_type = 0) OR (share_type = 1 AND share_with in (?" + strings.Repeat(",?", len(user.Groups)-1) + ")))" } else { query += "AND (share_with=? AND share_type = 0)" } - if err := m.db.QueryRow(query, params...).Scan(&s.UIDOwner, &s.UIDInitiator, &s.ShareWith, &s.Prefix, &s.ItemSource, &s.ID, &s.STime, &s.Permissions, &s.ShareType, &s.State, &s.RejectedBy); err != nil { + if err := m.db.QueryRow(query, params...).Scan(&s.UIDOwner, &s.UIDInitiator, &s.ShareWith, &s.Prefix, &s.ItemSource, &s.ItemType, &s.ID, &s.STime, &s.Permissions, &s.ShareType, &s.State, &s.RejectedBy); err != nil { if err == sql.ErrNoRows { return nil, errtypes.NotFound(key.String()) } diff --git a/pkg/cbox/utils/conversions.go b/pkg/cbox/utils/conversions.go index 9509c008257..2f73cc6ea50 100644 --- a/pkg/cbox/utils/conversions.go +++ b/pkg/cbox/utils/conversions.go @@ -37,6 +37,7 @@ type DBShare struct { UIDInitiator string Prefix string ItemSource string + ItemType string ShareWith string Token string Expiration string @@ -111,7 +112,7 @@ func SharePermToInt(p *provider.ResourcePermissions) int { } // IntTosharePerm retrieves read/write permissions from an integer -func IntTosharePerm(p int) *provider.ResourcePermissions { +func IntTosharePerm(p int, itemType string) *provider.ResourcePermissions { switch p { case 1: return &provider.ResourcePermissions{ @@ -125,7 +126,7 @@ func IntTosharePerm(p int) *provider.ResourcePermissions { InitiateFileDownload: true, } case 15: - return &provider.ResourcePermissions{ + perm := &provider.ResourcePermissions{ ListContainer: true, ListGrants: true, ListFileVersions: true, @@ -135,14 +136,17 @@ func IntTosharePerm(p int) *provider.ResourcePermissions { GetQuota: true, InitiateFileDownload: true, - Move: true, InitiateFileUpload: true, RestoreFileVersion: true, RestoreRecycleItem: true, - CreateContainer: true, - Delete: true, - PurgeRecycle: true, } + if itemType == "folder" { + perm.CreateContainer = true + perm.Delete = true + perm.Move = true + perm.PurgeRecycle = true + } + return perm default: // TODO we may have other options, for now this is a denial return &provider.ResourcePermissions{} @@ -199,7 +203,7 @@ func ConvertToCS3Share(s DBShare) *collaboration.Share { StorageId: s.Prefix, OpaqueId: s.ItemSource, }, - Permissions: &collaboration.SharePermissions{Permissions: IntTosharePerm(s.Permissions)}, + Permissions: &collaboration.SharePermissions{Permissions: IntTosharePerm(s.Permissions, s.ItemType)}, Grantee: ExtractGrantee(s.ShareType, s.ShareWith), Owner: ExtractUserID(s.UIDOwner), Creator: ExtractUserID(s.UIDInitiator), @@ -249,7 +253,7 @@ func ConvertToCS3PublicShare(s DBShare) *link.PublicShare { StorageId: s.Prefix, OpaqueId: s.ItemSource, }, - Permissions: &link.PublicSharePermissions{Permissions: IntTosharePerm(s.Permissions)}, + Permissions: &link.PublicSharePermissions{Permissions: IntTosharePerm(s.Permissions, s.ItemType)}, Owner: ExtractUserID(s.UIDOwner), Creator: ExtractUserID(s.UIDInitiator), Token: s.Token,