mirror of
https://github.com/opencloud-eu/opencloud.git
synced 2026-07-19 20:14:17 -04:00
fix thumbnailer for the new spaces approach
This commit is contained in:
@@ -65,7 +65,6 @@ type Thumbnail struct {
|
||||
WebdavAllowInsecure bool `ocisConfig:"webdav_allow_insecure"`
|
||||
CS3AllowInsecure bool `ocisConfig:"cs3_allow_insecure"`
|
||||
RevaGateway string `ocisConfig:"reva_gateway"`
|
||||
WebdavNamespace string `ocisConfig:"webdav_namespace"`
|
||||
FontMapFile string `ocisConfig:"font_map_file"`
|
||||
}
|
||||
|
||||
@@ -101,7 +100,6 @@ func DefaultConfig() *Config {
|
||||
},
|
||||
WebdavAllowInsecure: true,
|
||||
RevaGateway: "127.0.0.1:9142",
|
||||
WebdavNamespace: "/home",
|
||||
CS3AllowInsecure: false,
|
||||
},
|
||||
}
|
||||
|
||||
@@ -111,9 +111,5 @@ func structMappings(cfg *Config) []shared.EnvBinding {
|
||||
EnvVars: []string{"OCIS_INSECURE", "THUMBNAILS_CS3SOURCE_INSECURE"},
|
||||
Destination: &cfg.Thumbnail.CS3AllowInsecure,
|
||||
},
|
||||
{
|
||||
EnvVars: []string{"STORAGE_WEBDAV_NAMESPACE"},
|
||||
Destination: &cfg.Thumbnail.WebdavNamespace,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
"strings"
|
||||
|
||||
gateway "github.com/cs3org/go-cs3apis/cs3/gateway/v1beta1"
|
||||
userv1beta1 "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1"
|
||||
rpc "github.com/cs3org/go-cs3apis/cs3/rpc/v1beta1"
|
||||
provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1"
|
||||
revactx "github.com/cs3org/reva/pkg/ctx"
|
||||
@@ -30,8 +31,7 @@ func NewService(opts ...Option) v0proto.ThumbnailServiceHandler {
|
||||
logger.Fatal().Err(err).Msg("resolutions not configured correctly")
|
||||
}
|
||||
svc := Thumbnail{
|
||||
serviceID: options.Config.Server.Namespace + "." + options.Config.Server.Name,
|
||||
webdavNamespace: options.Config.Thumbnail.WebdavNamespace,
|
||||
serviceID: options.Config.Server.Namespace + "." + options.Config.Server.Name,
|
||||
manager: thumbnail.NewSimpleManager(
|
||||
resolutions,
|
||||
options.ThumbnailStorage,
|
||||
@@ -52,7 +52,6 @@ func NewService(opts ...Option) v0proto.ThumbnailServiceHandler {
|
||||
// Thumbnail implements the GRPC handler.
|
||||
type Thumbnail struct {
|
||||
serviceID string
|
||||
webdavNamespace string
|
||||
manager thumbnail.Manager
|
||||
webdavSource imgsource.Source
|
||||
cs3Source imgsource.Source
|
||||
@@ -100,7 +99,7 @@ func (g Thumbnail) GetThumbnail(ctx context.Context, req *v0proto.GetThumbnailRe
|
||||
|
||||
func (g Thumbnail) handleCS3Source(ctx context.Context, req *v0proto.GetThumbnailRequest, encoder thumbnail.Encoder) ([]byte, error) {
|
||||
src := req.GetCs3Source()
|
||||
sRes, err := g.stat(src.Path, src.Authorization)
|
||||
sRes, err := g.stat(src.Path, src.Authorization, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -144,7 +143,11 @@ func (g Thumbnail) handleWebdavSource(ctx context.Context, req *v0proto.GetThumb
|
||||
return nil, errors.Wrap(err, "source url is invalid")
|
||||
}
|
||||
|
||||
var auth, statPath string
|
||||
var (
|
||||
auth, statPath string
|
||||
user *userv1beta1.User
|
||||
)
|
||||
|
||||
if src.IsPublicLink {
|
||||
q := imgURL.Query()
|
||||
var rsp *gateway.AuthenticateResponse
|
||||
@@ -171,12 +174,14 @@ func (g Thumbnail) handleWebdavSource(ctx context.Context, req *v0proto.GetThumb
|
||||
return nil, merrors.InternalServerError(g.serviceID, "could not authenticate: %s", err.Error())
|
||||
}
|
||||
auth = rsp.Token
|
||||
user = rsp.User
|
||||
statPath = path.Join("/public", src.PublicLinkToken, req.Filepath)
|
||||
} else {
|
||||
auth = src.RevaAuthorization
|
||||
statPath = path.Join(g.webdavNamespace, req.Filepath)
|
||||
statPath = req.Filepath
|
||||
user = revactx.ContextMustGetUser(ctx)
|
||||
}
|
||||
sRes, err := g.stat(statPath, auth)
|
||||
sRes, err := g.stat(statPath, auth, user)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -214,7 +219,7 @@ func (g Thumbnail) handleWebdavSource(ctx context.Context, req *v0proto.GetThumb
|
||||
return thumb, nil
|
||||
}
|
||||
|
||||
func (g Thumbnail) stat(path, auth string) (*provider.StatResponse, error) {
|
||||
func (g Thumbnail) stat(path, auth string, user *userv1beta1.User) (*provider.StatResponse, error) {
|
||||
ctx := metadata.AppendToOutgoingContext(context.Background(), revactx.TokenHeader, auth)
|
||||
|
||||
req := &provider.StatRequest{
|
||||
|
||||
@@ -57,6 +57,7 @@ type Config struct {
|
||||
Service Service `ocisConfig:"service"`
|
||||
OcisPublicURL string `ocisConfig:"ocis_public_url"`
|
||||
WebdavNamespace string `ocisConfig:"webdav_namespace"`
|
||||
RevaGateway string `ocisConfig:"reva_gateway"`
|
||||
|
||||
Context context.Context
|
||||
Supervised bool
|
||||
@@ -97,6 +98,7 @@ func DefaultConfig() *Config {
|
||||
Namespace: "com.owncloud.web",
|
||||
},
|
||||
OcisPublicURL: "https://127.0.0.1:9200",
|
||||
WebdavNamespace: "/home",
|
||||
WebdavNamespace: "/users/{{.Id.OpaqueId}}",
|
||||
RevaGateway: "127.0.0.1:9142",
|
||||
}
|
||||
}
|
||||
|
||||
@@ -103,5 +103,9 @@ func structMappings(cfg *Config) []shared.EnvBinding {
|
||||
EnvVars: []string{"STORAGE_WEBDAV_NAMESPACE"},
|
||||
Destination: &cfg.WebdavNamespace,
|
||||
},
|
||||
{
|
||||
EnvVars: []string{"REVA_GATEWAY"},
|
||||
Destination: &cfg.RevaGateway,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,11 +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
|
||||
}
|
||||
|
||||
// ParseThumbnailRequest extracts all required parameters from a http request.
|
||||
func ParseThumbnailRequest(r *http.Request) (*ThumbnailRequest, error) {
|
||||
fp, err := extractFilePath(r)
|
||||
fp, username, err := extractFilePath(r)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -55,6 +57,7 @@ func ParseThumbnailRequest(r *http.Request) (*ThumbnailRequest, error) {
|
||||
Width: int32(width),
|
||||
Height: int32(height),
|
||||
PublicLinkToken: chi.URLParam(r, "token"),
|
||||
Username: username,
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -64,23 +67,23 @@ 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, error) {
|
||||
func extractFilePath(r *http.Request) (string, string, error) {
|
||||
user := chi.URLParam(r, "user")
|
||||
user, err := url.QueryUnescape(user)
|
||||
if err != nil {
|
||||
return "", errors.New("could not unescape user")
|
||||
return "", "", errors.New("could not unescape user")
|
||||
}
|
||||
if user != "" {
|
||||
parts := strings.SplitN(r.URL.Path, user, 2)
|
||||
return parts[1], nil
|
||||
return parts[1], user, nil
|
||||
}
|
||||
|
||||
token := chi.URLParam(r, "token")
|
||||
if token != "" {
|
||||
parts := strings.SplitN(r.URL.Path, token, 2)
|
||||
return parts[1], nil
|
||||
return parts[1], "", nil
|
||||
}
|
||||
return "", errors.New("could not extract file path")
|
||||
return "", "", errors.New("could not extract file path")
|
||||
}
|
||||
|
||||
func parseDimensions(q url.Values) (int64, int64, error) {
|
||||
|
||||
@@ -23,7 +23,7 @@ func Server(opts ...Option) (http.Service, error) {
|
||||
http.Flags(options.Flags...),
|
||||
)
|
||||
|
||||
handle := svc.NewService(
|
||||
handle, err := svc.NewService(
|
||||
svc.Logger(options.Logger),
|
||||
svc.Config(options.Config),
|
||||
svc.Middleware(
|
||||
@@ -47,6 +47,9 @@ func Server(opts ...Option) (http.Service, error) {
|
||||
),
|
||||
),
|
||||
)
|
||||
if err != nil {
|
||||
return http.Service{}, err
|
||||
}
|
||||
|
||||
{
|
||||
handle = svc.NewInstrument(handle, options.Metrics)
|
||||
|
||||
@@ -3,11 +3,17 @@ package svc
|
||||
import (
|
||||
"encoding/xml"
|
||||
"net/http"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
gatewayv1beta1 "github.com/cs3org/go-cs3apis/cs3/gateway/v1beta1"
|
||||
userv1beta1 "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1"
|
||||
rpcv1beta1 "github.com/cs3org/go-cs3apis/cs3/rpc/v1beta1"
|
||||
"github.com/cs3org/reva/pkg/rgrpc/todo/pool"
|
||||
"github.com/cs3org/reva/pkg/storage/utils/templates"
|
||||
"github.com/go-chi/render"
|
||||
merrors "go-micro.dev/v4/errors"
|
||||
"google.golang.org/grpc/metadata"
|
||||
|
||||
"github.com/owncloud/ocis/ocis-pkg/log"
|
||||
"github.com/owncloud/ocis/ocis-pkg/service/grpc"
|
||||
@@ -38,17 +44,24 @@ type Service interface {
|
||||
}
|
||||
|
||||
// NewService returns a service implementation for Service.
|
||||
func NewService(opts ...Option) Service {
|
||||
func NewService(opts ...Option) (Service, error) {
|
||||
options := newOptions(opts...)
|
||||
conf := options.Config
|
||||
|
||||
m := chi.NewMux()
|
||||
m.Use(options.Middleware...)
|
||||
|
||||
gwc, err := pool.GetGatewayServiceClient(conf.RevaGateway)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
svc := Webdav{
|
||||
config: options.Config,
|
||||
config: conf,
|
||||
log: options.Logger,
|
||||
mux: m,
|
||||
thumbnailsClient: thumbnails.NewThumbnailService("com.owncloud.api.thumbnails", grpc.DefaultClient),
|
||||
revaClient: gwc,
|
||||
}
|
||||
|
||||
m.Route(options.Config.HTTP.Root, func(r chi.Router) {
|
||||
@@ -57,7 +70,7 @@ func NewService(opts ...Option) Service {
|
||||
r.Head("/remote.php/dav/public-files/{token}/*", svc.PublicThumbnailHead)
|
||||
})
|
||||
|
||||
return svc
|
||||
return svc, nil
|
||||
}
|
||||
|
||||
// Webdav defines implements the business logic for Service.
|
||||
@@ -66,6 +79,7 @@ type Webdav struct {
|
||||
log log.Logger
|
||||
mux *chi.Mux
|
||||
thumbnailsClient thumbnails.ThumbnailService
|
||||
revaClient gatewayv1beta1.GatewayAPIClient
|
||||
}
|
||||
|
||||
// ServeHTTP implements the Service interface.
|
||||
@@ -83,6 +97,18 @@ func (g Webdav) Thumbnail(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
t := r.Header.Get(TokenHeader)
|
||||
ctx := metadata.AppendToOutgoingContext(r.Context(), TokenHeader, t)
|
||||
userRes, err := g.revaClient.GetUserByClaim(ctx, &userv1beta1.GetUserByClaimRequest{
|
||||
Claim: "username",
|
||||
Value: tr.Username,
|
||||
})
|
||||
if err != nil || userRes.Status.Code != rpcv1beta1.Code_CODE_OK {
|
||||
g.log.Error().Err(err).Msg("could not get user")
|
||||
renderError(w, r, errInternalError("could not get user"))
|
||||
return
|
||||
}
|
||||
|
||||
fullPath := filepath.Join(templates.WithUser(userRes.User, g.config.WebdavNamespace), tr.Filepath)
|
||||
rsp, err := g.thumbnailsClient.GetThumbnail(r.Context(), &thumbnails.GetThumbnailRequest{
|
||||
Filepath: strings.TrimLeft(tr.Filepath, "/"),
|
||||
ThumbnailType: extensionToThumbnailType(strings.TrimLeft(tr.Extension, ".")),
|
||||
@@ -90,7 +116,7 @@ func (g Webdav) Thumbnail(w http.ResponseWriter, r *http.Request) {
|
||||
Height: tr.Height,
|
||||
Source: &thumbnails.GetThumbnailRequest_Cs3Source{
|
||||
Cs3Source: &thumbnails.CS3Source{
|
||||
Path: path.Join(g.config.WebdavNamespace, tr.Filepath),
|
||||
Path: fullPath,
|
||||
Authorization: t,
|
||||
},
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user