diff --git a/changelog/unreleased/public-share-share-types.md b/changelog/unreleased/public-share-share-types.md new file mode 100644 index 00000000000..6854c32e9d7 --- /dev/null +++ b/changelog/unreleased/public-share-share-types.md @@ -0,0 +1,5 @@ +Enhancement: Add public link share type to propfind response + +Added share type for public links to propfind responses. + +https://github.com/cs3org/reva/pull/2213 diff --git a/internal/http/services/owncloud/ocdav/propfind.go b/internal/http/services/owncloud/ocdav/propfind.go index 90600e393ed..0b97e42d85e 100644 --- a/internal/http/services/owncloud/ocdav/propfind.go +++ b/internal/http/services/owncloud/ocdav/propfind.go @@ -40,6 +40,7 @@ import ( "github.com/cs3org/reva/internal/http/services/owncloud/ocs/conversions" "github.com/cs3org/reva/pkg/appctx" ctxpkg "github.com/cs3org/reva/pkg/ctx" + "github.com/cs3org/reva/pkg/publicshare" rtrace "github.com/cs3org/reva/pkg/trace" "github.com/cs3org/reva/pkg/utils" "github.com/rs/zerolog" @@ -134,7 +135,30 @@ func (s *svc) handleSpacesPropfind(w http.ResponseWriter, r *http.Request, space } func (s *svc) propfindResponse(ctx context.Context, w http.ResponseWriter, r *http.Request, namespace string, pf propfindXML, parentInfo *provider.ResourceInfo, resourceInfos []*provider.ResourceInfo, log zerolog.Logger) { - propRes, err := s.multistatusResponse(ctx, &pf, resourceInfos, namespace) + filters := make([]*link.ListPublicSharesRequest_Filter, 0, len(resourceInfos)) + for i := range resourceInfos { + filters = append(filters, publicshare.ResourceIDFilter(resourceInfos[i].Id)) + } + + client, err := s.getClient() + if err != nil { + log.Error().Err(err).Msg("error getting grpc client") + w.WriteHeader(http.StatusInternalServerError) + return + } + + listResp, err := client.ListPublicShares(ctx, &link.ListPublicSharesRequest{Filters: filters}) + if err != nil { + w.WriteHeader(http.StatusInternalServerError) + return + } + + linkshares := make(map[string]struct{}) + for i := range listResp.Share { + linkshares[listResp.Share[i].ResourceId.OpaqueId] = struct{}{} + } + + propRes, err := s.multistatusResponse(ctx, &pf, resourceInfos, namespace, linkshares) if err != nil { log.Error().Err(err).Msg("error formatting propfind") w.WriteHeader(http.StatusInternalServerError) @@ -374,10 +398,10 @@ func readPropfind(r io.Reader) (pf propfindXML, status int, err error) { return pf, 0, nil } -func (s *svc) multistatusResponse(ctx context.Context, pf *propfindXML, mds []*provider.ResourceInfo, ns string) (string, error) { +func (s *svc) multistatusResponse(ctx context.Context, pf *propfindXML, mds []*provider.ResourceInfo, ns string, linkshares map[string]struct{}) (string, error) { responses := make([]*responseXML, 0, len(mds)) for i := range mds { - res, err := s.mdToPropResponse(ctx, pf, mds[i], ns) + res, err := s.mdToPropResponse(ctx, pf, mds[i], ns, linkshares) if err != nil { return "", err } @@ -429,7 +453,7 @@ func (s *svc) newPropRaw(key, val string) *propertyXML { // mdToPropResponse converts the CS3 metadata into a webdav PropResponse // ns is the CS3 namespace that needs to be removed from the CS3 path before // prefixing it with the baseURI -func (s *svc) mdToPropResponse(ctx context.Context, pf *propfindXML, md *provider.ResourceInfo, ns string) (*responseXML, error) { +func (s *svc) mdToPropResponse(ctx context.Context, pf *propfindXML, md *provider.ResourceInfo, ns string, linkshares map[string]struct{}) (*responseXML, error) { sublog := appctx.GetLogger(ctx).With().Interface("md", md).Str("ns", ns).Logger() md.Path = strings.TrimPrefix(md.Path, ns) @@ -739,11 +763,21 @@ func (s *svc) mdToPropResponse(ctx context.Context, pf *propfindXML, md *provide propstatNotFound.Prop = append(propstatNotFound.Prop, s.newProp("oc:checksums", "")) } case "share-types": // desktop + var types strings.Builder k := md.GetArbitraryMetadata() amd := k.GetMetadata() if amdv, ok := amd[metadataKeyOf(&pf.Prop[i])]; ok { - st := fmt.Sprintf("%s", amdv) - propstatOK.Prop = append(propstatOK.Prop, s.newPropRaw("oc:share-types", st)) + types.WriteString("") + types.WriteString(amdv) + types.WriteString("") + } + + if _, ok := linkshares[md.Id.OpaqueId]; ok { + types.WriteString("3") + } + + if types.Len() != 0 { + propstatOK.Prop = append(propstatOK.Prop, s.newPropRaw("oc:share-types", types.String())) } else { propstatNotFound.Prop = append(propstatNotFound.Prop, s.newProp("oc:"+pf.Prop[i].Local, "")) } diff --git a/internal/http/services/owncloud/ocdav/publicfile.go b/internal/http/services/owncloud/ocdav/publicfile.go index 932a8ce996f..b369f6650b6 100644 --- a/internal/http/services/owncloud/ocdav/publicfile.go +++ b/internal/http/services/owncloud/ocdav/publicfile.go @@ -186,7 +186,7 @@ func (s *svc) handlePropfindOnToken(w http.ResponseWriter, r *http.Request, ns s infos := s.getPublicFileInfos(onContainer, depth == "0", tokenStatInfo) - propRes, err := s.multistatusResponse(ctx, &pf, infos, ns) + propRes, err := s.multistatusResponse(ctx, &pf, infos, ns, nil) if err != nil { sublog.Error().Err(err).Msg("error formatting propfind") w.WriteHeader(http.StatusInternalServerError) diff --git a/internal/http/services/owncloud/ocdav/report.go b/internal/http/services/owncloud/ocdav/report.go index aab2ff90bbd..49df7b4f1d9 100644 --- a/internal/http/services/owncloud/ocdav/report.go +++ b/internal/http/services/owncloud/ocdav/report.go @@ -119,7 +119,7 @@ func (s *svc) doFilterFiles(w http.ResponseWriter, r *http.Request, ff *reportFi infos = append(infos, statRes.Info) } - responsesXML, err := s.multistatusResponse(ctx, &propfindXML{Prop: ff.Prop}, infos, namespace) + responsesXML, err := s.multistatusResponse(ctx, &propfindXML{Prop: ff.Prop}, infos, namespace, nil) if err != nil { log.Error().Err(err).Msg("error formatting propfind") w.WriteHeader(http.StatusInternalServerError) diff --git a/internal/http/services/owncloud/ocdav/versions.go b/internal/http/services/owncloud/ocdav/versions.go index fc281fa155c..ad6620ccd91 100644 --- a/internal/http/services/owncloud/ocdav/versions.go +++ b/internal/http/services/owncloud/ocdav/versions.go @@ -164,7 +164,7 @@ func (h *VersionsHandler) doListVersions(w http.ResponseWriter, r *http.Request, infos = append(infos, vi) } - propRes, err := s.multistatusResponse(ctx, &pf, infos, "") + propRes, err := s.multistatusResponse(ctx, &pf, infos, "", nil) if err != nil { sublog.Error().Err(err).Msg("error formatting propfind") w.WriteHeader(http.StatusInternalServerError)