From 7448ce014b028d24541840e4f820ac0d606c9f39 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn=20Friedrich=20Dreyer?= Date: Fri, 14 Jul 2023 16:08:17 +0200 Subject: [PATCH] bump reva to 283ecff63 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Jörn Friedrich Dreyer --- changelog/unreleased/bump-reva.md | 1 + go.mod | 2 +- go.sum | 4 +- .../grpc/services/appprovider/appprovider.go | 5 +- .../http/services/datagateway/datagateway.go | 38 +-- .../http/services/owncloud/ocdav/ocdav.go | 2 + .../http/services/owncloud/ocdav/put.go | 12 + .../http/services/owncloud/ocdav/tus.go | 13 + .../reva/v2/pkg/app/registry/loader/loader.go | 1 + .../reva/v2/pkg/app/registry/micro/config.go | 40 +++ .../reva/v2/pkg/app/registry/micro/manager.go | 265 ++++++++++++++++++ .../reva/v2/pkg/app/registry/micro/micro.go | 50 ++++ .../cs3org/reva/v2/pkg/micro/ocdav/option.go | 12 +- .../utils/decomposedfs/upload/processing.go | 10 +- .../utils/decomposedfs/upload/upload.go | 38 ++- vendor/modules.txt | 3 +- 16 files changed, 465 insertions(+), 31 deletions(-) create mode 100644 vendor/github.com/cs3org/reva/v2/pkg/app/registry/micro/config.go create mode 100644 vendor/github.com/cs3org/reva/v2/pkg/app/registry/micro/manager.go create mode 100644 vendor/github.com/cs3org/reva/v2/pkg/app/registry/micro/micro.go diff --git a/changelog/unreleased/bump-reva.md b/changelog/unreleased/bump-reva.md index b66dff3658..0ed21c7254 100644 --- a/changelog/unreleased/bump-reva.md +++ b/changelog/unreleased/bump-reva.md @@ -29,3 +29,4 @@ https://github.com/owncloud/ocis/pull/6544 https://github.com/owncloud/ocis/pull/6507 https://github.com/owncloud/ocis/pull/6572 https://github.com/owncloud/ocis/pull/6590 +https://github.com/owncloud/ocis/pull/6812 \ No newline at end of file diff --git a/go.mod b/go.mod index 535819180c..3f1448c495 100644 --- a/go.mod +++ b/go.mod @@ -13,7 +13,7 @@ require ( github.com/coreos/go-oidc v2.2.1+incompatible github.com/coreos/go-oidc/v3 v3.6.0 github.com/cs3org/go-cs3apis v0.0.0-20230516150832-730ac860c71d - github.com/cs3org/reva/v2 v2.14.1-0.20230712131605-76f38842c6d2 + github.com/cs3org/reva/v2 v2.14.1-0.20230714140226-283ecff63fe4 github.com/disintegration/imaging v1.6.2 github.com/dutchcoders/go-clamd v0.0.0-20170520113014-b970184f4d9e github.com/egirna/icap-client v0.1.1 diff --git a/go.sum b/go.sum index aebb344b42..1c6513766d 100644 --- a/go.sum +++ b/go.sum @@ -625,8 +625,8 @@ github.com/crewjam/httperr v0.2.0 h1:b2BfXR8U3AlIHwNeFFvZ+BV1LFvKLlzMjzaTnZMybNo github.com/crewjam/httperr v0.2.0/go.mod h1:Jlz+Sg/XqBQhyMjdDiC+GNNRzZTD7x39Gu3pglZ5oH4= github.com/crewjam/saml v0.4.13 h1:TYHggH/hwP7eArqiXSJUvtOPNzQDyQ7vwmwEqlFWhMc= github.com/crewjam/saml v0.4.13/go.mod h1:igEejV+fihTIlHXYP8zOec3V5A8y3lws5bQBFsTm4gA= -github.com/cs3org/reva/v2 v2.14.1-0.20230712131605-76f38842c6d2 h1:i9hn9nmcLLezXh4Dt9aa867CtCXQhNujEWTL+4+M3S4= -github.com/cs3org/reva/v2 v2.14.1-0.20230712131605-76f38842c6d2/go.mod h1:4z5EQghS2LhSWZWocH51Dw9VAs16No1zSFvFgQtgS7w= +github.com/cs3org/reva/v2 v2.14.1-0.20230714140226-283ecff63fe4 h1:9hbfPVNRrrCpHNGZQwF39ymkVEZjbp7T9KxS6vmPfgk= +github.com/cs3org/reva/v2 v2.14.1-0.20230714140226-283ecff63fe4/go.mod h1:4z5EQghS2LhSWZWocH51Dw9VAs16No1zSFvFgQtgS7w= github.com/cubewise-code/go-mime v0.0.0-20200519001935-8c5762b177d8 h1:Z9lwXumT5ACSmJ7WGnFl+OMLLjpz5uR2fyz7dC255FI= github.com/cubewise-code/go-mime v0.0.0-20200519001935-8c5762b177d8/go.mod h1:4abs/jPXcmJzYoYGF91JF9Uq9s/KL5n1jvFDix8KcqY= github.com/cyberdelia/templates v0.0.0-20141128023046-ca7fffd4298c/go.mod h1:GyV+0YP4qX0UQ7r2MoYZ+AvYDp12OF5yg4q8rGnyNh4= diff --git a/vendor/github.com/cs3org/reva/v2/internal/grpc/services/appprovider/appprovider.go b/vendor/github.com/cs3org/reva/v2/internal/grpc/services/appprovider/appprovider.go index e745f368b7..d3b5ff557e 100644 --- a/vendor/github.com/cs3org/reva/v2/internal/grpc/services/appprovider/appprovider.go +++ b/vendor/github.com/cs3org/reva/v2/internal/grpc/services/appprovider/appprovider.go @@ -94,7 +94,10 @@ func New(m map[string]interface{}, ss *grpc.Server) (rgrpc.Service, error) { provider: provider, } - go service.registerProvider() + go func() { + // TODO: implement me to call service.registerProvider with a ticker + service.registerProvider() + }() return service, nil } diff --git a/vendor/github.com/cs3org/reva/v2/internal/http/services/datagateway/datagateway.go b/vendor/github.com/cs3org/reva/v2/internal/http/services/datagateway/datagateway.go index 69fe36f5ea..5e66ad413d 100644 --- a/vendor/github.com/cs3org/reva/v2/internal/http/services/datagateway/datagateway.go +++ b/vendor/github.com/cs3org/reva/v2/internal/http/services/datagateway/datagateway.go @@ -58,8 +58,8 @@ func init() { global.Register("datagateway", New) } -// transferClaims are custom claims for a JWT token to be used between the metadata and data gateways. -type transferClaims struct { +// TransferClaims are custom claims for a JWT token to be used between the metadata and data gateways. +type TransferClaims struct { jwt.StandardClaims Target string `json:"target"` } @@ -161,7 +161,24 @@ func addCorsHeader(res http.ResponseWriter) { headers.Set("Access-Control-Allow-Methods", "GET, POST, OPTIONS, HEAD") } -func (s *svc) verify(ctx context.Context, r *http.Request) (*transferClaims, error) { +// Verify a transfer token against the given secret +func Verify(ctx context.Context, token string, secret string) (*TransferClaims, error) { + j, err := jwt.ParseWithClaims(token, &TransferClaims{}, func(token *jwt.Token) (interface{}, error) { + return []byte(secret), nil + }) + + if err != nil { + return nil, errors.Wrap(err, "error parsing token") + } + + if claims, ok := j.Claims.(*TransferClaims); ok && j.Valid { + return claims, nil + } + err = errtypes.InvalidCredentials("token invalid") + return nil, err +} + +func (s *svc) verify(ctx context.Context, r *http.Request) (*TransferClaims, error) { // Extract transfer token from request header. If not existing, assume that it's the last path segment instead. token := r.Header.Get(TokenTransportHeader) if token == "" { @@ -169,20 +186,7 @@ func (s *svc) verify(ctx context.Context, r *http.Request) (*transferClaims, err r.Header.Set(TokenTransportHeader, token) } - j, err := jwt.ParseWithClaims(token, &transferClaims{}, func(token *jwt.Token) (interface{}, error) { - return []byte(s.conf.TransferSharedSecret), nil - }) - - if err != nil { - return nil, errors.Wrap(err, "error parsing token") - } - - if claims, ok := j.Claims.(*transferClaims); ok && j.Valid { - return claims, nil - } - - err = errtypes.InvalidCredentials("token invalid") - return nil, err + return Verify(ctx, token, s.conf.TransferSharedSecret) } func (s *svc) doHead(w http.ResponseWriter, r *http.Request) { diff --git a/vendor/github.com/cs3org/reva/v2/internal/http/services/owncloud/ocdav/ocdav.go b/vendor/github.com/cs3org/reva/v2/internal/http/services/owncloud/ocdav/ocdav.go index e0291a3194..e96e1b445f 100644 --- a/vendor/github.com/cs3org/reva/v2/internal/http/services/owncloud/ocdav/ocdav.go +++ b/vendor/github.com/cs3org/reva/v2/internal/http/services/owncloud/ocdav/ocdav.go @@ -85,6 +85,8 @@ type Config struct { Product string `mapstructure:"product"` ProductName string `mapstructure:"product_name"` ProductVersion string `mapstructure:"product_version"` + // optional, if set will unpack the transfer token and directly send uploads to the data provider + TransferSharedSecret string `mapstructure:"transfer_shared_secret"` NameValidation NameValidation `mapstructure:"validation"` diff --git a/vendor/github.com/cs3org/reva/v2/internal/http/services/owncloud/ocdav/put.go b/vendor/github.com/cs3org/reva/v2/internal/http/services/owncloud/ocdav/put.go index 58063e5ee2..e6e8322f7b 100644 --- a/vendor/github.com/cs3org/reva/v2/internal/http/services/owncloud/ocdav/put.go +++ b/vendor/github.com/cs3org/reva/v2/internal/http/services/owncloud/ocdav/put.go @@ -298,6 +298,18 @@ func (s *svc) handlePut(ctx context.Context, w http.ResponseWriter, r *http.Requ } } + // if we know the transfer secret we can directly talk to the dataprovider + if s.c.TransferSharedSecret != "" { + claims, err := datagateway.Verify(ctx, token, s.c.TransferSharedSecret) + if err != nil { + log.Error().Err(err).Msg("error verifying transfer token") + w.WriteHeader(http.StatusInternalServerError) + return + } + // directly send request to target + ep = claims.Target + } + httpReq, err := rhttp.NewRequest(ctx, http.MethodPut, ep, r.Body) if err != nil { w.WriteHeader(http.StatusInternalServerError) diff --git a/vendor/github.com/cs3org/reva/v2/internal/http/services/owncloud/ocdav/tus.go b/vendor/github.com/cs3org/reva/v2/internal/http/services/owncloud/ocdav/tus.go index 5371472f71..0d4e30fa7c 100644 --- a/vendor/github.com/cs3org/reva/v2/internal/http/services/owncloud/ocdav/tus.go +++ b/vendor/github.com/cs3org/reva/v2/internal/http/services/owncloud/ocdav/tus.go @@ -32,6 +32,7 @@ import ( link "github.com/cs3org/go-cs3apis/cs3/sharing/link/v1beta1" provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1" typespb "github.com/cs3org/go-cs3apis/cs3/types/v1beta1" + "github.com/cs3org/reva/v2/internal/http/services/datagateway" "github.com/cs3org/reva/v2/internal/http/services/owncloud/ocdav/errors" "github.com/cs3org/reva/v2/internal/http/services/owncloud/ocdav/net" "github.com/cs3org/reva/v2/internal/http/services/owncloud/ocdav/spacelookup" @@ -254,6 +255,18 @@ func (s *svc) handleTusPost(ctx context.Context, w http.ResponseWriter, r *http. } var httpRes *http.Response + // if we know the transfer secret we can directly talk to the dataprovider + if s.c.TransferSharedSecret != "" { + claims, err := datagateway.Verify(ctx, token, s.c.TransferSharedSecret) + if err != nil { + log.Error().Err(err).Msg("error verifying transfer token") + w.WriteHeader(http.StatusInternalServerError) + return + } + // directly send request to target + ep = claims.Target + } + httpReq, err := rhttp.NewRequest(ctx, http.MethodPatch, ep, r.Body) if err != nil { log.Debug().Err(err).Msg("wrong request") diff --git a/vendor/github.com/cs3org/reva/v2/pkg/app/registry/loader/loader.go b/vendor/github.com/cs3org/reva/v2/pkg/app/registry/loader/loader.go index 862c15ce25..175eab887c 100644 --- a/vendor/github.com/cs3org/reva/v2/pkg/app/registry/loader/loader.go +++ b/vendor/github.com/cs3org/reva/v2/pkg/app/registry/loader/loader.go @@ -20,6 +20,7 @@ package loader import ( // Load core app registry drivers. + _ "github.com/cs3org/reva/v2/pkg/app/registry/micro" _ "github.com/cs3org/reva/v2/pkg/app/registry/static" // Add your own here ) diff --git a/vendor/github.com/cs3org/reva/v2/pkg/app/registry/micro/config.go b/vendor/github.com/cs3org/reva/v2/pkg/app/registry/micro/config.go new file mode 100644 index 0000000000..938ae048b3 --- /dev/null +++ b/vendor/github.com/cs3org/reva/v2/pkg/app/registry/micro/config.go @@ -0,0 +1,40 @@ +// Copyright 2018-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 micro + +import "github.com/mitchellh/mapstructure" + +type config struct { + Namespace string `mapstructure:"namespace"` + MimeTypes []*mimeTypeConfig `mapstructure:"mime_types"` +} + +func (c *config) init() { + if c.Namespace == "" { + c.Namespace = "cs3" + } +} + +func parseConfig(m map[string]interface{}) (*config, error) { + c := &config{} + if err := mapstructure.Decode(m, c); err != nil { + return nil, err + } + return c, nil +} diff --git a/vendor/github.com/cs3org/reva/v2/pkg/app/registry/micro/manager.go b/vendor/github.com/cs3org/reva/v2/pkg/app/registry/micro/manager.go new file mode 100644 index 0000000000..26fa6b5f56 --- /dev/null +++ b/vendor/github.com/cs3org/reva/v2/pkg/app/registry/micro/manager.go @@ -0,0 +1,265 @@ +// Copyright 2018-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 micro + +import ( + "context" + "sort" + "strconv" + "sync" + "time" + + registrypb "github.com/cs3org/go-cs3apis/cs3/app/registry/v1beta1" + typesv1beta1 "github.com/cs3org/go-cs3apis/cs3/types/v1beta1" + "github.com/cs3org/reva/v2/pkg/app" + "github.com/cs3org/reva/v2/pkg/appctx" + "github.com/cs3org/reva/v2/pkg/errtypes" + oreg "github.com/owncloud/ocis/v2/ocis-pkg/registry" + "github.com/rs/zerolog/log" + mreg "go-micro.dev/v4/registry" +) + +type manager struct { + namespace string + sync.RWMutex + cancelFunc context.CancelFunc + mimeTypes map[string][]*registrypb.ProviderInfo + providers []*registrypb.ProviderInfo + config *config +} + +// New returns an implementation of the app.Registry interface. +func New(m map[string]interface{}) (app.Registry, error) { + c, err := parseConfig(m) + if err != nil { + return nil, err + } + c.init() + + ctx, cancelFunc := context.WithCancel(context.Background()) + + newManager := manager{ + namespace: c.Namespace, + cancelFunc: cancelFunc, + config: c, + } + + err = newManager.updateProvidersFromMicroRegistry() + if err != nil { + if _, ok := err.(errtypes.NotFound); !ok { + return nil, err + } + } + + t := time.NewTicker(time.Second * 30) + + go func() { + for { + select { + case <-t.C: + log.Debug().Msg("app provider tick, updating local app list") + err = newManager.updateProvidersFromMicroRegistry() + if err != nil { + log.Error().Err(err).Msg("could not update the local provider cache") + continue + } + case <-ctx.Done(): + log.Debug().Msg("app provider stopped") + t.Stop() + } + } + }() + + return &newManager, nil +} + +// AddProvider does not do anything for this registry, it is a placeholder to satisfy the interface +func (m *manager) AddProvider(ctx context.Context, p *registrypb.ProviderInfo) error { + log := appctx.GetLogger(ctx) + + log.Info().Interface("provider", p).Msg("Tried to register through cs3 api, make sure the provider registers directly through go-micro") + + return nil +} + +// FindProvider returns all providers that can provide an app for the given mimeType +func (m *manager) FindProviders(ctx context.Context, mimeType string) ([]*registrypb.ProviderInfo, error) { + m.RLock() + defer m.RUnlock() + + if len(m.mimeTypes[mimeType]) < 1 { + return nil, mreg.ErrNotFound + } + + return m.mimeTypes[mimeType], nil +} + +// GetDefaultProviderForMimeType returns the default provider for the given mimeType +func (m *manager) GetDefaultProviderForMimeType(ctx context.Context, mimeType string) (*registrypb.ProviderInfo, error) { + m.RLock() + defer m.RUnlock() + + for _, mt := range m.config.MimeTypes { + if mt.MimeType != mimeType { + continue + } + for _, p := range m.mimeTypes[mimeType] { + if p.Name == mt.DefaultApp { + return p, nil + } + } + } + + return nil, mreg.ErrNotFound +} + +// ListProviders lists all registered Providers +func (m *manager) ListProviders(ctx context.Context) ([]*registrypb.ProviderInfo, error) { + return m.providers, nil +} + +// ListSupportedMimeTypes lists all supported mimeTypes +func (m *manager) ListSupportedMimeTypes(ctx context.Context) ([]*registrypb.MimeTypeInfo, error) { + m.RLock() + defer m.RUnlock() + + res := []*registrypb.MimeTypeInfo{} + for _, mime := range m.config.MimeTypes { + res = append(res, ®istrypb.MimeTypeInfo{ + MimeType: mime.MimeType, + Ext: mime.Extension, + Name: mime.Name, + Description: mime.Description, + Icon: mime.Icon, + AppProviders: m.mimeTypes[mime.MimeType], + AllowCreation: mime.AllowCreation, + DefaultApplication: mime.DefaultApp, + }) + } + return res, nil +} + +// SetDefaultProviderForMimeType sets the default provider for the given mimeType +func (m *manager) SetDefaultProviderForMimeType(ctx context.Context, mimeType string, p *registrypb.ProviderInfo) error { + m.Lock() + defer m.Unlock() + // NOTE: this is a dirty workaround: + + for _, mt := range m.config.MimeTypes { + if mt.MimeType == mimeType { + mt.DefaultApp = p.Name + return nil + } + } + + log.Info().Msgf("default provider for app is not set through the provider, but defined for the app") + return mreg.ErrNotFound +} + +func (m *manager) getProvidersFromMicroRegistry(ctx context.Context) ([]*registrypb.ProviderInfo, error) { + reg := oreg.GetRegistry() + services, err := reg.GetService(m.namespace+".api.app-provider", mreg.GetContext(ctx)) + if err != nil { + log.Warn().Err(err).Msg("getProvidersFromMicroRegistry") + } + + if len(services) == 0 { + return nil, errtypes.NotFound("no application provider service registered") + } + if len(services) > 1 { + return nil, errtypes.InternalError("more than one application provider services registered") + } + + providers := make([]*registrypb.ProviderInfo, 0, len(services[0].Nodes)) + for _, node := range services[0].Nodes { + p := m.providerFromMetadata(node.Metadata) + p.Address = node.Address + providers = append(providers, &p) + } + return providers, nil +} + +func (m *manager) providerFromMetadata(metadata map[string]string) registrypb.ProviderInfo { + p := registrypb.ProviderInfo{ + MimeTypes: splitMimeTypes(metadata[m.namespace+".app-provider.mime_type"]), + // Address: node.Address, + Name: metadata[m.namespace+".app-provider.name"], + Description: metadata[m.namespace+".app-provider.description"], + Icon: metadata[m.namespace+".app-provider.icon"], + DesktopOnly: metadata[m.namespace+".app-provider.desktop_only"] == "true", + Capability: registrypb.ProviderInfo_Capability(registrypb.ProviderInfo_Capability_value[metadata[m.namespace+".app-provider.capability"]]), + } + if metadata[m.namespace+".app-provider.priority"] != "" { + p.Opaque = &typesv1beta1.Opaque{Map: map[string]*typesv1beta1.OpaqueEntry{ + "priority": { + Decoder: "plain", + Value: []byte(metadata[m.namespace+".app-provider.priority"]), + }, + }} + } + return p +} + +func (m *manager) updateProvidersFromMicroRegistry() error { + lst, err := m.getProvidersFromMicroRegistry(context.Background()) + ma := map[string][]*registrypb.ProviderInfo{} + if err != nil { + return err + } + sortByPriority(lst) + for _, outer := range lst { + for _, inner := range outer.MimeTypes { + ma[inner] = append(ma[inner], outer) + } + } + m.Lock() + defer m.Unlock() + m.mimeTypes = ma + m.providers = lst + return nil +} + +func equalsProviderInfo(p1, p2 *registrypb.ProviderInfo) bool { + sameName := p1.Name == p2.Name + sameAddress := p1.Address == p2.Address + + if sameName && sameAddress { + return true + } + return false +} + +func getPriority(p *registrypb.ProviderInfo) string { + if p.Opaque != nil && len(p.Opaque.Map) != 0 { + if priority, ok := p.Opaque.Map["priority"]; ok { + return string(priority.GetValue()) + } + } + return defaultPriority +} + +func sortByPriority(providers []*registrypb.ProviderInfo) { + less := func(i, j int) bool { + prioI, _ := strconv.ParseInt(getPriority(providers[i]), 10, 64) + prioJ, _ := strconv.ParseInt(getPriority(providers[j]), 10, 64) + return prioI < prioJ + } + + sort.Slice(providers, less) +} diff --git a/vendor/github.com/cs3org/reva/v2/pkg/app/registry/micro/micro.go b/vendor/github.com/cs3org/reva/v2/pkg/app/registry/micro/micro.go new file mode 100644 index 0000000000..9d6df15b1c --- /dev/null +++ b/vendor/github.com/cs3org/reva/v2/pkg/app/registry/micro/micro.go @@ -0,0 +1,50 @@ +// Copyright 2018-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 micro + +import ( + "strings" + + "github.com/cs3org/reva/v2/pkg/app/registry/registry" +) + +const defaultPriority = "0" + +func init() { + registry.Register("micro", New) +} + +type mimeTypeConfig struct { + MimeType string `mapstructure:"mime_type"` + Extension string `mapstructure:"extension"` + Name string `mapstructure:"name"` + Description string `mapstructure:"description"` + Icon string `mapstructure:"icon"` + DefaultApp string `mapstructure:"default_app"` + AllowCreation bool `mapstructure:"allow_creation"` +} + +// use the UTF-8 record separator +func splitMimeTypes(s string) []string { + return strings.Split(s, "␞") +} + +func joinMimeTypes(mimetypes []string) string { + return strings.Join(mimetypes, "␞") +} diff --git a/vendor/github.com/cs3org/reva/v2/pkg/micro/ocdav/option.go b/vendor/github.com/cs3org/reva/v2/pkg/micro/ocdav/option.go index a6ebba9429..00da05f59b 100644 --- a/vendor/github.com/cs3org/reva/v2/pkg/micro/ocdav/option.go +++ b/vendor/github.com/cs3org/reva/v2/pkg/micro/ocdav/option.go @@ -43,8 +43,9 @@ type Options struct { Context context.Context // Metrics *metrics.Metrics // Flags []cli.Flag - Name string - JWTSecret string + Name string + JWTSecret string + TransferSecret string FavoriteManager favorite.Manager GatewaySelector pool.Selectable[gateway.GatewayAPIClient] @@ -109,6 +110,13 @@ func JWTSecret(s string) Option { } } +// TransferSecret provides a function to set the transfer secret option. +func TransferSecret(s string) Option { + return func(o *Options) { + o.config.TransferSharedSecret = s + } +} + // MachineAuthAPIKey provides a function to set the machine auth api key option. func MachineAuthAPIKey(s string) Option { return func(o *Options) { diff --git a/vendor/github.com/cs3org/reva/v2/pkg/storage/utils/decomposedfs/upload/processing.go b/vendor/github.com/cs3org/reva/v2/pkg/storage/utils/decomposedfs/upload/processing.go index 08bba8f996..7a668caae0 100644 --- a/vendor/github.com/cs3org/reva/v2/pkg/storage/utils/decomposedfs/upload/processing.go +++ b/vendor/github.com/cs3org/reva/v2/pkg/storage/utils/decomposedfs/upload/processing.go @@ -240,7 +240,11 @@ func Get(ctx context.Context, id string, lu *lookup.Lookup, tp Tree, fsRoot stri // CreateNodeForUpload will create the target node for the Upload func CreateNodeForUpload(upload *Upload, initAttrs node.Attributes) (*node.Node, error) { + ctx, span := tracer.Start(upload.Ctx, "CreateNodeForUpload") + defer span.End() + _, subspan := tracer.Start(ctx, "os.Stat") fi, err := os.Stat(upload.binPath) + subspan.End() if err != nil { return nil, err } @@ -258,13 +262,13 @@ func CreateNodeForUpload(upload *Upload, initAttrs node.Attributes) (*node.Node, nil, upload.lu, ) - n.SpaceRoot, err = node.ReadNode(upload.Ctx, upload.lu, spaceID, spaceID, false, nil, false) + n.SpaceRoot, err = node.ReadNode(ctx, upload.lu, spaceID, spaceID, false, nil, false) if err != nil { return nil, err } // check lock - if err := n.CheckLock(upload.Ctx); err != nil { + if err := n.CheckLock(ctx); err != nil { return nil, err } @@ -293,7 +297,7 @@ func CreateNodeForUpload(upload *Upload, initAttrs node.Attributes) (*node.Node, initAttrs.SetString(prefixes.StatusPrefix, node.ProcessingStatus+upload.Info.ID) // update node metadata with new blobid etc - err = n.SetXattrsWithContext(context.TODO(), initAttrs, false) + err = n.SetXattrsWithContext(ctx, initAttrs, false) if err != nil { return nil, errors.Wrap(err, "Decomposedfs: could not write metadata") } diff --git a/vendor/github.com/cs3org/reva/v2/pkg/storage/utils/decomposedfs/upload/upload.go b/vendor/github.com/cs3org/reva/v2/pkg/storage/utils/decomposedfs/upload/upload.go index f3e785836e..263a28e715 100644 --- a/vendor/github.com/cs3org/reva/v2/pkg/storage/utils/decomposedfs/upload/upload.go +++ b/vendor/github.com/cs3org/reva/v2/pkg/storage/utils/decomposedfs/upload/upload.go @@ -48,8 +48,16 @@ import ( "github.com/pkg/errors" "github.com/rs/zerolog" tusd "github.com/tus/tusd/pkg/handler" + "go.opentelemetry.io/otel" + "go.opentelemetry.io/otel/trace" ) +var tracer trace.Tracer + +func init() { + tracer = otel.Tracer("github.com/cs3org/reva/pkg/storage/utils/decomposedfs/upload") +} + // Tree is used to manage a tree hierarchy type Tree interface { Setup() error @@ -125,11 +133,13 @@ func buildUpload(ctx context.Context, info tusd.FileInfo, binPath string, infoPa // Cleanup cleans the upload func Cleanup(upload *Upload, failure bool, keepUpload bool) { + ctx, span := tracer.Start(upload.Ctx, "Cleanup") + defer span.End() upload.cleanup(failure, !keepUpload, !keepUpload) // unset processing status if upload.Node != nil { // node can be nil when there was an error before it was created (eg. checksum-mismatch) - if err := upload.Node.UnmarkProcessing(upload.Ctx, upload.Info.ID); err != nil { + if err := upload.Node.UnmarkProcessing(ctx, upload.Info.ID); err != nil { upload.log.Info().Str("path", upload.Node.InternalPath()).Err(err).Msg("unmarking processing failed") } } @@ -137,7 +147,11 @@ func Cleanup(upload *Upload, failure bool, keepUpload bool) { // WriteChunk writes the stream from the reader to the given offset of the upload func (upload *Upload) WriteChunk(_ context.Context, offset int64, src io.Reader) (int64, error) { + ctx, span := tracer.Start(upload.Ctx, "WriteChunk") + defer span.End() + _, subspan := tracer.Start(ctx, "os.OpenFile") file, err := os.OpenFile(upload.binPath, os.O_WRONLY|os.O_APPEND, defaultFilePerm) + subspan.End() if err != nil { return 0, err } @@ -147,7 +161,9 @@ func (upload *Upload) WriteChunk(_ context.Context, offset int64, src io.Reader) // TODO but how do we get the `Upload-Checksum`? WriteChunk() only has a context, offset and the reader ... // It is sent with the PATCH request, well or in the POST when the creation-with-upload extension is used // but the tus handler uses a context.Background() so we cannot really check the header and put it in the context ... + _, subspan = tracer.Start(ctx, "io.Copy") n, err := io.Copy(file, src) + subspan.End() // If the HTTP PATCH request gets interrupted in the middle (e.g. because // the user wants to pause the upload), Go's net/http returns an io.ErrUnexpectedEOF. @@ -168,11 +184,15 @@ func (upload *Upload) GetInfo(_ context.Context) (tusd.FileInfo, error) { // GetReader returns an io.Reader for the upload func (upload *Upload) GetReader(_ context.Context) (io.Reader, error) { + _, span := tracer.Start(upload.Ctx, "GetReader") + defer span.End() return os.Open(upload.binPath) } // FinishUpload finishes an upload and moves the file to the internal destination func (upload *Upload) FinishUpload(_ context.Context) error { + ctx, span := tracer.Start(upload.Ctx, "FinishUpload") + defer span.End() // set lockID to context if upload.Info.MetaData["lockid"] != "" { upload.Ctx = ctxpkg.ContextSetLockID(upload.Ctx, upload.Info.MetaData["lockid"]) @@ -188,7 +208,9 @@ func (upload *Upload) FinishUpload(_ context.Context) error { md5h := md5.New() adler32h := adler32.New() { + _, subspan := tracer.Start(ctx, "os.Open") f, err := os.Open(upload.binPath) + subspan.End() if err != nil { // we can continue if no oc checksum header is set log.Info().Err(err).Str("binPath", upload.binPath).Msg("error opening binPath") @@ -198,7 +220,9 @@ func (upload *Upload) FinishUpload(_ context.Context) error { r1 := io.TeeReader(f, sha1h) r2 := io.TeeReader(r1, md5h) + _, subspan = tracer.Start(ctx, "io.Copy") _, err = io.Copy(adler32h, r2) + subspan.End() if err != nil { log.Info().Err(err).Msg("error copying checksums") } @@ -315,6 +339,8 @@ func (upload *Upload) ConcatUploads(_ context.Context, uploads []tusd.Upload) (e // writeInfo updates the entire information. Everything will be overwritten. func (upload *Upload) writeInfo() error { + _, span := tracer.Start(upload.Ctx, "writeInfo") + defer span.End() data, err := json.Marshal(upload.Info) if err != nil { return err @@ -324,10 +350,12 @@ func (upload *Upload) writeInfo() error { // Finalize finalizes the upload (eg moves the file to the internal destination) func (upload *Upload) Finalize() (err error) { + ctx, span := tracer.Start(upload.Ctx, "Finalize") + defer span.End() n := upload.Node if n == nil { var err error - n, err = node.ReadNode(upload.Ctx, upload.lu, upload.Info.Storage["SpaceRoot"], upload.Info.Storage["NodeId"], false, nil, false) + n, err = node.ReadNode(ctx, upload.lu, upload.Info.Storage["SpaceRoot"], upload.Info.Storage["NodeId"], false, nil, false) if err != nil { return err } @@ -335,8 +363,10 @@ func (upload *Upload) Finalize() (err error) { } // upload the data to the blobstore - - if err := upload.tp.WriteBlob(n, upload.binPath); err != nil { + _, subspan := tracer.Start(ctx, "WriteBlob") + err = upload.tp.WriteBlob(n, upload.binPath) + subspan.End() + if err != nil { return errors.Wrap(err, "failed to upload file to blostore") } diff --git a/vendor/modules.txt b/vendor/modules.txt index c2d5a95cac..3a7af15503 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -352,7 +352,7 @@ github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1 github.com/cs3org/go-cs3apis/cs3/storage/registry/v1beta1 github.com/cs3org/go-cs3apis/cs3/tx/v1beta1 github.com/cs3org/go-cs3apis/cs3/types/v1beta1 -# github.com/cs3org/reva/v2 v2.14.1-0.20230712131605-76f38842c6d2 +# github.com/cs3org/reva/v2 v2.14.1-0.20230714140226-283ecff63fe4 ## explicit; go 1.20 github.com/cs3org/reva/v2/cmd/revad/internal/grace github.com/cs3org/reva/v2/cmd/revad/runtime @@ -448,6 +448,7 @@ github.com/cs3org/reva/v2/pkg/app/provider/loader github.com/cs3org/reva/v2/pkg/app/provider/registry github.com/cs3org/reva/v2/pkg/app/provider/wopi github.com/cs3org/reva/v2/pkg/app/registry/loader +github.com/cs3org/reva/v2/pkg/app/registry/micro github.com/cs3org/reva/v2/pkg/app/registry/registry github.com/cs3org/reva/v2/pkg/app/registry/static github.com/cs3org/reva/v2/pkg/appauth