diff --git a/go.mod b/go.mod index 72b8c2abd6f..0aa37482fc4 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.9.0 github.com/cs3org/go-cs3apis v0.0.0-20231023073225-7748710e0781 - github.com/cs3org/reva/v2 v2.17.1-0.20231215134723-5142bf31838d + github.com/cs3org/reva/v2 v2.17.1-0.20231218084648-8965ee0155b5 github.com/dhowden/tag v0.0.0-20230630033851-978a0926ee25 github.com/disintegration/imaging v1.6.2 github.com/dutchcoders/go-clamd v0.0.0-20170520113014-b970184f4d9e @@ -193,7 +193,7 @@ require ( github.com/go-logfmt/logfmt v0.5.1 // indirect github.com/go-logr/logr v1.3.0 // indirect github.com/go-logr/stdr v1.2.2 // indirect - github.com/go-micro/plugins/v4/events/natsjs v1.2.2-0.20230807070816-bc05fb076ce7 // indirect + github.com/go-micro/plugins/v4/events/natsjs v1.2.2-0.20231215124540-f7f8d3274bf9 // indirect github.com/go-micro/plugins/v4/store/nats-js-kv v0.0.0-00010101000000-000000000000 // indirect github.com/go-micro/plugins/v4/store/redis v1.2.1-0.20230510195111-07cd57e1bc9d // indirect github.com/go-playground/locales v0.14.1 // indirect diff --git a/go.sum b/go.sum index b2dba7dca6a..b390dc00a90 100644 --- a/go.sum +++ b/go.sum @@ -1021,10 +1021,8 @@ github.com/crewjam/saml v0.4.14 h1:g9FBNx62osKusnFzs3QTN5L9CVA/Egfgm+stJShzw/c= github.com/crewjam/saml v0.4.14/go.mod h1:UVSZCf18jJkk6GpWNVqcyQJMD5HsRugBPf4I1nl2mME= github.com/cs3org/go-cs3apis v0.0.0-20231023073225-7748710e0781 h1:BUdwkIlf8IS2FasrrPg8gGPHQPOrQ18MS1Oew2tmGtY= github.com/cs3org/go-cs3apis v0.0.0-20231023073225-7748710e0781/go.mod h1:UXha4TguuB52H14EMoSsCqDj7k8a/t7g4gVP+bgY5LY= -github.com/cs3org/reva/v2 v2.17.1-0.20231215113433-48c0ea55bf47 h1:6DfMeFpCXoqlfm/+FJ/mFs8Ul5WCZNlorsbDM9Z/ATE= -github.com/cs3org/reva/v2 v2.17.1-0.20231215113433-48c0ea55bf47/go.mod h1:oX1YtLKGr7jatGk0CpPM4GKbSEIdHhmsQuSAYElnN1U= -github.com/cs3org/reva/v2 v2.17.1-0.20231215134723-5142bf31838d h1:OYkjbcOAntD5JBMAuyj+bR1bg5jM+BjRvFBiTlmnxWQ= -github.com/cs3org/reva/v2 v2.17.1-0.20231215134723-5142bf31838d/go.mod h1:JyvlRw2v8BTH5t+ISj1Yc+EMDBcyf8LMB5o98HufWis= +github.com/cs3org/reva/v2 v2.17.1-0.20231218084648-8965ee0155b5 h1:swE/hDgqO/NjZiqZwQzDJ2cI6fT8TM39LXKcEwwhq/E= +github.com/cs3org/reva/v2 v2.17.1-0.20231218084648-8965ee0155b5/go.mod h1:QW31Q1IQ9ZCJMFv3u8/SdHSyLfCcSVNcRbqIJj+Y+7o= github.com/cyberdelia/templates v0.0.0-20141128023046-ca7fffd4298c/go.mod h1:GyV+0YP4qX0UQ7r2MoYZ+AvYDp12OF5yg4q8rGnyNh4= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= @@ -1197,8 +1195,8 @@ github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-micro/plugins/v4/client/grpc v1.2.1 h1:7xAwZRCO6mdUtBHsYIQs1/eCTdhCrnjF70GB+AVd6L0= github.com/go-micro/plugins/v4/client/grpc v1.2.1/go.mod h1:3fDuzyfYLwEImn8+lkhKl3W4Ay1jFevkTeC32PBlgQs= -github.com/go-micro/plugins/v4/events/natsjs v1.2.2-0.20230807070816-bc05fb076ce7 h1:/RpJVLKmKT2OcEnKCPaS6n+zygNzYDzwoYgPQEgcEiQ= -github.com/go-micro/plugins/v4/events/natsjs v1.2.2-0.20230807070816-bc05fb076ce7/go.mod h1:lYuiEYKQTpbE2LA8HEcC8D6kQ29M7ILfEak3dzeucEg= +github.com/go-micro/plugins/v4/events/natsjs v1.2.2-0.20231215124540-f7f8d3274bf9 h1:YOIavj+ZgO9HzukpdXZCvQv+AahjW/fTVFVF4QFRabw= +github.com/go-micro/plugins/v4/events/natsjs v1.2.2-0.20231215124540-f7f8d3274bf9/go.mod h1:cL0O63th39fZ+M/aRJvajz7Qnmv+UTXugOq1k3qrYiQ= github.com/go-micro/plugins/v4/logger/zerolog v1.2.0 h1:JZ516VQ9zekRoi868XG7x0EWxZ2AMq/euHIBChITsTI= github.com/go-micro/plugins/v4/logger/zerolog v1.2.0/go.mod h1:AieYOIeOxobYa5B8WGEqxXM3Ndi26tDIu9fZ4RYkCvQ= github.com/go-micro/plugins/v4/registry/consul v1.2.1 h1:3wctYMtstwQLCjoJ1HA6mKGGFF1hcdKDv5MzHakB1jE= diff --git a/vendor/github.com/cs3org/reva/v2/internal/grpc/interceptors/eventsmiddleware/events.go b/vendor/github.com/cs3org/reva/v2/internal/grpc/interceptors/eventsmiddleware/events.go index 35c4045d426..4162503d1db 100644 --- a/vendor/github.com/cs3org/reva/v2/internal/grpc/interceptors/eventsmiddleware/events.go +++ b/vendor/github.com/cs3org/reva/v2/internal/grpc/interceptors/eventsmiddleware/events.go @@ -228,7 +228,7 @@ func publisherFromConfig(m map[string]interface{}) (events.Publisher, error) { if ok { tlsCert = val.(string) } - return stream.NatsFromConfig(m["name"].(string), stream.NatsConfig{ + return stream.NatsFromConfig(m["name"].(string), false, stream.NatsConfig{ Endpoint: m["address"].(string), Cluster: m["clusterID"].(string), EnableTLS: m["enable-tls"].(bool), diff --git a/vendor/github.com/cs3org/reva/v2/internal/grpc/services/ocmshareprovider/ocmshareprovider.go b/vendor/github.com/cs3org/reva/v2/internal/grpc/services/ocmshareprovider/ocmshareprovider.go index 88d775eafec..0f68136fdfb 100644 --- a/vendor/github.com/cs3org/reva/v2/internal/grpc/services/ocmshareprovider/ocmshareprovider.go +++ b/vendor/github.com/cs3org/reva/v2/internal/grpc/services/ocmshareprovider/ocmshareprovider.go @@ -515,6 +515,14 @@ func (s *service) UpdateReceivedOCMShare(ctx context.Context, req *ocm.UpdateRec func (s *service) GetReceivedOCMShare(ctx context.Context, req *ocm.GetReceivedOCMShareRequest) (*ocm.GetReceivedOCMShareResponse, error) { user := ctxpkg.ContextMustGetUser(ctx) + if user.Id.GetType() == userpb.UserType_USER_TYPE_SERVICE { + var uid userpb.UserId + _ = utils.ReadJSONFromOpaque(req.Opaque, "userid", &uid) + user = &userpb.User{ + Id: &uid, + } + } + ocmshare, err := s.repo.GetReceivedShare(ctx, user, req.Ref) if err != nil { if errors.Is(err, share.ErrShareNotFound) { @@ -523,7 +531,7 @@ func (s *service) GetReceivedOCMShare(ctx context.Context, req *ocm.GetReceivedO }, nil } return &ocm.GetReceivedOCMShareResponse{ - Status: status.NewInternal(ctx, "error getting received share"), + Status: status.NewInternal(ctx, "error getting received share: "+err.Error()), }, nil } diff --git a/vendor/github.com/cs3org/reva/v2/internal/grpc/services/publicshareprovider/publicshareprovider.go b/vendor/github.com/cs3org/reva/v2/internal/grpc/services/publicshareprovider/publicshareprovider.go index 38b64f49d44..4cfd98cb26d 100644 --- a/vendor/github.com/cs3org/reva/v2/internal/grpc/services/publicshareprovider/publicshareprovider.go +++ b/vendor/github.com/cs3org/reva/v2/internal/grpc/services/publicshareprovider/publicshareprovider.go @@ -68,6 +68,7 @@ type config struct { } type passwordPolicy struct { + Disabled bool `mapstructure:"disabled"` MinCharacters int `mapstructure:"min_characters"` MinLowerCaseCharacters int `mapstructure:"min_lowercase_characters"` MinUpperCaseCharacters int `mapstructure:"min_uppercase_characters"` @@ -173,9 +174,10 @@ func New(m map[string]interface{}, ss *grpc.Server) (rgrpc.Service, error) { func newPasswordPolicy(c *passwordPolicy) password.Validator { if c == nil { - return password.NewPasswordPolicy(0, 0, 0, 0, 0, nil) + return password.NewPasswordPolicy(true, 0, 0, 0, 0, 0, nil) } return password.NewPasswordPolicy( + c.Disabled, c.MinCharacters, c.MinLowerCaseCharacters, c.MinUpperCaseCharacters, diff --git a/vendor/github.com/cs3org/reva/v2/internal/grpc/services/storageprovider/storageprovider.go b/vendor/github.com/cs3org/reva/v2/internal/grpc/services/storageprovider/storageprovider.go index f7812783cf6..5b1274c0e4a 100644 --- a/vendor/github.com/cs3org/reva/v2/internal/grpc/services/storageprovider/storageprovider.go +++ b/vendor/github.com/cs3org/reva/v2/internal/grpc/services/storageprovider/storageprovider.go @@ -1267,5 +1267,5 @@ func estreamFromConfig(c eventconfig) (events.Stream, error) { return nil, nil } - return stream.NatsFromConfig("storageprovider", stream.NatsConfig(c)) + return stream.NatsFromConfig("storageprovider", false, stream.NatsConfig(c)) } diff --git a/vendor/github.com/cs3org/reva/v2/internal/http/services/dataprovider/dataprovider.go b/vendor/github.com/cs3org/reva/v2/internal/http/services/dataprovider/dataprovider.go index 8c3a31195ff..cb930b95a73 100644 --- a/vendor/github.com/cs3org/reva/v2/internal/http/services/dataprovider/dataprovider.go +++ b/vendor/github.com/cs3org/reva/v2/internal/http/services/dataprovider/dataprovider.go @@ -80,7 +80,7 @@ func New(m map[string]interface{}, log *zerolog.Logger) (global.Service, error) if conf.NatsAddress == "" || conf.NatsClusterID == "" { log.Warn().Msg("missing or incomplete nats configuration. Events will not be published.") } else { - s, err := stream.NatsFromConfig("dataprovider", stream.NatsConfig{ + s, err := stream.NatsFromConfig("dataprovider", false, stream.NatsConfig{ Endpoint: conf.NatsAddress, Cluster: conf.NatsClusterID, EnableTLS: conf.NatsEnableTLS, 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 e648582c0d1..cb52ea695ae 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 @@ -137,6 +137,7 @@ func (s *svc) handlePut(ctx context.Context, w http.ResponseWriter, r *http.Requ length, err := getContentLength(w, r) if err != nil { + log.Error().Err(err).Msg("error getting the content length") w.WriteHeader(http.StatusBadRequest) return } diff --git a/vendor/github.com/cs3org/reva/v2/internal/http/services/owncloud/ocs/data/capabilities.go b/vendor/github.com/cs3org/reva/v2/internal/http/services/owncloud/ocs/data/capabilities.go index 369ca231792..f6abda35b0c 100644 --- a/vendor/github.com/cs3org/reva/v2/internal/http/services/owncloud/ocs/data/capabilities.go +++ b/vendor/github.com/cs3org/reva/v2/internal/http/services/owncloud/ocs/data/capabilities.go @@ -117,6 +117,7 @@ type CapabilitiesGraph struct { // CapabilitiesPasswordPolicy hold the password policy capabilities type CapabilitiesPasswordPolicy struct { + Disabled bool `json:"disabled" xml:"disabled" mapstructure:"disabled"` MinCharacters int `json:"min_characters" xml:"min_characters" mapstructure:"min_characters"` MaxCharacters int `json:"max_characters" xml:"max_characters" mapstructure:"max_characters"` MinLowerCaseCharacters int `json:"min_lowercase_characters" xml:"min_lowercase_characters" mapstructure:"min_lowercase_characters"` diff --git a/vendor/github.com/cs3org/reva/v2/internal/http/services/owncloud/ocs/handlers/apps/sharing/shares/shares.go b/vendor/github.com/cs3org/reva/v2/internal/http/services/owncloud/ocs/handlers/apps/sharing/shares/shares.go index 22265a857e9..303fc95d401 100644 --- a/vendor/github.com/cs3org/reva/v2/internal/http/services/owncloud/ocs/handlers/apps/sharing/shares/shares.go +++ b/vendor/github.com/cs3org/reva/v2/internal/http/services/owncloud/ocs/handlers/apps/sharing/shares/shares.go @@ -1734,9 +1734,10 @@ func publicPwdEnforced(c *config.Config) passwordEnforced { func passwordPolicies(c *config.Config) password.Validator { if c.Capabilities.Capabilities == nil || c.Capabilities.Capabilities.PasswordPolicy == nil { - return password.NewPasswordPolicy(0, 0, 0, 0, 0, nil) + return password.NewPasswordPolicy(true, 0, 0, 0, 0, 0, nil) } return password.NewPasswordPolicy( + c.Capabilities.Capabilities.PasswordPolicy.Disabled, c.Capabilities.Capabilities.PasswordPolicy.MinCharacters, c.Capabilities.Capabilities.PasswordPolicy.MinLowerCaseCharacters, c.Capabilities.Capabilities.PasswordPolicy.MinUpperCaseCharacters, diff --git a/vendor/github.com/cs3org/reva/v2/pkg/events/stream/nats.go b/vendor/github.com/cs3org/reva/v2/pkg/events/stream/nats.go index f302822fc7a..4910d694e23 100644 --- a/vendor/github.com/cs3org/reva/v2/pkg/events/stream/nats.go +++ b/vendor/github.com/cs3org/reva/v2/pkg/events/stream/nats.go @@ -25,7 +25,7 @@ type NatsConfig struct { } // NatsFromConfig returns a nats stream from the given config -func NatsFromConfig(connName string, cfg NatsConfig) (events.Stream, error) { +func NatsFromConfig(connName string, disableDurability bool, cfg NatsConfig) (events.Stream, error) { var tlsConf *tls.Config if cfg.EnableTLS { var rootCAPool *x509.CertPool @@ -48,13 +48,20 @@ func NatsFromConfig(connName string, cfg NatsConfig) (events.Stream, error) { RootCAs: rootCAPool, } } - return Nats( + + opts := []natsjs.Option{ natsjs.TLSConfig(tlsConf), natsjs.Address(cfg.Endpoint), natsjs.ClusterID(cfg.Cluster), natsjs.SynchronousPublish(true), natsjs.Name(connName), - ) + } + + if disableDurability { + opts = append(opts, natsjs.DisableDurableStreams()) + } + + return Nats(opts...) } diff --git a/vendor/github.com/cs3org/reva/v2/pkg/ocm/storage/received/ocm.go b/vendor/github.com/cs3org/reva/v2/pkg/ocm/storage/received/ocm.go index 95ab95492ea..28acb07a0a9 100644 --- a/vendor/github.com/cs3org/reva/v2/pkg/ocm/storage/received/ocm.go +++ b/vendor/github.com/cs3org/reva/v2/pkg/ocm/storage/received/ocm.go @@ -30,6 +30,7 @@ import ( "strings" gateway "github.com/cs3org/go-cs3apis/cs3/gateway/v1beta1" + userpb "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1" userv1beta1 "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1" rpc "github.com/cs3org/go-cs3apis/cs3/rpc/v1beta1" ocmpb "github.com/cs3org/go-cs3apis/cs3/sharing/ocm/v1beta1" @@ -59,8 +60,11 @@ type driver struct { } type config struct { - GatewaySVC string `mapstructure:"gatewaysvc"` - Insecure bool `mapstructure:"insecure"` + GatewaySVC string `mapstructure:"gatewaysvc"` + Insecure bool `mapstructure:"insecure"` + StorageRoot string `mapstructure:"storage_root"` + ServiceAccountID string `mapstructure:"service_account_id"` + ServiceAccountSecret string `mapstructure:"service_account_secret"` } func (c *config) ApplyDefaults() { @@ -136,15 +140,19 @@ func shareInfoFromReference(ref *provider.Reference) (*ocmpb.ShareId, string) { } -func (d *driver) getWebDAVFromShare(ctx context.Context, shareID *ocmpb.ShareId) (*ocmpb.ReceivedShare, string, string, error) { +func (d *driver) getWebDAVFromShare(ctx context.Context, forUser *userpb.UserId, shareID *ocmpb.ShareId) (*ocmpb.ReceivedShare, string, string, error) { // TODO: we may want to cache the share - res, err := d.gateway.GetReceivedOCMShare(ctx, &ocmpb.GetReceivedOCMShareRequest{ + req := &ocmpb.GetReceivedOCMShareRequest{ Ref: &ocmpb.ShareReference{ Spec: &ocmpb.ShareReference_Id{ Id: shareID, }, }, - }) + } + if forUser != nil { + req.Opaque = utils.AppendJSONToOpaque(nil, "userid", forUser) + } + res, err := d.gateway.GetReceivedOCMShare(ctx, req) if err != nil { return nil, "", "", err } @@ -173,10 +181,10 @@ func getWebDAVProtocol(protocols []*ocmpb.Protocol) (*ocmpb.WebDAVProtocol, bool return nil, false } -func (d *driver) webdavClient(ctx context.Context, ref *provider.Reference) (*gowebdav.Client, *ocmpb.ReceivedShare, string, error) { +func (d *driver) webdavClient(ctx context.Context, forUser *userpb.UserId, ref *provider.Reference) (*gowebdav.Client, *ocmpb.ReceivedShare, string, error) { id, rel := shareInfoFromReference(ref) - share, endpoint, secret, err := d.getWebDAVFromShare(ctx, id) + share, endpoint, secret, err := d.getWebDAVFromShare(ctx, forUser, id) if err != nil { return nil, nil, "", err } @@ -199,7 +207,7 @@ func (d *driver) webdavClient(ctx context.Context, ref *provider.Reference) (*go } func (d *driver) CreateDir(ctx context.Context, ref *provider.Reference) error { - client, _, rel, err := d.webdavClient(ctx, ref) + client, _, rel, err := d.webdavClient(ctx, nil, ref) if err != nil { return err } @@ -207,7 +215,7 @@ func (d *driver) CreateDir(ctx context.Context, ref *provider.Reference) error { } func (d *driver) Delete(ctx context.Context, ref *provider.Reference) error { - client, _, rel, err := d.webdavClient(ctx, ref) + client, _, rel, err := d.webdavClient(ctx, nil, ref) if err != nil { return err } @@ -215,7 +223,7 @@ func (d *driver) Delete(ctx context.Context, ref *provider.Reference) error { } func (d *driver) TouchFile(ctx context.Context, ref *provider.Reference, markprocessing bool, mtime string) error { - client, _, rel, err := d.webdavClient(ctx, ref) + client, _, rel, err := d.webdavClient(ctx, nil, ref) if err != nil { return err } @@ -223,7 +231,7 @@ func (d *driver) TouchFile(ctx context.Context, ref *provider.Reference, markpro } func (d *driver) Move(ctx context.Context, oldRef, newRef *provider.Reference) error { - client, _, relOld, err := d.webdavClient(ctx, oldRef) + client, _, relOld, err := d.webdavClient(ctx, nil, oldRef) if err != nil { return err } @@ -263,7 +271,7 @@ func convertStatToResourceInfo(ref *provider.Reference, f fs.FileInfo, share *oc } webdavProtocol, _ := getWebDAVProtocol(share.Protocols) - return &provider.ResourceInfo{ + ri := provider.ResourceInfo{ Type: t, Id: id, MimeType: mime.Detect(f.IsDir(), f.Name()), @@ -278,11 +286,17 @@ func convertStatToResourceInfo(ref *provider.Reference, f fs.FileInfo, share *oc Checksum: &provider.ResourceChecksum{ Type: provider.ResourceChecksumType_RESOURCE_CHECKSUM_TYPE_INVALID, }, - }, nil + } + + if f.(gowebdav.File).StatusCode() == 425 { + ri.Opaque = utils.AppendPlainToOpaque(ri.Opaque, "status", "processing") + } + + return &ri, nil } func (d *driver) GetMD(ctx context.Context, ref *provider.Reference, _ []string, _ []string) (*provider.ResourceInfo, error) { - client, share, rel, err := d.webdavClient(ctx, ref) + client, share, rel, err := d.webdavClient(ctx, nil, ref) if err != nil { return nil, err } @@ -299,7 +313,7 @@ func (d *driver) GetMD(ctx context.Context, ref *provider.Reference, _ []string, } func (d *driver) ListFolder(ctx context.Context, ref *provider.Reference, _ []string, _ []string) ([]*provider.ResourceInfo, error) { - client, share, rel, err := d.webdavClient(ctx, ref) + client, share, rel, err := d.webdavClient(ctx, nil, ref) if err != nil { return nil, err } @@ -320,35 +334,8 @@ func (d *driver) ListFolder(ctx context.Context, ref *provider.Reference, _ []st return res, nil } -func (d *driver) InitiateUpload(ctx context.Context, ref *provider.Reference, _ int64, _ map[string]string) (map[string]string, error) { - shareID, rel := shareInfoFromReference(ref) - p := getPathFromShareIDAndRelPath(shareID, rel) - - return map[string]string{ - "simple": p, - }, nil -} - -func (d *driver) Upload(ctx context.Context, req storage.UploadRequest, _ storage.UploadFinishedFunc) (provider.ResourceInfo, error) { - client, _, rel, err := d.webdavClient(ctx, req.Ref) - if err != nil { - return provider.ResourceInfo{}, err - } - client.SetInterceptor(func(method string, rq *http.Request) { - // Set the content length on the request struct directly instead of the header. - // The content-length header gets reset by the golang http library before - // sendind out the request, resulting in chunked encoding to be used which - // breaks the quota checks in ocdav. - if method == "PUT" { - rq.ContentLength = req.Length - } - }) - - return provider.ResourceInfo{}, client.WriteStream(rel, req.Body, 0) -} - func (d *driver) Download(ctx context.Context, ref *provider.Reference) (io.ReadCloser, error) { - client, _, rel, err := d.webdavClient(ctx, ref) + client, _, rel, err := d.webdavClient(ctx, nil, ref) if err != nil { return nil, err } diff --git a/vendor/github.com/cs3org/reva/v2/pkg/ocm/storage/received/upload.go b/vendor/github.com/cs3org/reva/v2/pkg/ocm/storage/received/upload.go new file mode 100644 index 00000000000..1e4a5c1fd17 --- /dev/null +++ b/vendor/github.com/cs3org/reva/v2/pkg/ocm/storage/received/upload.go @@ -0,0 +1,405 @@ +// Copyright 2018-2023 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 ocm + +import ( + "context" + "crypto/md5" + "crypto/sha1" + "encoding/hex" + "encoding/json" + "errors" + "fmt" + "hash" + "hash/adler32" + "io" + "net/http" + "os" + "path/filepath" + "strings" + + "github.com/google/uuid" + tusd "github.com/tus/tusd/pkg/handler" + + userpb "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1" + provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1" + "github.com/cs3org/reva/v2/pkg/appctx" + ctxpkg "github.com/cs3org/reva/v2/pkg/ctx" + "github.com/cs3org/reva/v2/pkg/errtypes" + "github.com/cs3org/reva/v2/pkg/storage" + "github.com/cs3org/reva/v2/pkg/utils" +) + +var defaultFilePerm = os.FileMode(0664) + +func (d *driver) ListUploadSessions(ctx context.Context, filter storage.UploadSessionFilter) ([]storage.UploadSession, error) { + return []storage.UploadSession{}, nil +} +func (d *driver) InitiateUpload(ctx context.Context, ref *provider.Reference, uploadLength int64, metadata map[string]string) (map[string]string, error) { + shareID, rel := shareInfoFromReference(ref) + p := getPathFromShareIDAndRelPath(shareID, rel) + + info := tusd.FileInfo{ + MetaData: tusd.MetaData{ + "filename": filepath.Base(p), + "dir": filepath.Dir(p), + }, + Size: uploadLength, + } + + upload, err := d.NewUpload(ctx, info) + if err != nil { + return nil, err + } + + info, _ = upload.GetInfo(ctx) + + return map[string]string{ + "simple": info.ID, + "tus": info.ID, + }, nil +} + +func (d *driver) Upload(ctx context.Context, req storage.UploadRequest, _ storage.UploadFinishedFunc) (provider.ResourceInfo, error) { + shareID, _ := shareInfoFromReference(req.Ref) + u, err := d.GetUpload(ctx, shareID.OpaqueId) + if err != nil { + return provider.ResourceInfo{}, err + } + + info, err := u.GetInfo(ctx) + if err != nil { + return provider.ResourceInfo{}, err + } + + client, _, rel, err := d.webdavClient(ctx, nil, &provider.Reference{ + Path: filepath.Join(info.MetaData["dir"], info.MetaData["filename"]), + }) + if err != nil { + return provider.ResourceInfo{}, err + } + client.SetInterceptor(func(method string, rq *http.Request) { + // Set the content length on the request struct directly instead of the header. + // The content-length header gets reset by the golang http library before + // sendind out the request, resulting in chunked encoding to be used which + // breaks the quota checks in ocdav. + if method == "PUT" { + rq.ContentLength = req.Length + } + }) + + return provider.ResourceInfo{}, client.WriteStream(rel, req.Body, 0) +} + +// UseIn tells the tus upload middleware which extensions it supports. +func (d *driver) UseIn(composer *tusd.StoreComposer) { + composer.UseCore(d) + composer.UseTerminater(d) + composer.UseConcater(d) + composer.UseLengthDeferrer(d) +} + +// AsTerminatableUpload returns a TerminatableUpload +// To implement the termination extension as specified in https://tus.io/protocols/resumable-upload.html#termination +// the storage needs to implement AsTerminatableUpload +func (d *driver) AsTerminatableUpload(up tusd.Upload) tusd.TerminatableUpload { + return up.(*upload) +} + +// AsLengthDeclarableUpload returns a LengthDeclarableUpload +// To implement the creation-defer-length extension as specified in https://tus.io/protocols/resumable-upload.html#creation +// the storage needs to implement AsLengthDeclarableUpload +func (d *driver) AsLengthDeclarableUpload(up tusd.Upload) tusd.LengthDeclarableUpload { + return up.(*upload) +} + +// AsConcatableUpload returns a ConcatableUpload +// To implement the concatenation extension as specified in https://tus.io/protocols/resumable-upload.html#concatenation +// the storage needs to implement AsConcatableUpload +func (d *driver) AsConcatableUpload(up tusd.Upload) tusd.ConcatableUpload { + return up.(*upload) +} + +// To implement the core tus.io protocol as specified in https://tus.io/protocols/resumable-upload.html#core-protocol +// - the storage needs to implement NewUpload and GetUpload +// - the upload needs to implement the tusd.Upload interface: WriteChunk, GetInfo, GetReader and FinishUpload + +// NewUpload returns a new tus Upload instance +func (d *driver) NewUpload(ctx context.Context, info tusd.FileInfo) (tusd.Upload, error) { + return NewUpload(ctx, d, d.c.StorageRoot, info) +} + +// GetUpload returns the Upload for the given upload id +func (d *driver) GetUpload(ctx context.Context, id string) (tusd.Upload, error) { + return GetUpload(ctx, d, d.c.StorageRoot, id) +} +func NewUpload(ctx context.Context, d *driver, storageRoot string, info tusd.FileInfo) (tusd.Upload, error) { + if info.MetaData["filename"] == "" { + return nil, errors.New("Decomposedfs: missing filename in metadata") + } + if info.MetaData["dir"] == "" { + return nil, errors.New("Decomposedfs: missing dir in metadata") + } + + uploadRoot := filepath.Join(storageRoot, "uploads") + info.ID = uuid.New().String() + + user, ok := ctxpkg.ContextGetUser(ctx) + if !ok { + return nil, errors.New("no user in context") + } + info.MetaData["user"] = user.GetId().GetOpaqueId() + info.MetaData["idp"] = user.GetId().GetIdp() + + info.Storage = map[string]string{ + "Type": "OCM", + "Path": uploadRoot, + } + + u := &upload{ + Info: info, + Ctx: ctx, + d: d, + } + + err := os.MkdirAll(uploadRoot, 0755) + if err != nil { + return nil, err + } + + file, err := os.OpenFile(u.BinPath(), os.O_CREATE|os.O_WRONLY, defaultFilePerm) + if err != nil { + return nil, err + } + defer file.Close() + + err = u.Persist() + if err != nil { + return nil, err + } + return u, nil +} + +func GetUpload(ctx context.Context, d *driver, storageRoot string, id string) (tusd.Upload, error) { + info := tusd.FileInfo{} + data, err := os.ReadFile(filepath.Join(storageRoot, "uploads", id+".info")) + if err != nil { + return nil, err + } + err = json.Unmarshal(data, &info) + if err != nil { + return nil, err + } + upload := &upload{ + Info: info, + Ctx: ctx, + d: d, + } + return upload, nil +} + +type upload struct { + Info tusd.FileInfo + Ctx context.Context + + d *driver +} + +func (u *upload) InfoPath() string { + return filepath.Join(u.Info.Storage["Path"], u.Info.ID+".info") +} + +func (u *upload) BinPath() string { + return filepath.Join(u.Info.Storage["Path"], u.Info.ID) +} + +func (u *upload) Persist() error { + data, err := json.Marshal(u.Info) + if err != nil { + return err + } + return os.WriteFile(u.InfoPath(), data, defaultFilePerm) +} + +func (u *upload) WriteChunk(ctx context.Context, offset int64, src io.Reader) (int64, error) { + file, err := os.OpenFile(u.BinPath(), os.O_WRONLY|os.O_APPEND, defaultFilePerm) + if err != nil { + return 0, err + } + defer file.Close() + + // calculate cheksum here? needed for the TUS checksum extension. https://tus.io/protocols/resumable-upload.html#checksum + // 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 ... + n, err := io.Copy(file, src) + + // 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. + // However, for the ocis driver it's not important whether the stream has ended + // on purpose or accidentally. + if err != nil && err != io.ErrUnexpectedEOF { + return n, err + } + + u.Info.Offset += n + return n, u.Persist() +} + +func (u *upload) GetInfo(ctx context.Context) (tusd.FileInfo, error) { + return u.Info, nil +} + +func (u *upload) GetReader(ctx context.Context) (io.Reader, error) { + return os.Open(u.BinPath()) +} + +func (u *upload) FinishUpload(ctx context.Context) error { + log := appctx.GetLogger(u.Ctx) + + // calculate the checksum of the written bytes + // they will all be written to the metadata later, so we cannot omit any of them + // TODO only calculate the checksum in sync that was requested to match, the rest could be async ... but the tests currently expect all to be present + // TODO the hashes all implement BinaryMarshaler so we could try to persist the state for resumable upload. we would neet do keep track of the copied bytes ... + sha1h := sha1.New() + md5h := md5.New() + adler32h := adler32.New() + { + f, err := os.Open(u.BinPath()) + if err != nil { + // we can continue if no oc checksum header is set + log.Info().Err(err).Str("binPath", u.BinPath()).Msg("error opening binPath") + } + defer f.Close() + + r1 := io.TeeReader(f, sha1h) + r2 := io.TeeReader(r1, md5h) + + _, err = io.Copy(adler32h, r2) + if err != nil { + log.Info().Err(err).Msg("error copying checksums") + } + } + + // compare if they match the sent checksum + // TODO the tus checksum extension would do this on every chunk, but I currently don't see an easy way to pass in the requested checksum. for now we do it in FinishUpload which is also called for chunked uploads + if u.Info.MetaData["checksum"] != "" { + var err error + parts := strings.SplitN(u.Info.MetaData["checksum"], " ", 2) + if len(parts) != 2 { + return errtypes.BadRequest("invalid checksum format. must be '[algorithm] [checksum]'") + } + switch parts[0] { + case "sha1": + err = u.checkHash(parts[1], sha1h) + case "md5": + err = u.checkHash(parts[1], md5h) + case "adler32": + err = u.checkHash(parts[1], adler32h) + default: + err = errtypes.BadRequest("unsupported checksum algorithm: " + parts[0]) + } + if err != nil { + u.cleanup() + return err + } + } + + // send to the remote storage via webdav + // shareID, rel := shareInfoFromReference(u.Info.MetaData["ref"]) + // p := getPathFromShareIDAndRelPath(shareID, rel) + + serviceUserCtx, err := utils.GetServiceUserContext(u.d.c.ServiceAccountID, u.d.gateway, u.d.c.ServiceAccountSecret) + if err != nil { + return err + } + client, _, rel, err := u.d.webdavClient(serviceUserCtx, &userpb.UserId{ + OpaqueId: u.Info.MetaData["user"], + Idp: u.Info.MetaData["idp"], + }, &provider.Reference{ + Path: filepath.Join(u.Info.MetaData["dir"], u.Info.MetaData["filename"]), + }) + if err != nil { + u.cleanup() + return err + } + + client.SetInterceptor(func(method string, rq *http.Request) { + // Set the content length on the request struct directly instead of the header. + // The content-length header gets reset by the golang http library before + // sendind out the request, resulting in chunked encoding to be used which + // breaks the quota checks in ocdav. + if method == "PUT" { + rq.ContentLength = u.Info.Size + } + }) + + f, err := os.Open(u.BinPath()) + if err != nil { + return err + } + defer f.Close() + return client.WriteStream(rel, f, 0) +} + +func (u *upload) cleanup() { + _ = os.Remove(u.BinPath()) + _ = os.Remove(u.InfoPath()) +} + +func (u *upload) Terminate(ctx context.Context) error { + u.cleanup() + return nil +} + +func (u *upload) ConcatUploads(_ context.Context, uploads []tusd.Upload) error { + file, err := os.OpenFile(u.BinPath(), os.O_WRONLY|os.O_APPEND, defaultFilePerm) + if err != nil { + return err + } + defer file.Close() + + for _, partialUpload := range uploads { + fileUpload := partialUpload.(*upload) + + src, err := os.Open(fileUpload.BinPath()) + if err != nil { + return err + } + defer src.Close() + + if _, err := io.Copy(file, src); err != nil { + return err + } + } + return nil +} + +func (u *upload) DeclareLength(ctx context.Context, length int64) error { + u.Info.Size = length + u.Info.SizeIsDeferred = false + return nil +} + +func (u *upload) checkHash(expected string, h hash.Hash) error { + if expected != hex.EncodeToString(h.Sum(nil)) { + return errtypes.ChecksumMismatch(fmt.Sprintf("invalid checksum: expected %s got %x", u.Info.MetaData["checksum"], h.Sum(nil))) + } + return nil +} diff --git a/vendor/github.com/cs3org/reva/v2/pkg/password/password_policies.go b/vendor/github.com/cs3org/reva/v2/pkg/password/password_policies.go index ec98783d318..ac126c9e873 100644 --- a/vendor/github.com/cs3org/reva/v2/pkg/password/password_policies.go +++ b/vendor/github.com/cs3org/reva/v2/pkg/password/password_policies.go @@ -18,6 +18,7 @@ type Validator interface { // Policies represents a password validation rules type Policies struct { + disabled bool minCharacters int minLowerCaseCharacters int minUpperCaseCharacters int @@ -29,8 +30,9 @@ type Policies struct { } // NewPasswordPolicy returns a new NewPasswordPolicy instance -func NewPasswordPolicy(minCharacters, minLowerCaseCharacters, minUpperCaseCharacters, minDigits, minSpecialCharacters int, bannedPasswordsList map[string]struct{}) Validator { +func NewPasswordPolicy(disabled bool, minCharacters, minLowerCaseCharacters, minUpperCaseCharacters, minDigits, minSpecialCharacters int, bannedPasswordsList map[string]struct{}) Validator { p := &Policies{ + disabled: disabled, minCharacters: minCharacters, minLowerCaseCharacters: minLowerCaseCharacters, minUpperCaseCharacters: minUpperCaseCharacters, @@ -46,6 +48,9 @@ func NewPasswordPolicy(minCharacters, minLowerCaseCharacters, minUpperCaseCharac // Validate implements a password validation regarding the policy func (s Policies) Validate(str string) error { + if s.disabled { + return nil + } var allErr error if !utf8.ValidString(str) { return fmt.Errorf("the password contains invalid characters") diff --git a/vendor/github.com/cs3org/reva/v2/pkg/share/manager/jsoncs3/jsoncs3.go b/vendor/github.com/cs3org/reva/v2/pkg/share/manager/jsoncs3/jsoncs3.go index 220c34b3f6d..f0fa2cbd51b 100644 --- a/vendor/github.com/cs3org/reva/v2/pkg/share/manager/jsoncs3/jsoncs3.go +++ b/vendor/github.com/cs3org/reva/v2/pkg/share/manager/jsoncs3/jsoncs3.go @@ -175,7 +175,7 @@ func NewDefault(m map[string]interface{}) (share.Manager, error) { var es events.Stream if c.Events.Endpoint != "" { - es, err = stream.NatsFromConfig("jsoncs3-share-manager", stream.NatsConfig(c.Events)) + es, err = stream.NatsFromConfig("jsoncs3-share-manager", false, stream.NatsConfig(c.Events)) if err != nil { return nil, err } diff --git a/vendor/github.com/go-micro/plugins/v4/events/natsjs/nats.go b/vendor/github.com/go-micro/plugins/v4/events/natsjs/nats.go index 0b4a984bc83..3deadfdeeb1 100644 --- a/vendor/github.com/go-micro/plugins/v4/events/natsjs/nats.go +++ b/vendor/github.com/go-micro/plugins/v4/events/natsjs/nats.go @@ -1,3 +1,4 @@ +// Package natsjs provides a NATS Jetstream implementation of the events.Stream interface. package natsjs import ( @@ -33,11 +34,14 @@ func NewStream(opts ...Option) (events.Stream, error) { } s := &stream{opts: options} + natsJetStreamCtx, err := connectToNatsJetStream(options) if err != nil { - return nil, fmt.Errorf("error connecting to nats cluster %v: %v", options.ClusterID, err) + return nil, fmt.Errorf("error connecting to nats cluster %v: %w", options.ClusterID, err) } + s.natsJetStreamCtx = natsJetStreamCtx + return s, nil } @@ -52,6 +56,7 @@ func connectToNatsJetStream(options Options) (nats.JetStreamContext, error) { nopts.Secure = true nopts.TLSConfig = options.TLSConfig } + if options.NkeyConfig != "" { nopts.Nkey = options.NkeyConfig } @@ -63,14 +68,21 @@ func connectToNatsJetStream(options Options) (nats.JetStreamContext, error) { if options.Name != "" { nopts.Name = options.Name } + + if options.Username != "" && options.Password != "" { + nopts.User = options.Username + nopts.Password = options.Password + } + conn, err := nopts.Connect() if err != nil { - return nil, fmt.Errorf("error connecting to nats at %v with tls enabled (%v): %v", options.Address, nopts.TLSConfig != nil, err) + tls := nopts.TLSConfig != nil + return nil, fmt.Errorf("error connecting to nats at %v with tls enabled (%v): %w", options.Address, tls, err) } js, err := conn.JetStream() if err != nil { - return nil, fmt.Errorf("error while obtaining JetStream context: %v", err) + return nil, fmt.Errorf("error while obtaining JetStream context: %w", err) } return js, nil @@ -125,6 +137,7 @@ func (s *stream) Publish(topic string, msg interface{}, opts ...events.PublishOp if err != nil { err = errors.Wrap(err, "Error publishing message to topic") } + return err } @@ -154,14 +167,14 @@ func (s *stream) Consume(topic string, opts ...events.ConsumeOption) (<-chan eve } // setup the subscriber - c := make(chan events.Event) - handleMsg := func(m *nats.Msg) { + channel := make(chan events.Event) + handleMsg := func(msg *nats.Msg) { ctx, cancel := context.WithCancel(context.TODO()) defer cancel() // decode the message var evt events.Event - if err := json.Unmarshal(m.Data, &evt); err != nil { + if err := json.Unmarshal(msg.Data, &evt); err != nil { log.Logf(logger.ErrorLevel, "Error decoding message: %v", err) // not acknowledging the message is the way to indicate an error occurred return @@ -170,23 +183,23 @@ func (s *stream) Consume(topic string, opts ...events.ConsumeOption) (<-chan eve if !options.AutoAck { // set up the ack funcs evt.SetAckFunc(func() error { - return m.Ack() + return msg.Ack() }) evt.SetNackFunc(func() error { - return m.Nak() + return msg.Nak() }) } // push onto the channel and wait for the consumer to take the event off before we acknowledge it. - c <- evt + channel <- evt if !options.AutoAck { return } - if err := m.Ack(nats.Context(ctx)); err != nil { + + if err := msg.Ack(nats.Context(ctx)); err != nil { log.Logf(logger.ErrorLevel, "Error acknowledging message: %v", err) } - } // ensure that a stream exists for that topic @@ -203,9 +216,7 @@ func (s *stream) Consume(topic string, opts ...events.ConsumeOption) (<-chan eve } // setup the options - subOpts := []nats.SubOpt{ - nats.Durable(options.Group), - } + subOpts := []nats.SubOpt{} if options.CustomRetries { subOpts = append(subOpts, nats.MaxDeliver(options.GetRetryLimit())) @@ -227,11 +238,18 @@ func (s *stream) Consume(topic string, opts ...events.ConsumeOption) (<-chan eve subOpts = append(subOpts, nats.AckWait(options.AckWait)) } - // connect the subscriber - _, err = s.natsJetStreamCtx.QueueSubscribe(topic, options.Group, handleMsg, subOpts...) + // connect the subscriber via a queue group only if durable streams are enabled + if !s.opts.DisableDurableStreams { + subOpts = append(subOpts, nats.Durable(options.Group)) + _, err = s.natsJetStreamCtx.QueueSubscribe(topic, options.Group, handleMsg, subOpts...) + } else { + subOpts = append(subOpts, nats.ConsumerName(options.Group)) + _, err = s.natsJetStreamCtx.Subscribe(topic, handleMsg, subOpts...) + } + if err != nil { return nil, errors.Wrap(err, "Error subscribing to topic") } - return c, nil + return channel, nil } diff --git a/vendor/github.com/go-micro/plugins/v4/events/natsjs/options.go b/vendor/github.com/go-micro/plugins/v4/events/natsjs/options.go index 8418628ad19..f7e83d5f1fe 100644 --- a/vendor/github.com/go-micro/plugins/v4/events/natsjs/options.go +++ b/vendor/github.com/go-micro/plugins/v4/events/natsjs/options.go @@ -8,14 +8,17 @@ import ( // Options which are used to configure the nats stream. type Options struct { - ClusterID string - ClientID string - Address string - NkeyConfig string - TLSConfig *tls.Config - Logger logger.Logger - SyncPublish bool - Name string + ClusterID string + ClientID string + Address string + NkeyConfig string + TLSConfig *tls.Config + Logger logger.Logger + SyncPublish bool + Name string + DisableDurableStreams bool + Username string + Password string } // Option is a function which configures options. @@ -49,30 +52,45 @@ func TLSConfig(t *tls.Config) Option { } } -// Nkey string to use when connecting to the cluster. +// NkeyConfig string to use when connecting to the cluster. func NkeyConfig(nkey string) Option { return func(o *Options) { o.NkeyConfig = nkey } } -// Logger sets the underlyin logger +// Logger sets the underlying logger. func Logger(log logger.Logger) Option { return func(o *Options) { o.Logger = log } } -// SynchronousPublish allows using a synchronous publishing instead of the default asynchronous +// SynchronousPublish allows using a synchronous publishing instead of the default asynchronous. func SynchronousPublish(sync bool) Option { return func(o *Options) { o.SyncPublish = sync } } -// Name allows to add a name to the natsjs connection +// Name allows to add a name to the natsjs connection. func Name(name string) Option { return func(o *Options) { o.Name = name } } + +// DisableDurableStreams will disable durable streams. +func DisableDurableStreams() Option { + return func(o *Options) { + o.DisableDurableStreams = true + } +} + +// Authenticate authenticates the connection with the given username and password. +func Authenticate(username, password string) Option { + return func(o *Options) { + o.Username = username + o.Password = password + } +} diff --git a/vendor/modules.txt b/vendor/modules.txt index e4089ff682c..5e032f4cb81 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -362,7 +362,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.17.1-0.20231215134723-5142bf31838d +# github.com/cs3org/reva/v2 v2.17.1-0.20231218084648-8965ee0155b5 ## explicit; go 1.21 github.com/cs3org/reva/v2/cmd/revad/internal/grace github.com/cs3org/reva/v2/cmd/revad/runtime @@ -904,7 +904,7 @@ github.com/go-logr/stdr # github.com/go-micro/plugins/v4/client/grpc v1.2.1 ## explicit; go 1.17 github.com/go-micro/plugins/v4/client/grpc -# github.com/go-micro/plugins/v4/events/natsjs v1.2.2-0.20230807070816-bc05fb076ce7 +# github.com/go-micro/plugins/v4/events/natsjs v1.2.2-0.20231215124540-f7f8d3274bf9 ## explicit; go 1.17 github.com/go-micro/plugins/v4/events/natsjs # github.com/go-micro/plugins/v4/logger/zerolog v1.2.0