@@ -8,9 +8,11 @@ import (
88 "net/http"
99 "net/url"
1010 "path"
11+ "slices"
1112 "strconv"
1213 "strings"
1314
15+ userv1beta1 "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1"
1416 provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1"
1517 merrors "go-micro.dev/v4/errors"
1618 "go-micro.dev/v4/metadata"
@@ -37,6 +39,22 @@ const (
3739// Search is the endpoint for retrieving search results for REPORT requests
3840func (g Webdav ) Search (w http.ResponseWriter , r * http.Request ) {
3941 logger := g .log .SubloggerWithRequestID (r .Context ())
42+ t := r .Header .Get (revactx .TokenHeader )
43+
44+ gatewayClient , err := g .gatewaySelector .Next ()
45+ if err != nil {
46+ logger .Error ().Err (err ).Msg ("could not get reva gatewayClient" )
47+ renderError (w , r , errInternalError ("could not get reva gatewayClient" ))
48+ return
49+ }
50+
51+ user , err := whoami (gatewayClient , r .Context (), t )
52+ if err != nil {
53+ logger .Error ().Err (err ).Msg ("could not get user" )
54+ renderError (w , r , errInternalError ("could not get user" ))
55+ return
56+ }
57+
4058 rep , err := readReport (r .Body )
4159 if err != nil {
4260 renderError (w , r , errBadRequest (err .Error ()))
@@ -50,7 +68,6 @@ func (g Webdav) Search(w http.ResponseWriter, r *http.Request) {
5068 return
5169 }
5270
53- t := r .Header .Get (revactx .TokenHeader )
5471 ctx := revactx .ContextSetToken (r .Context (), t )
5572 ctx = metadata .Set (ctx , revactx .TokenHeader , t )
5673
@@ -88,13 +105,12 @@ func (g Webdav) Search(w http.ResponseWriter, r *http.Request) {
88105 logger .Error ().Err (err ).Msg ("could not get search results" )
89106 return
90107 }
91-
92- g .sendSearchResponse (rsp , w , r )
108+ g .sendSearchResponse (rsp , w , r , user )
93109}
94110
95- func (g Webdav ) sendSearchResponse (rsp * searchsvc.SearchResponse , w http.ResponseWriter , r * http.Request ) {
111+ func (g Webdav ) sendSearchResponse (rsp * searchsvc.SearchResponse , w http.ResponseWriter , r * http.Request , user * userv1beta1. User ) {
96112 logger := g .log .SubloggerWithRequestID (r .Context ())
97- responsesXML , err := multistatusResponse (r .Context (), g .config .OpenCloudPublicURL , rsp .Matches )
113+ responsesXML , err := multistatusResponse (r .Context (), g .config .OpenCloudPublicURL , rsp .Matches , user )
98114 if err != nil {
99115 logger .Error ().Err (err ).Msg ("error formatting propfind" )
100116 w .WriteHeader (http .StatusInternalServerError )
@@ -112,10 +128,10 @@ func (g Webdav) sendSearchResponse(rsp *searchsvc.SearchResponse, w http.Respons
112128}
113129
114130// multistatusResponse converts a list of matches into a multistatus response string
115- func multistatusResponse (ctx context.Context , publicURL string , matches []* searchmsg.Match ) ([]byte , error ) {
131+ func multistatusResponse (ctx context.Context , publicURL string , matches []* searchmsg.Match , user * userv1beta1. User ) ([]byte , error ) {
116132 responses := make ([]* propfind.ResponseXML , 0 , len (matches ))
117133 for i := range matches {
118- res , err := matchToPropResponse (ctx , publicURL , matches [i ])
134+ res , err := matchToPropResponse (ctx , publicURL , matches [i ], user )
119135 if err != nil {
120136 return nil , err
121137 }
@@ -131,7 +147,7 @@ func multistatusResponse(ctx context.Context, publicURL string, matches []*searc
131147 return msg , nil
132148}
133149
134- func matchToPropResponse (ctx context.Context , publicURL string , match * searchmsg.Match ) (* propfind.ResponseXML , error ) {
150+ func matchToPropResponse (ctx context.Context , publicURL string , match * searchmsg.Match , user * userv1beta1. User ) (* propfind.ResponseXML , error ) {
135151 // unfortunately, search uses own versions of ResourceId and Ref. So we need to assert them here
136152 var (
137153 ref string
@@ -234,6 +250,11 @@ func matchToPropResponse(ctx context.Context, publicURL string, match *searchmsg
234250 propstatOK .Prop = append (propstatOK .Prop , prop .Escaped ("oc:privatelink" , privateURL .String ()))
235251 }
236252
253+ // enrich results with favorite flag for the user performing the search
254+ if slices .Contains (match .Entity .Favorites , user .Id .OpaqueId ) {
255+ propstatOK .Prop = append (propstatOK .Prop , prop .Escaped ("oc:favorite" , "1" ))
256+ }
257+
237258 if len (propstatOK .Prop ) > 0 {
238259 response .Propstat = append (response .Propstat , propstatOK )
239260 }
0 commit comments