From c167461b201d9942ab748f342f4e78c1244e78ad Mon Sep 17 00:00:00 2001 From: Gianmaria Del Monte <39946305+gmgigi96@users.noreply.github.com> Date: Thu, 11 May 2023 03:34:04 +0200 Subject: [PATCH] Fix creator/initiator in public and user shares (#3878) --- changelog/unreleased/fix-users-shares.md | 3 + pkg/cbox/publicshare/sql/sql.go | 40 +++++++-- pkg/cbox/share/sql/sql.go | 53 +++++++++--- pkg/cbox/utils/conversions.go | 101 +++++++++++++++++------ pkg/ocm/invite/repository/sql/sql.go | 35 ++++++-- 5 files changed, 178 insertions(+), 54 deletions(-) create mode 100644 changelog/unreleased/fix-users-shares.md diff --git a/changelog/unreleased/fix-users-shares.md b/changelog/unreleased/fix-users-shares.md new file mode 100644 index 00000000000..1fb75738a75 --- /dev/null +++ b/changelog/unreleased/fix-users-shares.md @@ -0,0 +1,3 @@ +Bugfix: Fix creator/initiator in public and user shares + +https://github.com/cs3org/reva/pull/3878 \ No newline at end of file diff --git a/pkg/cbox/publicshare/sql/sql.go b/pkg/cbox/publicshare/sql/sql.go index 4919675d4af..d06c396903d 100644 --- a/pkg/cbox/publicshare/sql/sql.go +++ b/pkg/cbox/publicshare/sql/sql.go @@ -29,6 +29,7 @@ import ( "syscall" "time" + gatewayv1beta1 "github.com/cs3org/go-cs3apis/cs3/gateway/v1beta1" 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" @@ -71,8 +72,9 @@ type config struct { } type manager struct { - c *config - db *sql.DB + c *config + db *sql.DB + client gatewayv1beta1.GatewayAPIClient } func (c *config) init() { @@ -118,9 +120,15 @@ func New(m map[string]interface{}) (publicshare.Manager, error) { return nil, err } + gw, err := pool.GetGatewayServiceClient(pool.Endpoint(c.GatewaySvc)) + if err != nil { + return nil, err + } + mgr := manager{ - c: c, - db: db, + c: c, + db: db, + client: gw, } go mgr.startJanitorRun() @@ -275,7 +283,11 @@ func (m *manager) getByToken(ctx context.Context, token string, u *user.User) (* } return nil, "", err } - return conversions.ConvertToCS3PublicShare(s), s.ShareWith, nil + share, err := conversions.ConvertToCS3PublicShare(ctx, m.client, s) + if err != nil { + return nil, "", err + } + return share, s.ShareWith, nil } func (m *manager) getByID(ctx context.Context, id *link.PublicShareId, u *user.User) (*link.PublicShare, string, error) { @@ -288,7 +300,11 @@ func (m *manager) getByID(ctx context.Context, id *link.PublicShareId, u *user.U } return nil, "", err } - return conversions.ConvertToCS3PublicShare(s), s.ShareWith, nil + share, err := conversions.ConvertToCS3PublicShare(ctx, m.client, s) + if err != nil { + return nil, "", err + } + return share, s.ShareWith, nil } func (m *manager) GetPublicShare(ctx context.Context, u *user.User, ref *link.PublicShareReference, sign bool) (*link.PublicShare, error) { @@ -385,13 +401,16 @@ func (m *manager) ListPublicShares(ctx context.Context, u *user.User, filters [] if err := rows.Scan(&s.UIDOwner, &s.UIDInitiator, &s.ShareWith, &s.Prefix, &s.ItemSource, &s.ItemType, &s.Token, &s.Expiration, &s.ShareName, &s.ID, &s.STime, &s.Permissions, &s.Quicklink, &s.Description); err != nil { continue } - cs3Share := conversions.ConvertToCS3PublicShare(s) + cs3Share, err := conversions.ConvertToCS3PublicShare(ctx, m.client, s) + if err != nil { + return nil, err + } if expired(cs3Share) { _ = m.cleanupExpiredShares() } else { if cs3Share.PasswordProtected && sign { if err := publicshare.AddSignature(cs3Share, s.ShareWith); err != nil { - return nil, err + continue } } shares = append(shares, cs3Share) @@ -448,7 +467,10 @@ func (m *manager) GetPublicShareByToken(ctx context.Context, token string, auth } return nil, err } - cs3Share := conversions.ConvertToCS3PublicShare(s) + cs3Share, err := conversions.ConvertToCS3PublicShare(ctx, m.client, s) + if err != nil { + return nil, err + } if expired(cs3Share) { if err := m.cleanupExpiredShares(); err != nil { return nil, err diff --git a/pkg/cbox/share/sql/sql.go b/pkg/cbox/share/sql/sql.go index 07cffda45d1..957b697943d 100644 --- a/pkg/cbox/share/sql/sql.go +++ b/pkg/cbox/share/sql/sql.go @@ -27,6 +27,7 @@ import ( "strings" "time" + gatewayv1beta1 "github.com/cs3org/go-cs3apis/cs3/gateway/v1beta1" 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" @@ -70,8 +71,9 @@ type config struct { } type mgr struct { - c *config - db *sql.DB + c *config + db *sql.DB + client gatewayv1beta1.GatewayAPIClient } // New returns a new share manager. @@ -87,9 +89,15 @@ func New(m map[string]interface{}) (share.Manager, error) { return nil, err } + gw, err := pool.GetGatewayServiceClient(pool.Endpoint(c.GatewaySvc)) + if err != nil { + return nil, err + } + return &mgr{ - c: c, - db: db, + c: c, + db: db, + client: gw, }, nil } @@ -183,7 +191,11 @@ func (m *mgr) getByID(ctx context.Context, id *collaboration.ShareId) (*collabor } return nil, err } - return conversions.ConvertToCS3Share(s), nil + share, err := conversions.ConvertToCS3Share(ctx, m.client, s) + if err != nil { + return nil, err + } + return share, nil } func (m *mgr) getByKey(ctx context.Context, key *collaboration.ShareKey) (*collaboration.Share, error) { @@ -199,7 +211,11 @@ func (m *mgr) getByKey(ctx context.Context, key *collaboration.ShareKey) (*colla } return nil, err } - return conversions.ConvertToCS3Share(s), nil + share, err := conversions.ConvertToCS3Share(ctx, m.client, s) + if err != nil { + return nil, err + } + return share, nil } func (m *mgr) GetShare(ctx context.Context, ref *collaboration.ShareReference) (*collaboration.Share, error) { @@ -329,7 +345,11 @@ func (m *mgr) ListShares(ctx context.Context, filters []*collaboration.Filter) ( 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)) + share, err := conversions.ConvertToCS3Share(ctx, m.client, s) + if err != nil { + continue + } + shares = append(shares, share) } if err = rows.Err(); err != nil { return nil, err @@ -382,7 +402,11 @@ func (m *mgr) ListReceivedShares(ctx context.Context, filters []*collaboration.F 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); err != nil { continue } - shares = append(shares, conversions.ConvertToCS3ReceivedShare(s)) + share, err := conversions.ConvertToCS3ReceivedShare(ctx, m.client, s) + if err != nil { + continue + } + shares = append(shares, share) } if err = rows.Err(); err != nil { return nil, err @@ -417,7 +441,11 @@ func (m *mgr) getReceivedByID(ctx context.Context, id *collaboration.ShareId) (* } return nil, err } - return conversions.ConvertToCS3ReceivedShare(s), nil + share, err := conversions.ConvertToCS3ReceivedShare(ctx, m.client, s) + if err != nil { + return nil, err + } + return share, nil } func (m *mgr) getReceivedByKey(ctx context.Context, key *collaboration.ShareKey) (*collaboration.ReceivedShare, error) { @@ -448,7 +476,12 @@ func (m *mgr) getReceivedByKey(ctx context.Context, key *collaboration.ShareKey) } return nil, err } - return conversions.ConvertToCS3ReceivedShare(s), nil + + share, err := conversions.ConvertToCS3ReceivedShare(ctx, m.client, s) + if err != nil { + return nil, err + } + return share, nil } func (m *mgr) GetReceivedShare(ctx context.Context, ref *collaboration.ShareReference) (*collaboration.ReceivedShare, error) { diff --git a/pkg/cbox/utils/conversions.go b/pkg/cbox/utils/conversions.go index 8fee7ac57a4..0c3262b5a1f 100644 --- a/pkg/cbox/utils/conversions.go +++ b/pkg/cbox/utils/conversions.go @@ -19,11 +19,14 @@ package utils import ( - "strings" + "context" + "errors" "time" + gatewayv1beta1 "github.com/cs3org/go-cs3apis/cs3/gateway/v1beta1" grouppb "github.com/cs3org/go-cs3apis/cs3/identity/group/v1beta1" userpb "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" link "github.com/cs3org/go-cs3apis/cs3/sharing/link/v1beta1" provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1" @@ -70,19 +73,27 @@ func FormatGrantee(g *provider.Grantee) (int, string) { } // ExtractGrantee retrieves the CS3API grantee from a formatted string. -func ExtractGrantee(t int, g string) *provider.Grantee { +func ExtractGrantee(ctx context.Context, gateway gatewayv1beta1.GatewayAPIClient, t int, g string) (*provider.Grantee, error) { var grantee provider.Grantee switch t { case 0: grantee.Type = provider.GranteeType_GRANTEE_TYPE_USER - grantee.Id = &provider.Grantee_UserId{UserId: ExtractUserID(g)} + user, err := ExtractUserID(ctx, gateway, g) + if err != nil { + return nil, err + } + grantee.Id = &provider.Grantee_UserId{UserId: user} case 1: grantee.Type = provider.GranteeType_GRANTEE_TYPE_GROUP - grantee.Id = &provider.Grantee_GroupId{GroupId: ExtractGroupID(g)} + group, err := ExtractGroupID(ctx, gateway, g) + if err != nil { + return nil, err + } + grantee.Id = &provider.Grantee_GroupId{GroupId: group} default: grantee.Type = provider.GranteeType_GRANTEE_TYPE_INVALID } - return &grantee + return &grantee, nil } // ResourceTypeToItem maps a resource type to a string. @@ -166,14 +177,18 @@ func FormatUserID(u *userpb.UserId) string { } // ExtractUserID retrieves a CS3API user ID from a string. -func ExtractUserID(u string) *userpb.UserId { - t := userpb.UserType_USER_TYPE_PRIMARY - if strings.HasPrefix(u, "guest:") { - t = userpb.UserType_USER_TYPE_LIGHTWEIGHT - } else if strings.Contains(u, "@") { - t = userpb.UserType_USER_TYPE_FEDERATED +func ExtractUserID(ctx context.Context, gateway gatewayv1beta1.GatewayAPIClient, u string) (*userpb.UserId, error) { + userRes, err := gateway.GetUser(ctx, &userpb.GetUserRequest{ + UserId: &userpb.UserId{OpaqueId: u}, + }) + if err != nil { + return nil, err } - return &userpb.UserId{OpaqueId: u, Type: t} + if userRes.Status.Code != rpcv1beta1.Code_CODE_OK { + return nil, errors.New(userRes.Status.Message) + } + + return userRes.User.Id, nil } // FormatGroupID formats a CS3API group ID to a string. @@ -182,15 +197,37 @@ func FormatGroupID(u *grouppb.GroupId) string { } // ExtractGroupID retrieves a CS3API group ID from a string. -func ExtractGroupID(u string) *grouppb.GroupId { - return &grouppb.GroupId{OpaqueId: u} +func ExtractGroupID(ctx context.Context, gateway gatewayv1beta1.GatewayAPIClient, u string) (*grouppb.GroupId, error) { + groupRes, err := gateway.GetGroup(ctx, &grouppb.GetGroupRequest{ + GroupId: &grouppb.GroupId{OpaqueId: u}, + }) + if err != nil { + return nil, err + } + if groupRes.Status.Code != rpcv1beta1.Code_CODE_OK { + return nil, errors.New(groupRes.Status.Message) + } + return groupRes.Group.Id, nil } // ConvertToCS3Share converts a DBShare to a CS3API collaboration share. -func ConvertToCS3Share(s DBShare) *collaboration.Share { +func ConvertToCS3Share(ctx context.Context, gateway gatewayv1beta1.GatewayAPIClient, s DBShare) (*collaboration.Share, error) { ts := &typespb.Timestamp{ Seconds: uint64(s.STime), } + owner, err := ExtractUserID(ctx, gateway, s.UIDOwner) + if err != nil { + return nil, err + } + creator, err := ExtractUserID(ctx, gateway, s.UIDInitiator) + if err != nil { + return nil, err + } + grantee, err := ExtractGrantee(ctx, gateway, s.ShareType, s.ShareWith) + if err != nil { + return nil, err + } + return &collaboration.Share{ Id: &collaboration.ShareId{ OpaqueId: s.ID, @@ -201,24 +238,28 @@ func ConvertToCS3Share(s DBShare) *collaboration.Share { OpaqueId: s.ItemSource, }, Permissions: &collaboration.SharePermissions{Permissions: IntTosharePerm(s.Permissions, s.ItemType)}, - Grantee: ExtractGrantee(s.ShareType, s.ShareWith), - Owner: ExtractUserID(s.UIDOwner), - Creator: ExtractUserID(s.UIDInitiator), + Grantee: grantee, + Owner: owner, + Creator: creator, Ctime: ts, Mtime: ts, - } + }, nil } // ConvertToCS3ReceivedShare converts a DBShare to a CS3API collaboration received share. -func ConvertToCS3ReceivedShare(s DBShare) *collaboration.ReceivedShare { +func ConvertToCS3ReceivedShare(ctx context.Context, gateway gatewayv1beta1.GatewayAPIClient, s DBShare) (*collaboration.ReceivedShare, error) { + share, err := ConvertToCS3Share(ctx, gateway, s) + if err != nil { + return nil, err + } return &collaboration.ReceivedShare{ - Share: ConvertToCS3Share(s), + Share: share, State: IntToShareState(s.State), - } + }, nil } // ConvertToCS3PublicShare converts a DBShare to a CS3API public share. -func ConvertToCS3PublicShare(s DBShare) *link.PublicShare { +func ConvertToCS3PublicShare(ctx context.Context, gateway gatewayv1beta1.GatewayAPIClient, s DBShare) (*link.PublicShare, error) { ts := &typespb.Timestamp{ Seconds: uint64(s.STime), } @@ -235,6 +276,14 @@ func ConvertToCS3PublicShare(s DBShare) *link.PublicShare { } } } + owner, err := ExtractUserID(ctx, gateway, s.UIDOwner) + if err != nil { + return nil, err + } + creator, err := ExtractUserID(ctx, gateway, s.UIDInitiator) + if err != nil { + return nil, err + } return &link.PublicShare{ Id: &link.PublicShareId{ OpaqueId: s.ID, @@ -244,8 +293,8 @@ func ConvertToCS3PublicShare(s DBShare) *link.PublicShare { OpaqueId: s.ItemSource, }, Permissions: &link.PublicSharePermissions{Permissions: IntTosharePerm(s.Permissions, s.ItemType)}, - Owner: ExtractUserID(s.UIDOwner), - Creator: ExtractUserID(s.UIDInitiator), + Owner: owner, + Creator: creator, Token: s.Token, DisplayName: s.ShareName, PasswordProtected: pwd, @@ -254,5 +303,5 @@ func ConvertToCS3PublicShare(s DBShare) *link.PublicShare { Mtime: ts, Quicklink: s.Quicklink, Description: s.Description, - } + }, nil } diff --git a/pkg/ocm/invite/repository/sql/sql.go b/pkg/ocm/invite/repository/sql/sql.go index fe27f2413a0..eccfe506a0e 100644 --- a/pkg/ocm/invite/repository/sql/sql.go +++ b/pkg/ocm/invite/repository/sql/sql.go @@ -24,12 +24,14 @@ import ( "fmt" "time" + gatewayv1beta1 "github.com/cs3org/go-cs3apis/cs3/gateway/v1beta1" userpb "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1" invitepb "github.com/cs3org/go-cs3apis/cs3/ocm/invite/v1beta1" types "github.com/cs3org/go-cs3apis/cs3/types/v1beta1" conversions "github.com/cs3org/reva/pkg/cbox/utils" "github.com/cs3org/reva/pkg/errtypes" "github.com/cs3org/reva/pkg/ocm/invite" + "github.com/cs3org/reva/pkg/rgrpc/todo/pool" "github.com/go-sql-driver/mysql" "github.com/cs3org/reva/pkg/ocm/invite/repository/registry" @@ -51,8 +53,9 @@ func init() { } type mgr struct { - c *config - db *sql.DB + c *config + db *sql.DB + client gatewayv1beta1.GatewayAPIClient } type config struct { @@ -88,9 +91,15 @@ func New(c map[string]interface{}) (invite.Repository, error) { return nil, errors.Wrap(err, "sql: error opening connection to mysql database") } + gw, err := pool.GetGatewayServiceClient(pool.Endpoint(conf.GatewaySvc)) + if err != nil { + return nil, err + } + mgr := mgr{ - c: conf, - db: db, + c: conf, + db: db, + client: gw, } return &mgr, nil } @@ -124,18 +133,22 @@ func (m *mgr) GetToken(ctx context.Context, token string) (*invitepb.InviteToken } return nil, err } - return convertToInviteToken(tkn), nil + return m.convertToInviteToken(ctx, tkn) } -func convertToInviteToken(tkn dbToken) *invitepb.InviteToken { +func (m *mgr) convertToInviteToken(ctx context.Context, tkn dbToken) (*invitepb.InviteToken, error) { + user, err := conversions.ExtractUserID(ctx, m.client, tkn.Initiator) + if err != nil { + return nil, err + } return &invitepb.InviteToken{ Token: tkn.Token, - UserId: conversions.ExtractUserID(tkn.Initiator), + UserId: user, Expiration: &types.Timestamp{ Seconds: uint64(tkn.Expiration.Unix()), }, Description: tkn.Description, - } + }, nil } func (m *mgr) ListTokens(ctx context.Context, initiator *userpb.UserId) ([]*invitepb.InviteToken, error) { @@ -152,7 +165,11 @@ func (m *mgr) ListTokens(ctx context.Context, initiator *userpb.UserId) ([]*invi if err := rows.Scan(&tkn.Token, &tkn.Initiator, &tkn.Expiration, &tkn.Description); err != nil { continue } - tokens = append(tokens, convertToInviteToken(tkn)) + token, err := m.convertToInviteToken(ctx, tkn) + if err != nil { + return nil, err + } + tokens = append(tokens, token) } return tokens, nil