diff --git a/changelog/unreleased/update-share-response.md b/changelog/unreleased/update-share-response.md new file mode 100644 index 0000000000..b7645c3c3d --- /dev/null +++ b/changelog/unreleased/update-share-response.md @@ -0,0 +1,5 @@ +Enhancement: Add share to update response + +After accepting or rejecting a share the API includes the updated share in the response. + +https://github.com/cs3org/reva/pull/1685 diff --git a/internal/grpc/services/gateway/usershareprovider.go b/internal/grpc/services/gateway/usershareprovider.go index 12cfe3df55..175258765f 100644 --- a/internal/grpc/services/gateway/usershareprovider.go +++ b/internal/grpc/services/gateway/usershareprovider.go @@ -196,23 +196,9 @@ func (s *svc) UpdateShare(ctx context.Context, req *collaboration.UpdateShareReq // TODO(labkode): if both commits are enabled they could be done concurrently. if s.c.CommitShareToStorageGrant { - getShareReq := &collaboration.GetShareRequest{ - Ref: req.Ref, - } - getShareRes, err := c.GetShare(ctx, getShareReq) - if err != nil { - return nil, errors.Wrap(err, "gateway: error calling GetShare") - } - - if getShareRes.Status.Code != rpc.Code_CODE_OK { - return &collaboration.UpdateShareResponse{ - Status: status.NewInternal(ctx, status.NewErrorFromCode(getShareRes.Status.Code, "gateway"), - "error getting share when committing to the share"), - }, nil - } - updateGrantStatus, err := s.updateGrant(ctx, getShareRes.GetShare().GetResourceId(), - getShareRes.GetShare().GetGrantee(), - getShareRes.GetShare().GetPermissions().GetPermissions()) + updateGrantStatus, err := s.updateGrant(ctx, res.GetShare().GetResourceId(), + res.GetShare().GetGrantee(), + res.GetShare().GetPermissions().GetPermissions()) if err != nil { return nil, errors.Wrap(err, "gateway: error calling updateGrant") @@ -221,6 +207,7 @@ func (s *svc) UpdateShare(ctx context.Context, req *collaboration.UpdateShareReq if updateGrantStatus.Code != rpc.Code_CODE_OK { return &collaboration.UpdateShareResponse{ Status: updateGrantStatus, + Share: res.Share, }, nil } } @@ -309,34 +296,17 @@ func (s *svc) UpdateReceivedShare(ctx context.Context, req *collaboration.Update // share display name and storage filename. if req.Field.GetState() != collaboration.ShareState_SHARE_STATE_INVALID { if req.Field.GetState() == collaboration.ShareState_SHARE_STATE_ACCEPTED { - getShareReq := &collaboration.GetReceivedShareRequest{Ref: req.Ref} - getShareRes, err := s.GetReceivedShare(ctx, getShareReq) - if err != nil { - log.Err(err).Msg("gateway: error calling GetReceivedShare") - return &collaboration.UpdateReceivedShareResponse{ - Status: &rpc.Status{ - Code: rpc.Code_CODE_INTERNAL, - }, - }, nil - } - - if getShareRes.Status.Code != rpc.Code_CODE_OK { - log.Error().Msg("gateway: error calling GetReceivedShare") - return &collaboration.UpdateReceivedShareResponse{ - Status: &rpc.Status{ - Code: rpc.Code_CODE_INTERNAL, - }, - }, nil - } - - share := getShareRes.Share + share := res.Share if share == nil { panic("gateway: error updating a received share: the share is nil") } - createRefStatus, err := s.createReference(ctx, share.Share.ResourceId) - return &collaboration.UpdateReceivedShareResponse{ - Status: createRefStatus, - }, err + createRefStatus := s.createReference(ctx, share.Share.ResourceId) + rsp := &collaboration.UpdateReceivedShareResponse{Status: createRefStatus} + + if createRefStatus.Code == rpc.Code_CODE_OK { + rsp.Share = share + } + return rsp, nil } else if req.Field.GetState() == collaboration.ShareState_SHARE_STATE_REJECTED { // Nothing more to do, return the original result return res, nil @@ -350,7 +320,7 @@ func (s *svc) UpdateReceivedShare(ctx context.Context, req *collaboration.Update }, nil } -func (s *svc) createReference(ctx context.Context, resourceID *provider.ResourceId) (*rpc.Status, error) { +func (s *svc) createReference(ctx context.Context, resourceID *provider.ResourceId) *rpc.Status { log := appctx.GetLogger(ctx) @@ -358,9 +328,9 @@ func (s *svc) createReference(ctx context.Context, resourceID *provider.Resource c, err := s.findByID(ctx, resourceID) if err != nil { if _, ok := err.(errtypes.IsNotFound); ok { - return status.NewNotFound(ctx, "storage provider not found"), nil + return status.NewNotFound(ctx, "storage provider not found") } - return status.NewInternal(ctx, err, "error finding storage provider"), nil + return status.NewInternal(ctx, err, "error finding storage provider") } statReq := &provider.StatRequest{ @@ -373,19 +343,19 @@ func (s *svc) createReference(ctx context.Context, resourceID *provider.Resource statRes, err := c.Stat(ctx, statReq) if err != nil { - return status.NewInternal(ctx, err, "gateway: error calling Stat for the share resource id: "+resourceID.String()), nil + return status.NewInternal(ctx, err, "gateway: error calling Stat for the share resource id: "+resourceID.String()) } if statRes.Status.Code != rpc.Code_CODE_OK { err := status.NewErrorFromCode(statRes.Status.GetCode(), "gateway") log.Err(err).Msg("gateway: Stat failed on the share resource id: " + resourceID.String()) - return status.NewInternal(ctx, err, "error updating received share"), nil + return status.NewInternal(ctx, err, "error updating received share") } homeRes, err := s.GetHome(ctx, &provider.GetHomeRequest{}) if err != nil { err := errors.Wrap(err, "gateway: error calling GetHome") - return status.NewInternal(ctx, err, "error updating received share"), nil + return status.NewInternal(ctx, err, "error updating received share") } // reference path is the home path + some name @@ -410,9 +380,9 @@ func (s *svc) createReference(ctx context.Context, resourceID *provider.Resource c, err = s.findByPath(ctx, refPath) if err != nil { if _, ok := err.(errtypes.IsNotFound); ok { - return status.NewNotFound(ctx, "storage provider not found"), nil + return status.NewNotFound(ctx, "storage provider not found") } - return status.NewInternal(ctx, err, "error finding storage provider"), nil + return status.NewInternal(ctx, err, "error finding storage provider") } createRefRes, err := c.CreateReference(ctx, createRefReq) @@ -420,15 +390,15 @@ func (s *svc) createReference(ctx context.Context, resourceID *provider.Resource log.Err(err).Msg("gateway: error calling GetHome") return &rpc.Status{ Code: rpc.Code_CODE_INTERNAL, - }, nil + } } if createRefRes.Status.Code != rpc.Code_CODE_OK { err := status.NewErrorFromCode(createRefRes.Status.GetCode(), "gateway") - return status.NewInternal(ctx, err, "error updating received share"), nil + return status.NewInternal(ctx, err, "error updating received share") } - return status.NewOK(ctx), nil + return status.NewOK(ctx) } func (s *svc) addGrant(ctx context.Context, id *provider.ResourceId, g *provider.Grantee, p *provider.ResourcePermissions) (*rpc.Status, error) { diff --git a/internal/grpc/services/usershareprovider/usershareprovider.go b/internal/grpc/services/usershareprovider/usershareprovider.go index 0e8521d900..a4997d405b 100644 --- a/internal/grpc/services/usershareprovider/usershareprovider.go +++ b/internal/grpc/services/usershareprovider/usershareprovider.go @@ -172,7 +172,7 @@ func (s *service) ListShares(ctx context.Context, req *collaboration.ListSharesR } func (s *service) UpdateShare(ctx context.Context, req *collaboration.UpdateShareRequest) (*collaboration.UpdateShareResponse, error) { - _, err := s.sm.UpdateShare(ctx, req.Ref, req.Field.GetPermissions()) // TODO(labkode): check what to update + share, err := s.sm.UpdateShare(ctx, req.Ref, req.Field.GetPermissions()) // TODO(labkode): check what to update if err != nil { return &collaboration.UpdateShareResponse{ Status: status.NewInternal(ctx, err, "error updating share"), @@ -181,6 +181,7 @@ func (s *service) UpdateShare(ctx context.Context, req *collaboration.UpdateShar res := &collaboration.UpdateShareResponse{ Status: status.NewOK(ctx), + Share: share, } return res, nil } @@ -219,7 +220,7 @@ func (s *service) GetReceivedShare(ctx context.Context, req *collaboration.GetRe } func (s *service) UpdateReceivedShare(ctx context.Context, req *collaboration.UpdateReceivedShareRequest) (*collaboration.UpdateReceivedShareResponse, error) { - _, err := s.sm.UpdateReceivedShare(ctx, req.Ref, req.Field) // TODO(labkode): check what to update + share, err := s.sm.UpdateReceivedShare(ctx, req.Ref, req.Field) // TODO(labkode): check what to update if err != nil { return &collaboration.UpdateReceivedShareResponse{ Status: status.NewInternal(ctx, err, "error updating received share"), @@ -228,6 +229,7 @@ func (s *service) UpdateReceivedShare(ctx context.Context, req *collaboration.Up res := &collaboration.UpdateReceivedShareResponse{ Status: status.NewOK(ctx), + Share: share, } return res, nil } diff --git a/internal/http/services/owncloud/ocs/handlers/apps/sharing/shares/group.go b/internal/http/services/owncloud/ocs/handlers/apps/sharing/shares/group.go index 9e24024c7b..56663aec29 100644 --- a/internal/http/services/owncloud/ocs/handlers/apps/sharing/shares/group.go +++ b/internal/http/services/owncloud/ocs/handlers/apps/sharing/shares/group.go @@ -80,30 +80,5 @@ func (h *Handler) createGroupShare(w http.ResponseWriter, r *http.Request, statI }, } - createShareResponse, err := c.CreateShare(ctx, createShareReq) - if err != nil { - response.WriteOCSError(w, r, response.MetaServerError.StatusCode, "error sending a grpc create share request", err) - return - } - if createShareResponse.Status.Code != rpc.Code_CODE_OK { - if createShareResponse.Status.Code == rpc.Code_CODE_NOT_FOUND { - response.WriteOCSError(w, r, response.MetaNotFound.StatusCode, "not found", nil) - return - } - response.WriteOCSError(w, r, response.MetaServerError.StatusCode, "grpc create share request failed", err) - return - } - s, err := conversions.CS3Share2ShareData(ctx, createShareResponse.Share) - if err != nil { - response.WriteOCSError(w, r, response.MetaServerError.StatusCode, "error mapping share data", err) - return - } - err = h.addFileInfo(ctx, s, statInfo) - if err != nil { - response.WriteOCSError(w, r, response.MetaServerError.StatusCode, "error adding fileinfo to share", err) - return - } - h.mapUserIds(ctx, c, s) - - response.WriteOCSSuccess(w, r, s) + h.createCs3Share(ctx, w, r, c, createShareReq, statInfo) } diff --git a/internal/http/services/owncloud/ocs/handlers/apps/sharing/shares/pending.go b/internal/http/services/owncloud/ocs/handlers/apps/sharing/shares/pending.go index 45eb94619c..4a7d06684a 100644 --- a/internal/http/services/owncloud/ocs/handlers/apps/sharing/shares/pending.go +++ b/internal/http/services/owncloud/ocs/handlers/apps/sharing/shares/pending.go @@ -20,31 +20,37 @@ package shares import ( "net/http" + "path" rpc "github.com/cs3org/go-cs3apis/cs3/rpc/v1beta1" collaboration "github.com/cs3org/go-cs3apis/cs3/sharing/collaboration/v1beta1" + "github.com/cs3org/reva/internal/http/services/owncloud/ocs/conversions" "github.com/cs3org/reva/internal/http/services/owncloud/ocs/response" + "github.com/cs3org/reva/pkg/appctx" "github.com/cs3org/reva/pkg/rgrpc/todo/pool" "github.com/pkg/errors" ) func (h *Handler) updateReceivedShare(w http.ResponseWriter, r *http.Request, shareID string, rejectShare bool) { ctx := r.Context() + logger := appctx.GetLogger(ctx) - uClient, err := pool.GetGatewayServiceClient(h.gatewayAddr) + client, err := pool.GetGatewayServiceClient(h.gatewayAddr) if err != nil { response.WriteOCSError(w, r, response.MetaServerError.StatusCode, "error getting grpc gateway client", err) return } - shareRequest := &collaboration.UpdateReceivedShareRequest{ - Ref: &collaboration.ShareReference{ - Spec: &collaboration.ShareReference_Id{ - Id: &collaboration.ShareId{ - OpaqueId: shareID, - }, + ref := &collaboration.ShareReference{ + Spec: &collaboration.ShareReference_Id{ + Id: &collaboration.ShareId{ + OpaqueId: shareID, }, }, + } + + shareRequest := &collaboration.UpdateReceivedShareRequest{ + Ref: ref, Field: &collaboration.UpdateReceivedShareRequest_UpdateField{ Field: &collaboration.UpdateReceivedShareRequest_UpdateField_State{ State: collaboration.ShareState_SHARE_STATE_ACCEPTED, @@ -59,7 +65,7 @@ func (h *Handler) updateReceivedShare(w http.ResponseWriter, r *http.Request, sh } } - shareRes, err := uClient.UpdateReceivedShare(ctx, shareRequest) + shareRes, err := client.UpdateReceivedShare(ctx, shareRequest) if err != nil { response.WriteOCSError(w, r, response.MetaServerError.StatusCode, "grpc update received share request failed", err) return @@ -73,4 +79,31 @@ func (h *Handler) updateReceivedShare(w http.ResponseWriter, r *http.Request, sh response.WriteOCSError(w, r, response.MetaServerError.StatusCode, "grpc update received share request failed", errors.Errorf("code: %d, message: %s", shareRes.Status.Code, shareRes.Status.Message)) return } + + rs := shareRes.GetShare() + + info, status, err := h.getResourceInfoByID(ctx, client, rs.Share.ResourceId) + if err != nil || status.Code != rpc.Code_CODE_OK { + h.logProblems(status, err, "could not stat, skipping") + } + + data, err := conversions.CS3Share2ShareData(r.Context(), rs.Share) + if err != nil { + logger.Debug().Interface("share", rs.Share).Interface("shareData", data).Err(err).Msg("could not CS3Share2ShareData, skipping") + } + + data.State = mapState(rs.GetState()) + + if err := h.addFileInfo(ctx, data, info); err != nil { + logger.Debug().Interface("received_share", rs).Interface("info", info).Interface("shareData", data).Err(err).Msg("could not add file info, skipping") + } + h.mapUserIds(r.Context(), client, data) + + if data.State == ocsStateAccepted { + // Needed because received shares can be jailed in a folder in the users home + data.FileTarget = path.Join(h.sharePrefix, path.Base(info.Path)) + data.Path = path.Join(h.sharePrefix, path.Base(info.Path)) + } + + response.WriteOCSSuccess(w, r, data) } diff --git a/internal/http/services/owncloud/ocs/handlers/apps/sharing/shares/public.go b/internal/http/services/owncloud/ocs/handlers/apps/sharing/shares/public.go index e574551d4e..5c8029f4a1 100644 --- a/internal/http/services/owncloud/ocs/handlers/apps/sharing/shares/public.go +++ b/internal/http/services/owncloud/ocs/handlers/apps/sharing/shares/public.go @@ -23,7 +23,6 @@ import ( "fmt" "net/http" "strconv" - "time" rpc "github.com/cs3org/go-cs3apis/cs3/rpc/v1beta1" collaboration "github.com/cs3org/go-cs3apis/cs3/sharing/collaboration/v1beta1" @@ -143,7 +142,7 @@ func (h *Handler) listPublicShares(r *http.Request, filters []*link.ListPublicSh ocsDataPayload := make([]*conversions.ShareData, 0) // TODO(refs) why is this guard needed? Are we moving towards a gateway only for service discovery? without a gateway this is dead code. if h.gatewayAddr != "" { - c, err := pool.GetGatewayServiceClient(h.gatewayAddr) + client, err := pool.GetGatewayServiceClient(h.gatewayAddr) if err != nil { return ocsDataPayload, nil, err } @@ -152,7 +151,7 @@ func (h *Handler) listPublicShares(r *http.Request, filters []*link.ListPublicSh Filters: filters, } - res, err := c.ListPublicShares(ctx, &req) + res, err := client.ListPublicShares(ctx, &req) if err != nil { return ocsDataPayload, nil, err } @@ -160,30 +159,11 @@ func (h *Handler) listPublicShares(r *http.Request, filters []*link.ListPublicSh return ocsDataPayload, res.Status, nil } - var info *provider.ResourceInfo for _, share := range res.GetShare() { - key := wrapResourceID(share.ResourceId) - if infoIf, err := h.resourceInfoCache.Get(key); h.resourceInfoCacheTTL > 0 && err == nil { - log.Debug().Msgf("cache hit for resource %+v", share.ResourceId) - info = infoIf.(*provider.ResourceInfo) - } else { - statRequest := &provider.StatRequest{ - Ref: &provider.Reference{ - Spec: &provider.Reference_Id{ - Id: share.ResourceId, - }, - }, - } - - statResponse, err := c.Stat(ctx, statRequest) - if err != nil || res.Status.Code != rpc.Code_CODE_OK { - log.Debug().Interface("share", share).Interface("response", statResponse).Err(err).Msg("could not stat share, skipping") - continue - } - info = statResponse.Info - if h.resourceInfoCacheTTL > 0 { - _ = h.resourceInfoCache.SetWithExpire(key, info, time.Second*h.resourceInfoCacheTTL) - } + info, status, err := h.getResourceInfoByID(ctx, client, share.ResourceId) + if err != nil || status.Code != rpc.Code_CODE_OK { + log.Debug().Interface("share", share).Interface("status", status).Err(err).Msg("could not stat share, skipping") + continue } sData := conversions.PublicShare2ShareData(share, r, h.publicURL) @@ -194,7 +174,7 @@ func (h *Handler) listPublicShares(r *http.Request, filters []*link.ListPublicSh log.Debug().Interface("share", share).Interface("info", info).Err(err).Msg("could not add file info, skipping") continue } - h.mapUserIds(ctx, c, sData) + h.mapUserIds(ctx, client, sData) log.Debug().Interface("share", share).Interface("info", info).Interface("shareData", share).Msg("mapped") diff --git a/internal/http/services/owncloud/ocs/handlers/apps/sharing/shares/shares.go b/internal/http/services/owncloud/ocs/handlers/apps/sharing/shares/shares.go index 10e13afbc2..fefe0acad2 100644 --- a/internal/http/services/owncloud/ocs/handlers/apps/sharing/shares/shares.go +++ b/internal/http/services/owncloud/ocs/handlers/apps/sharing/shares/shares.go @@ -61,10 +61,10 @@ type Handler struct { publicURL string sharePrefix string homeNamespace string - resourceInfoCacheTTL time.Duration additionalInfoTemplate *template.Template userIdentifierCache *ttlcache.Cache resourceInfoCache gcache.Cache + resourceInfoCacheTTL time.Duration } // we only cache the minimal set of data instead of the full user metadata @@ -87,14 +87,13 @@ func (h *Handler) Init(c *config.Config) error { h.publicURL = c.Config.Host h.sharePrefix = c.SharePrefix h.homeNamespace = c.HomeNamespace - h.resourceInfoCacheTTL = time.Duration(c.ResourceInfoCacheTTL) + h.resourceInfoCache = gcache.New(c.ResourceInfoCacheSize).LFU().Build() + h.resourceInfoCacheTTL = time.Second * time.Duration(c.ResourceInfoCacheTTL) h.additionalInfoTemplate, _ = template.New("additionalInfo").Parse(c.AdditionalInfoAttribute) h.userIdentifierCache = ttlcache.NewCache() - _ = h.userIdentifierCache.SetTTL(60 * time.Second) - - h.resourceInfoCache = gcache.New(c.ResourceInfoCacheSize).LFU().Build() + _ = h.userIdentifierCache.SetTTL(time.Second * 60) if h.resourceInfoCacheTTL > 0 { cwm, err := getCacheWarmupManager(c) @@ -208,7 +207,7 @@ func (h *Handler) createShare(w http.ResponseWriter, r *http.Request) { } // get user permissions on the shared file - c, err := pool.GetGatewayServiceClient(h.gatewayAddr) + client, err := pool.GetGatewayServiceClient(h.gatewayAddr) if err != nil { response.WriteOCSError(w, r, response.MetaServerError.StatusCode, "error getting grpc gateway client", err) return @@ -227,7 +226,7 @@ func (h *Handler) createShare(w http.ResponseWriter, r *http.Request) { sublog := appctx.GetLogger(ctx).With().Str("path", fn).Logger() - statRes, err := c.Stat(ctx, &statReq) + statRes, err := client.Stat(ctx, &statReq) if err != nil { sublog.Debug().Err(err).Str("createShare", "shares").Msg("error on stat call") response.WriteOCSError(w, r, response.MetaServerError.StatusCode, "missing resource information", fmt.Errorf("error getting resource information")) @@ -274,7 +273,6 @@ func (h *Handler) createShare(w http.ResponseWriter, r *http.Request) { func (h *Handler) extractPermissions(w http.ResponseWriter, r *http.Request, ri *provider.ResourceInfo, defaultPermissions *conversions.Role) (*conversions.Role, []byte, error) { reqRole, reqPermissions := r.FormValue("role"), r.FormValue("permissions") var role *conversions.Role - var permissions conversions.Permissions // the share role overrides the requested permissions if reqRole != "" { @@ -290,7 +288,7 @@ func (h *Handler) extractPermissions(w http.ResponseWriter, r *http.Request, ri response.WriteOCSError(w, r, response.MetaBadRequest.StatusCode, "permissions must be an integer", nil) return nil, nil, err } - permissions, err = conversions.NewPermissions(pint) + perm, err := conversions.NewPermissions(pint) if err != nil { if err == conversions.ErrPermissionNotInRange { response.WriteOCSError(w, r, http.StatusNotFound, err.Error(), nil) @@ -299,25 +297,25 @@ func (h *Handler) extractPermissions(w http.ResponseWriter, r *http.Request, ri } return nil, nil, err } - role = conversions.RoleFromOCSPermissions(permissions) + role = conversions.RoleFromOCSPermissions(perm) } } - permissions = role.OCSPermissions() + permissions := role.OCSPermissions() if ri != nil && ri.Type == provider.ResourceType_RESOURCE_TYPE_FILE { // Single file shares should never have delete or create permissions permissions &^= conversions.PermissionCreate permissions &^= conversions.PermissionDelete if permissions == conversions.PermissionInvalid { response.WriteOCSError(w, r, response.MetaBadRequest.StatusCode, "Cannot set the requested share permissions", nil) - return nil, nil, fmt.Errorf("Cannot set the requested share permissions") + return nil, nil, errors.New("cannot set the requested share permissions") } } existingPermissions := conversions.RoleFromResourcePermissions(ri.PermissionSet).OCSPermissions() if permissions == conversions.PermissionInvalid || !existingPermissions.Contain(permissions) { response.WriteOCSError(w, r, http.StatusNotFound, "Cannot set the requested share permissions", nil) - return nil, nil, fmt.Errorf("Cannot set the requested share permissions") + return nil, nil, errors.New("cannot set the requested share permissions") } role = conversions.RoleFromOCSPermissions(permissions) @@ -424,37 +422,17 @@ func (h *Handler) getShare(w http.ResponseWriter, r *http.Request, shareID strin return } - var info *provider.ResourceInfo - key := wrapResourceID(resourceID) - if infoIf, err := h.resourceInfoCache.Get(key); h.resourceInfoCacheTTL > 0 && err == nil { - logger.Debug().Msgf("cache hit for resource %+v", resourceID) - info = infoIf.(*provider.ResourceInfo) - } else { - // prepare the stat request - statReq := &provider.StatRequest{ - // prepare the reference - Ref: &provider.Reference{ - // using ResourceId from the share - Spec: &provider.Reference_Id{Id: resourceID}, - }, - } - - statResponse, err := client.Stat(ctx, statReq) - if err != nil { - log.Error().Err(err).Msg("error mapping share data") - response.WriteOCSError(w, r, response.MetaServerError.StatusCode, "error mapping share data", err) - return - } + info, status, err := h.getResourceInfoByID(ctx, client, resourceID) + if err != nil { + log.Error().Err(err).Msg("error mapping share data") + response.WriteOCSError(w, r, response.MetaServerError.StatusCode, "error mapping share data", err) + return + } - if statResponse.Status.Code != rpc.Code_CODE_OK { - log.Error().Err(err).Str("status", statResponse.Status.Code.String()).Msg("error mapping share data") - response.WriteOCSError(w, r, response.MetaServerError.StatusCode, "error mapping share data", err) - return - } - info = statResponse.Info - if h.resourceInfoCacheTTL > 0 { - _ = h.resourceInfoCache.SetWithExpire(key, info, time.Second*h.resourceInfoCacheTTL) - } + if status.Code != rpc.Code_CODE_OK { + log.Error().Err(err).Str("status", status.Code.String()).Msg("error mapping share data") + response.WriteOCSError(w, r, response.MetaServerError.StatusCode, "error mapping share data", err) + return } err = h.addFileInfo(ctx, share, info) @@ -487,7 +465,7 @@ func (h *Handler) updateShare(w http.ResponseWriter, r *http.Request, shareID st return } - uClient, err := pool.GetGatewayServiceClient(h.gatewayAddr) + client, err := pool.GetGatewayServiceClient(h.gatewayAddr) if err != nil { response.WriteOCSError(w, r, response.MetaServerError.StatusCode, "error getting grpc gateway client", err) return @@ -510,7 +488,7 @@ func (h *Handler) updateShare(w http.ResponseWriter, r *http.Request, shareID st }, }, } - uRes, err := uClient.UpdateShare(ctx, uReq) + uRes, err := client.UpdateShare(ctx, uReq) if err != nil { response.WriteOCSError(w, r, response.MetaServerError.StatusCode, "error sending a grpc update share request", err) return @@ -525,31 +503,7 @@ func (h *Handler) updateShare(w http.ResponseWriter, r *http.Request, shareID st return } - gReq := &collaboration.GetShareRequest{ - Ref: &collaboration.ShareReference{ - Spec: &collaboration.ShareReference_Id{ - Id: &collaboration.ShareId{ - OpaqueId: shareID, - }, - }, - }, - } - gRes, err := uClient.GetShare(ctx, gReq) - if err != nil { - response.WriteOCSError(w, r, response.MetaServerError.StatusCode, "error sending a grpc get share request", err) - return - } - - if gRes.Status.Code != rpc.Code_CODE_OK { - if gRes.Status.Code == rpc.Code_CODE_NOT_FOUND { - response.WriteOCSError(w, r, response.MetaNotFound.StatusCode, "not found", nil) - return - } - response.WriteOCSError(w, r, response.MetaServerError.StatusCode, "grpc get share request failed", err) - return - } - - share, err := conversions.CS3Share2ShareData(ctx, gRes.Share) + share, err := conversions.CS3Share2ShareData(ctx, uRes.Share) if err != nil { response.WriteOCSError(w, r, response.MetaServerError.StatusCode, "error mapping share data", err) return @@ -558,12 +512,12 @@ func (h *Handler) updateShare(w http.ResponseWriter, r *http.Request, shareID st statReq := provider.StatRequest{ Ref: &provider.Reference{ Spec: &provider.Reference_Id{ - Id: gRes.Share.ResourceId, + Id: uRes.Share.ResourceId, }, }, } - statRes, err := uClient.Stat(r.Context(), &statReq) + statRes, err := client.Stat(r.Context(), &statReq) if err != nil { log.Debug().Err(err).Str("shares", "update user share").Msg("error during stat") response.WriteOCSError(w, r, response.MetaServerError.StatusCode, "missing resource information", fmt.Errorf("error getting resource information")) @@ -585,7 +539,7 @@ func (h *Handler) updateShare(w http.ResponseWriter, r *http.Request, shareID st response.WriteOCSError(w, r, response.MetaServerError.StatusCode, err.Error(), err) return } - h.mapUserIds(ctx, uClient, share) + h.mapUserIds(ctx, client, share) response.WriteOCSSuccess(w, r, share) } @@ -601,35 +555,24 @@ func (h *Handler) isListSharesWithMe(w http.ResponseWriter, r *http.Request) (li return } -const ocsStateUnknown = -1 -const ocsStateAccepted = 0 -const ocsStatePending = 1 -const ocsStateRejected = 2 +const ( + ocsStateUnknown = -1 + ocsStateAccepted = 0 + ocsStatePending = 1 + ocsStateRejected = 2 +) func (h *Handler) listSharesWithMe(w http.ResponseWriter, r *http.Request) { // which pending state to list - var stateFilter collaboration.ShareState - switch r.FormValue("state") { - case "all": - stateFilter = ocsStateUnknown // no filter - case "0": // accepted - stateFilter = collaboration.ShareState_SHARE_STATE_ACCEPTED - case "1": // pending - stateFilter = collaboration.ShareState_SHARE_STATE_PENDING - case "2": // rejected - stateFilter = collaboration.ShareState_SHARE_STATE_REJECTED - default: - stateFilter = collaboration.ShareState_SHARE_STATE_ACCEPTED - } + stateFilter := getStateFilter(r.FormValue("state")) - gwc, err := pool.GetGatewayServiceClient(h.gatewayAddr) + client, err := pool.GetGatewayServiceClient(h.gatewayAddr) if err != nil { response.WriteOCSError(w, r, response.MetaServerError.StatusCode, "error getting grpc gateway client", err) return } ctx := r.Context() - logger := appctx.GetLogger(ctx) var pinfo *provider.ResourceInfo p := r.URL.Query().Get("path") @@ -638,46 +581,26 @@ func (h *Handler) listSharesWithMe(w http.ResponseWriter, r *http.Request) { // prefix the path with the owners home, because ocs share requests are relative to the home dir target := path.Join(h.homeNamespace, r.FormValue("path")) - if infoIf, err := h.resourceInfoCache.Get(target); h.resourceInfoCacheTTL > 0 && err == nil { - logger.Debug().Msgf("cache hit for resource %+v", target) - pinfo = infoIf.(*provider.ResourceInfo) - } else { - statReq := &provider.StatRequest{ - Ref: &provider.Reference{ - Spec: &provider.Reference_Path{ - Path: target, - }, - }, - } - - statRes, err := gwc.Stat(ctx, statReq) - if err != nil { - response.WriteOCSError(w, r, response.MetaServerError.StatusCode, "error sending a grpc stat request", err) - return - } - - if statRes.Status.Code != rpc.Code_CODE_OK { - switch statRes.Status.Code { - case rpc.Code_CODE_NOT_FOUND: - response.WriteOCSError(w, r, response.MetaNotFound.StatusCode, "path not found", nil) - case rpc.Code_CODE_PERMISSION_DENIED: - response.WriteOCSError(w, r, response.MetaUnauthorized.StatusCode, "permission denied", nil) - default: - response.WriteOCSError(w, r, response.MetaServerError.StatusCode, "grpc stat request failed", nil) - } - return - } - - pinfo = statRes.GetInfo() - if h.resourceInfoCacheTTL > 0 { - _ = h.resourceInfoCache.SetWithExpire(target, pinfo, time.Second*h.resourceInfoCacheTTL) + var status *rpc.Status + pinfo, status, err = h.getResourceInfoByPath(ctx, client, target) + if err != nil { + response.WriteOCSError(w, r, response.MetaServerError.StatusCode, "error sending a grpc stat request", err) + return + } + if status.Code != rpc.Code_CODE_OK { + switch status.Code { + case rpc.Code_CODE_NOT_FOUND: + response.WriteOCSError(w, r, response.MetaNotFound.StatusCode, "path not found", nil) + case rpc.Code_CODE_PERMISSION_DENIED: + response.WriteOCSError(w, r, response.MetaUnauthorized.StatusCode, "permission denied", nil) + default: + response.WriteOCSError(w, r, response.MetaServerError.StatusCode, "grpc stat request failed", nil) } + return } } - lrsReq := collaboration.ListReceivedSharesRequest{} - - lrsRes, err := gwc.ListReceivedShares(r.Context(), &lrsReq) + lrsRes, err := client.ListReceivedShares(ctx, &collaboration.ListReceivedSharesRequest{}) if err != nil { response.WriteOCSError(w, r, response.MetaServerError.StatusCode, "error sending a grpc ListReceivedShares request", err) return @@ -691,17 +614,15 @@ func (h *Handler) listSharesWithMe(w http.ResponseWriter, r *http.Request) { response.WriteOCSError(w, r, response.MetaServerError.StatusCode, "grpc ListReceivedShares request failed", err) return } - lrsRes.GetShares() - shares := make([]*conversions.ShareData, 0) + shares := make([]*conversions.ShareData, 0, len(lrsRes.GetShares())) - var info *provider.ResourceInfo // TODO(refs) filter out "invalid" shares for _, rs := range lrsRes.GetShares() { - if stateFilter != ocsStateUnknown && rs.GetState() != stateFilter { continue } + var info *provider.ResourceInfo if pinfo != nil { // check if the shared resource matches the path resource if rs.Share.ResourceId.StorageId != pinfo.GetId().StorageId || @@ -712,30 +633,11 @@ func (h *Handler) listSharesWithMe(w http.ResponseWriter, r *http.Request) { // we can reuse the stat info info = pinfo } else { - key := wrapResourceID(rs.Share.ResourceId) - if infoIf, err := h.resourceInfoCache.Get(key); h.resourceInfoCacheTTL > 0 && err == nil { - logger.Debug().Msgf("cache hit for resource %+v", rs.Share.ResourceId) - info = infoIf.(*provider.ResourceInfo) - } else { - // we need to do a stat call - statRequest := provider.StatRequest{ - Ref: &provider.Reference{ - Spec: &provider.Reference_Id{ - Id: rs.Share.ResourceId, - }, - }, - } - - statRes, err := gwc.Stat(r.Context(), &statRequest) - if err != nil || statRes.Status.Code != rpc.Code_CODE_OK { - h.logProblems(statRes.GetStatus(), err, "could not stat, skipping") - continue - } - - info = statRes.GetInfo() - if h.resourceInfoCacheTTL > 0 { - _ = h.resourceInfoCache.SetWithExpire(key, info, time.Second*h.resourceInfoCacheTTL) - } + var status *rpc.Status + info, status, err = h.getResourceInfoByID(ctx, client, rs.Share.ResourceId) + if err != nil || status.Code != rpc.Code_CODE_OK { + h.logProblems(status, err, "could not stat, skipping") + continue } } @@ -745,22 +647,13 @@ func (h *Handler) listSharesWithMe(w http.ResponseWriter, r *http.Request) { continue } - switch rs.GetState() { - case collaboration.ShareState_SHARE_STATE_PENDING: - data.State = ocsStatePending - case collaboration.ShareState_SHARE_STATE_ACCEPTED: - data.State = ocsStateAccepted - case collaboration.ShareState_SHARE_STATE_REJECTED: - data.State = ocsStateRejected - default: - data.State = ocsStateUnknown - } + data.State = mapState(rs.GetState()) if err := h.addFileInfo(ctx, data, info); err != nil { log.Debug().Interface("received_share", rs).Interface("info", info).Interface("shareData", data).Err(err).Msg("could not add file info, skipping") continue } - h.mapUserIds(r.Context(), gwc, data) + h.mapUserIds(r.Context(), client, data) if data.State == ocsStateAccepted { // Needed because received shares can be jailed in a folder in the users home @@ -836,48 +729,30 @@ func (h *Handler) logProblems(s *rpc.Status, e error, msg string) { func (h *Handler) addFilters(w http.ResponseWriter, r *http.Request, prefix string) ([]*collaboration.ListSharesRequest_Filter, []*link.ListPublicSharesRequest_Filter, error) { collaborationFilters := []*collaboration.ListSharesRequest_Filter{} linkFilters := []*link.ListPublicSharesRequest_Filter{} - var info *provider.ResourceInfo ctx := r.Context() // first check if the file exists - gwClient, err := pool.GetGatewayServiceClient(h.gatewayAddr) + client, err := pool.GetGatewayServiceClient(h.gatewayAddr) if err != nil { response.WriteOCSError(w, r, response.MetaServerError.StatusCode, "error getting grpc gateway client", err) return nil, nil, err } target := path.Join(prefix, r.FormValue("path")) - if infoIf, err := h.resourceInfoCache.Get(target); h.resourceInfoCacheTTL > 0 && err == nil { - info = infoIf.(*provider.ResourceInfo) - } else { - statReq := &provider.StatRequest{ - Ref: &provider.Reference{ - Spec: &provider.Reference_Path{ - Path: target, - }, - }, - } - - res, err := gwClient.Stat(ctx, statReq) - if err != nil { - response.WriteOCSError(w, r, response.MetaServerError.StatusCode, "error sending a grpc stat request", err) - return nil, nil, err - } + info, status, err := h.getResourceInfoByPath(ctx, client, target) + if err != nil { + response.WriteOCSError(w, r, response.MetaServerError.StatusCode, "error sending a grpc stat request", err) + return nil, nil, err + } - if res.Status.Code != rpc.Code_CODE_OK { - err = errors.New(res.Status.Message) - if res.Status.Code == rpc.Code_CODE_NOT_FOUND { - response.WriteOCSError(w, r, response.MetaNotFound.StatusCode, "not found", err) - return nil, nil, err - } - response.WriteOCSError(w, r, response.MetaServerError.StatusCode, "grpc stat request failed", err) + if status.Code != rpc.Code_CODE_OK { + err = errors.New(status.Message) + if status.Code == rpc.Code_CODE_NOT_FOUND { + response.WriteOCSError(w, r, response.MetaNotFound.StatusCode, "not found", err) return nil, nil, err } - - info = res.Info - if h.resourceInfoCacheTTL > 0 { - _ = h.resourceInfoCache.SetWithExpire(target, info, time.Second*h.resourceInfoCacheTTL) - } + response.WriteOCSError(w, r, response.MetaServerError.StatusCode, "grpc stat request failed", err) + return nil, nil, err } collaborationFilters = append(collaborationFilters, &collaboration.ListSharesRequest_Filter{ @@ -943,14 +818,13 @@ func (h *Handler) addFileInfo(ctx context.Context, s *conversions.ShareData, inf } // mustGetIdentifiers always returns a struct with identifiers, if the user or group could not be found they will all be empty -func (h *Handler) mustGetIdentifiers(ctx context.Context, c gateway.GatewayAPIClient, id string, isGroup bool) *userIdentifiers { +func (h *Handler) mustGetIdentifiers(ctx context.Context, client gateway.GatewayAPIClient, id string, isGroup bool) *userIdentifiers { sublog := appctx.GetLogger(ctx).With().Str("id", id).Logger() if id == "" { return &userIdentifiers{} } - idIf, err := h.userIdentifierCache.Get(id) - if err == nil { + if idIf, err := h.userIdentifierCache.Get(id); err == nil { sublog.Debug().Msg("cache hit") return idIf.(*userIdentifiers) } @@ -959,7 +833,7 @@ func (h *Handler) mustGetIdentifiers(ctx context.Context, c gateway.GatewayAPICl var ui *userIdentifiers if isGroup { - res, err := c.GetGroup(ctx, &grouppb.GetGroupRequest{ + res, err := client.GetGroup(ctx, &grouppb.GetGroupRequest{ GroupId: &grouppb.GroupId{ OpaqueId: id, }, @@ -988,7 +862,7 @@ func (h *Handler) mustGetIdentifiers(ctx context.Context, c gateway.GatewayAPICl Mail: res.Group.Mail, } } else { - res, err := c.GetUser(ctx, &userpb.GetUserRequest{ + res, err := client.GetUser(ctx, &userpb.GetUserRequest{ UserId: &userpb.UserId{ OpaqueId: id, }, @@ -1022,9 +896,9 @@ func (h *Handler) mustGetIdentifiers(ctx context.Context, c gateway.GatewayAPICl return ui } -func (h *Handler) mapUserIds(ctx context.Context, c gateway.GatewayAPIClient, s *conversions.ShareData) { +func (h *Handler) mapUserIds(ctx context.Context, client gateway.GatewayAPIClient, s *conversions.ShareData) { if s.UIDOwner != "" { - owner := h.mustGetIdentifiers(ctx, c, s.UIDOwner, false) + owner := h.mustGetIdentifiers(ctx, client, s.UIDOwner, false) s.UIDOwner = owner.Username if s.DisplaynameOwner == "" { s.DisplaynameOwner = owner.DisplayName @@ -1035,7 +909,7 @@ func (h *Handler) mapUserIds(ctx context.Context, c gateway.GatewayAPIClient, s } if s.UIDFileOwner != "" { - fileOwner := h.mustGetIdentifiers(ctx, c, s.UIDFileOwner, false) + fileOwner := h.mustGetIdentifiers(ctx, client, s.UIDFileOwner, false) s.UIDFileOwner = fileOwner.Username if s.DisplaynameFileOwner == "" { s.DisplaynameFileOwner = fileOwner.DisplayName @@ -1046,7 +920,7 @@ func (h *Handler) mapUserIds(ctx context.Context, c gateway.GatewayAPIClient, s } if s.ShareWith != "" && s.ShareWith != "***redacted***" { - shareWith := h.mustGetIdentifiers(ctx, c, s.ShareWith, s.ShareType == conversions.ShareTypeGroup) + shareWith := h.mustGetIdentifiers(ctx, client, s.ShareWith, s.ShareType == conversions.ShareTypeGroup) s.ShareWith = shareWith.Username if s.ShareWithDisplayname == "" { s.ShareWithDisplayname = shareWith.DisplayName @@ -1058,11 +932,123 @@ func (h *Handler) mapUserIds(ctx context.Context, c gateway.GatewayAPIClient, s } func (h *Handler) getAdditionalInfoAttribute(ctx context.Context, u *userIdentifiers) string { - b := bytes.Buffer{} - if err := h.additionalInfoTemplate.Execute(&b, u); err != nil { + var buf bytes.Buffer + if err := h.additionalInfoTemplate.Execute(&buf, u); err != nil { log := appctx.GetLogger(ctx) log.Warn().Err(err).Msg("failed to parse additional info template") return "" } - return b.String() + return buf.String() +} + +func (h *Handler) getResourceInfoByPath(ctx context.Context, client gateway.GatewayAPIClient, path string) (*provider.ResourceInfo, *rpc.Status, error) { + return h.getResourceInfo(ctx, client, path, &provider.Reference{ + Spec: &provider.Reference_Path{ + Path: path, + }, + }) +} + +func (h *Handler) getResourceInfoByID(ctx context.Context, client gateway.GatewayAPIClient, id *provider.ResourceId) (*provider.ResourceInfo, *rpc.Status, error) { + return h.getResourceInfo(ctx, client, wrapResourceID(id), &provider.Reference{ + Spec: &provider.Reference_Id{ + Id: id, + }, + }) +} + +// getResourceInfo retrieves the resource info to a target. +// This method utilizes caching if it is enabled. +func (h *Handler) getResourceInfo(ctx context.Context, client gateway.GatewayAPIClient, key string, ref *provider.Reference) (*provider.ResourceInfo, *rpc.Status, error) { + logger := appctx.GetLogger(ctx) + + var pinfo *provider.ResourceInfo + var status *rpc.Status + if infoIf, err := h.resourceInfoCache.Get(key); h.resourceInfoCacheTTL > 0 && err == nil { + logger.Debug().Msgf("cache hit for resource %+v", key) + pinfo = infoIf.(*provider.ResourceInfo) + status = &rpc.Status{Code: rpc.Code_CODE_OK} + } else { + statReq := &provider.StatRequest{ + Ref: ref, + } + + statRes, err := client.Stat(ctx, statReq) + if err != nil { + return nil, nil, err + } + + if statRes.Status.Code != rpc.Code_CODE_OK { + return nil, statRes.Status, nil + } + + pinfo = statRes.GetInfo() + status = statRes.Status + if h.resourceInfoCacheTTL > 0 { + _ = h.resourceInfoCache.SetWithExpire(key, pinfo, h.resourceInfoCacheTTL) + } + } + + return pinfo, status, nil +} + +func (h *Handler) createCs3Share(ctx context.Context, w http.ResponseWriter, r *http.Request, client gateway.GatewayAPIClient, req *collaboration.CreateShareRequest, info *provider.ResourceInfo) { + createShareResponse, err := client.CreateShare(ctx, req) + if err != nil { + response.WriteOCSError(w, r, response.MetaServerError.StatusCode, "error sending a grpc create share request", err) + return + } + if createShareResponse.Status.Code != rpc.Code_CODE_OK { + if createShareResponse.Status.Code == rpc.Code_CODE_NOT_FOUND { + response.WriteOCSError(w, r, response.MetaNotFound.StatusCode, "not found", nil) + return + } + response.WriteOCSError(w, r, response.MetaServerError.StatusCode, "grpc create share request failed", err) + return + } + s, err := conversions.CS3Share2ShareData(ctx, createShareResponse.Share) + if err != nil { + response.WriteOCSError(w, r, response.MetaServerError.StatusCode, "error mapping share data", err) + return + } + err = h.addFileInfo(ctx, s, info) + if err != nil { + response.WriteOCSError(w, r, response.MetaServerError.StatusCode, "error adding fileinfo to share", err) + return + } + h.mapUserIds(ctx, client, s) + + response.WriteOCSSuccess(w, r, s) +} + +func mapState(state collaboration.ShareState) int { + var mapped int + switch state { + case collaboration.ShareState_SHARE_STATE_PENDING: + mapped = ocsStatePending + case collaboration.ShareState_SHARE_STATE_ACCEPTED: + mapped = ocsStateAccepted + case collaboration.ShareState_SHARE_STATE_REJECTED: + mapped = ocsStateRejected + default: + mapped = ocsStateUnknown + } + return mapped +} + +func getStateFilter(s string) collaboration.ShareState { + var stateFilter collaboration.ShareState + switch s { + case "all": + stateFilter = ocsStateUnknown // no filter + case "0": // accepted + stateFilter = collaboration.ShareState_SHARE_STATE_ACCEPTED + case "1": // pending + stateFilter = collaboration.ShareState_SHARE_STATE_PENDING + case "2": // rejected + stateFilter = collaboration.ShareState_SHARE_STATE_REJECTED + default: + stateFilter = collaboration.ShareState_SHARE_STATE_ACCEPTED + } + return stateFilter } diff --git a/internal/http/services/owncloud/ocs/handlers/apps/sharing/shares/shares_test.go b/internal/http/services/owncloud/ocs/handlers/apps/sharing/shares/shares_test.go new file mode 100644 index 0000000000..d21b7e42dc --- /dev/null +++ b/internal/http/services/owncloud/ocs/handlers/apps/sharing/shares/shares_test.go @@ -0,0 +1,72 @@ +// Copyright 2021 CERN +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// In applying this license, CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction.package shares +package shares + +import ( + "testing" + + collaboration "github.com/cs3org/go-cs3apis/cs3/sharing/collaboration/v1beta1" +) + +func TestGetStateFilter(t *testing.T) { + tests := []struct { + input string + expected collaboration.ShareState + }{ + {"all", ocsStateUnknown}, + {"0", collaboration.ShareState_SHARE_STATE_ACCEPTED}, + {"1", collaboration.ShareState_SHARE_STATE_PENDING}, + {"2", collaboration.ShareState_SHARE_STATE_REJECTED}, + {"something_invalid", collaboration.ShareState_SHARE_STATE_ACCEPTED}, + {"", collaboration.ShareState_SHARE_STATE_ACCEPTED}, + } + + for _, tt := range tests { + state := getStateFilter(tt.input) + if state != tt.expected { + t.Errorf("getStateFilter(\"%s\") returned %s instead of expected %s", tt.input, state, tt.expected) + } + } +} + +func TestMapState(t *testing.T) { + // case collaboration.ShareState_SHARE_STATE_PENDING: + // mapped = ocsStatePending + // case collaboration.ShareState_SHARE_STATE_ACCEPTED: + // mapped = ocsStateAccepted + // case collaboration.ShareState_SHARE_STATE_REJECTED: + // mapped = ocsStateRejected + // default: + // mapped = ocsStateUnknown + tests := []struct { + input collaboration.ShareState + expected int + }{ + {collaboration.ShareState_SHARE_STATE_PENDING, ocsStatePending}, + {collaboration.ShareState_SHARE_STATE_ACCEPTED, ocsStateAccepted}, + {collaboration.ShareState_SHARE_STATE_REJECTED, ocsStateRejected}, + {42, ocsStateUnknown}, + } + + for _, tt := range tests { + state := mapState(tt.input) + if state != tt.expected { + t.Errorf("mapState(%d) returned %d instead of expected %d", tt.input, state, tt.expected) + } + } +} diff --git a/internal/http/services/owncloud/ocs/handlers/apps/sharing/shares/user.go b/internal/http/services/owncloud/ocs/handlers/apps/sharing/shares/user.go index cac4cf61f8..1a133f34b6 100644 --- a/internal/http/services/owncloud/ocs/handlers/apps/sharing/shares/user.go +++ b/internal/http/services/owncloud/ocs/handlers/apps/sharing/shares/user.go @@ -20,7 +20,6 @@ package shares import ( "net/http" - "time" userpb "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1" rpc "github.com/cs3org/go-cs3apis/cs3/rpc/v1beta1" @@ -83,32 +82,7 @@ func (h *Handler) createUserShare(w http.ResponseWriter, r *http.Request, statIn }, } - createShareResponse, err := c.CreateShare(ctx, createShareReq) - if err != nil { - response.WriteOCSError(w, r, response.MetaServerError.StatusCode, "error sending a grpc create share request", err) - return - } - if createShareResponse.Status.Code != rpc.Code_CODE_OK { - if createShareResponse.Status.Code == rpc.Code_CODE_NOT_FOUND { - response.WriteOCSError(w, r, response.MetaNotFound.StatusCode, "not found", nil) - return - } - response.WriteOCSError(w, r, response.MetaServerError.StatusCode, "grpc create share request failed", err) - return - } - s, err := conversions.CS3Share2ShareData(ctx, createShareResponse.Share) - if err != nil { - response.WriteOCSError(w, r, response.MetaServerError.StatusCode, "error mapping share data", err) - return - } - err = h.addFileInfo(ctx, s, statInfo) - if err != nil { - response.WriteOCSError(w, r, response.MetaServerError.StatusCode, "error adding fileinfo to share", err) - return - } - h.mapUserIds(ctx, c, s) - - response.WriteOCSSuccess(w, r, s) + h.createCs3Share(ctx, w, r, c, createShareReq, statInfo) } func (h *Handler) removeUserShare(w http.ResponseWriter, r *http.Request, shareID string) { @@ -157,13 +131,13 @@ func (h *Handler) listUserShares(r *http.Request, filters []*collaboration.ListS ocsDataPayload := make([]*conversions.ShareData, 0) if h.gatewayAddr != "" { // get a connection to the users share provider - c, err := pool.GetGatewayServiceClient(h.gatewayAddr) + client, err := pool.GetGatewayServiceClient(h.gatewayAddr) if err != nil { return ocsDataPayload, nil, err } // do list shares request. filtered - lsUserSharesResponse, err := c.ListShares(ctx, &lsUserSharesRequest) + lsUserSharesResponse, err := client.ListShares(ctx, &lsUserSharesRequest) if err != nil { return ocsDataPayload, nil, err } @@ -179,35 +153,17 @@ func (h *Handler) listUserShares(r *http.Request, filters []*collaboration.ListS continue } - var info *provider.ResourceInfo - key := wrapResourceID(s.ResourceId) - if infoIf, err := h.resourceInfoCache.Get(key); h.resourceInfoCacheTTL > 0 && err == nil { - log.Debug().Msgf("cache hit for resource %+v", s.ResourceId) - info = infoIf.(*provider.ResourceInfo) - } else { - // prepare the stat request - statReq := &provider.StatRequest{ - Ref: &provider.Reference{ - Spec: &provider.Reference_Id{Id: s.ResourceId}, - }, - } - - statResponse, err := c.Stat(ctx, statReq) - if err != nil || statResponse.Status.Code != rpc.Code_CODE_OK { - log.Debug().Interface("share", s).Interface("response", statResponse).Interface("shareData", data).Err(err).Msg("could not stat share, skipping") - continue - } - info = statResponse.Info - if h.resourceInfoCacheTTL > 0 { - _ = h.resourceInfoCache.SetWithExpire(key, info, time.Second*h.resourceInfoCacheTTL) - } + info, status, err := h.getResourceInfoByID(ctx, client, s.ResourceId) + if err != nil || status.Code != rpc.Code_CODE_OK { + log.Debug().Interface("share", s).Interface("status", status).Interface("shareData", data).Err(err).Msg("could not stat share, skipping") + continue } if err := h.addFileInfo(ctx, data, info); err != nil { log.Debug().Interface("share", s).Interface("info", info).Interface("shareData", data).Err(err).Msg("could not add file info, skipping") continue } - h.mapUserIds(ctx, c, data) + h.mapUserIds(ctx, client, data) log.Debug().Interface("share", s).Interface("info", info).Interface("shareData", data).Msg("mapped") ocsDataPayload = append(ocsDataPayload, data) diff --git a/tests/acceptance/expected-failures-on-OCIS-storage.md b/tests/acceptance/expected-failures-on-OCIS-storage.md index 5edf2e3a3b..b14d72b910 100644 --- a/tests/acceptance/expected-failures-on-OCIS-storage.md +++ b/tests/acceptance/expected-failures-on-OCIS-storage.md @@ -640,8 +640,6 @@ File and sync features in a shared scenario #### [Response is empty when accepting a share](https://github.com/owncloud/product/issues/207) - [apiShareManagementToShares/acceptShares.feature:82](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareManagementToShares/acceptShares.feature#L82) -- [apiShareManagementToShares/acceptShares.feature:173](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareManagementToShares/acceptShares.feature#L173) -- [apiShareManagementToShares/acceptShares.feature:186](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareManagementToShares/acceptShares.feature#L186) - [apiShareManagementToShares/acceptShares.feature:207](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareManagementToShares/acceptShares.feature#L207) - [apiShareManagementToShares/acceptShares.feature:260](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareManagementToShares/acceptShares.feature#L260) - [apiShareManagementToShares/acceptSharesToSharesFolder.feature:31](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareManagementToShares/acceptSharesToSharesFolder.feature#L31) @@ -667,8 +665,6 @@ File and sync features in a shared scenario - [apiShareManagementBasicToShares/createShareToSharesFolder.feature:157](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareManagementBasicToShares/createShareToSharesFolder.feature#L157) - [apiShareManagementBasicToShares/createShareToSharesFolder.feature:290](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareManagementBasicToShares/createShareToSharesFolder.feature#L290) - [apiShareManagementBasicToShares/createShareToSharesFolder.feature:291](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareManagementBasicToShares/createShareToSharesFolder.feature#L291) -- [apiShareManagementBasicToShares/createShareToSharesFolder.feature:308](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareManagementBasicToShares/createShareToSharesFolder.feature#L308) -- [apiShareManagementBasicToShares/createShareToSharesFolder.feature:309](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareManagementBasicToShares/createShareToSharesFolder.feature#L309) - [apiShareManagementBasicToShares/deleteShareFromShares.feature:46](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareManagementBasicToShares/deleteShareFromShares.feature#L46) - [apiShareManagementToShares/mergeShare.feature:32](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareManagementToShares/mergeShare.feature#L32) - [apiShareManagementToShares/mergeShare.feature:42](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareManagementToShares/mergeShare.feature#L42) @@ -713,10 +709,6 @@ File and sync features in a shared scenario - [apiShareManagementBasicToShares/createShareToSharesFolder.feature:554](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareManagementBasicToShares/createShareToSharesFolder.feature#L554) - [apiShareManagementBasicToShares/createShareToSharesFolder.feature:572](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareManagementBasicToShares/createShareToSharesFolder.feature#L572) -#### [Response is empty when accepting a share](https://github.com/owncloud/product/issues/207) -- [apiShareManagementBasicToShares/createShareToSharesFolder.feature:347](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareManagementBasicToShares/createShareToSharesFolder.feature#L347) -- [apiShareManagementBasicToShares/createShareToSharesFolder.feature:348](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareManagementBasicToShares/createShareToSharesFolder.feature#L348) - #### [File deletion using dav gives unique string in filename in the trashbin](https://github.com/owncloud/product/issues/178) - [apiShareManagementBasicToShares/deleteShareFromShares.feature:58](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareManagementBasicToShares/deleteShareFromShares.feature#L58) @@ -1006,14 +998,6 @@ _requires a [CS3 user provisioning api that can update the quota for a user](htt #### [Resharing does not work with ocis storage](https://github.com/owncloud/product/issues/265) -- [apiShareReshareToShares1/reShare.feature:61](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareReshareToShares1/reShare.feature#L61) -- [apiShareReshareToShares1/reShare.feature:62](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareReshareToShares1/reShare.feature#L62) -- [apiShareReshareToShares1/reShare.feature:78](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareReshareToShares1/reShare.feature#L78) -- [apiShareReshareToShares1/reShare.feature:79](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareReshareToShares1/reShare.feature#L79) -- [apiShareReshareToShares1/reShare.feature:95](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareReshareToShares1/reShare.feature#L95) -- [apiShareReshareToShares1/reShare.feature:96](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareReshareToShares1/reShare.feature#L96) -- [apiShareReshareToShares1/reShare.feature:112](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareReshareToShares1/reShare.feature#L112) -- [apiShareReshareToShares1/reShare.feature:113](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareReshareToShares1/reShare.feature#L113) - [apiShareReshareToShares1/reShare.feature:169](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareReshareToShares1/reShare.feature#L169) - [apiShareReshareToShares1/reShare.feature:170](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareReshareToShares1/reShare.feature#L170) - [apiShareReshareToShares1/reShare.feature:171](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareReshareToShares1/reShare.feature#L171) @@ -1073,8 +1057,6 @@ _requires a [CS3 user provisioning api that can update the quota for a user](htt - [apiShareReshareToShares2/reShareDisabled.feature:27](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareReshareToShares2/reShareDisabled.feature#L27) - [apiShareReshareToShares2/reShareDisabled.feature:28](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareReshareToShares2/reShareDisabled.feature#L28) -- [apiShareReshareToShares2/reShareDisabled.feature:42](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareReshareToShares2/reShareDisabled.feature#L42) -- [apiShareReshareToShares2/reShareDisabled.feature:43](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareReshareToShares2/reShareDisabled.feature#L43) #### [share permissions are not enforced](https://github.com/owncloud/product/issues/270) @@ -1878,16 +1860,12 @@ Scenario Outline: Do a PROPFIND to a non-existing URL - [apiShareCreateSpecialToShares1/createShareWhenExcludedFromSharing.feature:79](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareCreateSpecialToShares1/createShareWhenExcludedFromSharing.feature#L79) - [apiShareCreateSpecialToShares2/createShareWhenShareWithOnlyMembershipGroups.feature:26](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareCreateSpecialToShares2/createShareWhenShareWithOnlyMembershipGroups.feature#L26) - [apiShareCreateSpecialToShares2/createShareWhenShareWithOnlyMembershipGroups.feature:27](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareCreateSpecialToShares2/createShareWhenShareWithOnlyMembershipGroups.feature#L27) -- [apiShareCreateSpecialToShares2/createShareWhenShareWithOnlyMembershipGroups.feature:46](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareCreateSpecialToShares2/createShareWhenShareWithOnlyMembershipGroups.feature#L46) -- [apiShareCreateSpecialToShares2/createShareWhenShareWithOnlyMembershipGroups.feature:47](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareCreateSpecialToShares2/createShareWhenShareWithOnlyMembershipGroups.feature#L47) - [apiShareCreateSpecialToShares2/createShareWhenShareWithOnlyMembershipGroups.feature:67](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareCreateSpecialToShares2/createShareWhenShareWithOnlyMembershipGroups.feature#L67) - [apiShareCreateSpecialToShares2/createShareWhenShareWithOnlyMembershipGroups.feature:68](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareCreateSpecialToShares2/createShareWhenShareWithOnlyMembershipGroups.feature#L68) - [apiShareCreateSpecialToShares2/createShareWhenShareWithOnlyMembershipGroups.feature:87](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareCreateSpecialToShares2/createShareWhenShareWithOnlyMembershipGroups.feature#L87) - [apiShareCreateSpecialToShares2/createShareWhenShareWithOnlyMembershipGroups.feature:88](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareCreateSpecialToShares2/createShareWhenShareWithOnlyMembershipGroups.feature#L88) - [apiShareCreateSpecialToShares2/createShareWhenShareWithOnlyMembershipGroups.feature:108](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareCreateSpecialToShares2/createShareWhenShareWithOnlyMembershipGroups.feature#L108) - [apiShareCreateSpecialToShares2/createShareWhenShareWithOnlyMembershipGroups.feature:109](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareCreateSpecialToShares2/createShareWhenShareWithOnlyMembershipGroups.feature#L109) -- [apiShareCreateSpecialToShares2/createShareWhenShareWithOnlyMembershipGroups.feature:128](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareCreateSpecialToShares2/createShareWhenShareWithOnlyMembershipGroups.feature#L128) -- [apiShareCreateSpecialToShares2/createShareWhenShareWithOnlyMembershipGroups.feature:129](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareCreateSpecialToShares2/createShareWhenShareWithOnlyMembershipGroups.feature#L129) - [apiMain/caldav.feature:8](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiMain/caldav.feature#L8) - [apiMain/caldav.feature:15](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiMain/caldav.feature#L15) diff --git a/tests/acceptance/expected-failures-on-OWNCLOUD-storage.md b/tests/acceptance/expected-failures-on-OWNCLOUD-storage.md index d9b0756dba..42eb79096c 100644 --- a/tests/acceptance/expected-failures-on-OWNCLOUD-storage.md +++ b/tests/acceptance/expected-failures-on-OWNCLOUD-storage.md @@ -660,8 +660,6 @@ The following scenarios fail on OWNCLOUD storage but not on OCIS storage: #### [Response is empty when accepting a share](https://github.com/owncloud/product/issues/207) - [apiShareManagementToShares/acceptShares.feature:82](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareManagementToShares/acceptShares.feature#L82) -- [apiShareManagementToShares/acceptShares.feature:173](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareManagementToShares/acceptShares.feature#L173) -- [apiShareManagementToShares/acceptShares.feature:186](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareManagementToShares/acceptShares.feature#L186) - [apiShareManagementToShares/acceptShares.feature:207](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareManagementToShares/acceptShares.feature#L207) - [apiShareManagementToShares/acceptShares.feature:260](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareManagementToShares/acceptShares.feature#L260) - [apiShareManagementToShares/acceptSharesToSharesFolder.feature:31](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareManagementToShares/acceptSharesToSharesFolder.feature#L31) @@ -687,8 +685,6 @@ The following scenarios fail on OWNCLOUD storage but not on OCIS storage: - [apiShareManagementBasicToShares/createShareToSharesFolder.feature:157](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareManagementBasicToShares/createShareToSharesFolder.feature#L157) - [apiShareManagementBasicToShares/createShareToSharesFolder.feature:290](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareManagementBasicToShares/createShareToSharesFolder.feature#L290) - [apiShareManagementBasicToShares/createShareToSharesFolder.feature:291](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareManagementBasicToShares/createShareToSharesFolder.feature#L291) -- [apiShareManagementBasicToShares/createShareToSharesFolder.feature:308](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareManagementBasicToShares/createShareToSharesFolder.feature#L308) -- [apiShareManagementBasicToShares/createShareToSharesFolder.feature:309](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareManagementBasicToShares/createShareToSharesFolder.feature#L309) - [apiShareManagementBasicToShares/deleteShareFromShares.feature:46](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareManagementBasicToShares/deleteShareFromShares.feature#L46) - [apiShareManagementToShares/mergeShare.feature:32](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareManagementToShares/mergeShare.feature#L32) - [apiShareManagementToShares/mergeShare.feature:42](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareManagementToShares/mergeShare.feature#L42) @@ -733,10 +729,6 @@ The following scenarios fail on OWNCLOUD storage but not on OCIS storage: - [apiShareManagementBasicToShares/createShareToSharesFolder.feature:554](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareManagementBasicToShares/createShareToSharesFolder.feature#L554) - [apiShareManagementBasicToShares/createShareToSharesFolder.feature:572](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareManagementBasicToShares/createShareToSharesFolder.feature#L572) -#### [Response is empty when accepting a share](https://github.com/owncloud/product/issues/207) -- [apiShareManagementBasicToShares/createShareToSharesFolder.feature:347](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareManagementBasicToShares/createShareToSharesFolder.feature#L347) -- [apiShareManagementBasicToShares/createShareToSharesFolder.feature:348](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareManagementBasicToShares/createShareToSharesFolder.feature#L348) - #### [File deletion using dav gives unique string in filename in the trashbin](https://github.com/owncloud/product/issues/178) - [apiShareManagementBasicToShares/deleteShareFromShares.feature:58](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareManagementBasicToShares/deleteShareFromShares.feature#L58) @@ -1027,14 +1019,6 @@ _requires a [CS3 user provisioning api that can update the quota for a user](htt #### [Resharing does not work with ocis storage](https://github.com/owncloud/product/issues/265) -- [apiShareReshareToShares1/reShare.feature:61](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareReshareToShares1/reShare.feature#L61) -- [apiShareReshareToShares1/reShare.feature:62](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareReshareToShares1/reShare.feature#L62) -- [apiShareReshareToShares1/reShare.feature:78](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareReshareToShares1/reShare.feature#L78) -- [apiShareReshareToShares1/reShare.feature:79](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareReshareToShares1/reShare.feature#L79) -- [apiShareReshareToShares1/reShare.feature:95](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareReshareToShares1/reShare.feature#L95) -- [apiShareReshareToShares1/reShare.feature:96](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareReshareToShares1/reShare.feature#L96) -- [apiShareReshareToShares1/reShare.feature:112](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareReshareToShares1/reShare.feature#L112) -- [apiShareReshareToShares1/reShare.feature:113](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareReshareToShares1/reShare.feature#L113) - [apiShareReshareToShares1/reShare.feature:169](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareReshareToShares1/reShare.feature#L169) - [apiShareReshareToShares1/reShare.feature:170](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareReshareToShares1/reShare.feature#L170) - [apiShareReshareToShares1/reShare.feature:171](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareReshareToShares1/reShare.feature#L171) @@ -1145,8 +1129,6 @@ The following scenarios fail on OWNCLOUD storage but not on OCIS storage: - [apiShareReshareToShares2/reShareDisabled.feature:27](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareReshareToShares2/reShareDisabled.feature#L27) - [apiShareReshareToShares2/reShareDisabled.feature:28](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareReshareToShares2/reShareDisabled.feature#L28) -- [apiShareReshareToShares2/reShareDisabled.feature:42](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareReshareToShares2/reShareDisabled.feature#L42) -- [apiShareReshareToShares2/reShareDisabled.feature:43](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareReshareToShares2/reShareDisabled.feature#L43) #### [share permissions are not enforced](https://github.com/owncloud/product/issues/270) @@ -2008,16 +1990,12 @@ Scenario Outline: Do a PROPFIND to a non-existing URL - [apiShareCreateSpecialToShares1/createShareWhenExcludedFromSharing.feature:79](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareCreateSpecialToShares1/createShareWhenExcludedFromSharing.feature#L79) - [apiShareCreateSpecialToShares2/createShareWhenShareWithOnlyMembershipGroups.feature:26](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareCreateSpecialToShares2/createShareWhenShareWithOnlyMembershipGroups.feature#L26) - [apiShareCreateSpecialToShares2/createShareWhenShareWithOnlyMembershipGroups.feature:27](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareCreateSpecialToShares2/createShareWhenShareWithOnlyMembershipGroups.feature#L27) -- [apiShareCreateSpecialToShares2/createShareWhenShareWithOnlyMembershipGroups.feature:46](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareCreateSpecialToShares2/createShareWhenShareWithOnlyMembershipGroups.feature#L46) -- [apiShareCreateSpecialToShares2/createShareWhenShareWithOnlyMembershipGroups.feature:47](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareCreateSpecialToShares2/createShareWhenShareWithOnlyMembershipGroups.feature#L47) - [apiShareCreateSpecialToShares2/createShareWhenShareWithOnlyMembershipGroups.feature:67](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareCreateSpecialToShares2/createShareWhenShareWithOnlyMembershipGroups.feature#L67) - [apiShareCreateSpecialToShares2/createShareWhenShareWithOnlyMembershipGroups.feature:68](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareCreateSpecialToShares2/createShareWhenShareWithOnlyMembershipGroups.feature#L68) - [apiShareCreateSpecialToShares2/createShareWhenShareWithOnlyMembershipGroups.feature:87](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareCreateSpecialToShares2/createShareWhenShareWithOnlyMembershipGroups.feature#L87) - [apiShareCreateSpecialToShares2/createShareWhenShareWithOnlyMembershipGroups.feature:88](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareCreateSpecialToShares2/createShareWhenShareWithOnlyMembershipGroups.feature#L88) - [apiShareCreateSpecialToShares2/createShareWhenShareWithOnlyMembershipGroups.feature:108](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareCreateSpecialToShares2/createShareWhenShareWithOnlyMembershipGroups.feature#L108) - [apiShareCreateSpecialToShares2/createShareWhenShareWithOnlyMembershipGroups.feature:109](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareCreateSpecialToShares2/createShareWhenShareWithOnlyMembershipGroups.feature#L109) -- [apiShareCreateSpecialToShares2/createShareWhenShareWithOnlyMembershipGroups.feature:128](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareCreateSpecialToShares2/createShareWhenShareWithOnlyMembershipGroups.feature#L128) -- [apiShareCreateSpecialToShares2/createShareWhenShareWithOnlyMembershipGroups.feature:129](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareCreateSpecialToShares2/createShareWhenShareWithOnlyMembershipGroups.feature#L129) - [apiMain/caldav.feature:8](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiMain/caldav.feature#L8) - [apiMain/caldav.feature:15](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiMain/caldav.feature#L15) @@ -2233,12 +2211,3 @@ _ocdav: return checksum in upload response for chunked upload_ - [apiWebdavUploadTUS/uploadToShare.feature:248](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavUploadTUS/uploadToShare.feature#L248) - [apiWebdavUploadTUS/uploadToShare.feature:288](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavUploadTUS/uploadToShare.feature#L288) - [apiWebdavUploadTUS/uploadToShare.feature:289](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavUploadTUS/uploadToShare.feature#L289) - - -#### [Share inaccessible if folder with same name was deleted and recreated](https://github.com/owncloud/ocis/issues/1787) -- [apiShareReshareToShares1/reShare.feature:269](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareReshareToShares1/reShare.feature#L269) -- [apiShareReshareToShares1/reShare.feature:270](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareReshareToShares1/reShare.feature#L270) -- [apiShareReshareToShares1/reShare.feature:287](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareReshareToShares1/reShare.feature#L287) -- [apiShareReshareToShares1/reShare.feature:288](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareReshareToShares1/reShare.feature#L288) -- [apiShareReshareToShares1/reShare.feature:305](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareReshareToShares1/reShare.feature#L288) -- [apiShareReshareToShares1/reShare.feature:306](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareReshareToShares1/reShare.feature#L288) diff --git a/tests/acceptance/expected-failures-on-S3NG-storage.md b/tests/acceptance/expected-failures-on-S3NG-storage.md index 00e4e4bee6..1ff6314d6e 100644 --- a/tests/acceptance/expected-failures-on-S3NG-storage.md +++ b/tests/acceptance/expected-failures-on-S3NG-storage.md @@ -640,8 +640,6 @@ File and sync features in a shared scenario #### [Response is empty when accepting a share](https://github.com/owncloud/product/issues/207) - [apiShareManagementToShares/acceptShares.feature:82](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareManagementToShares/acceptShares.feature#L82) -- [apiShareManagementToShares/acceptShares.feature:173](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareManagementToShares/acceptShares.feature#L173) -- [apiShareManagementToShares/acceptShares.feature:186](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareManagementToShares/acceptShares.feature#L186) - [apiShareManagementToShares/acceptShares.feature:207](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareManagementToShares/acceptShares.feature#L207) - [apiShareManagementToShares/acceptShares.feature:260](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareManagementToShares/acceptShares.feature#L260) - [apiShareManagementToShares/acceptSharesToSharesFolder.feature:31](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareManagementToShares/acceptSharesToSharesFolder.feature#L31) @@ -667,8 +665,6 @@ File and sync features in a shared scenario - [apiShareManagementBasicToShares/createShareToSharesFolder.feature:157](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareManagementBasicToShares/createShareToSharesFolder.feature#L157) - [apiShareManagementBasicToShares/createShareToSharesFolder.feature:290](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareManagementBasicToShares/createShareToSharesFolder.feature#L290) - [apiShareManagementBasicToShares/createShareToSharesFolder.feature:291](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareManagementBasicToShares/createShareToSharesFolder.feature#L291) -- [apiShareManagementBasicToShares/createShareToSharesFolder.feature:308](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareManagementBasicToShares/createShareToSharesFolder.feature#L308) -- [apiShareManagementBasicToShares/createShareToSharesFolder.feature:309](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareManagementBasicToShares/createShareToSharesFolder.feature#L309) - [apiShareManagementBasicToShares/deleteShareFromShares.feature:46](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareManagementBasicToShares/deleteShareFromShares.feature#L46) - [apiShareManagementToShares/mergeShare.feature:32](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareManagementToShares/mergeShare.feature#L32) - [apiShareManagementToShares/mergeShare.feature:42](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareManagementToShares/mergeShare.feature#L42) @@ -713,10 +709,6 @@ File and sync features in a shared scenario - [apiShareManagementBasicToShares/createShareToSharesFolder.feature:554](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareManagementBasicToShares/createShareToSharesFolder.feature#L554) - [apiShareManagementBasicToShares/createShareToSharesFolder.feature:572](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareManagementBasicToShares/createShareToSharesFolder.feature#L572) -#### [Response is empty when accepting a share](https://github.com/owncloud/product/issues/207) -- [apiShareManagementBasicToShares/createShareToSharesFolder.feature:347](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareManagementBasicToShares/createShareToSharesFolder.feature#L347) -- [apiShareManagementBasicToShares/createShareToSharesFolder.feature:348](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareManagementBasicToShares/createShareToSharesFolder.feature#L348) - #### [File deletion using dav gives unique string in filename in the trashbin](https://github.com/owncloud/product/issues/178) - [apiShareManagementBasicToShares/deleteShareFromShares.feature:58](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareManagementBasicToShares/deleteShareFromShares.feature#L58) @@ -1006,14 +998,6 @@ _requires a [CS3 user provisioning api that can update the quota for a user](htt #### [Resharing does not work with ocis storage](https://github.com/owncloud/product/issues/265) -- [apiShareReshareToShares1/reShare.feature:61](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareReshareToShares1/reShare.feature#L61) -- [apiShareReshareToShares1/reShare.feature:62](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareReshareToShares1/reShare.feature#L62) -- [apiShareReshareToShares1/reShare.feature:78](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareReshareToShares1/reShare.feature#L78) -- [apiShareReshareToShares1/reShare.feature:79](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareReshareToShares1/reShare.feature#L79) -- [apiShareReshareToShares1/reShare.feature:95](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareReshareToShares1/reShare.feature#L95) -- [apiShareReshareToShares1/reShare.feature:96](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareReshareToShares1/reShare.feature#L96) -- [apiShareReshareToShares1/reShare.feature:112](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareReshareToShares1/reShare.feature#L112) -- [apiShareReshareToShares1/reShare.feature:113](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareReshareToShares1/reShare.feature#L113) - [apiShareReshareToShares1/reShare.feature:169](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareReshareToShares1/reShare.feature#L169) - [apiShareReshareToShares1/reShare.feature:170](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareReshareToShares1/reShare.feature#L170) - [apiShareReshareToShares1/reShare.feature:171](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareReshareToShares1/reShare.feature#L171) @@ -1073,8 +1057,6 @@ _requires a [CS3 user provisioning api that can update the quota for a user](htt - [apiShareReshareToShares2/reShareDisabled.feature:27](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareReshareToShares2/reShareDisabled.feature#L27) - [apiShareReshareToShares2/reShareDisabled.feature:28](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareReshareToShares2/reShareDisabled.feature#L28) -- [apiShareReshareToShares2/reShareDisabled.feature:42](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareReshareToShares2/reShareDisabled.feature#L42) -- [apiShareReshareToShares2/reShareDisabled.feature:43](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareReshareToShares2/reShareDisabled.feature#L43) #### [share permissions are not enforced](https://github.com/owncloud/product/issues/270) @@ -1883,16 +1865,12 @@ Scenario Outline: Do a PROPFIND to a non-existing URL - [apiShareCreateSpecialToShares1/createShareWhenExcludedFromSharing.feature:79](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareCreateSpecialToShares1/createShareWhenExcludedFromSharing.feature#L79) - [apiShareCreateSpecialToShares2/createShareWhenShareWithOnlyMembershipGroups.feature:26](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareCreateSpecialToShares2/createShareWhenShareWithOnlyMembershipGroups.feature#L26) - [apiShareCreateSpecialToShares2/createShareWhenShareWithOnlyMembershipGroups.feature:27](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareCreateSpecialToShares2/createShareWhenShareWithOnlyMembershipGroups.feature#L27) -- [apiShareCreateSpecialToShares2/createShareWhenShareWithOnlyMembershipGroups.feature:46](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareCreateSpecialToShares2/createShareWhenShareWithOnlyMembershipGroups.feature#L46) -- [apiShareCreateSpecialToShares2/createShareWhenShareWithOnlyMembershipGroups.feature:47](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareCreateSpecialToShares2/createShareWhenShareWithOnlyMembershipGroups.feature#L47) - [apiShareCreateSpecialToShares2/createShareWhenShareWithOnlyMembershipGroups.feature:67](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareCreateSpecialToShares2/createShareWhenShareWithOnlyMembershipGroups.feature#L67) - [apiShareCreateSpecialToShares2/createShareWhenShareWithOnlyMembershipGroups.feature:68](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareCreateSpecialToShares2/createShareWhenShareWithOnlyMembershipGroups.feature#L68) - [apiShareCreateSpecialToShares2/createShareWhenShareWithOnlyMembershipGroups.feature:87](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareCreateSpecialToShares2/createShareWhenShareWithOnlyMembershipGroups.feature#L87) - [apiShareCreateSpecialToShares2/createShareWhenShareWithOnlyMembershipGroups.feature:88](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareCreateSpecialToShares2/createShareWhenShareWithOnlyMembershipGroups.feature#L88) - [apiShareCreateSpecialToShares2/createShareWhenShareWithOnlyMembershipGroups.feature:108](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareCreateSpecialToShares2/createShareWhenShareWithOnlyMembershipGroups.feature#L108) - [apiShareCreateSpecialToShares2/createShareWhenShareWithOnlyMembershipGroups.feature:109](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareCreateSpecialToShares2/createShareWhenShareWithOnlyMembershipGroups.feature#L109) -- [apiShareCreateSpecialToShares2/createShareWhenShareWithOnlyMembershipGroups.feature:128](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareCreateSpecialToShares2/createShareWhenShareWithOnlyMembershipGroups.feature#L128) -- [apiShareCreateSpecialToShares2/createShareWhenShareWithOnlyMembershipGroups.feature:129](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareCreateSpecialToShares2/createShareWhenShareWithOnlyMembershipGroups.feature#L129) - [apiMain/caldav.feature:8](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiMain/caldav.feature#L8) - [apiMain/caldav.feature:15](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiMain/caldav.feature#L15)