diff --git a/changelog/unreleased/ocm-find-accepted-users.md b/changelog/unreleased/ocm-find-accepted-users.md new file mode 100644 index 00000000000..c9365e4f59a --- /dev/null +++ b/changelog/unreleased/ocm-find-accepted-users.md @@ -0,0 +1,3 @@ +Enhancement: Add FindAcceptedUsers method to OCM Invite API + +https://github.com/cs3org/reva/pull/1527 diff --git a/cmd/reva/ocm-share-create.go b/cmd/reva/ocm-share-create.go index 9b74a645a19..aa83d578576 100644 --- a/cmd/reva/ocm-share-create.go +++ b/cmd/reva/ocm-share-create.go @@ -19,7 +19,6 @@ package main import ( - "fmt" "io" "os" "strconv" @@ -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"}) diff --git a/go.mod b/go.mod index 01f2ca8f0c1..9521178c432 100644 --- a/go.mod +++ b/go.mod @@ -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 ) diff --git a/pkg/ocm/share/manager/json/json.go b/pkg/ocm/share/manager/json/json.go index 2f16661e88b..c5c2a3b1546 100644 --- a/pkg/ocm/share/manager/json/json.go +++ b/pkg/ocm/share/manager/json/json.go @@ -19,6 +19,7 @@ package json import ( + "bytes" "context" "encoding/json" "fmt" @@ -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" @@ -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 @@ -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 @@ -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 { @@ -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 { @@ -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 { @@ -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()) } @@ -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()) @@ -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 @@ -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 } } } @@ -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) } } } @@ -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 } } @@ -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) } @@ -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 } } } @@ -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() @@ -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")