mirror of
https://github.com/opencloud-eu/opencloud.git
synced 2026-02-23 10:45:25 -05:00
Merge pull request #3219 from owncloud/spaces-thumbnails
support thumbnails in spaces
This commit is contained in:
5
changelog/unreleased/spaces-thumbnails.md
Normal file
5
changelog/unreleased/spaces-thumbnails.md
Normal file
@@ -0,0 +1,5 @@
|
||||
Enhancement: Thumbnails in spaces
|
||||
|
||||
Added support for thumbnails in spaces.
|
||||
|
||||
https://github.com/owncloud/ocis/pull/3219
|
||||
@@ -217,11 +217,24 @@ func (g Thumbnail) handleWebdavSource(ctx context.Context, req *thumbnailssvc.Ge
|
||||
func (g Thumbnail) stat(path, auth string) (*provider.StatResponse, error) {
|
||||
ctx := metadata.AppendToOutgoingContext(context.Background(), revactx.TokenHeader, auth)
|
||||
|
||||
req := &provider.StatRequest{
|
||||
Ref: &provider.Reference{
|
||||
var ref *provider.Reference
|
||||
if strings.Contains(path, "!") {
|
||||
parts := strings.Split(path, "!")
|
||||
spaceID, path := parts[0], parts[1]
|
||||
ref = &provider.Reference{
|
||||
ResourceId: &provider.ResourceId{
|
||||
StorageId: spaceID,
|
||||
OpaqueId: spaceID,
|
||||
},
|
||||
Path: path,
|
||||
},
|
||||
}
|
||||
} else {
|
||||
ref = &provider.Reference{
|
||||
Path: path,
|
||||
}
|
||||
}
|
||||
|
||||
req := &provider.StatRequest{Ref: ref}
|
||||
rsp, err := g.cs3Client.Stat(ctx, req)
|
||||
if err != nil {
|
||||
g.logger.Error().Err(err).Str("path", path).Msg("could not stat file")
|
||||
|
||||
@@ -6,6 +6,7 @@ import (
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
gateway "github.com/cs3org/go-cs3apis/cs3/gateway/v1beta1"
|
||||
rpc "github.com/cs3org/go-cs3apis/cs3/rpc/v1beta1"
|
||||
@@ -42,12 +43,24 @@ func (s CS3) Get(ctx context.Context, path string) (io.ReadCloser, error) {
|
||||
if !ok {
|
||||
return nil, errors.New("cs3source: authorization missing")
|
||||
}
|
||||
ctx = metadata.AppendToOutgoingContext(context.Background(), revactx.TokenHeader, auth)
|
||||
rsp, err := s.client.InitiateFileDownload(ctx, &provider.InitiateFileDownloadRequest{
|
||||
Ref: &provider.Reference{
|
||||
var ref *provider.Reference
|
||||
if strings.Contains(path, "!") {
|
||||
parts := strings.Split(path, "!")
|
||||
spaceID, path := parts[0], parts[1]
|
||||
ref = &provider.Reference{
|
||||
ResourceId: &provider.ResourceId{
|
||||
StorageId: spaceID,
|
||||
OpaqueId: spaceID,
|
||||
},
|
||||
Path: path,
|
||||
},
|
||||
})
|
||||
}
|
||||
} else {
|
||||
ref = &provider.Reference{
|
||||
Path: path,
|
||||
}
|
||||
}
|
||||
ctx = metadata.AppendToOutgoingContext(context.Background(), revactx.TokenHeader, auth)
|
||||
rsp, err := s.client.InitiateFileDownload(ctx, &provider.InitiateFileDownloadRequest{Ref: ref})
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
@@ -33,13 +33,13 @@ type ThumbnailRequest struct {
|
||||
Height int32
|
||||
// In case of a public share the public link token.
|
||||
PublicLinkToken string
|
||||
// The username from the requested URL
|
||||
Username string
|
||||
// The Identifier from the requested URL
|
||||
Identifier string
|
||||
}
|
||||
|
||||
// ParseThumbnailRequest extracts all required parameters from a http request.
|
||||
func ParseThumbnailRequest(r *http.Request) (*ThumbnailRequest, error) {
|
||||
fp, username, err := extractFilePath(r)
|
||||
fp, id, err := extractFilePath(r)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -57,7 +57,7 @@ func ParseThumbnailRequest(r *http.Request) (*ThumbnailRequest, error) {
|
||||
Width: int32(width),
|
||||
Height: int32(height),
|
||||
PublicLinkToken: chi.URLParam(r, "token"),
|
||||
Username: username,
|
||||
Identifier: id,
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -68,16 +68,17 @@ func ParseThumbnailRequest(r *http.Request) (*ThumbnailRequest, error) {
|
||||
// User and filepath are dynamic and filepath can contain slashes
|
||||
// So using the URLParam function is not possible.
|
||||
func extractFilePath(r *http.Request) (string, string, error) {
|
||||
user := chi.URLParam(r, "user")
|
||||
user, err := url.QueryUnescape(user)
|
||||
id := chi.URLParam(r, "id")
|
||||
id, err := url.QueryUnescape(id)
|
||||
if err != nil {
|
||||
return "", "", errors.New("could not unescape user")
|
||||
}
|
||||
if user != "" {
|
||||
parts := strings.SplitN(r.URL.Path, user, 2)
|
||||
return parts[1], user, nil
|
||||
if id != "" {
|
||||
parts := strings.SplitN(r.URL.Path, id, 2)
|
||||
return parts[1], id, nil
|
||||
}
|
||||
|
||||
// This is for public links
|
||||
token := chi.URLParam(r, "token")
|
||||
if token != "" {
|
||||
parts := strings.SplitN(r.URL.Path, token, 2)
|
||||
|
||||
@@ -66,7 +66,8 @@ func NewService(opts ...Option) (Service, error) {
|
||||
}
|
||||
|
||||
m.Route(options.Config.HTTP.Root, func(r chi.Router) {
|
||||
r.Get("/remote.php/dav/files/{user}/*", svc.Thumbnail)
|
||||
r.Get("/remote.php/dav/spaces/{id}/*", svc.SpacesThumbnail)
|
||||
r.Get("/remote.php/dav/files/{id}/*", svc.Thumbnail)
|
||||
r.Get("/remote.php/dav/public-files/{token}/*", svc.PublicThumbnail)
|
||||
r.Head("/remote.php/dav/public-files/{token}/*", svc.PublicThumbnailHead)
|
||||
})
|
||||
@@ -88,6 +89,53 @@ func (g Webdav) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
g.mux.ServeHTTP(w, r)
|
||||
}
|
||||
|
||||
// SpacesThumbnail is the endpoint for retrieving thumbnails inside of spaces.
|
||||
func (g Webdav) SpacesThumbnail(w http.ResponseWriter, r *http.Request) {
|
||||
tr, err := requests.ParseThumbnailRequest(r)
|
||||
if err != nil {
|
||||
g.log.Error().Err(err).Msg("could not create Request")
|
||||
renderError(w, r, errBadRequest(err.Error()))
|
||||
return
|
||||
}
|
||||
t := r.Header.Get(TokenHeader)
|
||||
|
||||
fullPath := tr.Identifier + "!" + tr.Filepath
|
||||
rsp, err := g.thumbnailsClient.GetThumbnail(r.Context(), &thumbnailssvc.GetThumbnailRequest{
|
||||
Filepath: strings.TrimLeft(tr.Filepath, "/"),
|
||||
ThumbnailType: extensionToThumbnailType(strings.TrimLeft(tr.Extension, ".")),
|
||||
Width: tr.Width,
|
||||
Height: tr.Height,
|
||||
Source: &thumbnailssvc.GetThumbnailRequest_Cs3Source{
|
||||
Cs3Source: &thumbnailsmsg.CS3Source{
|
||||
Path: fullPath,
|
||||
Authorization: t,
|
||||
},
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
e := merrors.Parse(err.Error())
|
||||
switch e.Code {
|
||||
case http.StatusNotFound:
|
||||
// StatusNotFound is expected for unsupported files
|
||||
renderError(w, r, errNotFound(notFoundMsg(tr.Filename)))
|
||||
return
|
||||
case http.StatusBadRequest:
|
||||
renderError(w, r, errBadRequest(err.Error()))
|
||||
default:
|
||||
renderError(w, r, errInternalError(err.Error()))
|
||||
}
|
||||
g.log.Error().Err(err).Msg("could not get thumbnail")
|
||||
return
|
||||
}
|
||||
|
||||
if len(rsp.Thumbnail) == 0 {
|
||||
renderError(w, r, errNotFound(""))
|
||||
return
|
||||
}
|
||||
|
||||
g.mustRender(w, r, newThumbnailResponse(rsp))
|
||||
}
|
||||
|
||||
// Thumbnail implements the Service interface.
|
||||
func (g Webdav) Thumbnail(w http.ResponseWriter, r *http.Request) {
|
||||
tr, err := requests.ParseThumbnailRequest(r)
|
||||
@@ -101,7 +149,7 @@ func (g Webdav) Thumbnail(w http.ResponseWriter, r *http.Request) {
|
||||
ctx := metadata.AppendToOutgoingContext(r.Context(), TokenHeader, t)
|
||||
userRes, err := g.revaClient.GetUserByClaim(ctx, &userv1beta1.GetUserByClaimRequest{
|
||||
Claim: "username",
|
||||
Value: tr.Username,
|
||||
Value: tr.Identifier,
|
||||
})
|
||||
if err != nil || userRes.Status.Code != rpcv1beta1.Code_CODE_OK {
|
||||
g.log.Error().Err(err).Msg("could not get user")
|
||||
|
||||
Reference in New Issue
Block a user