Skip to content

Commit

Permalink
Persist mountpoints in the share managers followin the new cs3 api
Browse files Browse the repository at this point in the history
  • Loading branch information
aduffeck committed Sep 14, 2021
1 parent 0194696 commit 4bc5b90
Show file tree
Hide file tree
Showing 5 changed files with 148 additions and 53 deletions.
37 changes: 29 additions & 8 deletions pkg/share/manager/json/json.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ func loadOrCreate(file string) (*shareModel, error) {
return nil, err
}

m := &shareModel{State: j.State}
m := &shareModel{State: j.State, MountPoint: j.MountPoint}
for _, s := range j.Shares {
var decShare collaboration.Share
if err = utils.UnmarshalJSONToProtoV1([]byte(s), &decShare); err != nil {
Expand All @@ -108,24 +108,29 @@ func loadOrCreate(file string) (*shareModel, error) {
if m.State == nil {
m.State = map[string]map[string]collaboration.ShareState{}
}
if m.MountPoint == nil {
m.MountPoint = map[string]map[string]*provider.Reference{}
}

m.file = file
return m, nil
}

type shareModel struct {
file string
State map[string]map[string]collaboration.ShareState `json:"state"` // map[username]map[share_id]ShareState
Shares []*collaboration.Share `json:"shares"`
file string
State map[string]map[string]collaboration.ShareState `json:"state"` // map[username]map[share_id]ShareState
MountPoint map[string]map[string]*provider.Reference `json:"mount_point"` // map[username]map[share_id]MountPoint
Shares []*collaboration.Share `json:"shares"`
}

type jsonEncoding struct {
State map[string]map[string]collaboration.ShareState `json:"state"` // map[username]map[share_id]ShareState
Shares []string `json:"shares"`
State map[string]map[string]collaboration.ShareState `json:"state"` // map[username]map[share_id]ShareState
MountPoint map[string]map[string]*provider.Reference `json:"mount_point"` // map[username]map[share_id]MountPoint
Shares []string `json:"shares"`
}

func (m *shareModel) Save() error {
j := &jsonEncoding{State: m.State}
j := &jsonEncoding{State: m.State, MountPoint: m.MountPoint}
for _, s := range m.Shares {
encShare, err := utils.MarshalProtoV1ToJSON(s)
if err != nil {
Expand Down Expand Up @@ -420,6 +425,11 @@ func (m *mgr) convert(ctx context.Context, s *collaboration.Share) *collaboratio
rs.State = state
}
}
if v, ok := m.model.MountPoint[user.Id.String()]; ok {
if mp, ok := v[s.Id.String()]; ok {
rs.MountPoint = mp
}
}
return rs
}

Expand Down Expand Up @@ -470,6 +480,7 @@ func (m *mgr) UpdateReceivedShare(ctx context.Context, receivedShare *collaborat
}
}

// Persist state
if v, ok := m.model.State[user.Id.String()]; ok {
v[rs.Share.Id.String()] = rs.State
m.model.State[user.Id.String()] = v
Expand All @@ -480,11 +491,21 @@ func (m *mgr) UpdateReceivedShare(ctx context.Context, receivedShare *collaborat
m.model.State[user.Id.String()] = a
}

// Persist mount point
if v, ok := m.model.MountPoint[user.Id.String()]; ok {
v[rs.Share.Id.String()] = rs.MountPoint
m.model.MountPoint[user.Id.String()] = v
} else {
a := map[string]*provider.Reference{
rs.Share.Id.String(): rs.MountPoint,
}
m.model.MountPoint[user.Id.String()] = a
}

if err := m.model.Save(); err != nil {
err = errors.Wrap(err, "error saving model")
return nil, err
}
// TODO persist mount point

return rs, nil
}
26 changes: 23 additions & 3 deletions pkg/share/manager/memory/memory.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,11 @@ func init() {
// New returns a new manager.
func New(c map[string]interface{}) (share.Manager, error) {
state := map[string]map[*collaboration.ShareId]collaboration.ShareState{}
mp := map[string]map[*collaboration.ShareId]*provider.Reference{}
return &manager{
shareState: state,
lock: &sync.Mutex{},
shareState: state,
shareMountPoint: mp,
lock: &sync.Mutex{},
}, nil
}

Expand All @@ -59,6 +61,9 @@ type manager struct {
// shareState contains the share state for a user.
// map["alice"]["share-id"]state.
shareState map[string]map[*collaboration.ShareId]collaboration.ShareState
// shareMountPoint contains the mountpoint of a share for a user.
// map["alice"]["share-id"]reference.
shareMountPoint map[string]map[*collaboration.ShareId]*provider.Reference
}

func (m *manager) add(ctx context.Context, s *collaboration.Share) {
Expand Down Expand Up @@ -281,6 +286,11 @@ func (m *manager) convert(ctx context.Context, s *collaboration.Share) *collabor
rs.State = state
}
}
if v, ok := m.shareMountPoint[user.Id.String()]; ok {
if mp, ok := v[s.Id]; ok {
rs.MountPoint = mp
}
}
return rs
}

Expand Down Expand Up @@ -331,6 +341,7 @@ func (m *manager) UpdateReceivedShare(ctx context.Context, receivedShare *collab
}
}

// Persist state
if v, ok := m.shareState[user.Id.String()]; ok {
v[rs.Share.Id] = rs.State
m.shareState[user.Id.String()] = v
Expand All @@ -340,7 +351,16 @@ func (m *manager) UpdateReceivedShare(ctx context.Context, receivedShare *collab
}
m.shareState[user.Id.String()] = a
}
// TODO persist mount point
// Persist mount point
if v, ok := m.shareMountPoint[user.Id.String()]; ok {
v[rs.Share.Id] = rs.MountPoint
m.shareMountPoint[user.Id.String()] = v
} else {
a := map[*collaboration.ShareId]*provider.Reference{
rs.Share.Id: rs.MountPoint,
}
m.shareMountPoint[user.Id.String()] = a
}

return rs, nil
}
10 changes: 6 additions & 4 deletions pkg/share/manager/sql/conversions.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ package sql

import (
"context"
"strings"

grouppb "github.com/cs3org/go-cs3apis/cs3/identity/group/v1beta1"
userpb "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1"
Expand All @@ -41,7 +42,7 @@ type DBShare struct {
UIDOwner string
UIDInitiator string
ItemStorage string
ItemSource string
FileSource string
ShareWith string
Token string
Expiration string
Expand Down Expand Up @@ -232,7 +233,7 @@ func (m *mgr) convertToCS3Share(ctx context.Context, s DBShare, storageMountID s
},
ResourceId: &provider.ResourceId{
StorageId: storageMountID + "!" + s.ItemStorage,
OpaqueId: s.ItemSource,
OpaqueId: s.FileSource,
},
Permissions: &collaboration.SharePermissions{Permissions: permissions},
Grantee: grantee,
Expand All @@ -255,7 +256,8 @@ func (m *mgr) convertToCS3ReceivedShare(ctx context.Context, s DBShare, storageM
state = intToShareState(s.State)
}
return &collaboration.ReceivedShare{
Share: share,
State: state,
Share: share,
State: state,
MountPoint: &provider.Reference{Path: strings.TrimLeft(s.FileTarget, "/")},
}, nil
}
73 changes: 41 additions & 32 deletions pkg/share/manager/sql/sql.go
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ func (m *mgr) Share(ctx context.Context, md *provider.ResourceInfo, g *collabora
fileSource = 0
}

stmtString := "INSERT INTO oc_share (share_type,uid_owner,uid_initiator,item_type,item_source,file_source,permissions,stime,share_with,file_target) VALUES (?,?,?,?,?,?,?,?,?,?)"
stmtString := "INSERT INTO oc_share (share_type,uid_owner,uid_initiator,item_type,file_source,file_source,permissions,stime,share_with,file_target) VALUES (?,?,?,?,?,?,?,?,?,?)"
stmtValues := []interface{}{shareType, owner, user.Username, itemType, itemSource, fileSource, permissions, now, shareWith, targetPath}

stmt, err := m.db.Prepare(stmtString)
Expand Down Expand Up @@ -211,7 +211,7 @@ func (m *mgr) Unshare(ctx context.Context, ref *collaboration.ShareReference) er
return err
}
owner := formatUserID(key.Owner)
query = "DELETE FROM oc_share WHERE uid_owner=? AND item_source=? AND share_type=? AND share_with=? AND (uid_owner=? or uid_initiator=?)"
query = "DELETE FROM oc_share WHERE uid_owner=? AND file_source=? AND share_type=? AND share_with=? AND (uid_owner=? or uid_initiator=?)"
params = append(params, owner, key.ResourceId.StorageId, shareType, shareWith, uid, uid)
default:
return errtypes.NotFound(ref.String())
Expand Down Expand Up @@ -253,7 +253,7 @@ func (m *mgr) UpdateShare(ctx context.Context, ref *collaboration.ShareReference
return nil, err
}
owner := formatUserID(key.Owner)
query = "update oc_share set permissions=?,stime=? where (uid_owner=? or uid_initiator=?) AND item_source=? AND share_type=? AND share_with=? AND (uid_owner=? or uid_initiator=?)"
query = "update oc_share set permissions=?,stime=? where (uid_owner=? or uid_initiator=?) AND file_source=? AND share_type=? AND share_with=? AND (uid_owner=? or uid_initiator=?)"
params = append(params, permissions, time.Now().Unix(), owner, owner, key.ResourceId.StorageId, shareType, shareWith, uid, uid)
default:
return nil, errtypes.NotFound(ref.String())
Expand All @@ -272,12 +272,12 @@ func (m *mgr) UpdateShare(ctx context.Context, ref *collaboration.ShareReference

func (m *mgr) ListShares(ctx context.Context, filters []*collaboration.Filter) ([]*collaboration.Share, error) {
uid := ctxpkg.ContextMustGetUser(ctx).Username
query := "select coalesce(uid_owner, '') as uid_owner, coalesce(uid_initiator, '') as uid_initiator, coalesce(share_with, '') as share_with, coalesce(item_source, '') as item_source, id, stime, permissions, share_type FROM oc_share WHERE (uid_owner=? or uid_initiator=?) AND (share_type=? OR share_type=?)"
query := "select coalesce(uid_owner, '') as uid_owner, coalesce(uid_initiator, '') as uid_initiator, coalesce(share_with, '') as share_with, coalesce(file_source, '') as file_source, file_target, id, stime, permissions, share_type FROM oc_share WHERE (uid_owner=? or uid_initiator=?) AND (share_type=? OR share_type=?)"
var filterQuery string
params := []interface{}{uid, uid, 0, 1}
for i, f := range filters {
if f.Type == collaboration.Filter_TYPE_RESOURCE_ID {
filterQuery += "(item_source=?)"
filterQuery += "(file_source=?)"
if i != len(filters)-1 {
filterQuery += " AND "
}
Expand All @@ -299,7 +299,7 @@ func (m *mgr) ListShares(ctx context.Context, filters []*collaboration.Filter) (
var s DBShare
shares := []*collaboration.Share{}
for rows.Next() {
if err := rows.Scan(&s.UIDOwner, &s.UIDInitiator, &s.ShareWith, &s.ItemSource, &s.ID, &s.STime, &s.Permissions, &s.ShareType); err != nil {
if err := rows.Scan(&s.UIDOwner, &s.UIDInitiator, &s.ShareWith, &s.FileSource, &s.FileTarget, &s.ID, &s.STime, &s.Permissions, &s.ShareType); err != nil {
continue
}
share, err := m.convertToCS3Share(ctx, s, m.storageMountID)
Expand Down Expand Up @@ -331,7 +331,7 @@ func (m *mgr) ListReceivedShares(ctx context.Context, filters []*collaboration.F
} else { // sqlite3 upsert
homeConcat = "storages.id = 'home::' || ts.uid_owner"
}
query := "select coalesce(uid_owner, '') as uid_owner, coalesce(uid_initiator, '') as uid_initiator, coalesce(share_with, '') as share_with, coalesce(item_source, '') as item_source, ts.id, stime, permissions, share_type, accepted, storages.numeric_id FROM oc_share ts LEFT JOIN oc_storages storages ON " + homeConcat + " WHERE (uid_owner != ? AND uid_initiator != ?) "
query := "select coalesce(uid_owner, '') as uid_owner, coalesce(uid_initiator, '') as uid_initiator, coalesce(share_with, '') as share_with, coalesce(file_source, '') as file_source, file_target, ts.id, stime, permissions, share_type, accepted, storages.numeric_id FROM oc_share ts LEFT JOIN oc_storages storages ON " + homeConcat + " WHERE (uid_owner != ? AND uid_initiator != ?) "
if len(user.Groups) > 0 {
query += "AND (share_with=? OR share_with in (?" + strings.Repeat(",?", len(user.Groups)-1) + "))"
} else {
Expand All @@ -347,7 +347,7 @@ func (m *mgr) ListReceivedShares(ctx context.Context, filters []*collaboration.F
var s DBShare
shares := []*collaboration.ReceivedShare{}
for rows.Next() {
if err := rows.Scan(&s.UIDOwner, &s.UIDInitiator, &s.ShareWith, &s.ItemSource, &s.ID, &s.STime, &s.Permissions, &s.ShareType, &s.State, &s.ItemStorage); err != nil {
if err := rows.Scan(&s.UIDOwner, &s.UIDInitiator, &s.ShareWith, &s.FileSource, &s.FileTarget, &s.ID, &s.STime, &s.Permissions, &s.ShareType, &s.State, &s.ItemStorage); err != nil {
continue
}
share, err := m.convertToCS3ReceivedShare(ctx, s, m.storageMountID)
Expand Down Expand Up @@ -389,45 +389,54 @@ func (m *mgr) UpdateReceivedShare(ctx context.Context, receivedShare *collaborat
return nil, err
}

fields := []string{}
params := []interface{}{}
for i := range fieldMask.Paths {
switch fieldMask.Paths[i] {
case "state":
rs.State = receivedShare.State
fields = append(fields, "accepted=?")
switch rs.State {
case collaboration.ShareState_SHARE_STATE_REJECTED:
params = append(params, 2)
case collaboration.ShareState_SHARE_STATE_ACCEPTED:
params = append(params, 0)
}
case "mount_point":
fields = append(fields, "file_target=?")
rs.MountPoint = receivedShare.MountPoint
params = append(params, rs.MountPoint.Path)
default:
return nil, errtypes.NotSupported("updating " + fieldMask.Paths[i] + " is not supported")
}
}

var queryAccept string
switch rs.State {
case collaboration.ShareState_SHARE_STATE_REJECTED:
queryAccept = "update oc_share set accepted=2 where id=?"
case collaboration.ShareState_SHARE_STATE_ACCEPTED:
queryAccept = "update oc_share set accepted=0 where id=?"
if len(fields) == 0 {
return nil, fmt.Errorf("no valid field provided in the fieldmask")
}

if queryAccept != "" {
stmt, err := m.db.Prepare(queryAccept)
if err != nil {
return nil, err
}
_, err = stmt.Exec(rs.Share.Id.OpaqueId)
if err != nil {
return nil, err
}
query := "update oc_share set "
query += strings.Join(fields, ",")
query += " where id=?"
params = append(params, rs.Share.Id.OpaqueId)

stmt, err := m.db.Prepare(query)
if err != nil {
return nil, err
}
_, err = stmt.Exec(params...)
if err != nil {
return nil, err
}
// TODO persist mount point

return rs, nil
}

func (m *mgr) getByID(ctx context.Context, id *collaboration.ShareId) (*collaboration.Share, error) {
uid := ctxpkg.ContextMustGetUser(ctx).Username
s := 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(item_source, '') as item_source, stime, permissions, share_type FROM oc_share WHERE 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.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(file_source, '') as file_source, file_target, stime, permissions, share_type FROM oc_share WHERE 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.FileSource, &s.FileTarget, &s.STime, &s.Permissions, &s.ShareType); err != nil {
if err == sql.ErrNoRows {
return nil, errtypes.NotFound(id.OpaqueId)
}
Expand All @@ -448,8 +457,8 @@ func (m *mgr) getByKey(ctx context.Context, key *collaboration.ShareKey) (*colla
if err != nil {
return nil, err
}
query := "select coalesce(uid_owner, '') as uid_owner, coalesce(uid_initiator, '') as uid_initiator, coalesce(share_with, '') as share_with, coalesce(item_source, '') as item_source, id, stime, permissions, share_type FROM oc_share WHERE uid_owner=? 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, shareType, shareWith, uid, uid).Scan(&s.UIDOwner, &s.UIDInitiator, &s.ShareWith, &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(file_source, '') as file_source, file_target, id, stime, permissions, share_type FROM oc_share WHERE uid_owner=? AND file_source=? AND share_type=? AND share_with=? AND (uid_owner=? or uid_initiator=?)"
if err = m.db.QueryRow(query, owner, key.ResourceId.StorageId, shareType, shareWith, uid, uid).Scan(&s.UIDOwner, &s.UIDInitiator, &s.ShareWith, &s.FileSource, &s.FileTarget, &s.ID, &s.STime, &s.Permissions, &s.ShareType); err != nil {
if err == sql.ErrNoRows {
return nil, errtypes.NotFound(key.String())
}
Expand All @@ -468,13 +477,13 @@ func (m *mgr) getReceivedByID(ctx context.Context, id *collaboration.ShareId) (*
}

s := 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(item_source, '') as item_source, stime, permissions, share_type, accepted FROM oc_share ts WHERE ts.id=? "
query := "select coalesce(uid_owner, '') as uid_owner, coalesce(uid_initiator, '') as uid_initiator, coalesce(share_with, '') as share_with, coalesce(file_source, '') as file_source, file_target, stime, permissions, share_type, accepted FROM oc_share ts WHERE ts.id=? "
if len(user.Groups) > 0 {
query += "AND (share_with=? OR share_with in (?" + strings.Repeat(",?", len(user.Groups)-1) + "))"
} else {
query += "AND (share_with=?)"
}
if err := m.db.QueryRow(query, params...).Scan(&s.UIDOwner, &s.UIDInitiator, &s.ShareWith, &s.ItemSource, &s.STime, &s.Permissions, &s.ShareType, &s.State); err != nil {
if err := m.db.QueryRow(query, params...).Scan(&s.UIDOwner, &s.UIDInitiator, &s.ShareWith, &s.FileSource, &s.FileTarget, &s.STime, &s.Permissions, &s.ShareType, &s.State); err != nil {
if err == sql.ErrNoRows {
return nil, errtypes.NotFound(id.OpaqueId)
}
Expand All @@ -497,14 +506,14 @@ func (m *mgr) getReceivedByKey(ctx context.Context, key *collaboration.ShareKey)
}

s := DBShare{}
query := "select coalesce(uid_owner, '') as uid_owner, coalesce(uid_initiator, '') as uid_initiator, coalesce(share_with, '') as share_with, coalesce(item_source, '') as item_source, ts.id, stime, permissions, share_type, accepted FROM oc_share ts WHERE uid_owner=? 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(file_source, '') as file_source, file_target, ts.id, stime, permissions, share_type, accepted FROM oc_share ts WHERE uid_owner=? AND file_source=? AND share_type=? AND share_with=? "
if len(user.Groups) > 0 {
query += "AND (share_with=? OR share_with in (?" + strings.Repeat(",?", len(user.Groups)-1) + "))"
} else {
query += "AND (share_with=?)"
}

if err := m.db.QueryRow(query, params...).Scan(&s.UIDOwner, &s.UIDInitiator, &s.ShareWith, &s.ItemSource, &s.ID, &s.STime, &s.Permissions, &s.ShareType, &s.State); err != nil {
if err := m.db.QueryRow(query, params...).Scan(&s.UIDOwner, &s.UIDInitiator, &s.ShareWith, &s.FileSource, &s.FileTarget, &s.ID, &s.STime, &s.Permissions, &s.ShareType, &s.State); err != nil {
if err == sql.ErrNoRows {
return nil, errtypes.NotFound(key.String())
}
Expand Down
Loading

0 comments on commit 4bc5b90

Please sign in to comment.