Bump reva

This commit is contained in:
André Duffeck
2026-03-06 14:59:29 +01:00
parent 39bf204437
commit 2146e970ee
98 changed files with 5480 additions and 2869 deletions
@@ -25,6 +25,7 @@ import (
"github.com/mitchellh/mapstructure"
"github.com/opencloud-eu/reva/v2/pkg/appauth"
"github.com/opencloud-eu/reva/v2/pkg/appauth/manager/registry"
"github.com/opencloud-eu/reva/v2/pkg/appctx"
"github.com/opencloud-eu/reva/v2/pkg/errtypes"
"github.com/opencloud-eu/reva/v2/pkg/rgrpc"
"github.com/opencloud-eu/reva/v2/pkg/rgrpc/status"
@@ -104,8 +105,10 @@ func (s *service) UnprotectedEndpoints() []string {
}
func (s *service) GenerateAppPassword(ctx context.Context, req *appauthpb.GenerateAppPasswordRequest) (*appauthpb.GenerateAppPasswordResponse, error) {
logger := appctx.GetLogger(ctx)
pwd, err := s.am.GenerateAppPassword(ctx, req.TokenScope, req.Label, req.Expiration)
if err != nil {
logger.Debug().Err(err).Msg("error generating app password")
return &appauthpb.GenerateAppPasswordResponse{
Status: status.NewInternal(ctx, "error generating app password"),
}, nil
@@ -148,7 +151,7 @@ func (s *service) GetAppPassword(ctx context.Context, req *appauthpb.GetAppPassw
pwd, err := s.am.GetAppPassword(ctx, req.User, req.Password)
if err != nil {
return &appauthpb.GetAppPasswordResponse{
Status: status.NewInternal(ctx, "error getting app password via username/password"),
Status: status.NewStatusFromErrType(ctx, "error getting app password via username/password", err),
}, nil
}
@@ -23,8 +23,11 @@ import (
"fmt"
"net/url"
"path"
"slices"
"strings"
gateway "github.com/cs3org/go-cs3apis/cs3/gateway/v1beta1"
incoming "github.com/cs3org/go-cs3apis/cs3/ocm/incoming/v1beta1"
rpc "github.com/cs3org/go-cs3apis/cs3/rpc/v1beta1"
ocm "github.com/cs3org/go-cs3apis/cs3/sharing/ocm/v1beta1"
provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1"
@@ -332,7 +335,7 @@ func (s *svc) handleTransfer(ctx context.Context, share *ocm.ReceivedShare, tran
if !ok {
return errors.New("gateway: unable to retrieve transfer protocol")
}
sourceURI := protocol.SourceUri
sourceURI := protocol.Uri
// get the webdav endpoint of the grantee's idp
var granteeIdp string
@@ -434,11 +437,29 @@ func (s *svc) GetReceivedOCMShare(ctx context.Context, req *ocm.GetReceivedOCMSh
return res, nil
}
func (s *svc) getTransferProtocol(share *ocm.ReceivedShare) (*ocm.TransferProtocol, bool) {
func (s *svc) getTransferProtocol(share *ocm.ReceivedShare) (*ocm.WebDAVProtocol, bool) {
for _, p := range share.Protocols {
if d, ok := p.Term.(*ocm.Protocol_TransferOptions); ok {
return d.TransferOptions, true
if d, ok := p.Term.(*ocm.Protocol_WebdavOptions); ok {
if slices.Contains(d.WebdavOptions.AccessTypes, ocm.AccessType_ACCESS_TYPE_DATATX) {
return d.WebdavOptions, true
}
}
}
return nil, false
}
func (s *svc) CreateOCMIncomingShare(context.Context, *incoming.CreateOCMIncomingShareRequest) (*incoming.CreateOCMIncomingShareResponse, error) {
return nil, errtypes.NotSupported("gateway: CreateOCMIncomingShare is not supported")
}
func (s *svc) UpdateOCMIncomingShare(context.Context, *incoming.UpdateOCMIncomingShareRequest) (*incoming.UpdateOCMIncomingShareResponse, error) {
return nil, errtypes.NotSupported("gateway: UpdateOCMIncomingShare is not supported")
}
func (s *svc) DeleteOCMIncomingShare(context.Context, *incoming.DeleteOCMIncomingShareRequest) (*incoming.DeleteOCMIncomingShareResponse, error) {
return nil, errtypes.NotSupported("gateway: DeleteOCMIncomingShare is not supported")
}
func (s *svc) ListExistingOCMShares(context.Context, *ocm.ListOCMSharesRequest) (*gateway.ListExistingOCMSharesResponse, error) {
return nil, errtypes.NotSupported("gateway: ListExistingOCMShares is not supported")
}
@@ -144,7 +144,11 @@ func (s *service) GetGroupByClaim(ctx context.Context, req *grouppb.GetGroupByCl
}
func (s *service) FindGroups(ctx context.Context, req *grouppb.FindGroupsRequest) (*grouppb.FindGroupsResponse, error) {
groups, err := s.groupmgr.FindGroups(ctx, req.Filter, req.SkipFetchingMembers)
if len(req.Filters) > 1 || req.Filters[0].GetType() != grouppb.Filter_TYPE_QUERY {
return nil, fmt.Errorf("only one query filter supported")
}
groups, err := s.groupmgr.FindGroups(ctx, req.Filters[0].GetQuery(), req.SkipFetchingMembers)
if err != nil {
return &grouppb.FindGroupsResponse{
Status: status.NewInternal(ctx, "error finding groups"),
@@ -201,38 +201,6 @@ func (s *service) getWebappProtocol(share *ocm.Share) *ocmd.Webapp {
}
}
func (s *service) getDataTransferProtocol(ctx context.Context, share *ocm.Share) *ocmd.Datatx {
var size uint64
gatewayClient, err := s.gatewaySelector.Next()
if err != nil {
return nil
}
// get the path of the share
statRes, err := gatewayClient.Stat(ctx, &providerpb.StatRequest{
Ref: &providerpb.Reference{
ResourceId: share.ResourceId,
},
})
if err != nil {
return nil
}
err = s.walker.Walk(ctx, statRes.GetInfo().GetId(), func(path string, info *providerpb.ResourceInfo, err error) error {
if info.Type == providerpb.ResourceType_RESOURCE_TYPE_FILE {
size += info.Size
}
return nil
})
if err != nil {
return nil
}
return &ocmd.Datatx{
SourceURI: s.webdavURL(ctx, share),
Size: size,
}
}
func (s *service) getProtocols(ctx context.Context, share *ocm.Share) ocmd.Protocols {
var p ocmd.Protocols
for _, m := range share.AccessMethods {
@@ -242,8 +210,6 @@ func (s *service) getProtocols(ctx context.Context, share *ocm.Share) ocmd.Proto
newProtocol = s.getWebdavProtocol(ctx, share, t)
case *ocm.AccessMethod_WebappOptions:
newProtocol = s.getWebappProtocol(share)
case *ocm.AccessMethod_TransferOptions:
newProtocol = s.getDataTransferProtocol(ctx, share)
}
if newProtocol != nil {
p = append(p, newProtocol)
@@ -365,7 +365,7 @@ func (s *Service) InitiateFileUpload(ctx context.Context, req *provider.Initiate
if ifMatch != "" {
if !validateIfMatch(ifMatch, sRes.GetInfo()) {
return &provider.InitiateFileUploadResponse{
Status: status.NewFailedPrecondition(ctx, errors.New("etag mismatch"), "etag mismatch"),
Status: status.NewAborted(ctx, errors.New("etag mismatch"), "etag mismatch"),
}, nil
}
metadata["if-match"] = ifMatch
@@ -375,7 +375,7 @@ func (s *Service) InitiateFileUpload(ctx context.Context, req *provider.Initiate
metadata["if-unmodified-since"] = utils.TSToTime(ifUnmodifiedSince).Format(time.RFC3339Nano)
if !validateIfUnmodifiedSince(ifUnmodifiedSince, sRes.GetInfo()) {
return &provider.InitiateFileUploadResponse{
Status: status.NewFailedPrecondition(ctx, errors.New("resource has been modified"), "resource has been modified"),
Status: status.NewAborted(ctx, errors.New("resource has been modified"), "resource has been modified"),
}, nil
}
}
@@ -517,7 +517,7 @@ func (s *Service) CreateStorageSpace(ctx context.Context, req *provider.CreateSt
case errtypes.NotSupported:
// if trying to create a user home fall back to CreateHome
if u, ok := ctxpkg.ContextGetUser(ctx); ok && req.Type == "personal" && utils.UserEqual(req.GetOwner().GetId(), u.GetId()) {
if err := s.Storage.CreateHome(ctx); err != nil {
if err := s.Storage.CreateHome(ctx); err != nil { //nolint:staticcheck // falling back to deprecated method if the new one is not supported by the driver
st = status.NewInternal(ctx, "error creating home")
} else {
st = status.NewOK(ctx)
@@ -183,9 +183,13 @@ func (s *service) GetUserByClaim(ctx context.Context, req *userpb.GetUserByClaim
}
func (s *service) FindUsers(ctx context.Context, req *userpb.FindUsersRequest) (*userpb.FindUsersResponse, error) {
if len(req.Filters) > 1 || req.Filters[0].GetType() != userpb.Filter_TYPE_QUERY {
return nil, fmt.Errorf("only one query filter supported")
}
currentUser := revactx.ContextMustGetUser(ctx)
users, err := s.usermgr.FindUsers(ctx, req.Query, currentUser.GetId().GetTenantId(), req.SkipFetchingUserGroups)
users, err := s.usermgr.FindUsers(ctx, req.Filters[0].GetQuery(), currentUser.GetId().GetTenantId(), req.SkipFetchingUserGroups)
if err != nil {
res := &userpb.FindUsersResponse{
Status: status.NewInternal(ctx, "error finding users"),
@@ -180,10 +180,10 @@ type hijackLogger struct {
}
func (l *hijackLogger) Hijack() (net.Conn, *bufio.ReadWriter, error) {
h := l.responseLogger.w.(http.Hijacker)
h := l.w.(http.Hijacker)
conn, rw, err := h.Hijack()
if err == nil && l.responseLogger.status == 0 {
l.responseLogger.status = http.StatusSwitchingProtocols
if err == nil && l.status == 0 {
l.status = http.StatusSwitchingProtocols
}
return conn, rw, err
}
@@ -120,22 +120,9 @@ func (w *Webapp) ToOCMProtocol() *ocm.Protocol {
return ocmshare.NewWebappProtocol(w.URITemplate, utils.GetAppViewMode(w.ViewMode))
}
// Datatx contains the parameters for the Datatx protocol.
type Datatx struct {
SharedSecret string `json:"sharedSecret" validate:"required"`
SourceURI string `json:"srcUri" validate:"required"`
Size uint64 `json:"size" validate:"required"`
}
// ToOCMProtocol convert the protocol to a ocm Protocol struct.
func (w *Datatx) ToOCMProtocol() *ocm.Protocol {
return ocmshare.NewTransferProtocol(w.SourceURI, w.SharedSecret, w.Size)
}
var protocolImpl = map[string]reflect.Type{
"webdav": reflect.TypeOf(WebDAV{}),
"webapp": reflect.TypeOf(Webapp{}),
"datatx": reflect.TypeOf(Datatx{}),
}
// UnmarshalJSON implements the Unmarshaler interface.
@@ -304,7 +304,7 @@ func (h *DavHandler) Handler(s *svc) http.Handler {
sig := q.Get("signature")
expiration := q.Get("expiration")
// We restrict the pre-signed urls to downloads.
if sig != "" && expiration != "" && !(r.Method == http.MethodGet || r.Method == http.MethodHead) {
if sig != "" && expiration != "" && (r.Method != http.MethodGet && r.Method != http.MethodHead) {
w.WriteHeader(http.StatusUnauthorized)
return
}
@@ -372,7 +372,7 @@ func (h *DavHandler) Handler(s *svc) http.Handler {
}
fallthrough
case sRes.Status.Code == rpc.Code_CODE_NOT_FOUND:
log.Debug().Str("token", token).Interface("status", res.Status).Msg("resource not found")
log.Debug().Str("token", token).Interface("status", res.Status).Msg("Resource not found")
w.WriteHeader(http.StatusNotFound) // log the difference
return
case sRes.Status.Code == rpc.Code_CODE_UNAUTHENTICATED:
@@ -90,7 +90,7 @@ func (s *svc) handleDelete(ctx context.Context, w http.ResponseWriter, r *http.R
return http.StatusNoContent, nil
case res.Status.Code == rpc.Code_CODE_NOT_FOUND:
//lint:ignore ST1005 mimic the exact oc10 error message
return http.StatusNotFound, errors.New("Resource not found")
return http.StatusNotFound, errors.New("Resource not found") //nolint:staticcheck
case res.Status.Code == rpc.Code_CODE_PERMISSION_DENIED:
status = http.StatusForbidden
if lockID := utils.ReadPlainFromOpaque(res.Opaque, "lockid"); lockID != "" {
@@ -110,7 +110,7 @@ func (s *svc) handleDelete(ctx context.Context, w http.ResponseWriter, r *http.R
// TODO hide permission failed for users without access in every kind of request
// TODO should this be done in the driver?
//lint:ignore ST1005 mimic the exact oc10 error message
return http.StatusNotFound, errors.New("Resource not found")
return http.StatusNotFound, errors.New("Resource not found") //nolint:staticcheck
}
return status, errors.New("") // mimic the oc10 error messages which have an empty message in this case
case res.Status.Code == rpc.Code_CODE_INTERNAL && res.Status.Message == "can't delete mount path":
@@ -615,27 +615,27 @@ func writeLockInfo(w io.Writer, token string, ld LockDetails) (int, error) {
lockdiscovery.WriteString("<d:prop xmlns:d=\"DAV:\" xmlns:oc=\"http://owncloud.org/ns\"><d:lockdiscovery><d:activelock>\n")
lockdiscovery.WriteString(" <d:locktype><d:write/></d:locktype>\n")
lockdiscovery.WriteString(" <d:lockscope><d:exclusive/></d:lockscope>\n")
lockdiscovery.WriteString(fmt.Sprintf(" <d:depth>%s</d:depth>\n", depth))
fmt.Fprintf(&lockdiscovery, " <d:depth>%s</d:depth>\n", depth)
if ld.OwnerXML != "" {
lockdiscovery.WriteString(fmt.Sprintf(" <d:owner>%s</d:owner>\n", ld.OwnerXML))
fmt.Fprintf(&lockdiscovery, " <d:owner>%s</d:owner>\n", ld.OwnerXML)
}
if ld.Duration > 0 {
timeout := ld.Duration / time.Second
lockdiscovery.WriteString(fmt.Sprintf(" <d:timeout>Second-%d</d:timeout>\n", timeout))
fmt.Fprintf(&lockdiscovery, " <d:timeout>Second-%d</d:timeout>\n", timeout)
} else {
lockdiscovery.WriteString(" <d:timeout>Infinite</d:timeout>\n")
}
if token != "" {
lockdiscovery.WriteString(fmt.Sprintf(" <d:locktoken><d:href>%s</d:href></d:locktoken>\n", prop.Escape(token)))
fmt.Fprintf(&lockdiscovery, " <d:locktoken><d:href>%s</d:href></d:locktoken>\n", prop.Escape(token))
}
if href != "" {
lockdiscovery.WriteString(fmt.Sprintf(" <d:lockroot><d:href>%s</d:href></d:lockroot>\n", prop.Escape(href)))
fmt.Fprintf(&lockdiscovery, " <d:lockroot><d:href>%s</d:href></d:lockroot>\n", prop.Escape(href))
}
if ld.OwnerName != "" {
lockdiscovery.WriteString(fmt.Sprintf(" <oc:ownername>%s</oc:ownername>\n", prop.Escape(ld.OwnerName)))
fmt.Fprintf(&lockdiscovery, " <oc:ownername>%s</oc:ownername>\n", prop.Escape(ld.OwnerName))
}
if !ld.Locktime.IsZero() {
lockdiscovery.WriteString(fmt.Sprintf(" <oc:locktime>%s</oc:locktime>\n", prop.Escape(ld.Locktime.Format(time.RFC3339))))
fmt.Fprintf(&lockdiscovery, " <oc:locktime>%s</oc:locktime>\n", prop.Escape(ld.Locktime.Format(time.RFC3339)))
}
lockdiscovery.WriteString("</d:activelock></d:lockdiscovery></d:prop>")
@@ -63,7 +63,7 @@ func (s *svc) handlePathMkcol(w http.ResponseWriter, r *http.Request, ns string)
case sr.Status.Code == rpc.Code_CODE_OK:
// https://www.rfc-editor.org/rfc/rfc4918#section-9.3.1:
// 405 (Method Not Allowed) - MKCOL can only be executed on an unmapped URL.
return http.StatusMethodNotAllowed, fmt.Errorf("The resource you tried to create already exists")
return http.StatusMethodNotAllowed, fmt.Errorf("The resource you tried to create already exists") //nolint:staticcheck
case sr.Status.Code == rpc.Code_CODE_ABORTED:
return http.StatusPreconditionFailed, errtypes.NewErrtypeFromStatus(sr.Status)
case sr.Status.Code != rpc.Code_CODE_NOT_FOUND:
@@ -133,7 +133,7 @@ func (s *svc) handleMkcol(ctx context.Context, w http.ResponseWriter, r *http.Re
// This should never happen because if the parent collection does not exist we should
// get a Code_CODE_FAILED_PRECONDITION. We play stupid and return what the response gave us
//lint:ignore ST1005 mimic the exact oc10 error message
return http.StatusNotFound, errors.New("Resource not found")
return http.StatusNotFound, errors.New("Resource not found") //nolint:staticcheck
case res.Status.Code == rpc.Code_CODE_PERMISSION_DENIED:
// check if user has access to parent
sRes, err := client.Stat(ctx, &provider.StatRequest{Ref: &provider.Reference{
@@ -148,7 +148,7 @@ func (s *svc) handleMkcol(ctx context.Context, w http.ResponseWriter, r *http.Re
// TODO hide permission failed for users without access in every kind of request
// TODO should this be done in the driver?
//lint:ignore ST1005 mimic the exact oc10 error message
return http.StatusNotFound, errors.New("Resource not found")
return http.StatusNotFound, errors.New("Resource not found") //nolint:staticcheck
}
return http.StatusForbidden, errors.New(sRes.Status.Message)
case res.Status.Code == rpc.Code_CODE_ABORTED:
@@ -163,7 +163,7 @@ func (s *svc) handleMkcol(ctx context.Context, w http.ResponseWriter, r *http.Re
// https://www.rfc-editor.org/rfc/rfc4918#section-9.3.1:
// 405 (Method Not Allowed) - MKCOL can only be executed on an unmapped URL.
//lint:ignore ST1005 mimic the exact oc10 error message
return http.StatusMethodNotAllowed, errors.New("The resource you tried to create already exists")
return http.StatusMethodNotAllowed, errors.New("The resource you tried to create already exists") //nolint:staticcheck
}
return rstatus.HTTPStatusFromCode(res.Status.Code), errtypes.NewErrtypeFromStatus(res.Status)
}
@@ -849,7 +849,7 @@ func (p *Handler) getSpaceResourceInfos(ctx context.Context, w http.ResponseWrit
}
func metadataKeysWithPrefix(prefix string, keys []string) []string {
fullKeys := []string{}
fullKeys := make([]string, 0, len(keys))
for _, key := range keys {
fullKeys = append(fullKeys, fmt.Sprintf("%s.%s", prefix, key))
}
@@ -340,7 +340,7 @@ func (s *svc) formatProppatchResponse(ctx context.Context, acceptedProps []xml.N
}
if len(acceptedProps) > 0 {
propstatBody := []prop.PropertyXML{}
propstatBody := make([]prop.PropertyXML, 0, len(acceptedProps))
for i := range acceptedProps {
propstatBody = append(propstatBody, prop.EscapedNS(acceptedProps[i].Space, acceptedProps[i].Local, ""))
}
@@ -351,7 +351,7 @@ func (s *svc) formatProppatchResponse(ctx context.Context, acceptedProps []xml.N
}
if len(removedProps) > 0 {
propstatBody := []prop.PropertyXML{}
propstatBody := make([]prop.PropertyXML, 0, len(removedProps))
for i := range removedProps {
propstatBody = append(propstatBody, prop.EscapedNS(removedProps[i].Space, removedProps[i].Local, ""))
}
@@ -24,7 +24,6 @@ import (
"net/http"
rpcv1beta1 "github.com/cs3org/go-cs3apis/cs3/rpc/v1beta1"
provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1"
providerv1beta1 "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1"
"github.com/opencloud-eu/reva/v2/internal/http/services/owncloud/ocdav/net"
"github.com/opencloud-eu/reva/v2/internal/http/services/owncloud/ocdav/propfind"
@@ -100,7 +99,7 @@ func (s *svc) doFilterFiles(w http.ResponseWriter, r *http.Request, ff *reportFi
return
}
infos := make([]*provider.ResourceInfo, 0, len(favorites))
infos := make([]*providerv1beta1.ResourceInfo, 0, len(favorites))
for i := range favorites {
statRes, err := client.Stat(ctx, &providerv1beta1.StatRequest{Ref: &providerv1beta1.Reference{ResourceId: favorites[i]}})
if err != nil {
@@ -179,14 +178,15 @@ func readReport(r io.Reader) (rep *report, status int, err error) {
}
if v, ok := t.(xml.StartElement); ok {
if v.Name.Local == elementNameSearchFiles {
switch v.Name.Local {
case elementNameSearchFiles:
var repSF reportSearchFiles
err = decoder.DecodeElement(&repSF, &v)
if err != nil {
return nil, http.StatusBadRequest, err
}
rep.SearchFiles = &repSF
} else if v.Name.Local == elementNameFilterFiles {
case elementNameFilterFiles:
var repFF reportFilterFiles
err = decoder.DecodeElement(&repFF, &v)
if err != nil {
@@ -384,7 +384,7 @@ func (s *svc) performHTTPPush(ctx context.Context, r *http.Request, w http.Respo
defer httpDownloadRes.Body.Close()
if httpDownloadRes.StatusCode != http.StatusOK {
w.WriteHeader(httpDownloadRes.StatusCode)
return fmt.Errorf("Remote PUT returned status code %d", httpDownloadRes.StatusCode)
return fmt.Errorf("remote PUT returned status code %d", httpDownloadRes.StatusCode)
}
// send performance markers periodically every PerfMarkerResponseTime (5 seconds unless configured)
@@ -13,14 +13,11 @@ type Validator func(string) error
// ValidatorsFromConfig returns the configured Validators
func ValidatorsFromConfig(c *config.Config) []Validator {
// we always want to exclude empty names
vals := []Validator{notEmpty()}
// forbidden characters
vals = append(vals, doesNotContain(c.NameValidation.InvalidChars))
// max length
vals = append(vals, isShorterThan(c.NameValidation.MaxLength))
vals := []Validator{
notEmpty(), // we always want to exclude empty names
doesNotContain(c.NameValidation.InvalidChars), // forbidden characters
isShorterThan(c.NameValidation.MaxLength), // max length
}
return vals
}
@@ -66,7 +66,17 @@ func (h *Handler) FindSharees(w http.ResponseWriter, r *http.Request) {
response.WriteOCSError(w, r, response.MetaServerError.StatusCode, "error getting gateway grpc client", err)
return
}
usersRes, err := gwc.FindUsers(r.Context(), &userpb.FindUsersRequest{Query: term, SkipFetchingUserGroups: true})
usersRes, err := gwc.FindUsers(r.Context(), &userpb.FindUsersRequest{
Filters: []*userpb.Filter{
{
Type: userpb.Filter_TYPE_QUERY,
Term: &userpb.Filter_Query{
Query: term,
},
},
},
SkipFetchingUserGroups: true,
})
if err != nil {
response.WriteOCSError(w, r, response.MetaServerError.StatusCode, "error searching users", err)
return
@@ -106,7 +116,16 @@ func (h *Handler) FindSharees(w http.ResponseWriter, r *http.Request) {
}
}
groupsRes, err := gwc.FindGroups(r.Context(), &grouppb.FindGroupsRequest{Filter: term, SkipFetchingMembers: true})
groupsRes, err := gwc.FindGroups(r.Context(), &grouppb.FindGroupsRequest{
Filters: []*grouppb.Filter{
{
Type: grouppb.Filter_TYPE_QUERY,
Term: &grouppb.Filter_Query{
Query: term,
},
},
},
SkipFetchingMembers: true})
if err != nil {
response.WriteOCSError(w, r, response.MetaServerError.StatusCode, "error searching groups", err)
return
@@ -49,7 +49,6 @@ import (
"google.golang.org/protobuf/types/known/fieldmaskpb"
ocm "github.com/cs3org/go-cs3apis/cs3/sharing/ocm/v1beta1"
ocmv1beta1 "github.com/cs3org/go-cs3apis/cs3/sharing/ocm/v1beta1"
"github.com/jellydator/ttlcache/v2"
"github.com/opencloud-eu/reva/v2/internal/http/services/owncloud/ocs/config"
"github.com/opencloud-eu/reva/v2/internal/http/services/owncloud/ocs/response"
@@ -1305,8 +1304,8 @@ func (h *Handler) addFileInfo(ctx context.Context, s *conversions.ShareData, inf
s.ItemSource = storagespace.FormatResourceID(info.Id)
s.FileSource = s.ItemSource
s.Path = path.Join("/", info.Path)
switch {
case h.sharePrefix == "/":
switch h.sharePrefix {
case "/":
s.FileTarget = info.Path
client, err := h.getClient()
if err == nil {
@@ -1627,13 +1626,13 @@ func mapState(state collaboration.ShareState) int {
return mapped
}
func mapOCMState(state ocmv1beta1.ShareState) int {
func mapOCMState(state ocm.ShareState) int {
switch state {
case ocmv1beta1.ShareState_SHARE_STATE_PENDING:
case ocm.ShareState_SHARE_STATE_PENDING:
return ocsStatePending
case ocmv1beta1.ShareState_SHARE_STATE_ACCEPTED:
case ocm.ShareState_SHARE_STATE_ACCEPTED:
return ocsStateAccepted
case ocmv1beta1.ShareState_SHARE_STATE_REJECTED:
case ocm.ShareState_SHARE_STATE_REJECTED:
return ocsStateRejected
default:
return ocsStateUnknown
@@ -1657,18 +1656,18 @@ func getStateFilter(s string) collaboration.ShareState {
return stateFilter
}
func getOCMStateFilter(s string) ocmv1beta1.ShareState {
func getOCMStateFilter(s string) ocm.ShareState {
switch s {
case "all":
return ocsStateUnknown // no filter
case "0": // accepted
return ocmv1beta1.ShareState_SHARE_STATE_ACCEPTED
return ocm.ShareState_SHARE_STATE_ACCEPTED
case "1": // pending
return ocmv1beta1.ShareState_SHARE_STATE_PENDING
return ocm.ShareState_SHARE_STATE_PENDING
case "2": // rejected
return ocmv1beta1.ShareState_SHARE_STATE_REJECTED
return ocm.ShareState_SHARE_STATE_REJECTED
default:
return ocmv1beta1.ShareState_SHARE_STATE_ACCEPTED
return ocm.ShareState_SHARE_STATE_ACCEPTED
}
}
@@ -117,11 +117,11 @@ func (h *Handler) GetUsers(w http.ResponseWriter, r *http.Request) {
}
var user *cs3identity.User
switch {
case userid == "":
switch userid {
case "":
response.WriteOCSError(w, r, response.MetaBadRequest.StatusCode, "missing username", fmt.Errorf("missing username"))
return
case userid == currentUser.Username:
case currentUser.Username:
user = currentUser
default:
// FIXME allow fetching other users info? only for admins
+3 -2
View File
@@ -335,12 +335,13 @@ func getAppURLs(c *config) (map[string]map[string]string, error) {
var appURLs map[string]map[string]string
if discRes.StatusCode == http.StatusOK {
switch discRes.StatusCode {
case http.StatusOK:
appURLs, err = parseWopiDiscovery(discRes.Body)
if err != nil {
return nil, errors.Wrap(err, "error parsing wopi discovery response")
}
} else if discRes.StatusCode == http.StatusNotFound {
case http.StatusNotFound:
// this may be a bridge-supported app
discReq, err = http.NewRequest("GET", c.AppIntURL, nil)
if err != nil {
+1 -1
View File
@@ -139,7 +139,7 @@ func (m *manager) ListSupportedMimeTypes(ctx context.Context) ([]*registrypb.Mim
m.RLock()
defer m.RUnlock()
res := []*registrypb.MimeTypeInfo{}
res := make([]*registrypb.MimeTypeInfo, 0, len(m.config.MimeTypes))
for _, mime := range m.config.MimeTypes {
res = append(res, &registrypb.MimeTypeInfo{
MimeType: mime.MimeType,
+1 -1
View File
@@ -175,7 +175,7 @@ func (mgr *jsonManager) ListAppPasswords(ctx context.Context) ([]*apppb.AppPassw
userID := ctxpkg.ContextMustGetUser(ctx).GetId()
mgr.Lock()
defer mgr.Unlock()
appPasswords := []*apppb.AppPassword{}
appPasswords := make([]*apppb.AppPassword, 0, len(mgr.passwords[userID.String()]))
for _, pw := range mgr.passwords[userID.String()] {
appPasswords = append(appPasswords, pw)
}
@@ -4,6 +4,7 @@ import (
"context"
"encoding/json"
"fmt"
"math/rand"
"strings"
"sync"
"time"
@@ -37,10 +38,12 @@ func init() {
}
type manager struct {
sync.RWMutex // for lazy initialization
mds metadata.Storage
generator PasswordGenerator
initialized bool
sync.RWMutex // for lazy initialization
mds metadata.Storage
generator PasswordGenerator
uTimeUpdateInterval time.Duration
updateRetryCount int
initialized bool
}
type config struct {
@@ -50,6 +53,10 @@ type config struct {
MachineAuthAPIKey string `mapstructure:"machine_auth_apikey"`
Generator string `mapstructure:"password_generator"`
GeneratorConfig map[string]any `mapstructure:"generator_config"`
// Time interval in seconds to update the UTime of a token when calling GetAppPassword. Default is 5 min.
// For testing set this -1 to disable automatic updates.
UTimeUpdateInterval int `mapstructure:"utime_update_interval_seconds"`
UpdateRetryCount int `mapstructure:"update_retry_count"`
}
type updaterFunc func(map[string]*apppb.AppPassword) (map[string]*apppb.AppPassword, error)
@@ -82,6 +89,19 @@ func New(m map[string]any) (appauth.Manager, error) {
if c.Generator == "" {
c.Generator = "diceware"
}
if c.UpdateRetryCount <= 0 {
c.UpdateRetryCount = 5
}
var updateInterval time.Duration
switch c.UTimeUpdateInterval {
case -1:
updateInterval = 0
case 0:
updateInterval = 5 * time.Minute
default:
updateInterval = time.Duration(c.UTimeUpdateInterval) * time.Second
}
var pwgen PasswordGenerator
var err error
@@ -103,33 +123,39 @@ func New(m map[string]any) (appauth.Manager, error) {
return nil, err
}
return NewWithOptions(cs3, pwgen)
return NewWithOptions(cs3, pwgen, updateInterval, c.UpdateRetryCount)
}
func NewWithOptions(mds metadata.Storage, generator PasswordGenerator) (*manager, error) {
func NewWithOptions(mds metadata.Storage, generator PasswordGenerator, uTimeUpdateInterval time.Duration, updateRetries int) (*manager, error) {
return &manager{
mds: mds,
generator: generator,
mds: mds,
generator: generator,
uTimeUpdateInterval: uTimeUpdateInterval,
updateRetryCount: updateRetries,
}, nil
}
// GenerateAppPassword creates a password with specified scope to be used by
// third-party applications.
func (m *manager) GenerateAppPassword(ctx context.Context, scope map[string]*authpb.Scope, label string, expiration *typespb.Timestamp) (*apppb.AppPassword, error) {
logger := appctx.GetLogger(ctx)
ctx, span := appctx.GetTracerProvider(ctx).Tracer(tracerName).Start(ctx, "GenerateAppPassword")
defer span.End()
if err := m.initialize(ctx); err != nil {
logger.Error().Err(err).Msg("initializing appauth manager failed")
span.RecordError(err)
span.SetStatus(codes.Error, err.Error())
return nil, err
}
token, err := m.generator.GeneratePassword()
if err != nil {
logger.Debug().Err(err).Msg("error generating new password")
return nil, errors.Wrap(err, "error creating new token")
}
tokenHashed, err := argon2id.CreateHash(token, argon2id.DefaultParams)
if err != nil {
logger.Debug().Err(err).Msg("error generating password hash")
return nil, errors.Wrap(err, "error creating new token")
}
@@ -137,6 +163,7 @@ func (m *manager) GenerateAppPassword(ctx context.Context, scope map[string]*aut
if user, ok := ctxpkg.ContextGetUser(ctx); ok {
userID = user.GetId()
} else {
logger.Debug().Err(err).Msg("no user in context")
return nil, errtypes.BadRequest("no user in context")
}
@@ -156,12 +183,13 @@ func (m *manager) GenerateAppPassword(ctx context.Context, scope map[string]*aut
id := uuid.New().String()
err = m.updateWithRetry(ctx, 5, true, userID, func(a map[string]*apppb.AppPassword) (map[string]*apppb.AppPassword, error) {
err = m.updateWithRetry(ctx, m.updateRetryCount, true, userID, func(a map[string]*apppb.AppPassword) (map[string]*apppb.AppPassword, error) {
a[id] = appPass
return a, nil
})
if err != nil {
logger.Debug().Err(err).Msg("failed to store new app password")
return nil, err
}
@@ -248,7 +276,7 @@ func (m *manager) InvalidateAppPassword(ctx context.Context, secretOrId string)
return a, errtypes.NotFound("password not found")
}
err := m.updateWithRetry(ctx, 5, false, userID, updater)
err := m.updateWithRetry(ctx, m.updateRetryCount, false, userID, updater)
if err != nil {
log.Error().Err(err).Msg("getUserAppPasswords failed")
return errtypes.NotFound("password not found")
@@ -291,8 +319,8 @@ func (m *manager) GetAppPassword(ctx context.Context, user *userpb.UserId, secre
matchedID = id
// password not expired
// Updating the Utime will cause an Upload for every single GetAppPassword request. We are limiting this to one
// update per 5 minutes otherwise this backend will become unusable.
if time.Since(utils.TSToTime(pw.Utime)) > 5*time.Minute {
// update per 'uTimeUpdateInterval' (default 5 min) otherwise this backend will become unusable.
if time.Since(utils.TSToTime(pw.Utime)) > m.uTimeUpdateInterval {
a[id].Utime = utils.TSNow()
return a, nil
}
@@ -302,7 +330,7 @@ func (m *manager) GetAppPassword(ctx context.Context, user *userpb.UserId, secre
return nil, errtypes.NotFound("password not found")
}
err := m.updateWithRetry(ctx, 5, false, user, updater)
err := m.updateWithRetry(ctx, m.updateRetryCount, false, user, updater)
switch {
case err == nil:
fallthrough
@@ -317,6 +345,7 @@ func (m *manager) GetAppPassword(ctx context.Context, user *userpb.UserId, secre
func (m *manager) initialize(ctx context.Context) error {
_, span := appctx.GetTracerProvider(ctx).Tracer(tracerName).Start(ctx, "initialize")
logger := appctx.GetLogger(ctx)
defer span.End()
if m.initialized {
span.SetStatus(codes.Ok, "already initialized")
@@ -332,6 +361,7 @@ func (m *manager) initialize(ctx context.Context) error {
}
ctx = context.Background()
ctx = appctx.WithLogger(ctx, logger)
err := m.mds.Init(ctx, "jsoncs3-appauth-data")
if err != nil {
span.RecordError(err)
@@ -343,6 +373,7 @@ func (m *manager) initialize(ctx context.Context) error {
}
func (m *manager) updateWithRetry(ctx context.Context, retries int, createIfNotFound bool, userid *userpb.UserId, updater updaterFunc) error {
log := appctx.GetLogger(ctx)
_, span := appctx.GetTracerProvider(ctx).Tracer(tracerName).Start(ctx, "initialize")
defer span.End()
@@ -355,6 +386,12 @@ func (m *manager) updateWithRetry(ctx context.Context, retries int, createIfNotF
// retry for the specified number of times, then error out
for i := 0; i < retries && retry; i++ {
if i > 0 {
// if we're retrying, wait a bit before the next try
jitter := time.Duration(rand.Int63n(int64(100 * time.Millisecond)))
time.Sleep(jitter + 100*time.Millisecond)
}
etag, userAppPasswords, err = m.getUserAppPasswords(ctx, userid)
switch err.(type) {
case nil:
@@ -363,11 +400,18 @@ func (m *manager) updateWithRetry(ctx context.Context, retries int, createIfNotF
if createIfNotFound {
userAppPasswords = map[string]*apppb.AppPassword{}
} else {
log.Debug().Err(err).Msg("getUserAppPasswords failed (not found)")
span.RecordError(err)
span.SetStatus(codes.Error, "downloading app tokens failed")
return err
}
case errtypes.TooEarly:
// Ideally this should never happen as we disable asynchronous uploads for the metadata storage.
log.Debug().Err(err).Int("try", i).Msg("getUserAppPasswords failed (too early, retrying)")
retry = true
continue
default:
log.Debug().Err(err).Msg("getUserAppPasswords failed")
span.RecordError(err)
span.SetStatus(codes.Error, "downloading app tokens failed")
return err
@@ -382,17 +426,20 @@ func (m *manager) updateWithRetry(ctx context.Context, retries int, createIfNotF
switch err.(type) {
case nil:
retry = false
case errtypes.PreconditionFailed:
case errtypes.Aborted:
log.Debug().Err(err).Int("attempt", i).Msg("updateUserAppPassword failed (retrying)")
retry = true
default:
log.Debug().Err(err).Int("attempt", i).Msg("updateUserAppPassword failed (not retrying)")
span.RecordError(err)
span.SetStatus(codes.Error, err.Error())
return err
}
}
if retry {
log.Debug().Err(err).Msg("updateUserAppPassword failed")
span.RecordError(err)
span.SetStatus(codes.Error, "updating app tokens failed")
span.SetStatus(codes.Error, "updating app token failed")
return err
}
return nil
@@ -424,7 +471,7 @@ func (m *manager) updateUserAppPassword(ctx context.Context, userid *userpb.User
if err != nil {
span.RecordError(err)
span.SetStatus(codes.Error, err.Error())
log.Debug().Err(err).Msg("persisting provider cache failed")
log.Debug().Err(err).Msg("failed to upload AppPasswword")
return err
}
return nil
+1 -1
View File
@@ -50,7 +50,7 @@ type reg struct {
}
func (r *reg) ListProviders(ctx context.Context) ([]*registrypb.ProviderInfo, error) {
providers := []*registrypb.ProviderInfo{}
providers := make([]*registrypb.ProviderInfo, 0, len(r.rules))
for k, v := range r.rules {
providers = append(providers, &registrypb.ProviderInfo{
ProviderType: k,
+2 -2
View File
@@ -404,7 +404,7 @@ func (m *mgr) getReceivedByID(ctx context.Context, id *collaboration.ShareId) (*
user := ctxpkg.ContextMustGetUser(ctx)
uid := conversions.FormatUserID(user.Id)
params := []interface{}{uid, id.OpaqueId, uid}
params := []interface{}{uid, id.OpaqueId, uid} // nolint:prealloc
for _, v := range user.Groups {
params = append(params, v)
}
@@ -438,7 +438,7 @@ func (m *mgr) getReceivedByKey(ctx context.Context, key *collaboration.ShareKey)
uid := conversions.FormatUserID(user.Id)
shareType, shareWith := conversions.FormatGrantee(key.Grantee)
params := []interface{}{uid, conversions.FormatUserID(key.Owner), key.GetResourceId().SpaceId, key.ResourceId.OpaqueId, shareType, shareWith, shareWith}
params := []interface{}{uid, conversions.FormatUserID(key.Owner), key.GetResourceId().SpaceId, key.ResourceId.OpaqueId, shareType, shareWith, shareWith} // nolint:prealloc
for _, v := range user.Groups {
params = append(params, v)
}
+1 -4
View File
@@ -265,10 +265,7 @@ func ConvertToCS3PublicShare(ctx context.Context, gateway gatewayv1beta1.Gateway
ts := &typespb.Timestamp{
Seconds: uint64(s.STime),
}
pwd := false
if s.ShareWith != "" {
pwd = true
}
pwd := s.ShareWith != ""
var expires *typespb.Timestamp
if s.Expiration != "" {
t, err := time.Parse("2006-01-02 15:04:05", s.Expiration)
+5 -4
View File
@@ -240,7 +240,8 @@ func CS3Share2ShareData(ctx context.Context, share *collaboration.Share) *ShareD
UIDFileOwner: LocalUserIDToString(share.GetOwner()),
}
if share.Grantee.Type == provider.GranteeType_GRANTEE_TYPE_USER {
switch share.Grantee.Type {
case provider.GranteeType_GRANTEE_TYPE_USER:
sd.ShareType = ShareTypeUser
sd.ShareWith = LocalUserIDToString(share.Grantee.GetUserId())
shareType := share.GetGrantee().GetUserId().GetType()
@@ -249,7 +250,7 @@ func CS3Share2ShareData(ctx context.Context, share *collaboration.Share) *ShareD
} else {
sd.ShareWithUserType = ShareWithUserTypeUser
}
} else if share.Grantee.Type == provider.GranteeType_GRANTEE_TYPE_GROUP {
case provider.GranteeType_GRANTEE_TYPE_GROUP:
sd.ShareType = ShareTypeGroup
sd.ShareWith = LocalGroupIDToString(share.Grantee.GetGroupId())
}
@@ -343,8 +344,8 @@ func ReceivedOCMShare2ShareData(share *ocm.ReceivedShare, path string) (*ShareDa
ShareType: ShareTypeFederatedCloudShare,
Path: shareTarget,
FileTarget: shareTarget,
MimeType: mime.Detect(share.ResourceType == provider.ResourceType_RESOURCE_TYPE_CONTAINER, share.Name),
ItemType: ResourceType(share.ResourceType).String(),
MimeType: mime.Detect(share.ResourceType == provider.ResourceType_RESOURCE_TYPE_CONTAINER, share.Name), //nolint:staticcheck // we will update our ocm implementation later
ItemType: ResourceType(share.ResourceType).String(), //nolint:staticcheck // we will update our ocm implementation later
ItemSource: storagespace.FormatResourceID(&provider.ResourceId{
StorageId: utils.OCMStorageProviderID,
SpaceId: share.Id.OpaqueId,
+1 -1
View File
@@ -52,7 +52,7 @@ const (
var (
// ErrPermissionNotInRange defines a permission specific error.
ErrPermissionNotInRange = fmt.Errorf("The provided permission is not between %d and %d", PermissionMinInput, PermissionMaxInput)
ErrPermissionNotInRange = fmt.Errorf("the provided permission is not between %d and %d", PermissionMinInput, PermissionMaxInput)
// ErrZeroPermission defines a permission specific error
ErrZeroPermission = errors.New("permission is zero")
)
@@ -511,7 +511,7 @@ func (c *Client) SetAttr(ctx context.Context, auth eosclient.Authorization, attr
// We need to set the attrs on the version folder as they are not persisted across writes
// Except for the sys.eval.useracl attr as EOS uses that to determine if it needs to obey
// the user ACLs set on the file
if !(attr.Type == eosclient.SystemAttr && attr.Key == userACLEvalKey) {
if attr.Type != eosclient.SystemAttr || attr.Key != userACLEvalKey {
info, err = c.getRawFileInfoByPath(ctx, auth, path)
if err != nil {
return err
@@ -587,7 +587,7 @@ func (c *Client) UnsetAttr(ctx context.Context, auth eosclient.Authorization, at
// We need to set the attrs on the version folder as they are not persisted across writes
// Except for the sys.eval.useracl attr as EOS uses that to determine if it needs to obey
// the user ACLs set on the file
if !(attr.Type == eosclient.SystemAttr && attr.Key == userACLEvalKey) {
if attr.Type != eosclient.SystemAttr || attr.Key != userACLEvalKey {
info, err = c.getRawFileInfoByPath(ctx, auth, path)
if err != nil {
return err
@@ -927,10 +927,7 @@ func parseRecycleEntry(raw string) (*eosclient.DeletedEntry, error) {
if err != nil {
return nil, err
}
isDir := false
if kv["type"] == "recursive-dir" {
isDir = true
}
isDir := kv["type"] == "recursive-dir"
deletionMTime, err := strconv.ParseUint(strings.Split(kv["deletion-time"], ".")[0], 10, 64)
if err != nil {
return nil, err
@@ -1087,13 +1084,13 @@ func (c *Client) parseFileInfo(ctx context.Context, raw string, parseFavoriteKey
partsByEqual := strings.SplitN(p, "=", 2) // we have kv pairs like [size 14]
if len(partsByEqual) == 2 {
// handle xattrn and xattrv special cases
switch {
case partsByEqual[0] == "xattrn":
switch partsByEqual[0] {
case "xattrn":
previousXAttr = partsByEqual[1]
if previousXAttr != "user.acl" {
previousXAttr = strings.Replace(previousXAttr, "user.", "", 1)
}
case partsByEqual[0] == "xattrv":
case "xattrv":
attrs[previousXAttr] = partsByEqual[1]
previousXAttr = ""
default:
@@ -92,10 +92,11 @@ func (m *Metrics) Update(meshData *meshdata.MeshData) error {
}
func (m *Metrics) exportSiteMetrics(site *meshdata.Site) error {
mutators := make([]tag.Mutator, 0)
mutators = append(mutators, tag.Insert(tag.MustNewKey(keySiteID), site.ID))
mutators = append(mutators, tag.Insert(tag.MustNewKey(keySiteName), site.Name))
mutators = append(mutators, tag.Insert(tag.MustNewKey(keyServiceType), "SCIENCEMESH_HCHECK"))
mutators := []tag.Mutator{
tag.Insert(tag.MustNewKey(keySiteID), site.ID),
tag.Insert(tag.MustNewKey(keySiteName), site.Name),
tag.Insert(tag.MustNewKey(keyServiceType), "SCIENCEMESH_HCHECK"),
}
// Create a new context to serve the metrics
if ctx, err := tag.New(context.Background(), mutators...); err == nil {
+1 -1
View File
@@ -72,7 +72,7 @@ type MetricsJSONDriver struct {
// Configure configures this driver
func (d *MetricsJSONDriver) Configure(c *config.Config) error {
if c.MetricsDataLocation == "" {
err := errors.New("Unable to initialize a metrics data driver, has the data location (metrics_data_location) been configured?")
err := errors.New("unable to initialize a metrics data driver, has the data location (metrics_data_location) been configured?")
return err
}
@@ -399,26 +399,22 @@ func (m *mgr) UpdateShare(ctx context.Context, user *userpb.User, ref *ocm.Share
}
if am := f.GetAccessMethods(); am != nil {
var (
webdavOptions *ocm.WebDAVAccessMethod
webappOptions *ocm.WebappAccessMethod
transferOptions *ocm.TransferAccessMethod
webdavOptions *ocm.WebDAVAccessMethod
webappOptions *ocm.WebappAccessMethod
// TODO: *AccessMethod_GenericOptions
newWebdavOptions *ocm.WebDAVAccessMethod
newWebappOptions *ocm.WebappAccessMethod
newTransferOptions *ocm.TransferAccessMethod
newWebdavOptions *ocm.WebDAVAccessMethod
newWebappOptions *ocm.WebappAccessMethod
// TODO: *AccessMethod_GenericOptions
)
for _, sm := range s.GetAccessMethods() {
webdavOptions = sm.GetWebdavOptions()
webappOptions = sm.GetWebappOptions()
transferOptions = sm.GetTransferOptions()
}
newWebdavOptions = am.GetWebdavOptions()
newWebappOptions = am.GetWebappOptions()
newTransferOptions = am.GetTransferOptions()
newAccesMethods := []*ocm.AccessMethod{}
@@ -450,19 +446,6 @@ func (m *mgr) UpdateShare(ctx context.Context, user *userpb.User, ref *ocm.Share
})
}
if newTransferOptions != nil {
newAccesMethods = append(newAccesMethods, &ocm.AccessMethod{
Term: &ocm.AccessMethod_TransferOptions{
TransferOptions: newTransferOptions,
},
})
} else if transferOptions != nil {
newAccesMethods = append(newAccesMethods, &ocm.AccessMethod{
Term: &ocm.AccessMethod_TransferOptions{
TransferOptions: transferOptions,
},
})
}
s.AccessMethods = newAccesMethods
}
}
@@ -430,7 +430,7 @@ func (sm *Manager) do(ctx context.Context, a Action, username string) (int, []by
log.Info().Msgf("am.do response %d %s", resp.StatusCode, body)
if resp.StatusCode != http.StatusOK && resp.StatusCode != http.StatusCreated {
return 0, nil, fmt.Errorf("Unexpected response code from EFSS API: %d", resp.StatusCode)
return 0, nil, fmt.Errorf("unexpected response code from EFSS API: %d", resp.StatusCode)
}
return resp.StatusCode, body, nil
}
-22
View File
@@ -49,19 +49,6 @@ func NewWebappProtocol(uriTemplate string, viewMode appprovider.ViewMode) *ocm.P
}
}
// NewTransferProtocol is an abstraction for creating a Transfer protocol.
func NewTransferProtocol(sourceURI, sharedSecret string, size uint64) *ocm.Protocol {
return &ocm.Protocol{
Term: &ocm.Protocol_TransferOptions{
TransferOptions: &ocm.TransferProtocol{
SourceUri: sourceURI,
SharedSecret: sharedSecret,
Size: size,
},
},
}
}
// NewWebDavAccessMethod is an abstraction for creating a WebDAV access method.
func NewWebDavAccessMethod(perms *provider.ResourcePermissions) *ocm.AccessMethod {
return &ocm.AccessMethod{
@@ -83,12 +70,3 @@ func NewWebappAccessMethod(mode appprovider.ViewMode) *ocm.AccessMethod {
},
}
}
// NewTransferAccessMethod is an abstraction for creating a Transfer access method.
func NewTransferAccessMethod() *ocm.AccessMethod {
return &ocm.AccessMethod{
Term: &ocm.AccessMethod_TransferOptions{
TransferOptions: &ocm.TransferAccessMethod{},
},
}
}
+1 -1
View File
@@ -260,7 +260,7 @@ func convertStatToResourceInfo(ref *provider.Reference, f fs.FileInfo, share *oc
var name string
switch {
case share.ResourceType == provider.ResourceType_RESOURCE_TYPE_FILE:
case share.ResourceType == provider.ResourceType_RESOURCE_TYPE_FILE: //nolint:staticcheck // we will update our ocm implementation later
name = share.Name
case webdavFile.Path() == "/":
name = share.Name
+3 -3
View File
@@ -154,10 +154,10 @@ func (d *driver) GetUpload(ctx context.Context, id string) (tusd.Upload, error)
}
func NewUpload(ctx context.Context, d *driver, storageRoot string, info tusd.FileInfo) (tusd.Upload, error) {
if info.MetaData["filename"] == "" {
return nil, errors.New("Decomposedfs: missing filename in metadata")
return nil, errors.New("decomposedfs: missing filename in metadata")
}
if info.MetaData["dir"] == "" {
return nil, errors.New("Decomposedfs: missing dir in metadata")
return nil, errors.New("decomposedfs: missing dir in metadata")
}
uploadRoot := filepath.Join(storageRoot, "uploads")
@@ -328,7 +328,7 @@ func (u *upload) FinishUpload(ctx context.Context) error {
// shareID, rel := shareInfoFromReference(u.Info.MetaData["ref"])
// p := getPathFromShareIDAndRelPath(shareID, rel)
serviceUserCtx, err := utils.GetServiceUserContext(u.d.c.ServiceAccountID, u.d.gateway, u.d.c.ServiceAccountSecret)
serviceUserCtx, err := utils.GetServiceUserContextWithContext(context.Background(), u.d.gateway, u.d.c.ServiceAccountID, u.d.c.ServiceAccountSecret)
if err != nil {
return err
}
@@ -557,7 +557,7 @@ func (m *manager) ListPublicShares(ctx context.Context, u *user.User, filters []
cache[key] = struct{}{}
}
if local.PublicShare.PasswordProtected && sign {
if local.PasswordProtected && sign {
if err := publicshare.AddSignature(&local.PublicShare, local.Password); err != nil {
return nil, err
}
@@ -189,10 +189,7 @@ func (m *mgr) ConvertToCS3PublicShare(ctx context.Context, s DBShare) (*link.Pub
return nil, err
}
}
pwd := false
if s.ShareWith != "" {
pwd = true
}
pwd := s.ShareWith != ""
var expires *typespb.Timestamp
if s.Expiration != "" {
t, err := time.Parse("2006-01-02 15:04:05", s.Expiration)
@@ -677,7 +677,7 @@ func (m *Manager) listSharesByIDs(ctx context.Context, user *userv1beta1.User, f
continue
}
if !(share.IsCreatedByUser(s, user) || share.IsGrantedToUser(s, user)) {
if !share.IsCreatedByUser(s, user) && !share.IsGrantedToUser(s, user) {
key := storagespace.FormatResourceID(resourceID)
if _, hit := statCache[key]; !hit {
req := &provider.StatRequest{
@@ -25,7 +25,6 @@ import (
grouppb "github.com/cs3org/go-cs3apis/cs3/identity/group/v1beta1"
userpb "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1"
userprovider "github.com/cs3org/go-cs3apis/cs3/identity/user/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"
@@ -99,7 +98,7 @@ func (c *GatewayUserConverter) UserIDToUserName(ctx context.Context, userid *use
if err != nil {
return "", err
}
getUserResponse, err := gwConn.GetUser(ctx, &userprovider.GetUserRequest{
getUserResponse, err := gwConn.GetUser(ctx, &userpb.GetUserRequest{
UserId: userid,
SkipFetchingUserGroups: true,
})
@@ -484,7 +484,7 @@ func (m *mgr) UpdateReceivedShare(ctx context.Context, receivedShare *collaborat
return err
}
if affected < 1 {
return fmt.Errorf("No rows updated")
return fmt.Errorf("no rows updated")
}
return nil
}
@@ -538,7 +538,7 @@ func (m *mgr) getReceivedByID(ctx context.Context, id *collaboration.ShareId) (*
user := ctxpkg.ContextMustGetUser(ctx)
uid := user.Username
params := []interface{}{id.OpaqueId, id.OpaqueId, uid}
params := []interface{}{id.OpaqueId, id.OpaqueId, uid} //nolint:prealloc
for _, v := range user.Groups {
params = append(params, v)
}
@@ -559,16 +559,16 @@ func (m *mgr) getReceivedByID(ctx context.Context, id *collaboration.ShareId) (*
query := `
WITH results AS
(
SELECT s.*, storages.numeric_id
SELECT s.*, storages.numeric_id
FROM oc_share s
LEFT JOIN oc_storages storages ON ` + homeConcat + `
WHERE s.id=? OR s.parent=? ` + userSelect + `
)
SELECT COALESCE(r.uid_owner, '') AS uid_owner, COALESCE(r.uid_initiator, '') AS uid_initiator, COALESCE(r.share_with, '')
AS share_with, COALESCE(r.file_source, '') AS file_source, COALESCE(r2.file_target, r.file_target), r.id, r.stime, r.permissions, r.share_type, COALESCE(r2.accepted, r.accepted),
r.numeric_id, COALESCE(r.parent, -1) AS parent
FROM results r
LEFT JOIN results r2 ON r.id = r2.parent
r.numeric_id, COALESCE(r.parent, -1) AS parent
FROM results r
LEFT JOIN results r2 ON r.id = r2.parent
WHERE r.parent IS NULL;
`
+2 -2
View File
@@ -97,14 +97,14 @@ func getEndpoints() []endpoint {
func callAdministrationEndpoint(siteacc *SiteAccounts, ep endpoint, w http.ResponseWriter, r *http.Request, session *html.Session) {
if err := siteacc.ShowAdministrationPanel(w, r, session); err != nil {
w.WriteHeader(http.StatusInternalServerError)
_, _ = w.Write([]byte(fmt.Sprintf("Unable to show the administration panel: %v", err)))
_, _ = fmt.Fprintf(w, "Unable to show the administration panel: %v", err)
}
}
func callAccountEndpoint(siteacc *SiteAccounts, ep endpoint, w http.ResponseWriter, r *http.Request, session *html.Session) {
if err := siteacc.ShowAccountPanel(w, r, session); err != nil {
w.WriteHeader(http.StatusInternalServerError)
_, _ = w.Write([]byte(fmt.Sprintf("Unable to show the account panel: %v", err)))
_, _ = fmt.Fprintf(w, "Unable to show the account panel: %v", err)
}
}
+1 -1
View File
@@ -145,7 +145,7 @@ func (siteacc *SiteAccounts) RequestHandler() http.Handler {
if !epHandled {
w.WriteHeader(http.StatusBadRequest)
_, _ = w.Write([]byte(fmt.Sprintf("Unknown endpoint %v", r.URL.Path)))
_, _ = fmt.Fprintf(w, "Unknown endpoint %v", r.URL.Path)
}
})
}
+2 -2
View File
@@ -211,7 +211,7 @@ func (cache cacheStore) PushToCache(key string, src interface{}) error {
// List lists the keys on the configured database and table of the underlying store
func (cache cacheStore) List(opts ...microstore.ListOption) ([]string, error) {
o := []microstore.ListOption{
o := []microstore.ListOption{ // nolint:prealloc
microstore.ListFrom(cache.database, cache.table),
}
o = append(o, opts...)
@@ -224,7 +224,7 @@ func (cache cacheStore) List(opts ...microstore.ListOption) ([]string, error) {
// Delete deletes the given key on the configured database and table of the underlying store
func (cache cacheStore) Delete(key string, opts ...microstore.DeleteOption) error {
o := []microstore.DeleteOption{
o := []microstore.DeleteOption{ // nolint:prealloc
microstore.DeleteFrom(cache.database, cache.table),
}
o = append(o, opts...)
@@ -187,12 +187,14 @@ func (fs *hellofs) RestoreRecycleItem(ctx context.Context, ref *provider.Referen
}
// CreateHome creates a users home
//
// Deprecated: use CreateStorageSpace with type personal
func (fs *hellofs) CreateHome(ctx context.Context) error {
return errtypes.NotSupported("unimplemented")
}
// GetHome returns the path to the users home
//
// Deprecated: use ListStorageSpaces with type personal
func (fs *hellofs) GetHome(ctx context.Context) (string, error) {
return "", errtypes.NotSupported("unimplemented")
@@ -1113,9 +1113,9 @@ func (fs *owncloudsqlfs) UnsetArbitraryMetadata(ctx context.Context, ref *provid
if err = xattr.Remove(ip, mdPrefix+k); err != nil {
// a non-existing attribute will return an error, which we can ignore
// (using string compare because the error type is syscall.Errno and not wrapped/recognizable)
if e, ok := err.(*xattr.Error); !ok || !(e.Err.Error() == "no data available" ||
if e, ok := err.(*xattr.Error); !ok || (e.Err.Error() != "no data available" &&
// darwin
e.Err.Error() == "attribute not found") {
e.Err.Error() != "attribute not found") {
log.Error().Err(err).
Str("ipath", ip).
Str("key", k).
@@ -324,9 +324,10 @@ func (fs *owncloudsqlfs) GetUpload(ctx context.Context, id string) (tusd.Upload,
ctx = ctxpkg.ContextSetUser(ctx, u)
// TODO configure the logger the same way ... store and add traceid in file info
var opts []logger.Option
opts = append(opts, logger.WithLevel(info.Storage["LogLevel"]))
opts = append(opts, logger.WithWriter(os.Stderr, logger.ConsoleMode))
opts := []logger.Option{
logger.WithLevel(info.Storage["LogLevel"]),
logger.WithWriter(os.Stderr, logger.ConsoleMode),
}
l := logger.New(opts...)
sub := l.With().Int("pid", os.Getpid()).Logger()
@@ -83,8 +83,8 @@ type Lookup struct {
// New returns a new Lookup instance
func New(b metadata.Backend, um usermapper.Mapper, o *options.Options, tm node.TimeManager) *Lookup {
idHistoryConf := o.Options.IDCache
idHistoryConf.Table = o.Options.IDCache.Table + "_history"
idHistoryConf := o.IDCache
idHistoryConf.Table = o.IDCache.Table + "_history"
idHistoryConf.TTL = 1 * time.Minute
spaceRootCache, _ := lru.New[string, string](1000)
@@ -92,7 +92,7 @@ func New(b metadata.Backend, um usermapper.Mapper, o *options.Options, tm node.T
lu := &Lookup{
Options: o,
metadataBackend: b,
IDCache: NewStoreIDCache(o.Options.IDCache),
IDCache: NewStoreIDCache(o.IDCache),
IDHistoryCache: NewStoreIDCache(idHistoryConf),
spaceRootCache: spaceRootCache,
userMapper: um,
@@ -417,7 +417,7 @@ func (lu *Lookup) CopyMetadataWithSourceLock(ctx context.Context, src, target me
switch {
case lockedSource == nil:
return errors.New("no lock provided")
case lockedSource.File.Name() != lu.MetadataBackend().LockfilePath(src):
case lockedSource.Name() != lu.MetadataBackend().LockfilePath(src):
return errors.New("lockpath does not match filepath")
}
@@ -333,8 +333,7 @@ func (t *Tree) HandleFileDelete(path string, sendSSE bool) error {
return err
}
t.PublishEvent(events.ItemTrashed{
Owner: parentNode.Owner(),
Executant: parentNode.Owner(),
Owner: parentNode.Owner(),
Ref: &provider.Reference{
ResourceId: &provider.ResourceId{
StorageId: t.options.MountID,
@@ -538,10 +537,39 @@ func (t *Tree) assimilate(item scanItem) error {
t.log.Error().Err(err).Str("spaceID", spaceID).Str("id", id).Str("path", item.Path).Msg("could not cache id")
}
_, _, err := t.updateFile(item.Path, id, spaceID, fi)
fi, attrs, err := t.updateFile(item.Path, id, spaceID, fi)
if err != nil {
return err
}
if !fi.IsDir() {
ref := &provider.Reference{
ResourceId: &provider.ResourceId{
StorageId: t.options.MountID,
SpaceId: spaceID,
OpaqueId: id,
},
}
parentResourceID := &provider.ResourceId{
StorageId: t.options.MountID,
SpaceId: ref.ResourceId.SpaceId,
OpaqueId: string(attrs[prefixes.ParentidAttr]),
}
if fi.Size() == 0 {
t.PublishEvent(events.FileTouched{
Ref: ref,
ParentID: parentResourceID,
Timestamp: utils.TSNow(),
})
} else {
t.PublishEvent(events.UploadReady{
FileRef: ref,
ParentID: parentResourceID,
Timestamp: utils.TSNow(),
IsVersion: true,
})
}
}
}
} else {
t.log.Debug().Str("path", item.Path).Msg("new item detected")
@@ -583,7 +611,6 @@ func (t *Tree) assimilate(item scanItem) error {
OpaqueId: string(attrs[prefixes.ParentidAttr]),
}
}
ref := &provider.Reference{
ResourceId: &provider.ResourceId{
StorageId: t.options.MountID,
@@ -609,6 +636,7 @@ func (t *Tree) assimilate(item scanItem) error {
FileRef: ref,
ParentID: parentId,
Timestamp: utils.TSNow(),
IsVersion: false,
})
}
}
@@ -104,7 +104,7 @@ func (fs *Decomposedfs) AddGrant(ctx context.Context, ref *provider.Reference, g
// When the owner is empty but grants are set then we do want to check the grants.
// However, if we are trying to edit an existing grant we do not have to check for permission if the user owns the grant
// TODO: find a better to check this
if !(len(grants) == 0 && (owner == nil || owner.OpaqueId == "" || (owner.OpaqueId == grantNode.SpaceID && owner.Type == 8))) {
if len(grants) != 0 || (owner != nil && owner.OpaqueId != "" && (owner.OpaqueId != grantNode.SpaceID || owner.Type != 8)) {
rp, err := fs.p.AssemblePermissions(ctx, grantNode)
switch {
case err != nil:
@@ -232,13 +232,13 @@ func (fs *Decomposedfs) RemoveGrant(ctx context.Context, ref *provider.Reference
// FIXME we should invalidate the by-type index, but that requires reference counting
} else {
// invalidate space grant
switch {
case g.Grantee.Type == provider.GranteeType_GRANTEE_TYPE_USER:
switch g.Grantee.Type {
case provider.GranteeType_GRANTEE_TYPE_USER:
// remove from user index
if err := fs.userSpaceIndex.Remove(g.Grantee.GetUserId().GetOpaqueId(), grantNode.SpaceID); err != nil {
return err
}
case g.Grantee.Type == provider.GranteeType_GRANTEE_TYPE_GROUP:
case provider.GranteeType_GRANTEE_TYPE_GROUP:
// remove from group index
if err := fs.groupSpaceIndex.Remove(g.Grantee.GetGroupId().GetOpaqueId(), grantNode.SpaceID); err != nil {
return err
@@ -279,6 +279,7 @@ func (lu *Lookup) LockfilePaths(n *node.Node) []string {
}
// VersionPath returns the internal path for a version of a node
//
// Deprecated: use InternalPath instead
func (lu *Lookup) VersionPath(spaceID, nodeID, version string) string {
return lu.InternalPath(spaceID, nodeID) + node.RevisionIDDelimiter + version
@@ -337,7 +338,7 @@ func (lu *Lookup) CopyMetadataWithSourceLock(ctx context.Context, sourceNode, ta
switch {
case lockedSource == nil:
return errors.New("no lock provided")
case lockedSource.File.Name() != lu.MetadataBackend().LockfilePath(sourceNode):
case lockedSource.Name() != lu.MetadataBackend().LockfilePath(sourceNode):
return errors.New("lockpath does not match filepath")
}
@@ -852,10 +852,10 @@ func (fs *Decomposedfs) updateIndexes(ctx context.Context, grantee *provider.Gra
}
// create space grant index
switch {
case grantee.Type == provider.GranteeType_GRANTEE_TYPE_USER:
switch grantee.Type {
case provider.GranteeType_GRANTEE_TYPE_USER:
return fs.linkSpaceByUser(ctx, grantee.GetUserId().GetOpaqueId(), spaceID, target)
case grantee.Type == provider.GranteeType_GRANTEE_TYPE_GROUP:
case provider.GranteeType_GRANTEE_TYPE_GROUP:
return fs.linkSpaceByGroup(ctx, grantee.GetGroupId().GetOpaqueId(), spaceID, target)
default:
return errtypes.BadRequest("invalid grantee type: " + grantee.GetType().String())
@@ -941,14 +941,14 @@ func (fs *Decomposedfs) StorageSpaceFromNode(ctx context.Context, n *node.Node,
}
if n.IsSpaceRoot(ctx) {
// invalidate space grant
switch {
case g.Grantee.Type == provider.GranteeType_GRANTEE_TYPE_USER:
switch g.Grantee.Type {
case provider.GranteeType_GRANTEE_TYPE_USER:
// remove from user index
if err := fs.userSpaceIndex.Remove(g.Grantee.GetUserId().GetOpaqueId(), n.GetSpaceID()); err != nil {
sublog.Error().Err(err).Str("grantee", id).
Msg("failed to delete expired user space index")
}
case g.Grantee.Type == provider.GranteeType_GRANTEE_TYPE_GROUP:
case provider.GranteeType_GRANTEE_TYPE_GROUP:
// remove from group index
if err := fs.groupSpaceIndex.Remove(g.Grantee.GetGroupId().GetOpaqueId(), n.GetSpaceID()); err != nil {
sublog.Error().Err(err).Str("grantee", id).
+2
View File
@@ -137,9 +137,11 @@ type FS interface {
DeleteStorageSpace(ctx context.Context, req *provider.DeleteStorageSpaceRequest) error
// CreateHome creates a users home
//
// Deprecated: use CreateStorageSpace with type personal
CreateHome(ctx context.Context) error
// GetHome returns the path to the users home
//
// Deprecated: use ListStorageSpaces with type personal
GetHome(ctx context.Context) (string, error)
}
+1
View File
@@ -39,6 +39,7 @@ type UploadRequest struct {
}
// UploadsManager defines the interface for storage drivers that allow for managing uploads
//
// Deprecated: No longer used. Storage drivers should implement the UploadSessionLister.
type UploadsManager interface {
ListUploads() ([]tusd.FileInfo, error)
+1 -1
View File
@@ -79,7 +79,7 @@ func isComment(line string) bool {
// Serialize always serializes to short text form
func (m *ACLs) Serialize() string {
sysACL := []string{}
sysACL := make([]string, 0, len(m.Entries))
for _, e := range m.Entries {
sysACL = append(sysACL, e.CitrineSerialize())
}
@@ -104,7 +104,7 @@ func (fs *Decomposedfs) AddGrant(ctx context.Context, ref *provider.Reference, g
// When the owner is empty but grants are set then we do want to check the grants.
// However, if we are trying to edit an existing grant we do not have to check for permission if the user owns the grant
// TODO: find a better to check this
if !(len(grants) == 0 && (owner == nil || owner.OpaqueId == "" || (owner.OpaqueId == grantNode.SpaceID && owner.Type == 8))) {
if len(grants) != 0 || (owner != nil && owner.OpaqueId != "" && (owner.OpaqueId != grantNode.SpaceID || owner.Type != 8)) {
rp, err := fs.p.AssemblePermissions(ctx, grantNode)
switch {
case err != nil:
@@ -218,13 +218,13 @@ func (fs *Decomposedfs) RemoveGrant(ctx context.Context, ref *provider.Reference
// FIXME we should invalidate the by-type index, but that requires reference counting
} else {
// invalidate space grant
switch {
case g.Grantee.Type == provider.GranteeType_GRANTEE_TYPE_USER:
switch g.Grantee.Type {
case provider.GranteeType_GRANTEE_TYPE_USER:
// remove from user index
if err := fs.userSpaceIndex.Remove(g.Grantee.GetUserId().GetOpaqueId(), grantNode.SpaceID); err != nil {
return err
}
case g.Grantee.Type == provider.GranteeType_GRANTEE_TYPE_GROUP:
case provider.GranteeType_GRANTEE_TYPE_GROUP:
// remove from group index
if err := fs.groupSpaceIndex.Remove(g.Grantee.GetGroupId().GetOpaqueId(), grantNode.SpaceID); err != nil {
return err
@@ -362,7 +362,7 @@ func (lu *Lookup) CopyMetadataWithSourceLock(ctx context.Context, sourcePath, ta
switch {
case lockedSource == nil:
return errors.New("no lock provided")
case lockedSource.File.Name() != lu.MetadataBackend().LockfilePath(sourcePath):
case lockedSource.Name() != lu.MetadataBackend().LockfilePath(sourcePath):
return errors.New("lockpath does not match filepath")
}
@@ -52,7 +52,7 @@ func registerMigration(name string, migration migration) {
}
func allMigrations() []string {
ms := []string{}
ms := make([]string, 0, len(migrations))
for k := range migrations {
ms = append(ms, k)
@@ -823,10 +823,10 @@ func (fs *Decomposedfs) updateIndexes(ctx context.Context, grantee *provider.Gra
}
// create space grant index
switch {
case grantee.Type == provider.GranteeType_GRANTEE_TYPE_USER:
switch grantee.Type {
case provider.GranteeType_GRANTEE_TYPE_USER:
return fs.linkSpaceByUser(ctx, grantee.GetUserId().GetOpaqueId(), spaceID, target)
case grantee.Type == provider.GranteeType_GRANTEE_TYPE_GROUP:
case provider.GranteeType_GRANTEE_TYPE_GROUP:
return fs.linkSpaceByGroup(ctx, grantee.GetGroupId().GetOpaqueId(), spaceID, target)
default:
return errtypes.BadRequest("invalid grantee type: " + grantee.GetType().String())
@@ -912,14 +912,14 @@ func (fs *Decomposedfs) StorageSpaceFromNode(ctx context.Context, n *node.Node,
}
if n.IsSpaceRoot(ctx) {
// invalidate space grant
switch {
case g.Grantee.Type == provider.GranteeType_GRANTEE_TYPE_USER:
switch g.Grantee.Type {
case provider.GranteeType_GRANTEE_TYPE_USER:
// remove from user index
if err := fs.userSpaceIndex.Remove(g.Grantee.GetUserId().GetOpaqueId(), n.SpaceID); err != nil {
sublog.Error().Err(err).Str("grantee", id).
Msg("failed to delete expired user space index")
}
case g.Grantee.Type == provider.GranteeType_GRANTEE_TYPE_GROUP:
case provider.GranteeType_GRANTEE_TYPE_GROUP:
// remove from group index
if err := fs.groupSpaceIndex.Remove(g.Grantee.GetGroupId().GetOpaqueId(), n.SpaceID); err != nil {
sublog.Error().Err(err).Str("grantee", id).
+3 -3
View File
@@ -1166,8 +1166,8 @@ func (fs *eosfs) ListGrants(ctx context.Context, ref *provider.Reference) ([]*pr
grantList := []*provider.Grant{}
for _, a := range acls {
var grantee *provider.Grantee
switch {
case a.Type == acl.TypeUser:
switch a.Type {
case acl.TypeUser:
// EOS Citrine ACLs are stored with uid for users.
// This needs to be resolved to the user opaque ID.
qualifier, err := fs.getUserIDGateway(ctx, a.Qualifier)
@@ -1178,7 +1178,7 @@ func (fs *eosfs) ListGrants(ctx context.Context, ref *provider.Reference) ([]*pr
Id: &provider.Grantee_UserId{UserId: qualifier},
Type: grants.GetGranteeType(a.Type),
}
case a.Type == acl.TypeLightweight:
case acl.TypeLightweight:
a.Type = acl.TypeUser
grantee = &provider.Grantee{
Id: &provider.Grantee_UserId{UserId: &userpb.UserId{OpaqueId: a.Qualifier}},
@@ -459,9 +459,10 @@ func (fs *localfs) AddGrant(ctx context.Context, ref *provider.Reference, g *pro
return errors.Wrap(err, "localfs: error getting grantee type")
}
var grantee string
if granteeType == acl.TypeUser {
switch granteeType {
case acl.TypeUser:
grantee = fmt.Sprintf("%s:%s:%s@%s", granteeType, g.Grantee.GetUserId().OpaqueId, utils.UserTypeToString(g.Grantee.GetUserId().Type), g.Grantee.GetUserId().Idp)
} else if granteeType == acl.TypeGroup {
case acl.TypeGroup:
grantee = fmt.Sprintf("%s::%s@%s", granteeType, g.Grantee.GetGroupId().OpaqueId, g.Grantee.GetGroupId().Idp)
}
@@ -495,9 +496,10 @@ func (fs *localfs) ListGrants(ctx context.Context, ref *provider.Reference) ([]*
grantSplit := strings.Split(granteeID, ":")
grantee := &provider.Grantee{Type: grants.GetGranteeType(grantSplit[0])}
parts := strings.Split(grantSplit[2], "@")
if grantSplit[0] == acl.TypeUser {
switch grantSplit[0] {
case acl.TypeUser:
grantee.Id = &provider.Grantee_UserId{UserId: &userpb.UserId{OpaqueId: parts[0], Idp: parts[1], Type: utils.UserTypeMap(grantSplit[1])}}
} else if grantSplit[0] == acl.TypeGroup {
case acl.TypeGroup:
grantee.Id = &provider.Grantee_GroupId{GroupId: &grouppb.GroupId{OpaqueId: parts[0], Idp: parts[1]}}
}
permissions := grants.GetGrantPermissionSet(role)
@@ -523,9 +525,10 @@ func (fs *localfs) RemoveGrant(ctx context.Context, ref *provider.Reference, g *
return errors.Wrap(err, "localfs: error getting grantee type")
}
var grantee string
if granteeType == acl.TypeUser {
switch granteeType {
case acl.TypeUser:
grantee = fmt.Sprintf("%s:%s@%s", granteeType, g.Grantee.GetUserId().OpaqueId, g.Grantee.GetUserId().Idp)
} else if granteeType == acl.TypeGroup {
case acl.TypeGroup:
grantee = fmt.Sprintf("%s:%s@%s", granteeType, g.Grantee.GetGroupId().OpaqueId, g.Grantee.GetGroupId().Idp)
}
@@ -39,6 +39,7 @@ import (
"google.golang.org/grpc/metadata"
"github.com/opencloud-eu/reva/v2/internal/http/services/owncloud/ocdav/net"
"github.com/opencloud-eu/reva/v2/pkg/appctx"
ctxpkg "github.com/opencloud-eu/reva/v2/pkg/ctx"
"github.com/opencloud-eu/reva/v2/pkg/errtypes"
"github.com/opencloud-eu/reva/v2/pkg/rgrpc/todo/pool"
@@ -97,16 +98,19 @@ func (cs3 *CS3) Backend() string {
// Init creates the metadata space
func (cs3 *CS3) Init(ctx context.Context, spaceid string) (err error) {
logger := appctx.GetLogger(ctx)
ctx, span := tracer.Start(ctx, "Init")
defer span.End()
client, err := cs3.spacesClient()
if err != nil {
logger.Err(err).Msg("error getting spaces client")
return err
}
ctx, err = cs3.getAuthContext(ctx)
if err != nil {
logger.Err(err).Msg("error getting auth context")
return err
}
@@ -146,12 +150,14 @@ func (cs3 *CS3) Init(ctx context.Context, spaceid string) (err error) {
})
switch {
case err != nil:
logger.Err(err).Msg("error creating storage space")
return err
case cssr.Status.Code == rpc.Code_CODE_OK:
cs3.SpaceRoot = cssr.StorageSpace.Root
case cssr.Status.Code == rpc.Code_CODE_ALREADY_EXISTS:
return errtypes.AlreadyExists(fmt.Sprintf("user %s does not have access to metadata space %s, but it exists", cs3.serviceUser.Id.OpaqueId, spaceid))
default:
logger.Debug().Str("Status", cssr.Status.Message).Msg("error creating storage space")
return errtypes.NewErrtypeFromStatus(cssr.Status)
}
return nil
@@ -107,7 +107,7 @@ func (f *FS) GetHome(ctx context.Context) (string, error) {
}
}
res0, res1 := f.next.GetHome(ctx)
res0, res1 := f.next.GetHome(ctx) //nolint:staticcheck // we're just exposing the deprecated method here
for _, unhook := range unhooks {
if err := unhook(); err != nil {
@@ -134,7 +134,7 @@ func (f *FS) CreateHome(ctx context.Context) error {
}
}
res0 := f.next.CreateHome(ctx)
res0 := f.next.CreateHome(ctx) //nolint:staticcheck // we're just exposing the deprecated method here
for _, unhook := range unhooks {
if err := unhook(); err != nil {
+2 -3
View File
@@ -33,7 +33,6 @@ import (
"github.com/opencloud-eu/reva/v2/pkg/store/etcd"
"github.com/opencloud-eu/reva/v2/pkg/store/memory"
"go-micro.dev/v4/logger"
"go-micro.dev/v4/store"
microstore "go-micro.dev/v4/store"
)
@@ -162,8 +161,8 @@ func Create(opts ...microstore.Option) microstore.Store {
}
}
func updateNatsStore(opts []store.Option, ttl time.Duration, natsOptions nats.Options) error {
options := store.Options{}
func updateNatsStore(opts []microstore.Option, ttl time.Duration, natsOptions nats.Options) error {
options := microstore.Options{}
for _, o := range opts {
o(&options)
}
+1
View File
@@ -37,6 +37,7 @@ var (
)
// GetServiceUserContext returns an authenticated context of the given service user
//
// Deprecated: Use GetServiceUserContextWithContext()
func GetServiceUserContext(serviceUserID string, gwc gateway.GatewayAPIClient, serviceUserSecret string) (context.Context, error) {
return GetServiceUserContextWithContext(context.Background(), gwc, serviceUserID, serviceUserSecret)
+2 -2
View File
@@ -183,11 +183,11 @@ func (i *Identity) Setup() error {
if sharedconf.MultiTenantEnabled() {
if i.User.Schema.TenantID == "" {
return fmt.Errorf("Invalid configuration: a 'tenantId' user schema attribute must be defined for multi-tenant setups")
return fmt.Errorf("invalid configuration: a 'tenantId' user schema attribute must be defined for multi-tenant setups")
}
} else {
if i.User.Schema.TenantID != "" {
return fmt.Errorf("Invalid configuration: Superfluous 'tenantId' user schema attribute defined for single-tenant setups")
return fmt.Errorf("invalid configuration: superfluous 'tenantId' user schema attribute defined for single-tenant setups")
}
}
@@ -38,6 +38,8 @@ import (
grpc "google.golang.org/grpc"
incomingv1beta1 "github.com/cs3org/go-cs3apis/cs3/ocm/incoming/v1beta1"
invitev1beta1 "github.com/cs3org/go-cs3apis/cs3/ocm/invite/v1beta1"
linkv1beta1 "github.com/cs3org/go-cs3apis/cs3/sharing/link/v1beta1"
@@ -658,6 +660,79 @@ func (_c *GatewayAPIClient_CreateOCMCoreShare_Call) RunAndReturn(run func(contex
return _c
}
// CreateOCMIncomingShare provides a mock function with given fields: ctx, in, opts
func (_m *GatewayAPIClient) CreateOCMIncomingShare(ctx context.Context, in *incomingv1beta1.CreateOCMIncomingShareRequest, opts ...grpc.CallOption) (*incomingv1beta1.CreateOCMIncomingShareResponse, error) {
var tmpRet mock.Arguments
if len(opts) > 0 {
tmpRet = _m.Called(ctx, in, opts)
} else {
tmpRet = _m.Called(ctx, in)
}
ret := tmpRet
if len(ret) == 0 {
panic("no return value specified for CreateOCMIncomingShare")
}
var r0 *incomingv1beta1.CreateOCMIncomingShareResponse
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, *incomingv1beta1.CreateOCMIncomingShareRequest, ...grpc.CallOption) (*incomingv1beta1.CreateOCMIncomingShareResponse, error)); ok {
return rf(ctx, in, opts...)
}
if rf, ok := ret.Get(0).(func(context.Context, *incomingv1beta1.CreateOCMIncomingShareRequest, ...grpc.CallOption) *incomingv1beta1.CreateOCMIncomingShareResponse); ok {
r0 = rf(ctx, in, opts...)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*incomingv1beta1.CreateOCMIncomingShareResponse)
}
}
if rf, ok := ret.Get(1).(func(context.Context, *incomingv1beta1.CreateOCMIncomingShareRequest, ...grpc.CallOption) error); ok {
r1 = rf(ctx, in, opts...)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// GatewayAPIClient_CreateOCMIncomingShare_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'CreateOCMIncomingShare'
type GatewayAPIClient_CreateOCMIncomingShare_Call struct {
*mock.Call
}
// CreateOCMIncomingShare is a helper method to define mock.On call
// - ctx context.Context
// - in *incomingv1beta1.CreateOCMIncomingShareRequest
// - opts ...grpc.CallOption
func (_e *GatewayAPIClient_Expecter) CreateOCMIncomingShare(ctx interface{}, in interface{}, opts ...interface{}) *GatewayAPIClient_CreateOCMIncomingShare_Call {
return &GatewayAPIClient_CreateOCMIncomingShare_Call{Call: _e.mock.On("CreateOCMIncomingShare",
append([]interface{}{ctx, in}, opts...)...)}
}
func (_c *GatewayAPIClient_CreateOCMIncomingShare_Call) Run(run func(ctx context.Context, in *incomingv1beta1.CreateOCMIncomingShareRequest, opts ...grpc.CallOption)) *GatewayAPIClient_CreateOCMIncomingShare_Call {
_c.Call.Run(func(args mock.Arguments) {
variadicArgs := make([]grpc.CallOption, len(args)-2)
for i, a := range args[2:] {
if a != nil {
variadicArgs[i] = a.(grpc.CallOption)
}
}
run(args[0].(context.Context), args[1].(*incomingv1beta1.CreateOCMIncomingShareRequest), variadicArgs...)
})
return _c
}
func (_c *GatewayAPIClient_CreateOCMIncomingShare_Call) Return(_a0 *incomingv1beta1.CreateOCMIncomingShareResponse, _a1 error) *GatewayAPIClient_CreateOCMIncomingShare_Call {
_c.Call.Return(_a0, _a1)
return _c
}
func (_c *GatewayAPIClient_CreateOCMIncomingShare_Call) RunAndReturn(run func(context.Context, *incomingv1beta1.CreateOCMIncomingShareRequest, ...grpc.CallOption) (*incomingv1beta1.CreateOCMIncomingShareResponse, error)) *GatewayAPIClient_CreateOCMIncomingShare_Call {
_c.Call.Return(run)
return _c
}
// CreateOCMShare provides a mock function with given fields: ctx, in, opts
func (_m *GatewayAPIClient) CreateOCMShare(ctx context.Context, in *ocmv1beta1.CreateOCMShareRequest, opts ...grpc.CallOption) (*ocmv1beta1.CreateOCMShareResponse, error) {
var tmpRet mock.Arguments
@@ -1315,6 +1390,79 @@ func (_c *GatewayAPIClient_DeleteOCMCoreShare_Call) RunAndReturn(run func(contex
return _c
}
// DeleteOCMIncomingShare provides a mock function with given fields: ctx, in, opts
func (_m *GatewayAPIClient) DeleteOCMIncomingShare(ctx context.Context, in *incomingv1beta1.DeleteOCMIncomingShareRequest, opts ...grpc.CallOption) (*incomingv1beta1.DeleteOCMIncomingShareResponse, error) {
var tmpRet mock.Arguments
if len(opts) > 0 {
tmpRet = _m.Called(ctx, in, opts)
} else {
tmpRet = _m.Called(ctx, in)
}
ret := tmpRet
if len(ret) == 0 {
panic("no return value specified for DeleteOCMIncomingShare")
}
var r0 *incomingv1beta1.DeleteOCMIncomingShareResponse
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, *incomingv1beta1.DeleteOCMIncomingShareRequest, ...grpc.CallOption) (*incomingv1beta1.DeleteOCMIncomingShareResponse, error)); ok {
return rf(ctx, in, opts...)
}
if rf, ok := ret.Get(0).(func(context.Context, *incomingv1beta1.DeleteOCMIncomingShareRequest, ...grpc.CallOption) *incomingv1beta1.DeleteOCMIncomingShareResponse); ok {
r0 = rf(ctx, in, opts...)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*incomingv1beta1.DeleteOCMIncomingShareResponse)
}
}
if rf, ok := ret.Get(1).(func(context.Context, *incomingv1beta1.DeleteOCMIncomingShareRequest, ...grpc.CallOption) error); ok {
r1 = rf(ctx, in, opts...)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// GatewayAPIClient_DeleteOCMIncomingShare_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'DeleteOCMIncomingShare'
type GatewayAPIClient_DeleteOCMIncomingShare_Call struct {
*mock.Call
}
// DeleteOCMIncomingShare is a helper method to define mock.On call
// - ctx context.Context
// - in *incomingv1beta1.DeleteOCMIncomingShareRequest
// - opts ...grpc.CallOption
func (_e *GatewayAPIClient_Expecter) DeleteOCMIncomingShare(ctx interface{}, in interface{}, opts ...interface{}) *GatewayAPIClient_DeleteOCMIncomingShare_Call {
return &GatewayAPIClient_DeleteOCMIncomingShare_Call{Call: _e.mock.On("DeleteOCMIncomingShare",
append([]interface{}{ctx, in}, opts...)...)}
}
func (_c *GatewayAPIClient_DeleteOCMIncomingShare_Call) Run(run func(ctx context.Context, in *incomingv1beta1.DeleteOCMIncomingShareRequest, opts ...grpc.CallOption)) *GatewayAPIClient_DeleteOCMIncomingShare_Call {
_c.Call.Run(func(args mock.Arguments) {
variadicArgs := make([]grpc.CallOption, len(args)-2)
for i, a := range args[2:] {
if a != nil {
variadicArgs[i] = a.(grpc.CallOption)
}
}
run(args[0].(context.Context), args[1].(*incomingv1beta1.DeleteOCMIncomingShareRequest), variadicArgs...)
})
return _c
}
func (_c *GatewayAPIClient_DeleteOCMIncomingShare_Call) Return(_a0 *incomingv1beta1.DeleteOCMIncomingShareResponse, _a1 error) *GatewayAPIClient_DeleteOCMIncomingShare_Call {
_c.Call.Return(_a0, _a1)
return _c
}
func (_c *GatewayAPIClient_DeleteOCMIncomingShare_Call) RunAndReturn(run func(context.Context, *incomingv1beta1.DeleteOCMIncomingShareRequest, ...grpc.CallOption) (*incomingv1beta1.DeleteOCMIncomingShareResponse, error)) *GatewayAPIClient_DeleteOCMIncomingShare_Call {
_c.Call.Return(run)
return _c
}
// DeleteStorageSpace provides a mock function with given fields: ctx, in, opts
func (_m *GatewayAPIClient) DeleteStorageSpace(ctx context.Context, in *providerv1beta1.DeleteStorageSpaceRequest, opts ...grpc.CallOption) (*providerv1beta1.DeleteStorageSpaceResponse, error) {
var tmpRet mock.Arguments
@@ -4381,6 +4529,79 @@ func (_c *GatewayAPIClient_ListContainerStream_Call) RunAndReturn(run func(conte
return _c
}
// ListExistingOCMShares provides a mock function with given fields: ctx, in, opts
func (_m *GatewayAPIClient) ListExistingOCMShares(ctx context.Context, in *ocmv1beta1.ListOCMSharesRequest, opts ...grpc.CallOption) (*gatewayv1beta1.ListExistingOCMSharesResponse, error) {
var tmpRet mock.Arguments
if len(opts) > 0 {
tmpRet = _m.Called(ctx, in, opts)
} else {
tmpRet = _m.Called(ctx, in)
}
ret := tmpRet
if len(ret) == 0 {
panic("no return value specified for ListExistingOCMShares")
}
var r0 *gatewayv1beta1.ListExistingOCMSharesResponse
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, *ocmv1beta1.ListOCMSharesRequest, ...grpc.CallOption) (*gatewayv1beta1.ListExistingOCMSharesResponse, error)); ok {
return rf(ctx, in, opts...)
}
if rf, ok := ret.Get(0).(func(context.Context, *ocmv1beta1.ListOCMSharesRequest, ...grpc.CallOption) *gatewayv1beta1.ListExistingOCMSharesResponse); ok {
r0 = rf(ctx, in, opts...)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*gatewayv1beta1.ListExistingOCMSharesResponse)
}
}
if rf, ok := ret.Get(1).(func(context.Context, *ocmv1beta1.ListOCMSharesRequest, ...grpc.CallOption) error); ok {
r1 = rf(ctx, in, opts...)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// GatewayAPIClient_ListExistingOCMShares_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ListExistingOCMShares'
type GatewayAPIClient_ListExistingOCMShares_Call struct {
*mock.Call
}
// ListExistingOCMShares is a helper method to define mock.On call
// - ctx context.Context
// - in *ocmv1beta1.ListOCMSharesRequest
// - opts ...grpc.CallOption
func (_e *GatewayAPIClient_Expecter) ListExistingOCMShares(ctx interface{}, in interface{}, opts ...interface{}) *GatewayAPIClient_ListExistingOCMShares_Call {
return &GatewayAPIClient_ListExistingOCMShares_Call{Call: _e.mock.On("ListExistingOCMShares",
append([]interface{}{ctx, in}, opts...)...)}
}
func (_c *GatewayAPIClient_ListExistingOCMShares_Call) Run(run func(ctx context.Context, in *ocmv1beta1.ListOCMSharesRequest, opts ...grpc.CallOption)) *GatewayAPIClient_ListExistingOCMShares_Call {
_c.Call.Run(func(args mock.Arguments) {
variadicArgs := make([]grpc.CallOption, len(args)-2)
for i, a := range args[2:] {
if a != nil {
variadicArgs[i] = a.(grpc.CallOption)
}
}
run(args[0].(context.Context), args[1].(*ocmv1beta1.ListOCMSharesRequest), variadicArgs...)
})
return _c
}
func (_c *GatewayAPIClient_ListExistingOCMShares_Call) Return(_a0 *gatewayv1beta1.ListExistingOCMSharesResponse, _a1 error) *GatewayAPIClient_ListExistingOCMShares_Call {
_c.Call.Return(_a0, _a1)
return _c
}
func (_c *GatewayAPIClient_ListExistingOCMShares_Call) RunAndReturn(run func(context.Context, *ocmv1beta1.ListOCMSharesRequest, ...grpc.CallOption) (*gatewayv1beta1.ListExistingOCMSharesResponse, error)) *GatewayAPIClient_ListExistingOCMShares_Call {
_c.Call.Return(run)
return _c
}
// ListExistingPublicShares provides a mock function with given fields: ctx, in, opts
func (_m *GatewayAPIClient) ListExistingPublicShares(ctx context.Context, in *linkv1beta1.ListPublicSharesRequest, opts ...grpc.CallOption) (*gatewayv1beta1.ListExistingPublicSharesResponse, error) {
var tmpRet mock.Arguments
@@ -6863,6 +7084,79 @@ func (_c *GatewayAPIClient_UpdateOCMCoreShare_Call) RunAndReturn(run func(contex
return _c
}
// UpdateOCMIncomingShare provides a mock function with given fields: ctx, in, opts
func (_m *GatewayAPIClient) UpdateOCMIncomingShare(ctx context.Context, in *incomingv1beta1.UpdateOCMIncomingShareRequest, opts ...grpc.CallOption) (*incomingv1beta1.UpdateOCMIncomingShareResponse, error) {
var tmpRet mock.Arguments
if len(opts) > 0 {
tmpRet = _m.Called(ctx, in, opts)
} else {
tmpRet = _m.Called(ctx, in)
}
ret := tmpRet
if len(ret) == 0 {
panic("no return value specified for UpdateOCMIncomingShare")
}
var r0 *incomingv1beta1.UpdateOCMIncomingShareResponse
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, *incomingv1beta1.UpdateOCMIncomingShareRequest, ...grpc.CallOption) (*incomingv1beta1.UpdateOCMIncomingShareResponse, error)); ok {
return rf(ctx, in, opts...)
}
if rf, ok := ret.Get(0).(func(context.Context, *incomingv1beta1.UpdateOCMIncomingShareRequest, ...grpc.CallOption) *incomingv1beta1.UpdateOCMIncomingShareResponse); ok {
r0 = rf(ctx, in, opts...)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*incomingv1beta1.UpdateOCMIncomingShareResponse)
}
}
if rf, ok := ret.Get(1).(func(context.Context, *incomingv1beta1.UpdateOCMIncomingShareRequest, ...grpc.CallOption) error); ok {
r1 = rf(ctx, in, opts...)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// GatewayAPIClient_UpdateOCMIncomingShare_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'UpdateOCMIncomingShare'
type GatewayAPIClient_UpdateOCMIncomingShare_Call struct {
*mock.Call
}
// UpdateOCMIncomingShare is a helper method to define mock.On call
// - ctx context.Context
// - in *incomingv1beta1.UpdateOCMIncomingShareRequest
// - opts ...grpc.CallOption
func (_e *GatewayAPIClient_Expecter) UpdateOCMIncomingShare(ctx interface{}, in interface{}, opts ...interface{}) *GatewayAPIClient_UpdateOCMIncomingShare_Call {
return &GatewayAPIClient_UpdateOCMIncomingShare_Call{Call: _e.mock.On("UpdateOCMIncomingShare",
append([]interface{}{ctx, in}, opts...)...)}
}
func (_c *GatewayAPIClient_UpdateOCMIncomingShare_Call) Run(run func(ctx context.Context, in *incomingv1beta1.UpdateOCMIncomingShareRequest, opts ...grpc.CallOption)) *GatewayAPIClient_UpdateOCMIncomingShare_Call {
_c.Call.Run(func(args mock.Arguments) {
variadicArgs := make([]grpc.CallOption, len(args)-2)
for i, a := range args[2:] {
if a != nil {
variadicArgs[i] = a.(grpc.CallOption)
}
}
run(args[0].(context.Context), args[1].(*incomingv1beta1.UpdateOCMIncomingShareRequest), variadicArgs...)
})
return _c
}
func (_c *GatewayAPIClient_UpdateOCMIncomingShare_Call) Return(_a0 *incomingv1beta1.UpdateOCMIncomingShareResponse, _a1 error) *GatewayAPIClient_UpdateOCMIncomingShare_Call {
_c.Call.Return(_a0, _a1)
return _c
}
func (_c *GatewayAPIClient_UpdateOCMIncomingShare_Call) RunAndReturn(run func(context.Context, *incomingv1beta1.UpdateOCMIncomingShareRequest, ...grpc.CallOption) (*incomingv1beta1.UpdateOCMIncomingShareResponse, error)) *GatewayAPIClient_UpdateOCMIncomingShare_Call {
_c.Call.Return(run)
return _c
}
// UpdateOCMShare provides a mock function with given fields: ctx, in, opts
func (_m *GatewayAPIClient) UpdateOCMShare(ctx context.Context, in *ocmv1beta1.UpdateOCMShareRequest, opts ...grpc.CallOption) (*ocmv1beta1.UpdateOCMShareResponse, error) {
var tmpRet mock.Arguments