Skip to content

Commit

Permalink
Refactor OCM shares json driver
Browse files Browse the repository at this point in the history
  • Loading branch information
ishank011 committed Mar 10, 2021
1 parent 6105bd9 commit 95b0c24
Show file tree
Hide file tree
Showing 4 changed files with 116 additions and 76 deletions.
3 changes: 3 additions & 0 deletions changelog/unreleased/ocm-find-accepted-users.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Enhancement: Add FindAcceptedUsers method to OCM Invite API

https://github.com/cs3org/reva/pull/1527
2 changes: 0 additions & 2 deletions cmd/reva/ocm-share-create.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
package main

import (
"fmt"
"io"
"os"
"strconv"
Expand Down Expand Up @@ -148,7 +147,6 @@ func ocmShareCreateCommand() *command {
return formatError(shareRes.Status)
}

fmt.Println("create share done")
t := table.NewWriter()
t.SetOutputMirror(os.Stdout)
t.AppendHeader(table.Row{"#", "Owner.Idp", "Owner.OpaqueId", "ResourceId", "Permissions", "Type", "Grantee.Idp", "Grantee.OpaqueId", "Created", "Updated"})
Expand Down
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,6 @@ go 1.13
replace (
github.com/cs3org/go-cs3apis => ../cs3apis/build/go-cs3apis
github.com/eventials/go-tus => github.com/andrewmostello/go-tus v0.0.0-20200314041820-904a9904af9a
github.com/oleiade/reflections => github.com/oleiade/reflections v1.0.1
google.golang.org/grpc => google.golang.org/grpc v1.26.0 // temporary downgrade
github.com/oleiade/reflections => github.com/oleiade/reflections v1.0.1
google.golang.org/grpc => google.golang.org/grpc v1.26.0 // temporary downgrade
)
183 changes: 111 additions & 72 deletions pkg/ocm/share/manager/json/json.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
package json

import (
"bytes"
"context"
"encoding/json"
"fmt"
Expand All @@ -43,6 +44,7 @@ import (
tokenpkg "github.com/cs3org/reva/pkg/token"
"github.com/cs3org/reva/pkg/user"
"github.com/cs3org/reva/pkg/utils"
"github.com/golang/protobuf/jsonpb"
"github.com/google/uuid"
"github.com/mitchellh/mapstructure"
"github.com/pkg/errors"
Expand Down Expand Up @@ -76,6 +78,8 @@ func New(m map[string]interface{}) (share.Manager, error) {
client: rhttp.GetHTTPClient(
rhttp.Timeout(5 * time.Second),
),
marshaler: jsonpb.Marshaler{},
unmarshaler: jsonpb.Unmarshaler{},
}

return mgr, nil
Expand Down Expand Up @@ -109,8 +113,11 @@ func loadOrCreate(file string) (*shareModel, error) {
return nil, err
}

if m.State == nil {
m.State = map[string]map[string]ocm.ShareState{}
if m.Shares == nil {
m.Shares = map[string]interface{}{}
}
if m.ReceivedShares == nil {
m.ReceivedShares = map[string]interface{}{}
}
m.file = file

Expand All @@ -119,9 +126,8 @@ func loadOrCreate(file string) (*shareModel, error) {

type shareModel struct {
file string
State map[string]map[string]ocm.ShareState `json:"state"` // map[username]map[share_id]boolean
Shares []*ocm.Share `json:"shares"`
ReceivedShares []*ocm.Share `json:"received_shares"`
Shares map[string]interface{} `json:"shares"`
ReceivedShares map[string]interface{} `json:"received_shares"`
}

type config struct {
Expand All @@ -136,10 +142,12 @@ func (c *config) init() {
}

type mgr struct {
c *config
sync.Mutex // concurrent access to the file
model *shareModel
client *http.Client
c *config
sync.Mutex // concurrent access to the file
model *shareModel
marshaler jsonpb.Marshaler
unmarshaler jsonpb.Unmarshaler
client *http.Client
}

func (m *shareModel) Save() error {
Expand Down Expand Up @@ -331,10 +339,24 @@ func (m *mgr) Share(ctx context.Context, md *provider.ResourceId, g *ocm.ShareGr
err = errors.Wrap(err, "error reading model")
return nil, err
}

if isOwnersMeshProvider {
m.model.Shares = append(m.model.Shares, s)
encShare := bytes.Buffer{}
err = m.marshaler.Marshal(&encShare, s)
if err != nil {
return nil, err
}
m.model.Shares[s.Id.OpaqueId] = encShare.String()
} else {
m.model.ReceivedShares = append(m.model.ReceivedShares, s)
encShare := bytes.Buffer{}
err = m.marshaler.Marshal(&encShare, &ocm.ReceivedShare{
Share: s,
State: ocm.ShareState_SHARE_STATE_PENDING,
})
if err != nil {
return nil, err
}
m.model.ReceivedShares[s.Id.OpaqueId] = encShare.String()
}

if err := m.model.Save(); err != nil {
Expand All @@ -355,11 +377,15 @@ func (m *mgr) getByID(ctx context.Context, id *ocm.ShareId) (*ocm.Share, error)
return nil, err
}

for _, s := range m.model.Shares {
if s.GetId().OpaqueId == id.OpaqueId {
return s, nil
if s, ok := m.model.Shares[id.OpaqueId]; ok {
var share ocm.Share
r := bytes.NewBuffer([]byte(s.(string)))
if err := m.unmarshaler.Unmarshal(r, &share); err != nil {
return nil, err
}
return &share, nil
}

return nil, errtypes.NotFound(id.String())
}

Expand All @@ -373,9 +399,14 @@ func (m *mgr) getByKey(ctx context.Context, key *ocm.ShareKey) (*ocm.Share, erro
}

for _, s := range m.model.Shares {
if (utils.UserEqual(key.Owner, s.Owner) || utils.UserEqual(key.Owner, s.Creator)) &&
utils.ResourceEqual(key.ResourceId, s.ResourceId) && utils.GranteeEqual(key.Grantee, s.Grantee) {
return s, nil
var share ocm.Share
r := bytes.NewBuffer([]byte(s.(string)))
if err := m.unmarshaler.Unmarshal(r, &share); err != nil {
continue
}
if (utils.UserEqual(key.Owner, share.Owner) || utils.UserEqual(key.Owner, share.Creator)) &&
utils.ResourceEqual(key.ResourceId, share.ResourceId) && utils.GranteeEqual(key.Grantee, share.Grantee) {
return &share, nil
}
}
return nil, errtypes.NotFound(key.String())
Expand Down Expand Up @@ -424,11 +455,15 @@ func (m *mgr) Unshare(ctx context.Context, ref *ocm.ShareReference) error {
}

user := user.ContextMustGetUser(ctx)
for i, s := range m.model.Shares {
if sharesEqual(ref, s) {
if utils.UserEqual(user.Id, s.Owner) || utils.UserEqual(user.Id, s.Creator) {
m.model.Shares[len(m.model.Shares)-1], m.model.Shares[i] = m.model.Shares[i], m.model.Shares[len(m.model.Shares)-1]
m.model.Shares = m.model.Shares[:len(m.model.Shares)-1]
for id, s := range m.model.Shares {
var share ocm.Share
r := bytes.NewBuffer([]byte(s.(string)))
if err := m.unmarshaler.Unmarshal(r, &share); err != nil {
continue
}
if sharesEqual(ref, &share) {
if utils.UserEqual(user.Id, share.Owner) || utils.UserEqual(user.Id, share.Creator) {
delete(m.model.Shares, id)
if err := m.model.Save(); err != nil {
err = errors.Wrap(err, "error saving model")
return err
Expand Down Expand Up @@ -464,20 +499,30 @@ func (m *mgr) UpdateShare(ctx context.Context, ref *ocm.ShareReference, p *ocm.S
}

user := user.ContextMustGetUser(ctx)
for i, s := range m.model.Shares {
if sharesEqual(ref, s) {
if utils.UserEqual(user.Id, s.Owner) || utils.UserEqual(user.Id, s.Creator) {
for id, s := range m.model.Shares {
var share ocm.Share
r := bytes.NewBuffer([]byte(s.(string)))
if err := m.unmarshaler.Unmarshal(r, &share); err != nil {
continue
}
if sharesEqual(ref, &share) {
if utils.UserEqual(user.Id, share.Owner) || utils.UserEqual(user.Id, share.Creator) {
now := time.Now().UnixNano()
m.model.Shares[i].Permissions = p
m.model.Shares[i].Mtime = &typespb.Timestamp{
share.Permissions = p
share.Mtime = &typespb.Timestamp{
Seconds: uint64(now / 1000000000),
Nanos: uint32(now % 1000000000),
}
encShare := bytes.Buffer{}
if err := m.marshaler.Marshal(&encShare, &share); err != nil {
return nil, err
}
m.model.Shares[id] = encShare.String()
if err := m.model.Save(); err != nil {
err = errors.Wrap(err, "error saving model")
return nil, err
}
return m.model.Shares[i], nil
return &share, nil
}
}
}
Expand All @@ -496,17 +541,22 @@ func (m *mgr) ListShares(ctx context.Context, filters []*ocm.ListOCMSharesReques

user := user.ContextMustGetUser(ctx)
for _, s := range m.model.Shares {
if utils.UserEqual(user.Id, s.Owner) || utils.UserEqual(user.Id, s.Creator) {
var share ocm.Share
r := bytes.NewBuffer([]byte(s.(string)))
if err := m.unmarshaler.Unmarshal(r, &share); err != nil {
continue
}
if utils.UserEqual(user.Id, share.Owner) || utils.UserEqual(user.Id, share.Creator) {
// no filter we return earlier
if len(filters) == 0 {
ss = append(ss, s)
ss = append(ss, &share)
} else {
// check filters
// TODO(labkode): add the rest of filters.
for _, f := range filters {
if f.Type == ocm.ListOCMSharesRequest_Filter_TYPE_RESOURCE_ID {
if s.ResourceId.StorageId == f.GetResourceId().StorageId && s.ResourceId.OpaqueId == f.GetResourceId().OpaqueId {
ss = append(ss, s)
if share.ResourceId.StorageId == f.GetResourceId().StorageId && share.ResourceId.OpaqueId == f.GetResourceId().OpaqueId {
ss = append(ss, &share)
}
}
}
Expand All @@ -528,19 +578,23 @@ func (m *mgr) ListReceivedShares(ctx context.Context) ([]*ocm.ReceivedShare, err

user := user.ContextMustGetUser(ctx)
for _, s := range m.model.ReceivedShares {
if utils.UserEqual(user.Id, s.Owner) || utils.UserEqual(user.Id, s.Creator) {
var rs ocm.ReceivedShare
r := bytes.NewBuffer([]byte(s.(string)))
if err := m.unmarshaler.Unmarshal(r, &rs); err != nil {
continue
}
share := rs.Share
if utils.UserEqual(user.Id, share.Owner) || utils.UserEqual(user.Id, share.Creator) {
// omit shares created by me
continue
}
if s.Grantee.Type == provider.GranteeType_GRANTEE_TYPE_USER && utils.UserEqual(user.Id, s.Grantee.GetUserId()) {
rs := m.convert(ctx, s)
rss = append(rss, rs)
} else if s.Grantee.Type == provider.GranteeType_GRANTEE_TYPE_GROUP {
if share.Grantee.Type == provider.GranteeType_GRANTEE_TYPE_USER && utils.UserEqual(user.Id, share.Grantee.GetUserId()) {
rss = append(rss, &rs)
} else if share.Grantee.Type == provider.GranteeType_GRANTEE_TYPE_GROUP {
// check if all user groups match this share; TODO(labkode): filter shares created by us.
for _, g := range user.Groups {
if g == s.Grantee.GetGroupId().OpaqueId {
rs := m.convert(ctx, s)
rss = append(rss, rs)
if g == share.Grantee.GetGroupId().OpaqueId {
rss = append(rss, &rs)
break
}
}
Expand All @@ -549,21 +603,6 @@ func (m *mgr) ListReceivedShares(ctx context.Context) ([]*ocm.ReceivedShare, err
return rss, nil
}

// convert must be called in a lock-controlled block.
func (m *mgr) convert(ctx context.Context, s *ocm.Share) *ocm.ReceivedShare {
rs := &ocm.ReceivedShare{
Share: s,
State: ocm.ShareState_SHARE_STATE_PENDING,
}
user := user.ContextMustGetUser(ctx)
if v, ok := m.model.State[user.Id.String()]; ok {
if state, ok := v[s.Id.String()]; ok {
rs.State = state
}
}
return rs
}

func (m *mgr) GetReceivedShare(ctx context.Context, ref *ocm.ShareReference) (*ocm.ReceivedShare, error) {
return m.getReceived(ctx, ref)
}
Expand All @@ -579,15 +618,19 @@ func (m *mgr) getReceived(ctx context.Context, ref *ocm.ShareReference) (*ocm.Re

user := user.ContextMustGetUser(ctx)
for _, s := range m.model.ReceivedShares {
if sharesEqual(ref, s) {
if s.Grantee.Type == provider.GranteeType_GRANTEE_TYPE_USER && utils.UserEqual(user.Id, s.Grantee.GetUserId()) {
rs := m.convert(ctx, s)
return rs, nil
} else if s.Grantee.Type == provider.GranteeType_GRANTEE_TYPE_GROUP {
var rs ocm.ReceivedShare
r := bytes.NewBuffer([]byte(s.(string)))
if err := m.unmarshaler.Unmarshal(r, &rs); err != nil {
continue
}
share := rs.Share
if sharesEqual(ref, share) {
if share.Grantee.Type == provider.GranteeType_GRANTEE_TYPE_USER && utils.UserEqual(user.Id, share.Grantee.GetUserId()) {
return &rs, nil
} else if share.Grantee.Type == provider.GranteeType_GRANTEE_TYPE_GROUP {
for _, g := range user.Groups {
if s.Grantee.GetGroupId().OpaqueId == g {
rs := m.convert(ctx, s)
return rs, nil
if share.Grantee.GetGroupId().OpaqueId == g {
return &rs, nil
}
}
}
Expand All @@ -602,7 +645,6 @@ func (m *mgr) UpdateReceivedShare(ctx context.Context, ref *ocm.ShareReference,
return nil, err
}

user := user.ContextMustGetUser(ctx)
m.Lock()
defer m.Unlock()

Expand All @@ -611,15 +653,12 @@ func (m *mgr) UpdateReceivedShare(ctx context.Context, ref *ocm.ShareReference,
return nil, err
}

if v, ok := m.model.State[user.Id.String()]; ok {
v[rs.Share.Id.String()] = f.GetState()
m.model.State[user.Id.String()] = v
} else {
a := map[string]ocm.ShareState{
rs.Share.Id.String(): f.GetState(),
}
m.model.State[user.Id.String()] = a
rs.State = f.GetState()
encShare := bytes.Buffer{}
if err := m.marshaler.Marshal(&encShare, rs); err != nil {
return nil, err
}
m.model.ReceivedShares[rs.Share.Id.GetOpaqueId()] = encShare.String()

if err := m.model.Save(); err != nil {
err = errors.Wrap(err, "error saving model")
Expand Down

0 comments on commit 95b0c24

Please sign in to comment.