diff --git a/go.mod b/go.mod index 2da25b8957..b5f22bb209 100644 --- a/go.mod +++ b/go.mod @@ -14,7 +14,7 @@ require ( github.com/blevesearch/bleve/v2 v2.5.7 github.com/cenkalti/backoff v2.2.1+incompatible github.com/coreos/go-oidc/v3 v3.17.0 - github.com/cs3org/go-cs3apis v0.0.0-20260130145416-2dc593dc27e7 + github.com/cs3org/go-cs3apis v0.0.0-20260310080202-fb97596763d6 github.com/davidbyttow/govips/v2 v2.17.0 github.com/dhowden/tag v0.0.0-20240417053706-3d75831295e8 github.com/dutchcoders/go-clamd v0.0.0-20170520113014-b970184f4d9e @@ -64,8 +64,8 @@ require ( github.com/onsi/gomega v1.39.1 github.com/open-policy-agent/opa v1.14.1 github.com/opencloud-eu/icap-client v0.0.0-20250930132611-28a2afe62d89 - github.com/opencloud-eu/libre-graph-api-go v1.0.8-0.20260204102724-10bcda1b3068 - github.com/opencloud-eu/reva/v2 v2.42.5 + github.com/opencloud-eu/libre-graph-api-go v1.0.8-0.20260310090739-853d972b282d + github.com/opencloud-eu/reva/v2 v2.42.6-0.20260311175421-d77bc89ffe35 github.com/opensearch-project/opensearch-go/v4 v4.6.0 github.com/orcaman/concurrent-map v1.0.0 github.com/pkg/errors v0.9.1 @@ -238,11 +238,10 @@ require ( github.com/golang-jwt/jwt/v4 v4.5.2 // indirect github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 // indirect github.com/golang/snappy v0.0.4 // indirect - github.com/gomodule/redigo v1.9.3 // indirect github.com/google/go-querystring v1.1.0 // indirect github.com/google/go-tpm v0.9.8 // indirect github.com/google/pprof v0.0.0-20260115054156-294ebfa9ad83 // indirect - github.com/google/renameio/v2 v2.0.1 // indirect + github.com/google/renameio/v2 v2.0.2 // indirect github.com/gookit/goutil v0.7.1 // indirect github.com/gorilla/handlers v1.5.1 // indirect github.com/gorilla/schema v1.4.1 // indirect @@ -290,7 +289,7 @@ require ( github.com/minio/crc64nvme v1.1.1 // indirect github.com/minio/highwayhash v1.0.4-0.20251030100505-070ab1a87a76 // indirect github.com/minio/md5-simd v1.1.2 // indirect - github.com/minio/minio-go/v7 v7.0.98 // indirect + github.com/minio/minio-go/v7 v7.0.99 // indirect github.com/mitchellh/copystructure v1.2.0 // indirect github.com/mitchellh/reflectwalk v1.0.2 // indirect github.com/moby/docker-image-spec v1.3.1 // indirect diff --git a/go.sum b/go.sum index bc0ea8b693..b74c935feb 100644 --- a/go.sum +++ b/go.sum @@ -265,8 +265,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.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-20260130145416-2dc593dc27e7 h1:ez+InorrZ2HXkPmPeeDstPSTkjNmySUZXaT7xEJNOkk= -github.com/cs3org/go-cs3apis v0.0.0-20260130145416-2dc593dc27e7/go.mod h1:DedpcqXl193qF/08Y04IO0PpxyyMu8+GrkD6kWK2MEQ= +github.com/cs3org/go-cs3apis v0.0.0-20260310080202-fb97596763d6 h1:Akwn9gHJugKd8M48LyV+WeIQ6yMXoxZdgZabR53I9q4= +github.com/cs3org/go-cs3apis v0.0.0-20260310080202-fb97596763d6/go.mod h1:DedpcqXl193qF/08Y04IO0PpxyyMu8+GrkD6kWK2MEQ= github.com/cyberdelia/templates v0.0.0-20141128023046-ca7fffd4298c/go.mod h1:GyV+0YP4qX0UQ7r2MoYZ+AvYDp12OF5yg4q8rGnyNh4= github.com/cyphar/filepath-securejoin v0.5.1 h1:eYgfMq5yryL4fbWfkLpFFy2ukSELzaJOTaUTuh+oF48= github.com/cyphar/filepath-securejoin v0.5.1/go.mod h1:Sdj7gXlvMcPZsbhwhQ33GguGLDGQL7h7bg04C/+u9jI= @@ -542,8 +542,6 @@ github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8l github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golangci/lint-1 v0.0.0-20181222135242-d2cdd8c08219/go.mod h1:/X8TswGSh1pIozq4ZwCfxS0WA5JGXguxk94ar/4c87Y= -github.com/gomodule/redigo v1.9.3 h1:dNPSXeXv6HCq2jdyWfjgmhBdqnR6PRO3m/G05nvpPC8= -github.com/gomodule/redigo v1.9.3/go.mod h1:KsU3hiK/Ay8U42qpaJk+kuNa3C+spxapWpM+ywhcgtw= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/flatbuffers v25.2.10+incompatible h1:F3vclr7C3HpB1k9mxCGRMXq6FdUalZ6H/pNX4FP1v0Q= @@ -585,8 +583,8 @@ github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hf github.com/google/pprof v0.0.0-20260115054156-294ebfa9ad83 h1:z2ogiKUYzX5Is6zr/vP9vJGqPwcdqsWjOt+V8J7+bTc= github.com/google/pprof v0.0.0-20260115054156-294ebfa9ad83/go.mod h1:MxpfABSjhmINe3F1It9d+8exIHFvUqtLIRCdOGNXqiI= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= -github.com/google/renameio/v2 v2.0.1 h1:HyOM6qd9gF9sf15AvhbptGHUnaLTpEI9akAFFU3VyW0= -github.com/google/renameio/v2 v2.0.1/go.mod h1:BtmJXm5YlszgC+TD4HOEEUFgkJP3nLxehU6hfe7jRt4= +github.com/google/renameio/v2 v2.0.2 h1:qKZs+tfn+arruZZhQ7TKC/ergJunuJicWS6gLDt/dGw= +github.com/google/renameio/v2 v2.0.2/go.mod h1:OX+G6WHHpHq3NVj7cAOleLOwJfcQ1s3uUJQCrr78SWo= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= @@ -852,8 +850,8 @@ github.com/minio/highwayhash v1.0.4-0.20251030100505-070ab1a87a76 h1:KGuD/pM2JpL github.com/minio/highwayhash v1.0.4-0.20251030100505-070ab1a87a76/go.mod h1:GGYsuwP/fPD6Y9hMiXuapVvlIUEhFhMTh0rxU3ik1LQ= github.com/minio/md5-simd v1.1.2 h1:Gdi1DZK69+ZVMoNHRXJyNcxrMA4dSxoYHZSQbirFg34= github.com/minio/md5-simd v1.1.2/go.mod h1:MzdKDxYpY2BT9XQFocsiZf/NKVtR7nkE4RoEpN+20RM= -github.com/minio/minio-go/v7 v7.0.98 h1:MeAVKjLVz+XJ28zFcuYyImNSAh8Mq725uNW4beRisi0= -github.com/minio/minio-go/v7 v7.0.98/go.mod h1:cY0Y+W7yozf0mdIclrttzo1Iiu7mEf9y7nk2uXqMOvM= +github.com/minio/minio-go/v7 v7.0.99 h1:2vH/byrwUkIpFQFOilvTfaUpvAX3fEFhEzO+DR3DlCE= +github.com/minio/minio-go/v7 v7.0.99/go.mod h1:EtGNKtlX20iL2yaYnxEigaIvj0G0GwSDnifnG8ClIdw= github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw= github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s= @@ -959,10 +957,10 @@ github.com/opencloud-eu/icap-client v0.0.0-20250930132611-28a2afe62d89 h1:W1ms+l github.com/opencloud-eu/icap-client v0.0.0-20250930132611-28a2afe62d89/go.mod h1:vigJkNss1N2QEceCuNw/ullDehncuJNFB6mEnzfq9UI= github.com/opencloud-eu/inotifywaitgo v0.0.0-20251111171128-a390bae3c5e9 h1:dIftlX03Bzfbujhp9B54FbgER0VBDWJi/w8RBxJlzxU= github.com/opencloud-eu/inotifywaitgo v0.0.0-20251111171128-a390bae3c5e9/go.mod h1:JWyDC6H+5oZRdUJUgKuaye+8Ph5hEs6HVzVoPKzWSGI= -github.com/opencloud-eu/libre-graph-api-go v1.0.8-0.20260204102724-10bcda1b3068 h1:i09YEVYbiUBMhxyak93REn/ZJOTRhAN4I3PXp2nCXgU= -github.com/opencloud-eu/libre-graph-api-go v1.0.8-0.20260204102724-10bcda1b3068/go.mod h1:pzatilMEHZFT3qV7C/X3MqOa3NlRQuYhlRhZTL+hN6Q= -github.com/opencloud-eu/reva/v2 v2.42.5 h1:Srhk8++3zJe3KA1u2Vqh4VbmljbblF75DR7t4HW0Kxw= -github.com/opencloud-eu/reva/v2 v2.42.5/go.mod h1:U3UaHyAQcutavXyLaLE3UVY5n6t2pRAN9uv09n69lwI= +github.com/opencloud-eu/libre-graph-api-go v1.0.8-0.20260310090739-853d972b282d h1:JcqGDiyrcaQwVyV861TUyQgO7uEmsjkhfm7aQd84dOw= +github.com/opencloud-eu/libre-graph-api-go v1.0.8-0.20260310090739-853d972b282d/go.mod h1:pzatilMEHZFT3qV7C/X3MqOa3NlRQuYhlRhZTL+hN6Q= +github.com/opencloud-eu/reva/v2 v2.42.6-0.20260311175421-d77bc89ffe35 h1:Qfx8AelrxsyPk3Lacj3feWULGD7BD2Vsg1X6rve7bHU= +github.com/opencloud-eu/reva/v2 v2.42.6-0.20260311175421-d77bc89ffe35/go.mod h1:0k9+Qits/aemqVdCXs5hSEgTppPx9RZuxutuxqZKQF0= github.com/opencloud-eu/secure v0.0.0-20260312082735-b6f5cb2244e4 h1:l2oB/RctH+t8r7QBj5p8thfEHCM/jF35aAY3WQ3hADI= github.com/opencloud-eu/secure v0.0.0-20260312082735-b6f5cb2244e4/go.mod h1:BmF5hyM6tXczk3MpQkFf1hpKSRqCyhqcbiQtiAF7+40= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= diff --git a/protogen/gen/opencloud/messages/search/v0/search.pb.go b/protogen/gen/opencloud/messages/search/v0/search.pb.go index 8bbb1cadba..e5c74946ea 100644 --- a/protogen/gen/opencloud/messages/search/v0/search.pb.go +++ b/protogen/gen/opencloud/messages/search/v0/search.pb.go @@ -559,6 +559,7 @@ type Entity struct { RemoteItemId *ResourceID `protobuf:"bytes,17,opt,name=remote_item_id,json=remoteItemId,proto3" json:"remote_item_id,omitempty"` Image *Image `protobuf:"bytes,18,opt,name=image,proto3" json:"image,omitempty"` Photo *Photo `protobuf:"bytes,19,opt,name=photo,proto3" json:"photo,omitempty"` + Favorites []string `protobuf:"bytes,20,rep,name=favorites,proto3" json:"favorites,omitempty"` } func (x *Entity) Reset() { @@ -726,6 +727,13 @@ func (x *Entity) GetPhoto() *Photo { return nil } +func (x *Entity) GetFavorites() []string { + if x != nil { + return x.Favorites + } + return nil +} + type Match struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -900,7 +908,7 @@ var file_opencloud_messages_search_v0_search_proto_rawDesc = []byte{ 0x6c, 0x4c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x42, 0x06, 0x0a, 0x04, 0x5f, 0x69, 0x73, 0x6f, 0x42, 0x0e, 0x0a, 0x0c, 0x5f, 0x6f, 0x72, 0x69, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x10, 0x0a, 0x0e, 0x5f, 0x74, 0x61, 0x6b, 0x65, 0x6e, 0x44, 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, - 0x65, 0x22, 0xdc, 0x06, 0x0a, 0x06, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x12, 0x39, 0x0a, 0x03, + 0x65, 0x22, 0xfa, 0x06, 0x0a, 0x06, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x12, 0x39, 0x0a, 0x03, 0x72, 0x65, 0x66, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x2e, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x2e, 0x76, 0x30, 0x2e, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, @@ -954,18 +962,20 @@ var file_opencloud_messages_search_v0_search_proto_rawDesc = []byte{ 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x2e, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x2e, 0x76, 0x30, 0x2e, 0x50, 0x68, 0x6f, 0x74, 0x6f, 0x52, 0x05, 0x70, 0x68, 0x6f, 0x74, 0x6f, - 0x22, 0x5b, 0x0a, 0x05, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x12, 0x3c, 0x0a, 0x06, 0x65, 0x6e, 0x74, - 0x69, 0x74, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x6f, 0x70, 0x65, 0x6e, - 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x2e, 0x73, - 0x65, 0x61, 0x72, 0x63, 0x68, 0x2e, 0x76, 0x30, 0x2e, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x52, - 0x06, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x63, 0x6f, 0x72, 0x65, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x02, 0x52, 0x05, 0x73, 0x63, 0x6f, 0x72, 0x65, 0x42, 0x4d, 0x5a, - 0x4b, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x70, 0x65, 0x6e, - 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2d, 0x65, 0x75, 0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6c, 0x6f, - 0x75, 0x64, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x67, 0x65, 0x6e, 0x2f, 0x67, 0x65, 0x6e, 0x2f, - 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, - 0x65, 0x73, 0x2f, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x2f, 0x76, 0x30, 0x62, 0x06, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x33, + 0x12, 0x1c, 0x0a, 0x09, 0x66, 0x61, 0x76, 0x6f, 0x72, 0x69, 0x74, 0x65, 0x73, 0x18, 0x14, 0x20, + 0x03, 0x28, 0x09, 0x52, 0x09, 0x66, 0x61, 0x76, 0x6f, 0x72, 0x69, 0x74, 0x65, 0x73, 0x22, 0x5b, + 0x0a, 0x05, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x12, 0x3c, 0x0a, 0x06, 0x65, 0x6e, 0x74, 0x69, 0x74, + 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6c, + 0x6f, 0x75, 0x64, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x2e, 0x73, 0x65, 0x61, + 0x72, 0x63, 0x68, 0x2e, 0x76, 0x30, 0x2e, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x52, 0x06, 0x65, + 0x6e, 0x74, 0x69, 0x74, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x63, 0x6f, 0x72, 0x65, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x02, 0x52, 0x05, 0x73, 0x63, 0x6f, 0x72, 0x65, 0x42, 0x4d, 0x5a, 0x4b, 0x67, + 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6c, + 0x6f, 0x75, 0x64, 0x2d, 0x65, 0x75, 0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6c, 0x6f, 0x75, 0x64, + 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x67, 0x65, 0x6e, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x6f, 0x70, + 0x65, 0x6e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, + 0x2f, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x2f, 0x76, 0x30, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x33, } var ( diff --git a/protogen/gen/opencloud/messages/settings/v0/settings.pb.go b/protogen/gen/opencloud/messages/settings/v0/settings.pb.go index 99641dcb8c..aa9f81b327 100644 --- a/protogen/gen/opencloud/messages/settings/v0/settings.pb.go +++ b/protogen/gen/opencloud/messages/settings/v0/settings.pb.go @@ -627,13 +627,13 @@ type Bundle struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` // @gotags: yaml:"id" - Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` // @gotags: yaml:"name" - Type Bundle_Type `protobuf:"varint,3,opt,name=type,proto3,enum=opencloud.messages.settings.v0.Bundle_Type" json:"type,omitempty"` // @gotags: yaml:"type" - Extension string `protobuf:"bytes,4,opt,name=extension,proto3" json:"extension,omitempty"` // @gotags: yaml:"extension" - DisplayName string `protobuf:"bytes,5,opt,name=display_name,json=displayName,proto3" json:"display_name,omitempty"` // @gotags: yaml:"display_name" - Settings []*Setting `protobuf:"bytes,6,rep,name=settings,proto3" json:"settings,omitempty"` // @gotags: yaml:"settings" - Resource *Resource `protobuf:"bytes,7,opt,name=resource,proto3" json:"resource,omitempty"` // @gotags: yaml:"resource" + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty" yaml:"id"` // @gotags: yaml:"id" + Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty" yaml:"name"` // @gotags: yaml:"name" + Type Bundle_Type `protobuf:"varint,3,opt,name=type,proto3,enum=opencloud.messages.settings.v0.Bundle_Type" json:"type,omitempty" yaml:"type"` // @gotags: yaml:"type" + Extension string `protobuf:"bytes,4,opt,name=extension,proto3" json:"extension,omitempty" yaml:"extension"` // @gotags: yaml:"extension" + DisplayName string `protobuf:"bytes,5,opt,name=display_name,json=displayName,proto3" json:"display_name,omitempty" yaml:"display_name"` // @gotags: yaml:"display_name" + Settings []*Setting `protobuf:"bytes,6,rep,name=settings,proto3" json:"settings,omitempty" yaml:"settings"` // @gotags: yaml:"settings" + Resource *Resource `protobuf:"bytes,7,opt,name=resource,proto3" json:"resource,omitempty" yaml:"resource"` // @gotags: yaml:"resource" } func (x *Bundle) Reset() { @@ -722,10 +722,10 @@ type Setting struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` // @gotags: yaml:"id" - Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` // @gotags: yaml:"name" - DisplayName string `protobuf:"bytes,3,opt,name=display_name,json=displayName,proto3" json:"display_name,omitempty"` // @gotags: yaml:"display_name" - Description string `protobuf:"bytes,4,opt,name=description,proto3" json:"description,omitempty"` // @gotags: yaml:"description" + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty" yaml:"id"` // @gotags: yaml:"id" + Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty" yaml:"name"` // @gotags: yaml:"name" + DisplayName string `protobuf:"bytes,3,opt,name=display_name,json=displayName,proto3" json:"display_name,omitempty" yaml:"display_name"` // @gotags: yaml:"display_name" + Description string `protobuf:"bytes,4,opt,name=description,proto3" json:"description,omitempty" yaml:"description"` // @gotags: yaml:"description" // Types that are assignable to Value: // // *Setting_IntValue @@ -736,7 +736,7 @@ type Setting struct { // *Setting_PermissionValue // *Setting_MultiChoiceCollectionValue Value isSetting_Value `protobuf_oneof:"value"` - Resource *Resource `protobuf:"bytes,11,opt,name=resource,proto3" json:"resource,omitempty"` // @gotags: yaml:"resource" + Resource *Resource `protobuf:"bytes,11,opt,name=resource,proto3" json:"resource,omitempty" yaml:"resource"` // @gotags: yaml:"resource" } func (x *Setting) Reset() { @@ -867,31 +867,31 @@ type isSetting_Value interface { } type Setting_IntValue struct { - IntValue *Int `protobuf:"bytes,5,opt,name=int_value,json=intValue,proto3,oneof"` // @gotags: yaml:"int_value" + IntValue *Int `protobuf:"bytes,5,opt,name=int_value,json=intValue,proto3,oneof" yaml:"int_value"` // @gotags: yaml:"int_value" } type Setting_StringValue struct { - StringValue *String `protobuf:"bytes,6,opt,name=string_value,json=stringValue,proto3,oneof"` // @gotags: yaml:"string_value" + StringValue *String `protobuf:"bytes,6,opt,name=string_value,json=stringValue,proto3,oneof" yaml:"string_value"` // @gotags: yaml:"string_value" } type Setting_BoolValue struct { - BoolValue *Bool `protobuf:"bytes,7,opt,name=bool_value,json=boolValue,proto3,oneof"` // @gotags: yaml:"bool_value" + BoolValue *Bool `protobuf:"bytes,7,opt,name=bool_value,json=boolValue,proto3,oneof" yaml:"bool_value"` // @gotags: yaml:"bool_value" } type Setting_SingleChoiceValue struct { - SingleChoiceValue *SingleChoiceList `protobuf:"bytes,8,opt,name=single_choice_value,json=singleChoiceValue,proto3,oneof"` // @gotags: yaml:"single_choice_value" + SingleChoiceValue *SingleChoiceList `protobuf:"bytes,8,opt,name=single_choice_value,json=singleChoiceValue,proto3,oneof" yaml:"single_choice_value"` // @gotags: yaml:"single_choice_value" } type Setting_MultiChoiceValue struct { - MultiChoiceValue *MultiChoiceList `protobuf:"bytes,9,opt,name=multi_choice_value,json=multiChoiceValue,proto3,oneof"` // @gotags: yaml:"multi_choice_value" + MultiChoiceValue *MultiChoiceList `protobuf:"bytes,9,opt,name=multi_choice_value,json=multiChoiceValue,proto3,oneof" yaml:"multi_choice_value"` // @gotags: yaml:"multi_choice_value" } type Setting_PermissionValue struct { - PermissionValue *Permission `protobuf:"bytes,10,opt,name=permission_value,json=permissionValue,proto3,oneof"` // @gotags: yaml:"permission_value" + PermissionValue *Permission `protobuf:"bytes,10,opt,name=permission_value,json=permissionValue,proto3,oneof" yaml:"permission_value"` // @gotags: yaml:"permission_value" } type Setting_MultiChoiceCollectionValue struct { - MultiChoiceCollectionValue *MultiChoiceCollection `protobuf:"bytes,12,opt,name=multi_choice_collection_value,json=multiChoiceCollectionValue,proto3,oneof"` // @gotags: yaml:"multi_choice_collection_value" + MultiChoiceCollectionValue *MultiChoiceCollection `protobuf:"bytes,12,opt,name=multi_choice_collection_value,json=multiChoiceCollectionValue,proto3,oneof" yaml:"multi_choice_collection_value"` // @gotags: yaml:"multi_choice_collection_value" } func (*Setting_IntValue) isSetting_Value() {} @@ -913,11 +913,11 @@ type Int struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Default int64 `protobuf:"varint,1,opt,name=default,proto3" json:"default,omitempty"` // @gotags: yaml:"default" - Min int64 `protobuf:"varint,2,opt,name=min,proto3" json:"min,omitempty"` // @gotags: yaml:"min" - Max int64 `protobuf:"varint,3,opt,name=max,proto3" json:"max,omitempty"` // @gotags: yaml:"max" - Step int64 `protobuf:"varint,4,opt,name=step,proto3" json:"step,omitempty"` // @gotags: yaml:"step" - Placeholder string `protobuf:"bytes,5,opt,name=placeholder,proto3" json:"placeholder,omitempty"` // @gotags: yaml:"placeholder" + Default int64 `protobuf:"varint,1,opt,name=default,proto3" json:"default,omitempty" yaml:"default"` // @gotags: yaml:"default" + Min int64 `protobuf:"varint,2,opt,name=min,proto3" json:"min,omitempty" yaml:"min"` // @gotags: yaml:"min" + Max int64 `protobuf:"varint,3,opt,name=max,proto3" json:"max,omitempty" yaml:"max"` // @gotags: yaml:"max" + Step int64 `protobuf:"varint,4,opt,name=step,proto3" json:"step,omitempty" yaml:"step"` // @gotags: yaml:"step" + Placeholder string `protobuf:"bytes,5,opt,name=placeholder,proto3" json:"placeholder,omitempty" yaml:"placeholder"` // @gotags: yaml:"placeholder" } func (x *Int) Reset() { @@ -992,11 +992,11 @@ type String struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Default string `protobuf:"bytes,1,opt,name=default,proto3" json:"default,omitempty"` // @gotags: yaml:"default" - Required bool `protobuf:"varint,2,opt,name=required,proto3" json:"required,omitempty"` // @gotags: yaml:"required" - MinLength int32 `protobuf:"varint,3,opt,name=min_length,json=minLength,proto3" json:"min_length,omitempty"` // @gotags: yaml:"min_length" - MaxLength int32 `protobuf:"varint,4,opt,name=max_length,json=maxLength,proto3" json:"max_length,omitempty"` // @gotags: yaml:"max_length" - Placeholder string `protobuf:"bytes,5,opt,name=placeholder,proto3" json:"placeholder,omitempty"` // @gotags: yaml:"placeholder" + Default string `protobuf:"bytes,1,opt,name=default,proto3" json:"default,omitempty" yaml:"default"` // @gotags: yaml:"default" + Required bool `protobuf:"varint,2,opt,name=required,proto3" json:"required,omitempty" yaml:"required"` // @gotags: yaml:"required" + MinLength int32 `protobuf:"varint,3,opt,name=min_length,json=minLength,proto3" json:"min_length,omitempty" yaml:"min_length"` // @gotags: yaml:"min_length" + MaxLength int32 `protobuf:"varint,4,opt,name=max_length,json=maxLength,proto3" json:"max_length,omitempty" yaml:"max_length"` // @gotags: yaml:"max_length" + Placeholder string `protobuf:"bytes,5,opt,name=placeholder,proto3" json:"placeholder,omitempty" yaml:"placeholder"` // @gotags: yaml:"placeholder" } func (x *String) Reset() { @@ -1071,8 +1071,8 @@ type Bool struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Default bool `protobuf:"varint,1,opt,name=default,proto3" json:"default,omitempty"` // @gotags: yaml:"default" - Label string `protobuf:"bytes,2,opt,name=label,proto3" json:"label,omitempty"` // @gotags: yaml:"label" + Default bool `protobuf:"varint,1,opt,name=default,proto3" json:"default,omitempty" yaml:"default"` // @gotags: yaml:"default" + Label string `protobuf:"bytes,2,opt,name=label,proto3" json:"label,omitempty" yaml:"label"` // @gotags: yaml:"label" } func (x *Bool) Reset() { @@ -1126,7 +1126,7 @@ type SingleChoiceList struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Options []*ListOption `protobuf:"bytes,1,rep,name=options,proto3" json:"options,omitempty"` // @gotags: yaml:"options" + Options []*ListOption `protobuf:"bytes,1,rep,name=options,proto3" json:"options,omitempty" yaml:"options"` // @gotags: yaml:"options" } func (x *SingleChoiceList) Reset() { @@ -1173,7 +1173,7 @@ type MultiChoiceList struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Options []*ListOption `protobuf:"bytes,1,rep,name=options,proto3" json:"options,omitempty"` // @gotags: yaml:"options" + Options []*ListOption `protobuf:"bytes,1,rep,name=options,proto3" json:"options,omitempty" yaml:"options"` // @gotags: yaml:"options" } func (x *MultiChoiceList) Reset() { @@ -1220,9 +1220,9 @@ type ListOption struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Value *ListOptionValue `protobuf:"bytes,1,opt,name=value,proto3" json:"value,omitempty"` // @gotags: yaml:"value" - Default bool `protobuf:"varint,2,opt,name=default,proto3" json:"default,omitempty"` // @gotags: yaml:"default" - DisplayValue string `protobuf:"bytes,3,opt,name=display_value,json=displayValue,proto3" json:"display_value,omitempty"` // @gotags: yaml:"display_value" + Value *ListOptionValue `protobuf:"bytes,1,opt,name=value,proto3" json:"value,omitempty" yaml:"value"` // @gotags: yaml:"value" + Default bool `protobuf:"varint,2,opt,name=default,proto3" json:"default,omitempty" yaml:"default"` // @gotags: yaml:"default" + DisplayValue string `protobuf:"bytes,3,opt,name=display_value,json=displayValue,proto3" json:"display_value,omitempty" yaml:"display_value"` // @gotags: yaml:"display_value" } func (x *ListOption) Reset() { @@ -1283,7 +1283,7 @@ type MultiChoiceCollection struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Options []*MultiChoiceCollectionOption `protobuf:"bytes,1,rep,name=options,proto3" json:"options,omitempty"` // @gotags: yaml:"options" + Options []*MultiChoiceCollectionOption `protobuf:"bytes,1,rep,name=options,proto3" json:"options,omitempty" yaml:"options"` // @gotags: yaml:"options" } func (x *MultiChoiceCollection) Reset() { @@ -1330,10 +1330,10 @@ type MultiChoiceCollectionOption struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Value *MultiChoiceCollectionOptionValue `protobuf:"bytes,1,opt,name=value,proto3" json:"value,omitempty"` // @gotags: yaml:"value" - Key string `protobuf:"bytes,2,opt,name=key,proto3" json:"key,omitempty"` // @gotags: yaml:"key" - Attribute string `protobuf:"bytes,3,opt,name=attribute,proto3" json:"attribute,omitempty"` // @gotags: yaml:"attribute" - DisplayValue string `protobuf:"bytes,4,opt,name=display_value,json=displayValue,proto3" json:"display_value,omitempty"` // @gotags: yaml:"display_value" + Value *MultiChoiceCollectionOptionValue `protobuf:"bytes,1,opt,name=value,proto3" json:"value,omitempty" yaml:"value"` // @gotags: yaml:"value" + Key string `protobuf:"bytes,2,opt,name=key,proto3" json:"key,omitempty" yaml:"key"` // @gotags: yaml:"key" + Attribute string `protobuf:"bytes,3,opt,name=attribute,proto3" json:"attribute,omitempty" yaml:"attribute"` // @gotags: yaml:"attribute" + DisplayValue string `protobuf:"bytes,4,opt,name=display_value,json=displayValue,proto3" json:"display_value,omitempty" yaml:"display_value"` // @gotags: yaml:"display_value" } func (x *MultiChoiceCollectionOption) Reset() { @@ -1474,15 +1474,15 @@ type isMultiChoiceCollectionOptionValue_Option interface { } type MultiChoiceCollectionOptionValue_IntValue struct { - IntValue *Int `protobuf:"bytes,1,opt,name=int_value,json=intValue,proto3,oneof"` // @gotags: yaml:"int_value" + IntValue *Int `protobuf:"bytes,1,opt,name=int_value,json=intValue,proto3,oneof" yaml:"int_value"` // @gotags: yaml:"int_value" } type MultiChoiceCollectionOptionValue_StringValue struct { - StringValue *String `protobuf:"bytes,2,opt,name=string_value,json=stringValue,proto3,oneof"` // @gotags: yaml:"string_value" + StringValue *String `protobuf:"bytes,2,opt,name=string_value,json=stringValue,proto3,oneof" yaml:"string_value"` // @gotags: yaml:"string_value" } type MultiChoiceCollectionOptionValue_BoolValue struct { - BoolValue *Bool `protobuf:"bytes,3,opt,name=bool_value,json=boolValue,proto3,oneof"` // @gotags: yaml:"bool_value" + BoolValue *Bool `protobuf:"bytes,3,opt,name=bool_value,json=boolValue,proto3,oneof" yaml:"bool_value"` // @gotags: yaml:"bool_value" } func (*MultiChoiceCollectionOptionValue_IntValue) isMultiChoiceCollectionOptionValue_Option() {} @@ -1496,8 +1496,8 @@ type Permission struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Operation Permission_Operation `protobuf:"varint,1,opt,name=operation,proto3,enum=opencloud.messages.settings.v0.Permission_Operation" json:"operation,omitempty"` // @gotags: yaml:"operation" - Constraint Permission_Constraint `protobuf:"varint,2,opt,name=constraint,proto3,enum=opencloud.messages.settings.v0.Permission_Constraint" json:"constraint,omitempty"` // @gotags: yaml:"constraint" + Operation Permission_Operation `protobuf:"varint,1,opt,name=operation,proto3,enum=opencloud.messages.settings.v0.Permission_Operation" json:"operation,omitempty" yaml:"operation"` // @gotags: yaml:"operation" + Constraint Permission_Constraint `protobuf:"varint,2,opt,name=constraint,proto3,enum=opencloud.messages.settings.v0.Permission_Constraint" json:"constraint,omitempty" yaml:"constraint"` // @gotags: yaml:"constraint" } func (x *Permission) Reset() { @@ -1552,12 +1552,12 @@ type Value struct { unknownFields protoimpl.UnknownFields // id is the id of the Value. It is generated on saving it. - Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` // @gotags: yaml:"id" - BundleId string `protobuf:"bytes,2,opt,name=bundle_id,json=bundleId,proto3" json:"bundle_id,omitempty"` // @gotags: yaml:"bundle_id" + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty" yaml:"id"` // @gotags: yaml:"id" + BundleId string `protobuf:"bytes,2,opt,name=bundle_id,json=bundleId,proto3" json:"bundle_id,omitempty" yaml:"bundle_id"` // @gotags: yaml:"bundle_id" // setting_id is the id of the setting from within its bundle. - SettingId string `protobuf:"bytes,3,opt,name=setting_id,json=settingId,proto3" json:"setting_id,omitempty"` // @gotags: yaml:"setting_id" - AccountUuid string `protobuf:"bytes,4,opt,name=account_uuid,json=accountUuid,proto3" json:"account_uuid,omitempty"` // @gotags: yaml:"account_uuid" - Resource *Resource `protobuf:"bytes,5,opt,name=resource,proto3" json:"resource,omitempty"` // @gotags: yaml:"resource" + SettingId string `protobuf:"bytes,3,opt,name=setting_id,json=settingId,proto3" json:"setting_id,omitempty" yaml:"setting_id"` // @gotags: yaml:"setting_id" + AccountUuid string `protobuf:"bytes,4,opt,name=account_uuid,json=accountUuid,proto3" json:"account_uuid,omitempty" yaml:"account_uuid"` // @gotags: yaml:"account_uuid" + Resource *Resource `protobuf:"bytes,5,opt,name=resource,proto3" json:"resource,omitempty" yaml:"resource"` // @gotags: yaml:"resource" // Types that are assignable to Value: // // *Value_BoolValue @@ -1682,23 +1682,23 @@ type isValue_Value interface { } type Value_BoolValue struct { - BoolValue bool `protobuf:"varint,6,opt,name=bool_value,json=boolValue,proto3,oneof"` // @gotags: yaml:"bool_value" + BoolValue bool `protobuf:"varint,6,opt,name=bool_value,json=boolValue,proto3,oneof" yaml:"bool_value"` // @gotags: yaml:"bool_value" } type Value_IntValue struct { - IntValue int64 `protobuf:"varint,7,opt,name=int_value,json=intValue,proto3,oneof"` // @gotags: yaml:"int_value" + IntValue int64 `protobuf:"varint,7,opt,name=int_value,json=intValue,proto3,oneof" yaml:"int_value"` // @gotags: yaml:"int_value" } type Value_StringValue struct { - StringValue string `protobuf:"bytes,8,opt,name=string_value,json=stringValue,proto3,oneof"` // @gotags: yaml:"string_value" + StringValue string `protobuf:"bytes,8,opt,name=string_value,json=stringValue,proto3,oneof" yaml:"string_value"` // @gotags: yaml:"string_value" } type Value_ListValue struct { - ListValue *ListValue `protobuf:"bytes,9,opt,name=list_value,json=listValue,proto3,oneof"` // @gotags: yaml:"list_value" + ListValue *ListValue `protobuf:"bytes,9,opt,name=list_value,json=listValue,proto3,oneof" yaml:"list_value"` // @gotags: yaml:"list_value" } type Value_CollectionValue struct { - CollectionValue *CollectionValue `protobuf:"bytes,10,opt,name=collection_value,json=collectionValue,proto3,oneof"` // @gotags: yaml:"collection_value" + CollectionValue *CollectionValue `protobuf:"bytes,10,opt,name=collection_value,json=collectionValue,proto3,oneof" yaml:"collection_value"` // @gotags: yaml:"collection_value" } func (*Value_BoolValue) isValue_Value() {} @@ -1716,7 +1716,7 @@ type ListValue struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Values []*ListOptionValue `protobuf:"bytes,1,rep,name=values,proto3" json:"values,omitempty"` // @gotags: yaml:"values" + Values []*ListOptionValue `protobuf:"bytes,1,rep,name=values,proto3" json:"values,omitempty" yaml:"values"` // @gotags: yaml:"values" } func (x *ListValue) Reset() { @@ -1836,15 +1836,15 @@ type isListOptionValue_Option interface { } type ListOptionValue_StringValue struct { - StringValue string `protobuf:"bytes,1,opt,name=string_value,json=stringValue,proto3,oneof"` // @gotags: yaml:"string_value" + StringValue string `protobuf:"bytes,1,opt,name=string_value,json=stringValue,proto3,oneof" yaml:"string_value"` // @gotags: yaml:"string_value" } type ListOptionValue_IntValue struct { - IntValue int64 `protobuf:"varint,2,opt,name=int_value,json=intValue,proto3,oneof"` // @gotags: yaml:"int_value" + IntValue int64 `protobuf:"varint,2,opt,name=int_value,json=intValue,proto3,oneof" yaml:"int_value"` // @gotags: yaml:"int_value" } type ListOptionValue_BoolValue struct { - BoolValue bool `protobuf:"varint,3,opt,name=bool_value,json=boolValue,proto3,oneof"` // @gotags: yaml:"bool_value" + BoolValue bool `protobuf:"varint,3,opt,name=bool_value,json=boolValue,proto3,oneof" yaml:"bool_value"` // @gotags: yaml:"bool_value" } func (*ListOptionValue_StringValue) isListOptionValue_Option() {} @@ -1858,7 +1858,7 @@ type CollectionValue struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Values []*CollectionOption `protobuf:"bytes,1,rep,name=values,proto3" json:"values,omitempty"` // @gotags: yaml:"values" + Values []*CollectionOption `protobuf:"bytes,1,rep,name=values,proto3" json:"values,omitempty" yaml:"values"` // @gotags: yaml:"values" } func (x *CollectionValue) Reset() { @@ -1906,7 +1906,7 @@ type CollectionOption struct { unknownFields protoimpl.UnknownFields // required - Key string `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` // @gotags: yaml:"key" + Key string `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty" yaml:"key"` // @gotags: yaml:"key" // Types that are assignable to Option: // // *CollectionOption_IntValue @@ -1987,15 +1987,15 @@ type isCollectionOption_Option interface { } type CollectionOption_IntValue struct { - IntValue int64 `protobuf:"varint,2,opt,name=int_value,json=intValue,proto3,oneof"` // @gotags: yaml:"int_value" + IntValue int64 `protobuf:"varint,2,opt,name=int_value,json=intValue,proto3,oneof" yaml:"int_value"` // @gotags: yaml:"int_value" } type CollectionOption_StringValue struct { - StringValue string `protobuf:"bytes,3,opt,name=string_value,json=stringValue,proto3,oneof"` // @gotags: yaml:"string_value" + StringValue string `protobuf:"bytes,3,opt,name=string_value,json=stringValue,proto3,oneof" yaml:"string_value"` // @gotags: yaml:"string_value" } type CollectionOption_BoolValue struct { - BoolValue bool `protobuf:"varint,4,opt,name=bool_value,json=boolValue,proto3,oneof"` // @gotags: yaml:"bool_value" + BoolValue bool `protobuf:"varint,4,opt,name=bool_value,json=boolValue,proto3,oneof" yaml:"bool_value"` // @gotags: yaml:"bool_value" } func (*CollectionOption_IntValue) isCollectionOption_Option() {} diff --git a/protogen/gen/opencloud/services/search/v0/search.swagger.json b/protogen/gen/opencloud/services/search/v0/search.swagger.json index df7b3661d4..f04f10fc6b 100644 --- a/protogen/gen/opencloud/services/search/v0/search.swagger.json +++ b/protogen/gen/opencloud/services/search/v0/search.swagger.json @@ -282,6 +282,12 @@ }, "photo": { "$ref": "#/definitions/v0Photo" + }, + "favorites": { + "type": "array", + "items": { + "type": "string" + } } } }, diff --git a/protogen/proto/opencloud/messages/search/v0/search.proto b/protogen/proto/opencloud/messages/search/v0/search.proto index b52b549b53..4633a2cee7 100644 --- a/protogen/proto/opencloud/messages/search/v0/search.proto +++ b/protogen/proto/opencloud/messages/search/v0/search.proto @@ -79,6 +79,7 @@ message Entity { ResourceID remote_item_id = 17; Image image = 18; Photo photo = 19; + repeated string favorites = 20; } message Match { diff --git a/services/graph/pkg/service/v0/follow.go b/services/graph/pkg/service/v0/follow.go new file mode 100644 index 0000000000..4ccf20c171 --- /dev/null +++ b/services/graph/pkg/service/v0/follow.go @@ -0,0 +1,167 @@ +package svc + +import ( + "net/http" + + rpc "github.com/cs3org/go-cs3apis/cs3/rpc/v1beta1" + provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1" + "github.com/go-chi/render" + "github.com/opencloud-eu/opencloud/services/graph/pkg/errorcode" + revaCtx "github.com/opencloud-eu/reva/v2/pkg/ctx" + revactx "github.com/opencloud-eu/reva/v2/pkg/ctx" + "github.com/opencloud-eu/reva/v2/pkg/events" +) + +// FollowDriveItem marks a drive item as favorite. +func (g Graph) FollowDriveItem(w http.ResponseWriter, r *http.Request) { + ctx := r.Context() + + itemID, err := parseIDParam(r, "itemID") + if err != nil { + g.logger.Debug().Err(err).Msg("could not parse itemID") + return + } + + gatewayClient, err := g.gatewaySelector.Next() + if err != nil { + g.logger.Error().Err(err).Msg("could not select next gateway client") + errorcode.ServiceNotAvailable.Render(w, r, http.StatusServiceUnavailable, "could not select next gateway client") + return + } + + ref := &provider.Reference{ + ResourceId: &itemID, + } + + u, ok := revactx.ContextGetUser(ctx) + if !ok { + errorcode.GeneralException.Render(w, r, http.StatusUnauthorized, "User not found in context") + return + } + + statReq := &provider.StatRequest{ + Ref: ref, + } + statRes, err := gatewayClient.Stat(ctx, statReq) + if err != nil { + g.logger.Error().Err(err).Msg("could not stat resource") + errorcode.GeneralException.Render(w, r, http.StatusInternalServerError, "could not stat resource") + return + } + switch statRes.GetStatus().GetCode() { + case rpc.Code_CODE_OK: + // continue + case rpc.Code_CODE_NOT_FOUND: + errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest, "resource not found") + return + default: + errorcode.GeneralException.Render(w, r, http.StatusInternalServerError, "could not stat resource") + return + } + + req := &provider.AddFavoriteRequest{ + Ref: ref, + UserId: u.Id, + } + + res, err := gatewayClient.AddFavorite(ctx, req) + if err != nil { + g.logger.Error().Err(err).Msg("could not add favorite") + errorcode.GeneralException.Render(w, r, http.StatusInternalServerError, "could not add favorite") + return + } + + if res.Status.Code != rpc.Code_CODE_OK { + errorcode.GeneralException.Render(w, r, http.StatusInternalServerError, "could not add favorite") + return + } + + if g.eventsPublisher != nil { + ev := events.FavoriteAdded{ + Ref: &provider.Reference{ + ResourceId: &itemID, + Path: ".", + }, + UserID: u.Id, + Executant: revaCtx.ContextMustGetUser(r.Context()).Id, + } + if err := events.Publish(r.Context(), g.eventsPublisher, ev); err != nil { + g.logger.Error().Err(err).Msg("Failed to publish FavoriteAdded event") + } + } + + driveItem, err := cs3ResourceToDriveItem(g.logger, statRes.GetInfo()) + if err != nil { + errorcode.GeneralException.Render(w, r, http.StatusInternalServerError, err.Error()) + return + } + + render.Status(r, http.StatusCreated) + render.JSON(w, r, &driveItem) +} + +// UnfollowDriveItem unmarks a drive item as favorite. +func (g Graph) UnfollowDriveItem(w http.ResponseWriter, r *http.Request) { + ctx := r.Context() + itemID, err := parseIDParam(r, "itemID") + if err != nil { + g.logger.Debug().Err(err).Msg("could not parse itemID") + return + } + + gatewayClient, err := g.gatewaySelector.Next() + if err != nil { + g.logger.Error().Err(err).Msg("could not select next gateway client") + errorcode.ServiceNotAvailable.Render(w, r, http.StatusServiceUnavailable, "could not select next gateway client") + return + } + + ref := &provider.Reference{ + ResourceId: &itemID, + } + + u, ok := revactx.ContextGetUser(ctx) + if !ok { + errorcode.GeneralException.Render(w, r, http.StatusUnauthorized, "User not found in context") + return + } + + req := &provider.RemoveFavoriteRequest{ + Ref: ref, + UserId: u.Id, + } + + res, err := gatewayClient.RemoveFavorite(ctx, req) + if err != nil { + g.logger.Error().Err(err).Msg("could not remove favorite") + errorcode.GeneralException.Render(w, r, http.StatusInternalServerError, "could not remove favorite") + return + } + + switch res.Status.Code { + case rpc.Code_CODE_OK: + // continue + case rpc.Code_CODE_NOT_FOUND: + errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest, "favorite not found") + return + default: + errorcode.GeneralException.Render(w, r, http.StatusInternalServerError, "could not remove favorite") + return + } + + if g.eventsPublisher != nil { + ev := events.FavoriteRemoved{ + Ref: &provider.Reference{ + ResourceId: &itemID, + Path: ".", + }, + UserID: u.Id, + Executant: revaCtx.ContextMustGetUser(r.Context()).Id, + } + if err := events.Publish(r.Context(), g.eventsPublisher, ev); err != nil { + g.logger.Error().Err(err).Msg("Failed to publish FavoriteRemoved event") + } + } + + w.WriteHeader(http.StatusNoContent) +} diff --git a/services/graph/pkg/service/v0/service.go b/services/graph/pkg/service/v0/service.go index f130de6dc1..ba87c73164 100644 --- a/services/graph/pkg/service/v0/service.go +++ b/services/graph/pkg/service/v0/service.go @@ -309,6 +309,8 @@ func NewService(opts ...Option) (Graph, error) { //nolint:maintidx r.Route("/drive", func(r chi.Router) { r.Get("/", svc.GetUserDrive) r.Get("/root/children", svc.GetRootDriveChildren) + r.Post("/items/{itemID}/follow", svc.FollowDriveItem) + r.Delete("/following/{itemID}", svc.UnfollowDriveItem) }) r.Get("/drives", svc.GetDrives(APIVersion_1)) r.Post("/changePassword", svc.ChangeOwnPassword) diff --git a/services/search/pkg/bleve/backend.go b/services/search/pkg/bleve/backend.go index 40c1ba3675..8adcdda09e 100644 --- a/services/search/pkg/bleve/backend.go +++ b/services/search/pkg/bleve/backend.go @@ -134,6 +134,7 @@ func (b *Backend) Search(_ context.Context, sir *searchService.SearchIndexReques MimeType: getFieldValue[string](hit.Fields, "MimeType"), Deleted: getFieldValue[bool](hit.Fields, "Deleted"), Tags: getFieldSliceValue[string](hit.Fields, "Tags"), + Favorites: getFieldSliceValue[string](hit.Fields, "Favorites"), Highlights: getFragmentValue(hit.Fragments, "Content", 0), Audio: getAudioValue[searchMessage.Audio](hit.Fields), Image: getImageValue[searchMessage.Image](hit.Fields), diff --git a/services/search/pkg/bleve/bleve.go b/services/search/pkg/bleve/bleve.go index bf68fabaf1..64e5f1832b 100644 --- a/services/search/pkg/bleve/bleve.go +++ b/services/search/pkg/bleve/bleve.go @@ -186,17 +186,18 @@ func matchToResource(match *bleveSearch.DocumentMatch) *search.Resource { Type: uint64(getFieldValue[float64](match.Fields, "Type")), Deleted: getFieldValue[bool](match.Fields, "Deleted"), Document: content.Document{ - Name: getFieldValue[string](match.Fields, "Name"), - Title: getFieldValue[string](match.Fields, "Title"), - Size: uint64(getFieldValue[float64](match.Fields, "Size")), - Mtime: getFieldValue[string](match.Fields, "Mtime"), - MimeType: getFieldValue[string](match.Fields, "MimeType"), - Content: getFieldValue[string](match.Fields, "Content"), - Tags: getFieldSliceValue[string](match.Fields, "Tags"), - Audio: getAudioValue[libregraph.Audio](match.Fields), - Image: getImageValue[libregraph.Image](match.Fields), - Location: getLocationValue[libregraph.GeoCoordinates](match.Fields), - Photo: getPhotoValue[libregraph.Photo](match.Fields), + Name: getFieldValue[string](match.Fields, "Name"), + Title: getFieldValue[string](match.Fields, "Title"), + Size: uint64(getFieldValue[float64](match.Fields, "Size")), + Mtime: getFieldValue[string](match.Fields, "Mtime"), + MimeType: getFieldValue[string](match.Fields, "MimeType"), + Content: getFieldValue[string](match.Fields, "Content"), + Tags: getFieldSliceValue[string](match.Fields, "Tags"), + Favorites: getFieldSliceValue[string](match.Fields, "Favorites"), + Audio: getAudioValue[libregraph.Audio](match.Fields), + Image: getImageValue[libregraph.Image](match.Fields), + Location: getLocationValue[libregraph.GeoCoordinates](match.Fields), + Photo: getPhotoValue[libregraph.Photo](match.Fields), }, } } diff --git a/services/search/pkg/bleve/index.go b/services/search/pkg/bleve/index.go index b910d49396..717ff6d586 100644 --- a/services/search/pkg/bleve/index.go +++ b/services/search/pkg/bleve/index.go @@ -52,6 +52,7 @@ func NewMapping() (mapping.IndexMapping, error) { docMapping := bleve.NewDocumentMapping() docMapping.AddFieldMappingsAt("Name", nameMapping) docMapping.AddFieldMappingsAt("Tags", lowercaseMapping) + docMapping.AddFieldMappingsAt("Favorites", lowercaseMapping) docMapping.AddFieldMappingsAt("Content", fulltextFieldMapping) indexMapping := bleve.NewIndexMapping() diff --git a/services/search/pkg/content/basic.go b/services/search/pkg/content/basic.go index 77ca9163f5..1499258c98 100644 --- a/services/search/pkg/content/basic.go +++ b/services/search/pkg/content/basic.go @@ -2,6 +2,7 @@ package content import ( "context" + "encoding/json" "time" storageProvider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1" @@ -34,6 +35,24 @@ func (b Basic) Extract(_ context.Context, ri *storageProvider.ResourceInfo) (Doc } } + if m := ri.Opaque.GetMap(); m != nil && m["favorites"] != nil { + favEntry := m["favorites"] + + switch favEntry.Decoder { + case "json": + favorites := []string{} + err := json.Unmarshal(favEntry.Value, &favorites) + if err != nil { + b.logger.Error().Err(err).Msg("failed to unmarshal favorites") + break + } + + doc.Favorites = favorites + default: + b.logger.Error().Msgf("unsupported decoder for favorites: %s", favEntry.Decoder) + } + } + if ri.Mtime != nil { doc.Mtime = utils.TSToTime(ri.Mtime).UTC().Format(time.RFC3339Nano) } diff --git a/services/search/pkg/content/basic_test.go b/services/search/pkg/content/basic_test.go index 79ba9c3631..86832ed418 100644 --- a/services/search/pkg/content/basic_test.go +++ b/services/search/pkg/content/basic_test.go @@ -2,6 +2,7 @@ package content_test import ( "context" + "encoding/json" storageProvider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1" cs3Types "github.com/cs3org/go-cs3apis/cs3/types/v1beta1" @@ -86,5 +87,26 @@ var _ = Describe("Basic", func() { Expect(doc.Mtime).To(Equal(data.expect)) } }) + + It("extracts favorites", func() { + favorites := []string{"foo", "bar"} + favBytes, _ := json.Marshal(favorites) + + ri := &storageProvider.ResourceInfo{ + Opaque: &cs3Types.Opaque{ + Map: map[string]*cs3Types.OpaqueEntry{ + "favorites": { + Decoder: "json", + Value: favBytes, + }, + }, + }, + } + + doc, err := basic.Extract(ctx, ri) + Expect(err).To(BeNil()) + Expect(doc).ToNot(BeNil()) + Expect(doc.Favorites).To(Equal(favorites)) + }) }) }) diff --git a/services/search/pkg/content/content.go b/services/search/pkg/content/content.go index e43f1cd03e..e185351678 100644 --- a/services/search/pkg/content/content.go +++ b/services/search/pkg/content/content.go @@ -14,17 +14,18 @@ func init() { // Document wraps all resource meta fields, // it is used as a content extraction result. type Document struct { - Title string - Name string - Content string - Size uint64 - Mtime string - MimeType string - Tags []string - Audio *libregraph.Audio `json:"audio,omitempty"` - Image *libregraph.Image `json:"image,omitempty"` - Location *libregraph.GeoCoordinates `json:"location,omitempty"` - Photo *libregraph.Photo `json:"photo,omitempty"` + Title string + Name string + Content string + Size uint64 + Mtime string + MimeType string + Tags []string + Favorites []string + Audio *libregraph.Audio `json:"audio,omitempty"` + Image *libregraph.Image `json:"image,omitempty"` + Location *libregraph.GeoCoordinates `json:"location,omitempty"` + Photo *libregraph.Photo `json:"photo,omitempty"` } func CleanString(content, langCode string) string { diff --git a/services/search/pkg/query/bleve/compiler.go b/services/search/pkg/query/bleve/compiler.go index 77d151651f..e9d466e936 100644 --- a/services/search/pkg/query/bleve/compiler.go +++ b/services/search/pkg/query/bleve/compiler.go @@ -23,6 +23,7 @@ var _fields = map[string]string{ "tags": "Tags", "content": "Content", "hidden": "Hidden", + "favorite": "Favorites", } // The following quoted string enumerates the characters which may be escaped: "+-=&|> cs3.types.v1beta1.Opaque @@ -2450,181 +2469,185 @@ var file_cs3_gateway_v1beta1_gateway_api_proto_depIdxs = []int32{ 53, // 65: cs3.gateway.v1beta1.GatewayAPI.ListStorageSpaces:input_type -> cs3.storage.provider.v1beta1.ListStorageSpacesRequest 54, // 66: cs3.gateway.v1beta1.GatewayAPI.UpdateStorageSpace:input_type -> cs3.storage.provider.v1beta1.UpdateStorageSpaceRequest 55, // 67: cs3.gateway.v1beta1.GatewayAPI.DeleteStorageSpace:input_type -> cs3.storage.provider.v1beta1.DeleteStorageSpaceRequest - 13, // 68: cs3.gateway.v1beta1.GatewayAPI.OpenInApp:input_type -> cs3.gateway.v1beta1.OpenInAppRequest - 56, // 69: cs3.gateway.v1beta1.GatewayAPI.CreateShare:input_type -> cs3.sharing.collaboration.v1beta1.CreateShareRequest - 57, // 70: cs3.gateway.v1beta1.GatewayAPI.RemoveShare:input_type -> cs3.sharing.collaboration.v1beta1.RemoveShareRequest - 58, // 71: cs3.gateway.v1beta1.GatewayAPI.GetShare:input_type -> cs3.sharing.collaboration.v1beta1.GetShareRequest - 59, // 72: cs3.gateway.v1beta1.GatewayAPI.ListShares:input_type -> cs3.sharing.collaboration.v1beta1.ListSharesRequest - 59, // 73: cs3.gateway.v1beta1.GatewayAPI.ListExistingShares:input_type -> cs3.sharing.collaboration.v1beta1.ListSharesRequest - 60, // 74: cs3.gateway.v1beta1.GatewayAPI.UpdateShare:input_type -> cs3.sharing.collaboration.v1beta1.UpdateShareRequest - 61, // 75: cs3.gateway.v1beta1.GatewayAPI.ListReceivedShares:input_type -> cs3.sharing.collaboration.v1beta1.ListReceivedSharesRequest - 61, // 76: cs3.gateway.v1beta1.GatewayAPI.ListExistingReceivedShares:input_type -> cs3.sharing.collaboration.v1beta1.ListReceivedSharesRequest - 62, // 77: cs3.gateway.v1beta1.GatewayAPI.UpdateReceivedShare:input_type -> cs3.sharing.collaboration.v1beta1.UpdateReceivedShareRequest - 63, // 78: cs3.gateway.v1beta1.GatewayAPI.GetReceivedShare:input_type -> cs3.sharing.collaboration.v1beta1.GetReceivedShareRequest - 64, // 79: cs3.gateway.v1beta1.GatewayAPI.SetKey:input_type -> cs3.preferences.v1beta1.SetKeyRequest - 65, // 80: cs3.gateway.v1beta1.GatewayAPI.GetKey:input_type -> cs3.preferences.v1beta1.GetKeyRequest - 66, // 81: cs3.gateway.v1beta1.GatewayAPI.CreatePublicShare:input_type -> cs3.sharing.link.v1beta1.CreatePublicShareRequest - 67, // 82: cs3.gateway.v1beta1.GatewayAPI.RemovePublicShare:input_type -> cs3.sharing.link.v1beta1.RemovePublicShareRequest - 68, // 83: cs3.gateway.v1beta1.GatewayAPI.GetPublicShare:input_type -> cs3.sharing.link.v1beta1.GetPublicShareRequest - 69, // 84: cs3.gateway.v1beta1.GatewayAPI.GetPublicShareByToken:input_type -> cs3.sharing.link.v1beta1.GetPublicShareByTokenRequest - 70, // 85: cs3.gateway.v1beta1.GatewayAPI.ListPublicShares:input_type -> cs3.sharing.link.v1beta1.ListPublicSharesRequest - 70, // 86: cs3.gateway.v1beta1.GatewayAPI.ListExistingPublicShares:input_type -> cs3.sharing.link.v1beta1.ListPublicSharesRequest - 71, // 87: cs3.gateway.v1beta1.GatewayAPI.UpdatePublicShare:input_type -> cs3.sharing.link.v1beta1.UpdatePublicShareRequest - 72, // 88: cs3.gateway.v1beta1.GatewayAPI.CreateOCMShare:input_type -> cs3.sharing.ocm.v1beta1.CreateOCMShareRequest - 73, // 89: cs3.gateway.v1beta1.GatewayAPI.RemoveOCMShare:input_type -> cs3.sharing.ocm.v1beta1.RemoveOCMShareRequest - 74, // 90: cs3.gateway.v1beta1.GatewayAPI.GetOCMShare:input_type -> cs3.sharing.ocm.v1beta1.GetOCMShareRequest - 75, // 91: cs3.gateway.v1beta1.GatewayAPI.GetOCMShareByToken:input_type -> cs3.sharing.ocm.v1beta1.GetOCMShareByTokenRequest - 76, // 92: cs3.gateway.v1beta1.GatewayAPI.ListOCMShares:input_type -> cs3.sharing.ocm.v1beta1.ListOCMSharesRequest - 76, // 93: cs3.gateway.v1beta1.GatewayAPI.ListExistingOCMShares:input_type -> cs3.sharing.ocm.v1beta1.ListOCMSharesRequest - 77, // 94: cs3.gateway.v1beta1.GatewayAPI.UpdateOCMShare:input_type -> cs3.sharing.ocm.v1beta1.UpdateOCMShareRequest - 78, // 95: cs3.gateway.v1beta1.GatewayAPI.ListReceivedOCMShares:input_type -> cs3.sharing.ocm.v1beta1.ListReceivedOCMSharesRequest - 79, // 96: cs3.gateway.v1beta1.GatewayAPI.UpdateReceivedOCMShare:input_type -> cs3.sharing.ocm.v1beta1.UpdateReceivedOCMShareRequest - 80, // 97: cs3.gateway.v1beta1.GatewayAPI.GetReceivedOCMShare:input_type -> cs3.sharing.ocm.v1beta1.GetReceivedOCMShareRequest - 81, // 98: cs3.gateway.v1beta1.GatewayAPI.GetAppProviders:input_type -> cs3.app.registry.v1beta1.GetAppProvidersRequest - 82, // 99: cs3.gateway.v1beta1.GatewayAPI.AddAppProvider:input_type -> cs3.app.registry.v1beta1.AddAppProviderRequest - 83, // 100: cs3.gateway.v1beta1.GatewayAPI.ListAppProviders:input_type -> cs3.app.registry.v1beta1.ListAppProvidersRequest - 84, // 101: cs3.gateway.v1beta1.GatewayAPI.ListSupportedMimeTypes:input_type -> cs3.app.registry.v1beta1.ListSupportedMimeTypesRequest - 85, // 102: cs3.gateway.v1beta1.GatewayAPI.GetDefaultAppProviderForMimeType:input_type -> cs3.app.registry.v1beta1.GetDefaultAppProviderForMimeTypeRequest - 86, // 103: cs3.gateway.v1beta1.GatewayAPI.SetDefaultAppProviderForMimeType:input_type -> cs3.app.registry.v1beta1.SetDefaultAppProviderForMimeTypeRequest - 87, // 104: cs3.gateway.v1beta1.GatewayAPI.GetUser:input_type -> cs3.identity.user.v1beta1.GetUserRequest - 88, // 105: cs3.gateway.v1beta1.GatewayAPI.GetUserByClaim:input_type -> cs3.identity.user.v1beta1.GetUserByClaimRequest - 89, // 106: cs3.gateway.v1beta1.GatewayAPI.GetUserGroups:input_type -> cs3.identity.user.v1beta1.GetUserGroupsRequest - 90, // 107: cs3.gateway.v1beta1.GatewayAPI.FindUsers:input_type -> cs3.identity.user.v1beta1.FindUsersRequest - 91, // 108: cs3.gateway.v1beta1.GatewayAPI.GetGroup:input_type -> cs3.identity.group.v1beta1.GetGroupRequest - 92, // 109: cs3.gateway.v1beta1.GatewayAPI.GetGroupByClaim:input_type -> cs3.identity.group.v1beta1.GetGroupByClaimRequest - 93, // 110: cs3.gateway.v1beta1.GatewayAPI.GetMembers:input_type -> cs3.identity.group.v1beta1.GetMembersRequest - 94, // 111: cs3.gateway.v1beta1.GatewayAPI.HasMember:input_type -> cs3.identity.group.v1beta1.HasMemberRequest - 95, // 112: cs3.gateway.v1beta1.GatewayAPI.FindGroups:input_type -> cs3.identity.group.v1beta1.FindGroupsRequest - 96, // 113: cs3.gateway.v1beta1.GatewayAPI.ListAuthProviders:input_type -> cs3.auth.registry.v1beta1.ListAuthProvidersRequest - 97, // 114: cs3.gateway.v1beta1.GatewayAPI.GetHome:input_type -> cs3.storage.provider.v1beta1.GetHomeRequest - 98, // 115: cs3.gateway.v1beta1.GatewayAPI.GenerateInviteToken:input_type -> cs3.ocm.invite.v1beta1.GenerateInviteTokenRequest - 99, // 116: cs3.gateway.v1beta1.GatewayAPI.ListInviteTokens:input_type -> cs3.ocm.invite.v1beta1.ListInviteTokensRequest - 100, // 117: cs3.gateway.v1beta1.GatewayAPI.ForwardInvite:input_type -> cs3.ocm.invite.v1beta1.ForwardInviteRequest - 101, // 118: cs3.gateway.v1beta1.GatewayAPI.AcceptInvite:input_type -> cs3.ocm.invite.v1beta1.AcceptInviteRequest - 102, // 119: cs3.gateway.v1beta1.GatewayAPI.GetAcceptedUser:input_type -> cs3.ocm.invite.v1beta1.GetAcceptedUserRequest - 103, // 120: cs3.gateway.v1beta1.GatewayAPI.FindAcceptedUsers:input_type -> cs3.ocm.invite.v1beta1.FindAcceptedUsersRequest - 104, // 121: cs3.gateway.v1beta1.GatewayAPI.DeleteAcceptedUser:input_type -> cs3.ocm.invite.v1beta1.DeleteAcceptedUserRequest - 105, // 122: cs3.gateway.v1beta1.GatewayAPI.IsProviderAllowed:input_type -> cs3.ocm.provider.v1beta1.IsProviderAllowedRequest - 106, // 123: cs3.gateway.v1beta1.GatewayAPI.GetInfoByDomain:input_type -> cs3.ocm.provider.v1beta1.GetInfoByDomainRequest - 107, // 124: cs3.gateway.v1beta1.GatewayAPI.ListAllProviders:input_type -> cs3.ocm.provider.v1beta1.ListAllProvidersRequest - 108, // 125: cs3.gateway.v1beta1.GatewayAPI.CreateOCMIncomingShare:input_type -> cs3.ocm.incoming.v1beta1.CreateOCMIncomingShareRequest - 109, // 126: cs3.gateway.v1beta1.GatewayAPI.UpdateOCMIncomingShare:input_type -> cs3.ocm.incoming.v1beta1.UpdateOCMIncomingShareRequest - 110, // 127: cs3.gateway.v1beta1.GatewayAPI.DeleteOCMIncomingShare:input_type -> cs3.ocm.incoming.v1beta1.DeleteOCMIncomingShareRequest - 111, // 128: cs3.gateway.v1beta1.GatewayAPI.CreateOCMCoreShare:input_type -> cs3.ocm.core.v1beta1.CreateOCMCoreShareRequest - 112, // 129: cs3.gateway.v1beta1.GatewayAPI.UpdateOCMCoreShare:input_type -> cs3.ocm.core.v1beta1.UpdateOCMCoreShareRequest - 113, // 130: cs3.gateway.v1beta1.GatewayAPI.DeleteOCMCoreShare:input_type -> cs3.ocm.core.v1beta1.DeleteOCMCoreShareRequest - 114, // 131: cs3.gateway.v1beta1.GatewayAPI.CreateTransfer:input_type -> cs3.tx.v1beta1.CreateTransferRequest - 115, // 132: cs3.gateway.v1beta1.GatewayAPI.GetTransferStatus:input_type -> cs3.tx.v1beta1.GetTransferStatusRequest - 116, // 133: cs3.gateway.v1beta1.GatewayAPI.CancelTransfer:input_type -> cs3.tx.v1beta1.CancelTransferRequest - 117, // 134: cs3.gateway.v1beta1.GatewayAPI.ListTransfers:input_type -> cs3.tx.v1beta1.ListTransfersRequest - 118, // 135: cs3.gateway.v1beta1.GatewayAPI.RetryTransfer:input_type -> cs3.tx.v1beta1.RetryTransferRequest - 119, // 136: cs3.gateway.v1beta1.GatewayAPI.CheckPermission:input_type -> cs3.permissions.v1beta1.CheckPermissionRequest - 2, // 137: cs3.gateway.v1beta1.GatewayAPI.Authenticate:output_type -> cs3.gateway.v1beta1.AuthenticateResponse - 4, // 138: cs3.gateway.v1beta1.GatewayAPI.WhoAmI:output_type -> cs3.gateway.v1beta1.WhoAmIResponse - 120, // 139: cs3.gateway.v1beta1.GatewayAPI.GenerateAppPassword:output_type -> cs3.auth.applications.v1beta1.GenerateAppPasswordResponse - 121, // 140: cs3.gateway.v1beta1.GatewayAPI.ListAppPasswords:output_type -> cs3.auth.applications.v1beta1.ListAppPasswordsResponse - 122, // 141: cs3.gateway.v1beta1.GatewayAPI.InvalidateAppPassword:output_type -> cs3.auth.applications.v1beta1.InvalidateAppPasswordResponse - 123, // 142: cs3.gateway.v1beta1.GatewayAPI.GetAppPassword:output_type -> cs3.auth.applications.v1beta1.GetAppPasswordResponse - 124, // 143: cs3.gateway.v1beta1.GatewayAPI.CreateContainer:output_type -> cs3.storage.provider.v1beta1.CreateContainerResponse - 125, // 144: cs3.gateway.v1beta1.GatewayAPI.TouchFile:output_type -> cs3.storage.provider.v1beta1.TouchFileResponse - 126, // 145: cs3.gateway.v1beta1.GatewayAPI.Delete:output_type -> cs3.storage.provider.v1beta1.DeleteResponse - 127, // 146: cs3.gateway.v1beta1.GatewayAPI.GetPath:output_type -> cs3.storage.provider.v1beta1.GetPathResponse - 128, // 147: cs3.gateway.v1beta1.GatewayAPI.GetQuota:output_type -> cs3.storage.provider.v1beta1.GetQuotaResponse - 6, // 148: cs3.gateway.v1beta1.GatewayAPI.InitiateFileDownload:output_type -> cs3.gateway.v1beta1.InitiateFileDownloadResponse - 7, // 149: cs3.gateway.v1beta1.GatewayAPI.InitiateFileUpload:output_type -> cs3.gateway.v1beta1.InitiateFileUploadResponse - 129, // 150: cs3.gateway.v1beta1.GatewayAPI.ListContainerStream:output_type -> cs3.storage.provider.v1beta1.ListContainerStreamResponse - 130, // 151: cs3.gateway.v1beta1.GatewayAPI.ListContainer:output_type -> cs3.storage.provider.v1beta1.ListContainerResponse - 131, // 152: cs3.gateway.v1beta1.GatewayAPI.ListFileVersions:output_type -> cs3.storage.provider.v1beta1.ListFileVersionsResponse - 132, // 153: cs3.gateway.v1beta1.GatewayAPI.ListRecycleStream:output_type -> cs3.storage.provider.v1beta1.ListRecycleStreamResponse - 133, // 154: cs3.gateway.v1beta1.GatewayAPI.ListRecycle:output_type -> cs3.storage.provider.v1beta1.ListRecycleResponse - 134, // 155: cs3.gateway.v1beta1.GatewayAPI.Move:output_type -> cs3.storage.provider.v1beta1.MoveResponse - 135, // 156: cs3.gateway.v1beta1.GatewayAPI.PurgeRecycle:output_type -> cs3.storage.provider.v1beta1.PurgeRecycleResponse - 136, // 157: cs3.gateway.v1beta1.GatewayAPI.RestoreFileVersion:output_type -> cs3.storage.provider.v1beta1.RestoreFileVersionResponse - 137, // 158: cs3.gateway.v1beta1.GatewayAPI.RestoreRecycleItem:output_type -> cs3.storage.provider.v1beta1.RestoreRecycleItemResponse - 138, // 159: cs3.gateway.v1beta1.GatewayAPI.Stat:output_type -> cs3.storage.provider.v1beta1.StatResponse - 139, // 160: cs3.gateway.v1beta1.GatewayAPI.CreateSymlink:output_type -> cs3.storage.provider.v1beta1.CreateSymlinkResponse - 140, // 161: cs3.gateway.v1beta1.GatewayAPI.SetArbitraryMetadata:output_type -> cs3.storage.provider.v1beta1.SetArbitraryMetadataResponse - 141, // 162: cs3.gateway.v1beta1.GatewayAPI.UnsetArbitraryMetadata:output_type -> cs3.storage.provider.v1beta1.UnsetArbitraryMetadataResponse - 142, // 163: cs3.gateway.v1beta1.GatewayAPI.SetLock:output_type -> cs3.storage.provider.v1beta1.SetLockResponse - 143, // 164: cs3.gateway.v1beta1.GatewayAPI.GetLock:output_type -> cs3.storage.provider.v1beta1.GetLockResponse - 144, // 165: cs3.gateway.v1beta1.GatewayAPI.RefreshLock:output_type -> cs3.storage.provider.v1beta1.RefreshLockResponse - 145, // 166: cs3.gateway.v1beta1.GatewayAPI.Unlock:output_type -> cs3.storage.provider.v1beta1.UnlockResponse - 146, // 167: cs3.gateway.v1beta1.GatewayAPI.CreateHome:output_type -> cs3.storage.provider.v1beta1.CreateHomeResponse - 147, // 168: cs3.gateway.v1beta1.GatewayAPI.CreateStorageSpace:output_type -> cs3.storage.provider.v1beta1.CreateStorageSpaceResponse - 148, // 169: cs3.gateway.v1beta1.GatewayAPI.ListStorageSpaces:output_type -> cs3.storage.provider.v1beta1.ListStorageSpacesResponse - 149, // 170: cs3.gateway.v1beta1.GatewayAPI.UpdateStorageSpace:output_type -> cs3.storage.provider.v1beta1.UpdateStorageSpaceResponse - 150, // 171: cs3.gateway.v1beta1.GatewayAPI.DeleteStorageSpace:output_type -> cs3.storage.provider.v1beta1.DeleteStorageSpaceResponse - 151, // 172: cs3.gateway.v1beta1.GatewayAPI.OpenInApp:output_type -> cs3.app.provider.v1beta1.OpenInAppResponse - 152, // 173: cs3.gateway.v1beta1.GatewayAPI.CreateShare:output_type -> cs3.sharing.collaboration.v1beta1.CreateShareResponse - 153, // 174: cs3.gateway.v1beta1.GatewayAPI.RemoveShare:output_type -> cs3.sharing.collaboration.v1beta1.RemoveShareResponse - 154, // 175: cs3.gateway.v1beta1.GatewayAPI.GetShare:output_type -> cs3.sharing.collaboration.v1beta1.GetShareResponse - 155, // 176: cs3.gateway.v1beta1.GatewayAPI.ListShares:output_type -> cs3.sharing.collaboration.v1beta1.ListSharesResponse - 9, // 177: cs3.gateway.v1beta1.GatewayAPI.ListExistingShares:output_type -> cs3.gateway.v1beta1.ListExistingSharesResponse - 156, // 178: cs3.gateway.v1beta1.GatewayAPI.UpdateShare:output_type -> cs3.sharing.collaboration.v1beta1.UpdateShareResponse - 157, // 179: cs3.gateway.v1beta1.GatewayAPI.ListReceivedShares:output_type -> cs3.sharing.collaboration.v1beta1.ListReceivedSharesResponse - 10, // 180: cs3.gateway.v1beta1.GatewayAPI.ListExistingReceivedShares:output_type -> cs3.gateway.v1beta1.ListExistingReceivedSharesResponse - 158, // 181: cs3.gateway.v1beta1.GatewayAPI.UpdateReceivedShare:output_type -> cs3.sharing.collaboration.v1beta1.UpdateReceivedShareResponse - 159, // 182: cs3.gateway.v1beta1.GatewayAPI.GetReceivedShare:output_type -> cs3.sharing.collaboration.v1beta1.GetReceivedShareResponse - 160, // 183: cs3.gateway.v1beta1.GatewayAPI.SetKey:output_type -> cs3.preferences.v1beta1.SetKeyResponse - 161, // 184: cs3.gateway.v1beta1.GatewayAPI.GetKey:output_type -> cs3.preferences.v1beta1.GetKeyResponse - 162, // 185: cs3.gateway.v1beta1.GatewayAPI.CreatePublicShare:output_type -> cs3.sharing.link.v1beta1.CreatePublicShareResponse - 163, // 186: cs3.gateway.v1beta1.GatewayAPI.RemovePublicShare:output_type -> cs3.sharing.link.v1beta1.RemovePublicShareResponse - 164, // 187: cs3.gateway.v1beta1.GatewayAPI.GetPublicShare:output_type -> cs3.sharing.link.v1beta1.GetPublicShareResponse - 165, // 188: cs3.gateway.v1beta1.GatewayAPI.GetPublicShareByToken:output_type -> cs3.sharing.link.v1beta1.GetPublicShareByTokenResponse - 166, // 189: cs3.gateway.v1beta1.GatewayAPI.ListPublicShares:output_type -> cs3.sharing.link.v1beta1.ListPublicSharesResponse - 11, // 190: cs3.gateway.v1beta1.GatewayAPI.ListExistingPublicShares:output_type -> cs3.gateway.v1beta1.ListExistingPublicSharesResponse - 167, // 191: cs3.gateway.v1beta1.GatewayAPI.UpdatePublicShare:output_type -> cs3.sharing.link.v1beta1.UpdatePublicShareResponse - 168, // 192: cs3.gateway.v1beta1.GatewayAPI.CreateOCMShare:output_type -> cs3.sharing.ocm.v1beta1.CreateOCMShareResponse - 169, // 193: cs3.gateway.v1beta1.GatewayAPI.RemoveOCMShare:output_type -> cs3.sharing.ocm.v1beta1.RemoveOCMShareResponse - 170, // 194: cs3.gateway.v1beta1.GatewayAPI.GetOCMShare:output_type -> cs3.sharing.ocm.v1beta1.GetOCMShareResponse - 171, // 195: cs3.gateway.v1beta1.GatewayAPI.GetOCMShareByToken:output_type -> cs3.sharing.ocm.v1beta1.GetOCMShareByTokenResponse - 172, // 196: cs3.gateway.v1beta1.GatewayAPI.ListOCMShares:output_type -> cs3.sharing.ocm.v1beta1.ListOCMSharesResponse - 12, // 197: cs3.gateway.v1beta1.GatewayAPI.ListExistingOCMShares:output_type -> cs3.gateway.v1beta1.ListExistingOCMSharesResponse - 173, // 198: cs3.gateway.v1beta1.GatewayAPI.UpdateOCMShare:output_type -> cs3.sharing.ocm.v1beta1.UpdateOCMShareResponse - 174, // 199: cs3.gateway.v1beta1.GatewayAPI.ListReceivedOCMShares:output_type -> cs3.sharing.ocm.v1beta1.ListReceivedOCMSharesResponse - 175, // 200: cs3.gateway.v1beta1.GatewayAPI.UpdateReceivedOCMShare:output_type -> cs3.sharing.ocm.v1beta1.UpdateReceivedOCMShareResponse - 176, // 201: cs3.gateway.v1beta1.GatewayAPI.GetReceivedOCMShare:output_type -> cs3.sharing.ocm.v1beta1.GetReceivedOCMShareResponse - 177, // 202: cs3.gateway.v1beta1.GatewayAPI.GetAppProviders:output_type -> cs3.app.registry.v1beta1.GetAppProvidersResponse - 178, // 203: cs3.gateway.v1beta1.GatewayAPI.AddAppProvider:output_type -> cs3.app.registry.v1beta1.AddAppProviderResponse - 179, // 204: cs3.gateway.v1beta1.GatewayAPI.ListAppProviders:output_type -> cs3.app.registry.v1beta1.ListAppProvidersResponse - 180, // 205: cs3.gateway.v1beta1.GatewayAPI.ListSupportedMimeTypes:output_type -> cs3.app.registry.v1beta1.ListSupportedMimeTypesResponse - 181, // 206: cs3.gateway.v1beta1.GatewayAPI.GetDefaultAppProviderForMimeType:output_type -> cs3.app.registry.v1beta1.GetDefaultAppProviderForMimeTypeResponse - 182, // 207: cs3.gateway.v1beta1.GatewayAPI.SetDefaultAppProviderForMimeType:output_type -> cs3.app.registry.v1beta1.SetDefaultAppProviderForMimeTypeResponse - 183, // 208: cs3.gateway.v1beta1.GatewayAPI.GetUser:output_type -> cs3.identity.user.v1beta1.GetUserResponse - 184, // 209: cs3.gateway.v1beta1.GatewayAPI.GetUserByClaim:output_type -> cs3.identity.user.v1beta1.GetUserByClaimResponse - 185, // 210: cs3.gateway.v1beta1.GatewayAPI.GetUserGroups:output_type -> cs3.identity.user.v1beta1.GetUserGroupsResponse - 186, // 211: cs3.gateway.v1beta1.GatewayAPI.FindUsers:output_type -> cs3.identity.user.v1beta1.FindUsersResponse - 187, // 212: cs3.gateway.v1beta1.GatewayAPI.GetGroup:output_type -> cs3.identity.group.v1beta1.GetGroupResponse - 188, // 213: cs3.gateway.v1beta1.GatewayAPI.GetGroupByClaim:output_type -> cs3.identity.group.v1beta1.GetGroupByClaimResponse - 189, // 214: cs3.gateway.v1beta1.GatewayAPI.GetMembers:output_type -> cs3.identity.group.v1beta1.GetMembersResponse - 190, // 215: cs3.gateway.v1beta1.GatewayAPI.HasMember:output_type -> cs3.identity.group.v1beta1.HasMemberResponse - 191, // 216: cs3.gateway.v1beta1.GatewayAPI.FindGroups:output_type -> cs3.identity.group.v1beta1.FindGroupsResponse - 8, // 217: cs3.gateway.v1beta1.GatewayAPI.ListAuthProviders:output_type -> cs3.gateway.v1beta1.ListAuthProvidersResponse - 192, // 218: cs3.gateway.v1beta1.GatewayAPI.GetHome:output_type -> cs3.storage.provider.v1beta1.GetHomeResponse - 193, // 219: cs3.gateway.v1beta1.GatewayAPI.GenerateInviteToken:output_type -> cs3.ocm.invite.v1beta1.GenerateInviteTokenResponse - 194, // 220: cs3.gateway.v1beta1.GatewayAPI.ListInviteTokens:output_type -> cs3.ocm.invite.v1beta1.ListInviteTokensResponse - 195, // 221: cs3.gateway.v1beta1.GatewayAPI.ForwardInvite:output_type -> cs3.ocm.invite.v1beta1.ForwardInviteResponse - 196, // 222: cs3.gateway.v1beta1.GatewayAPI.AcceptInvite:output_type -> cs3.ocm.invite.v1beta1.AcceptInviteResponse - 197, // 223: cs3.gateway.v1beta1.GatewayAPI.GetAcceptedUser:output_type -> cs3.ocm.invite.v1beta1.GetAcceptedUserResponse - 198, // 224: cs3.gateway.v1beta1.GatewayAPI.FindAcceptedUsers:output_type -> cs3.ocm.invite.v1beta1.FindAcceptedUsersResponse - 199, // 225: cs3.gateway.v1beta1.GatewayAPI.DeleteAcceptedUser:output_type -> cs3.ocm.invite.v1beta1.DeleteAcceptedUserResponse - 200, // 226: cs3.gateway.v1beta1.GatewayAPI.IsProviderAllowed:output_type -> cs3.ocm.provider.v1beta1.IsProviderAllowedResponse - 201, // 227: cs3.gateway.v1beta1.GatewayAPI.GetInfoByDomain:output_type -> cs3.ocm.provider.v1beta1.GetInfoByDomainResponse - 202, // 228: cs3.gateway.v1beta1.GatewayAPI.ListAllProviders:output_type -> cs3.ocm.provider.v1beta1.ListAllProvidersResponse - 203, // 229: cs3.gateway.v1beta1.GatewayAPI.CreateOCMIncomingShare:output_type -> cs3.ocm.incoming.v1beta1.CreateOCMIncomingShareResponse - 204, // 230: cs3.gateway.v1beta1.GatewayAPI.UpdateOCMIncomingShare:output_type -> cs3.ocm.incoming.v1beta1.UpdateOCMIncomingShareResponse - 205, // 231: cs3.gateway.v1beta1.GatewayAPI.DeleteOCMIncomingShare:output_type -> cs3.ocm.incoming.v1beta1.DeleteOCMIncomingShareResponse - 206, // 232: cs3.gateway.v1beta1.GatewayAPI.CreateOCMCoreShare:output_type -> cs3.ocm.core.v1beta1.CreateOCMCoreShareResponse - 207, // 233: cs3.gateway.v1beta1.GatewayAPI.UpdateOCMCoreShare:output_type -> cs3.ocm.core.v1beta1.UpdateOCMCoreShareResponse - 208, // 234: cs3.gateway.v1beta1.GatewayAPI.DeleteOCMCoreShare:output_type -> cs3.ocm.core.v1beta1.DeleteOCMCoreShareResponse - 209, // 235: cs3.gateway.v1beta1.GatewayAPI.CreateTransfer:output_type -> cs3.tx.v1beta1.CreateTransferResponse - 210, // 236: cs3.gateway.v1beta1.GatewayAPI.GetTransferStatus:output_type -> cs3.tx.v1beta1.GetTransferStatusResponse - 211, // 237: cs3.gateway.v1beta1.GatewayAPI.CancelTransfer:output_type -> cs3.tx.v1beta1.CancelTransferResponse - 212, // 238: cs3.gateway.v1beta1.GatewayAPI.ListTransfers:output_type -> cs3.tx.v1beta1.ListTransfersResponse - 213, // 239: cs3.gateway.v1beta1.GatewayAPI.RetryTransfer:output_type -> cs3.tx.v1beta1.RetryTransferResponse - 214, // 240: cs3.gateway.v1beta1.GatewayAPI.CheckPermission:output_type -> cs3.permissions.v1beta1.CheckPermissionResponse - 137, // [137:241] is the sub-list for method output_type - 33, // [33:137] is the sub-list for method input_type + 56, // 68: cs3.gateway.v1beta1.GatewayAPI.AddFavorite:input_type -> cs3.storage.provider.v1beta1.AddFavoriteRequest + 57, // 69: cs3.gateway.v1beta1.GatewayAPI.RemoveFavorite:input_type -> cs3.storage.provider.v1beta1.RemoveFavoriteRequest + 13, // 70: cs3.gateway.v1beta1.GatewayAPI.OpenInApp:input_type -> cs3.gateway.v1beta1.OpenInAppRequest + 58, // 71: cs3.gateway.v1beta1.GatewayAPI.CreateShare:input_type -> cs3.sharing.collaboration.v1beta1.CreateShareRequest + 59, // 72: cs3.gateway.v1beta1.GatewayAPI.RemoveShare:input_type -> cs3.sharing.collaboration.v1beta1.RemoveShareRequest + 60, // 73: cs3.gateway.v1beta1.GatewayAPI.GetShare:input_type -> cs3.sharing.collaboration.v1beta1.GetShareRequest + 61, // 74: cs3.gateway.v1beta1.GatewayAPI.ListShares:input_type -> cs3.sharing.collaboration.v1beta1.ListSharesRequest + 61, // 75: cs3.gateway.v1beta1.GatewayAPI.ListExistingShares:input_type -> cs3.sharing.collaboration.v1beta1.ListSharesRequest + 62, // 76: cs3.gateway.v1beta1.GatewayAPI.UpdateShare:input_type -> cs3.sharing.collaboration.v1beta1.UpdateShareRequest + 63, // 77: cs3.gateway.v1beta1.GatewayAPI.ListReceivedShares:input_type -> cs3.sharing.collaboration.v1beta1.ListReceivedSharesRequest + 63, // 78: cs3.gateway.v1beta1.GatewayAPI.ListExistingReceivedShares:input_type -> cs3.sharing.collaboration.v1beta1.ListReceivedSharesRequest + 64, // 79: cs3.gateway.v1beta1.GatewayAPI.UpdateReceivedShare:input_type -> cs3.sharing.collaboration.v1beta1.UpdateReceivedShareRequest + 65, // 80: cs3.gateway.v1beta1.GatewayAPI.GetReceivedShare:input_type -> cs3.sharing.collaboration.v1beta1.GetReceivedShareRequest + 66, // 81: cs3.gateway.v1beta1.GatewayAPI.SetKey:input_type -> cs3.preferences.v1beta1.SetKeyRequest + 67, // 82: cs3.gateway.v1beta1.GatewayAPI.GetKey:input_type -> cs3.preferences.v1beta1.GetKeyRequest + 68, // 83: cs3.gateway.v1beta1.GatewayAPI.CreatePublicShare:input_type -> cs3.sharing.link.v1beta1.CreatePublicShareRequest + 69, // 84: cs3.gateway.v1beta1.GatewayAPI.RemovePublicShare:input_type -> cs3.sharing.link.v1beta1.RemovePublicShareRequest + 70, // 85: cs3.gateway.v1beta1.GatewayAPI.GetPublicShare:input_type -> cs3.sharing.link.v1beta1.GetPublicShareRequest + 71, // 86: cs3.gateway.v1beta1.GatewayAPI.GetPublicShareByToken:input_type -> cs3.sharing.link.v1beta1.GetPublicShareByTokenRequest + 72, // 87: cs3.gateway.v1beta1.GatewayAPI.ListPublicShares:input_type -> cs3.sharing.link.v1beta1.ListPublicSharesRequest + 72, // 88: cs3.gateway.v1beta1.GatewayAPI.ListExistingPublicShares:input_type -> cs3.sharing.link.v1beta1.ListPublicSharesRequest + 73, // 89: cs3.gateway.v1beta1.GatewayAPI.UpdatePublicShare:input_type -> cs3.sharing.link.v1beta1.UpdatePublicShareRequest + 74, // 90: cs3.gateway.v1beta1.GatewayAPI.CreateOCMShare:input_type -> cs3.sharing.ocm.v1beta1.CreateOCMShareRequest + 75, // 91: cs3.gateway.v1beta1.GatewayAPI.RemoveOCMShare:input_type -> cs3.sharing.ocm.v1beta1.RemoveOCMShareRequest + 76, // 92: cs3.gateway.v1beta1.GatewayAPI.GetOCMShare:input_type -> cs3.sharing.ocm.v1beta1.GetOCMShareRequest + 77, // 93: cs3.gateway.v1beta1.GatewayAPI.GetOCMShareByToken:input_type -> cs3.sharing.ocm.v1beta1.GetOCMShareByTokenRequest + 78, // 94: cs3.gateway.v1beta1.GatewayAPI.ListOCMShares:input_type -> cs3.sharing.ocm.v1beta1.ListOCMSharesRequest + 78, // 95: cs3.gateway.v1beta1.GatewayAPI.ListExistingOCMShares:input_type -> cs3.sharing.ocm.v1beta1.ListOCMSharesRequest + 79, // 96: cs3.gateway.v1beta1.GatewayAPI.UpdateOCMShare:input_type -> cs3.sharing.ocm.v1beta1.UpdateOCMShareRequest + 80, // 97: cs3.gateway.v1beta1.GatewayAPI.ListReceivedOCMShares:input_type -> cs3.sharing.ocm.v1beta1.ListReceivedOCMSharesRequest + 81, // 98: cs3.gateway.v1beta1.GatewayAPI.UpdateReceivedOCMShare:input_type -> cs3.sharing.ocm.v1beta1.UpdateReceivedOCMShareRequest + 82, // 99: cs3.gateway.v1beta1.GatewayAPI.GetReceivedOCMShare:input_type -> cs3.sharing.ocm.v1beta1.GetReceivedOCMShareRequest + 83, // 100: cs3.gateway.v1beta1.GatewayAPI.GetAppProviders:input_type -> cs3.app.registry.v1beta1.GetAppProvidersRequest + 84, // 101: cs3.gateway.v1beta1.GatewayAPI.AddAppProvider:input_type -> cs3.app.registry.v1beta1.AddAppProviderRequest + 85, // 102: cs3.gateway.v1beta1.GatewayAPI.ListAppProviders:input_type -> cs3.app.registry.v1beta1.ListAppProvidersRequest + 86, // 103: cs3.gateway.v1beta1.GatewayAPI.ListSupportedMimeTypes:input_type -> cs3.app.registry.v1beta1.ListSupportedMimeTypesRequest + 87, // 104: cs3.gateway.v1beta1.GatewayAPI.GetDefaultAppProviderForMimeType:input_type -> cs3.app.registry.v1beta1.GetDefaultAppProviderForMimeTypeRequest + 88, // 105: cs3.gateway.v1beta1.GatewayAPI.SetDefaultAppProviderForMimeType:input_type -> cs3.app.registry.v1beta1.SetDefaultAppProviderForMimeTypeRequest + 89, // 106: cs3.gateway.v1beta1.GatewayAPI.GetUser:input_type -> cs3.identity.user.v1beta1.GetUserRequest + 90, // 107: cs3.gateway.v1beta1.GatewayAPI.GetUserByClaim:input_type -> cs3.identity.user.v1beta1.GetUserByClaimRequest + 91, // 108: cs3.gateway.v1beta1.GatewayAPI.GetUserGroups:input_type -> cs3.identity.user.v1beta1.GetUserGroupsRequest + 92, // 109: cs3.gateway.v1beta1.GatewayAPI.FindUsers:input_type -> cs3.identity.user.v1beta1.FindUsersRequest + 93, // 110: cs3.gateway.v1beta1.GatewayAPI.GetGroup:input_type -> cs3.identity.group.v1beta1.GetGroupRequest + 94, // 111: cs3.gateway.v1beta1.GatewayAPI.GetGroupByClaim:input_type -> cs3.identity.group.v1beta1.GetGroupByClaimRequest + 95, // 112: cs3.gateway.v1beta1.GatewayAPI.GetMembers:input_type -> cs3.identity.group.v1beta1.GetMembersRequest + 96, // 113: cs3.gateway.v1beta1.GatewayAPI.HasMember:input_type -> cs3.identity.group.v1beta1.HasMemberRequest + 97, // 114: cs3.gateway.v1beta1.GatewayAPI.FindGroups:input_type -> cs3.identity.group.v1beta1.FindGroupsRequest + 98, // 115: cs3.gateway.v1beta1.GatewayAPI.ListAuthProviders:input_type -> cs3.auth.registry.v1beta1.ListAuthProvidersRequest + 99, // 116: cs3.gateway.v1beta1.GatewayAPI.GetHome:input_type -> cs3.storage.provider.v1beta1.GetHomeRequest + 100, // 117: cs3.gateway.v1beta1.GatewayAPI.GenerateInviteToken:input_type -> cs3.ocm.invite.v1beta1.GenerateInviteTokenRequest + 101, // 118: cs3.gateway.v1beta1.GatewayAPI.ListInviteTokens:input_type -> cs3.ocm.invite.v1beta1.ListInviteTokensRequest + 102, // 119: cs3.gateway.v1beta1.GatewayAPI.ForwardInvite:input_type -> cs3.ocm.invite.v1beta1.ForwardInviteRequest + 103, // 120: cs3.gateway.v1beta1.GatewayAPI.AcceptInvite:input_type -> cs3.ocm.invite.v1beta1.AcceptInviteRequest + 104, // 121: cs3.gateway.v1beta1.GatewayAPI.GetAcceptedUser:input_type -> cs3.ocm.invite.v1beta1.GetAcceptedUserRequest + 105, // 122: cs3.gateway.v1beta1.GatewayAPI.FindAcceptedUsers:input_type -> cs3.ocm.invite.v1beta1.FindAcceptedUsersRequest + 106, // 123: cs3.gateway.v1beta1.GatewayAPI.DeleteAcceptedUser:input_type -> cs3.ocm.invite.v1beta1.DeleteAcceptedUserRequest + 107, // 124: cs3.gateway.v1beta1.GatewayAPI.IsProviderAllowed:input_type -> cs3.ocm.provider.v1beta1.IsProviderAllowedRequest + 108, // 125: cs3.gateway.v1beta1.GatewayAPI.GetInfoByDomain:input_type -> cs3.ocm.provider.v1beta1.GetInfoByDomainRequest + 109, // 126: cs3.gateway.v1beta1.GatewayAPI.ListAllProviders:input_type -> cs3.ocm.provider.v1beta1.ListAllProvidersRequest + 110, // 127: cs3.gateway.v1beta1.GatewayAPI.CreateOCMIncomingShare:input_type -> cs3.ocm.incoming.v1beta1.CreateOCMIncomingShareRequest + 111, // 128: cs3.gateway.v1beta1.GatewayAPI.UpdateOCMIncomingShare:input_type -> cs3.ocm.incoming.v1beta1.UpdateOCMIncomingShareRequest + 112, // 129: cs3.gateway.v1beta1.GatewayAPI.DeleteOCMIncomingShare:input_type -> cs3.ocm.incoming.v1beta1.DeleteOCMIncomingShareRequest + 113, // 130: cs3.gateway.v1beta1.GatewayAPI.CreateOCMCoreShare:input_type -> cs3.ocm.core.v1beta1.CreateOCMCoreShareRequest + 114, // 131: cs3.gateway.v1beta1.GatewayAPI.UpdateOCMCoreShare:input_type -> cs3.ocm.core.v1beta1.UpdateOCMCoreShareRequest + 115, // 132: cs3.gateway.v1beta1.GatewayAPI.DeleteOCMCoreShare:input_type -> cs3.ocm.core.v1beta1.DeleteOCMCoreShareRequest + 116, // 133: cs3.gateway.v1beta1.GatewayAPI.CreateTransfer:input_type -> cs3.tx.v1beta1.CreateTransferRequest + 117, // 134: cs3.gateway.v1beta1.GatewayAPI.GetTransferStatus:input_type -> cs3.tx.v1beta1.GetTransferStatusRequest + 118, // 135: cs3.gateway.v1beta1.GatewayAPI.CancelTransfer:input_type -> cs3.tx.v1beta1.CancelTransferRequest + 119, // 136: cs3.gateway.v1beta1.GatewayAPI.ListTransfers:input_type -> cs3.tx.v1beta1.ListTransfersRequest + 120, // 137: cs3.gateway.v1beta1.GatewayAPI.RetryTransfer:input_type -> cs3.tx.v1beta1.RetryTransferRequest + 121, // 138: cs3.gateway.v1beta1.GatewayAPI.CheckPermission:input_type -> cs3.permissions.v1beta1.CheckPermissionRequest + 2, // 139: cs3.gateway.v1beta1.GatewayAPI.Authenticate:output_type -> cs3.gateway.v1beta1.AuthenticateResponse + 4, // 140: cs3.gateway.v1beta1.GatewayAPI.WhoAmI:output_type -> cs3.gateway.v1beta1.WhoAmIResponse + 122, // 141: cs3.gateway.v1beta1.GatewayAPI.GenerateAppPassword:output_type -> cs3.auth.applications.v1beta1.GenerateAppPasswordResponse + 123, // 142: cs3.gateway.v1beta1.GatewayAPI.ListAppPasswords:output_type -> cs3.auth.applications.v1beta1.ListAppPasswordsResponse + 124, // 143: cs3.gateway.v1beta1.GatewayAPI.InvalidateAppPassword:output_type -> cs3.auth.applications.v1beta1.InvalidateAppPasswordResponse + 125, // 144: cs3.gateway.v1beta1.GatewayAPI.GetAppPassword:output_type -> cs3.auth.applications.v1beta1.GetAppPasswordResponse + 126, // 145: cs3.gateway.v1beta1.GatewayAPI.CreateContainer:output_type -> cs3.storage.provider.v1beta1.CreateContainerResponse + 127, // 146: cs3.gateway.v1beta1.GatewayAPI.TouchFile:output_type -> cs3.storage.provider.v1beta1.TouchFileResponse + 128, // 147: cs3.gateway.v1beta1.GatewayAPI.Delete:output_type -> cs3.storage.provider.v1beta1.DeleteResponse + 129, // 148: cs3.gateway.v1beta1.GatewayAPI.GetPath:output_type -> cs3.storage.provider.v1beta1.GetPathResponse + 130, // 149: cs3.gateway.v1beta1.GatewayAPI.GetQuota:output_type -> cs3.storage.provider.v1beta1.GetQuotaResponse + 6, // 150: cs3.gateway.v1beta1.GatewayAPI.InitiateFileDownload:output_type -> cs3.gateway.v1beta1.InitiateFileDownloadResponse + 7, // 151: cs3.gateway.v1beta1.GatewayAPI.InitiateFileUpload:output_type -> cs3.gateway.v1beta1.InitiateFileUploadResponse + 131, // 152: cs3.gateway.v1beta1.GatewayAPI.ListContainerStream:output_type -> cs3.storage.provider.v1beta1.ListContainerStreamResponse + 132, // 153: cs3.gateway.v1beta1.GatewayAPI.ListContainer:output_type -> cs3.storage.provider.v1beta1.ListContainerResponse + 133, // 154: cs3.gateway.v1beta1.GatewayAPI.ListFileVersions:output_type -> cs3.storage.provider.v1beta1.ListFileVersionsResponse + 134, // 155: cs3.gateway.v1beta1.GatewayAPI.ListRecycleStream:output_type -> cs3.storage.provider.v1beta1.ListRecycleStreamResponse + 135, // 156: cs3.gateway.v1beta1.GatewayAPI.ListRecycle:output_type -> cs3.storage.provider.v1beta1.ListRecycleResponse + 136, // 157: cs3.gateway.v1beta1.GatewayAPI.Move:output_type -> cs3.storage.provider.v1beta1.MoveResponse + 137, // 158: cs3.gateway.v1beta1.GatewayAPI.PurgeRecycle:output_type -> cs3.storage.provider.v1beta1.PurgeRecycleResponse + 138, // 159: cs3.gateway.v1beta1.GatewayAPI.RestoreFileVersion:output_type -> cs3.storage.provider.v1beta1.RestoreFileVersionResponse + 139, // 160: cs3.gateway.v1beta1.GatewayAPI.RestoreRecycleItem:output_type -> cs3.storage.provider.v1beta1.RestoreRecycleItemResponse + 140, // 161: cs3.gateway.v1beta1.GatewayAPI.Stat:output_type -> cs3.storage.provider.v1beta1.StatResponse + 141, // 162: cs3.gateway.v1beta1.GatewayAPI.CreateSymlink:output_type -> cs3.storage.provider.v1beta1.CreateSymlinkResponse + 142, // 163: cs3.gateway.v1beta1.GatewayAPI.SetArbitraryMetadata:output_type -> cs3.storage.provider.v1beta1.SetArbitraryMetadataResponse + 143, // 164: cs3.gateway.v1beta1.GatewayAPI.UnsetArbitraryMetadata:output_type -> cs3.storage.provider.v1beta1.UnsetArbitraryMetadataResponse + 144, // 165: cs3.gateway.v1beta1.GatewayAPI.SetLock:output_type -> cs3.storage.provider.v1beta1.SetLockResponse + 145, // 166: cs3.gateway.v1beta1.GatewayAPI.GetLock:output_type -> cs3.storage.provider.v1beta1.GetLockResponse + 146, // 167: cs3.gateway.v1beta1.GatewayAPI.RefreshLock:output_type -> cs3.storage.provider.v1beta1.RefreshLockResponse + 147, // 168: cs3.gateway.v1beta1.GatewayAPI.Unlock:output_type -> cs3.storage.provider.v1beta1.UnlockResponse + 148, // 169: cs3.gateway.v1beta1.GatewayAPI.CreateHome:output_type -> cs3.storage.provider.v1beta1.CreateHomeResponse + 149, // 170: cs3.gateway.v1beta1.GatewayAPI.CreateStorageSpace:output_type -> cs3.storage.provider.v1beta1.CreateStorageSpaceResponse + 150, // 171: cs3.gateway.v1beta1.GatewayAPI.ListStorageSpaces:output_type -> cs3.storage.provider.v1beta1.ListStorageSpacesResponse + 151, // 172: cs3.gateway.v1beta1.GatewayAPI.UpdateStorageSpace:output_type -> cs3.storage.provider.v1beta1.UpdateStorageSpaceResponse + 152, // 173: cs3.gateway.v1beta1.GatewayAPI.DeleteStorageSpace:output_type -> cs3.storage.provider.v1beta1.DeleteStorageSpaceResponse + 153, // 174: cs3.gateway.v1beta1.GatewayAPI.AddFavorite:output_type -> cs3.storage.provider.v1beta1.AddFavoriteResponse + 154, // 175: cs3.gateway.v1beta1.GatewayAPI.RemoveFavorite:output_type -> cs3.storage.provider.v1beta1.RemoveFavoriteResponse + 155, // 176: cs3.gateway.v1beta1.GatewayAPI.OpenInApp:output_type -> cs3.app.provider.v1beta1.OpenInAppResponse + 156, // 177: cs3.gateway.v1beta1.GatewayAPI.CreateShare:output_type -> cs3.sharing.collaboration.v1beta1.CreateShareResponse + 157, // 178: cs3.gateway.v1beta1.GatewayAPI.RemoveShare:output_type -> cs3.sharing.collaboration.v1beta1.RemoveShareResponse + 158, // 179: cs3.gateway.v1beta1.GatewayAPI.GetShare:output_type -> cs3.sharing.collaboration.v1beta1.GetShareResponse + 159, // 180: cs3.gateway.v1beta1.GatewayAPI.ListShares:output_type -> cs3.sharing.collaboration.v1beta1.ListSharesResponse + 9, // 181: cs3.gateway.v1beta1.GatewayAPI.ListExistingShares:output_type -> cs3.gateway.v1beta1.ListExistingSharesResponse + 160, // 182: cs3.gateway.v1beta1.GatewayAPI.UpdateShare:output_type -> cs3.sharing.collaboration.v1beta1.UpdateShareResponse + 161, // 183: cs3.gateway.v1beta1.GatewayAPI.ListReceivedShares:output_type -> cs3.sharing.collaboration.v1beta1.ListReceivedSharesResponse + 10, // 184: cs3.gateway.v1beta1.GatewayAPI.ListExistingReceivedShares:output_type -> cs3.gateway.v1beta1.ListExistingReceivedSharesResponse + 162, // 185: cs3.gateway.v1beta1.GatewayAPI.UpdateReceivedShare:output_type -> cs3.sharing.collaboration.v1beta1.UpdateReceivedShareResponse + 163, // 186: cs3.gateway.v1beta1.GatewayAPI.GetReceivedShare:output_type -> cs3.sharing.collaboration.v1beta1.GetReceivedShareResponse + 164, // 187: cs3.gateway.v1beta1.GatewayAPI.SetKey:output_type -> cs3.preferences.v1beta1.SetKeyResponse + 165, // 188: cs3.gateway.v1beta1.GatewayAPI.GetKey:output_type -> cs3.preferences.v1beta1.GetKeyResponse + 166, // 189: cs3.gateway.v1beta1.GatewayAPI.CreatePublicShare:output_type -> cs3.sharing.link.v1beta1.CreatePublicShareResponse + 167, // 190: cs3.gateway.v1beta1.GatewayAPI.RemovePublicShare:output_type -> cs3.sharing.link.v1beta1.RemovePublicShareResponse + 168, // 191: cs3.gateway.v1beta1.GatewayAPI.GetPublicShare:output_type -> cs3.sharing.link.v1beta1.GetPublicShareResponse + 169, // 192: cs3.gateway.v1beta1.GatewayAPI.GetPublicShareByToken:output_type -> cs3.sharing.link.v1beta1.GetPublicShareByTokenResponse + 170, // 193: cs3.gateway.v1beta1.GatewayAPI.ListPublicShares:output_type -> cs3.sharing.link.v1beta1.ListPublicSharesResponse + 11, // 194: cs3.gateway.v1beta1.GatewayAPI.ListExistingPublicShares:output_type -> cs3.gateway.v1beta1.ListExistingPublicSharesResponse + 171, // 195: cs3.gateway.v1beta1.GatewayAPI.UpdatePublicShare:output_type -> cs3.sharing.link.v1beta1.UpdatePublicShareResponse + 172, // 196: cs3.gateway.v1beta1.GatewayAPI.CreateOCMShare:output_type -> cs3.sharing.ocm.v1beta1.CreateOCMShareResponse + 173, // 197: cs3.gateway.v1beta1.GatewayAPI.RemoveOCMShare:output_type -> cs3.sharing.ocm.v1beta1.RemoveOCMShareResponse + 174, // 198: cs3.gateway.v1beta1.GatewayAPI.GetOCMShare:output_type -> cs3.sharing.ocm.v1beta1.GetOCMShareResponse + 175, // 199: cs3.gateway.v1beta1.GatewayAPI.GetOCMShareByToken:output_type -> cs3.sharing.ocm.v1beta1.GetOCMShareByTokenResponse + 176, // 200: cs3.gateway.v1beta1.GatewayAPI.ListOCMShares:output_type -> cs3.sharing.ocm.v1beta1.ListOCMSharesResponse + 12, // 201: cs3.gateway.v1beta1.GatewayAPI.ListExistingOCMShares:output_type -> cs3.gateway.v1beta1.ListExistingOCMSharesResponse + 177, // 202: cs3.gateway.v1beta1.GatewayAPI.UpdateOCMShare:output_type -> cs3.sharing.ocm.v1beta1.UpdateOCMShareResponse + 178, // 203: cs3.gateway.v1beta1.GatewayAPI.ListReceivedOCMShares:output_type -> cs3.sharing.ocm.v1beta1.ListReceivedOCMSharesResponse + 179, // 204: cs3.gateway.v1beta1.GatewayAPI.UpdateReceivedOCMShare:output_type -> cs3.sharing.ocm.v1beta1.UpdateReceivedOCMShareResponse + 180, // 205: cs3.gateway.v1beta1.GatewayAPI.GetReceivedOCMShare:output_type -> cs3.sharing.ocm.v1beta1.GetReceivedOCMShareResponse + 181, // 206: cs3.gateway.v1beta1.GatewayAPI.GetAppProviders:output_type -> cs3.app.registry.v1beta1.GetAppProvidersResponse + 182, // 207: cs3.gateway.v1beta1.GatewayAPI.AddAppProvider:output_type -> cs3.app.registry.v1beta1.AddAppProviderResponse + 183, // 208: cs3.gateway.v1beta1.GatewayAPI.ListAppProviders:output_type -> cs3.app.registry.v1beta1.ListAppProvidersResponse + 184, // 209: cs3.gateway.v1beta1.GatewayAPI.ListSupportedMimeTypes:output_type -> cs3.app.registry.v1beta1.ListSupportedMimeTypesResponse + 185, // 210: cs3.gateway.v1beta1.GatewayAPI.GetDefaultAppProviderForMimeType:output_type -> cs3.app.registry.v1beta1.GetDefaultAppProviderForMimeTypeResponse + 186, // 211: cs3.gateway.v1beta1.GatewayAPI.SetDefaultAppProviderForMimeType:output_type -> cs3.app.registry.v1beta1.SetDefaultAppProviderForMimeTypeResponse + 187, // 212: cs3.gateway.v1beta1.GatewayAPI.GetUser:output_type -> cs3.identity.user.v1beta1.GetUserResponse + 188, // 213: cs3.gateway.v1beta1.GatewayAPI.GetUserByClaim:output_type -> cs3.identity.user.v1beta1.GetUserByClaimResponse + 189, // 214: cs3.gateway.v1beta1.GatewayAPI.GetUserGroups:output_type -> cs3.identity.user.v1beta1.GetUserGroupsResponse + 190, // 215: cs3.gateway.v1beta1.GatewayAPI.FindUsers:output_type -> cs3.identity.user.v1beta1.FindUsersResponse + 191, // 216: cs3.gateway.v1beta1.GatewayAPI.GetGroup:output_type -> cs3.identity.group.v1beta1.GetGroupResponse + 192, // 217: cs3.gateway.v1beta1.GatewayAPI.GetGroupByClaim:output_type -> cs3.identity.group.v1beta1.GetGroupByClaimResponse + 193, // 218: cs3.gateway.v1beta1.GatewayAPI.GetMembers:output_type -> cs3.identity.group.v1beta1.GetMembersResponse + 194, // 219: cs3.gateway.v1beta1.GatewayAPI.HasMember:output_type -> cs3.identity.group.v1beta1.HasMemberResponse + 195, // 220: cs3.gateway.v1beta1.GatewayAPI.FindGroups:output_type -> cs3.identity.group.v1beta1.FindGroupsResponse + 8, // 221: cs3.gateway.v1beta1.GatewayAPI.ListAuthProviders:output_type -> cs3.gateway.v1beta1.ListAuthProvidersResponse + 196, // 222: cs3.gateway.v1beta1.GatewayAPI.GetHome:output_type -> cs3.storage.provider.v1beta1.GetHomeResponse + 197, // 223: cs3.gateway.v1beta1.GatewayAPI.GenerateInviteToken:output_type -> cs3.ocm.invite.v1beta1.GenerateInviteTokenResponse + 198, // 224: cs3.gateway.v1beta1.GatewayAPI.ListInviteTokens:output_type -> cs3.ocm.invite.v1beta1.ListInviteTokensResponse + 199, // 225: cs3.gateway.v1beta1.GatewayAPI.ForwardInvite:output_type -> cs3.ocm.invite.v1beta1.ForwardInviteResponse + 200, // 226: cs3.gateway.v1beta1.GatewayAPI.AcceptInvite:output_type -> cs3.ocm.invite.v1beta1.AcceptInviteResponse + 201, // 227: cs3.gateway.v1beta1.GatewayAPI.GetAcceptedUser:output_type -> cs3.ocm.invite.v1beta1.GetAcceptedUserResponse + 202, // 228: cs3.gateway.v1beta1.GatewayAPI.FindAcceptedUsers:output_type -> cs3.ocm.invite.v1beta1.FindAcceptedUsersResponse + 203, // 229: cs3.gateway.v1beta1.GatewayAPI.DeleteAcceptedUser:output_type -> cs3.ocm.invite.v1beta1.DeleteAcceptedUserResponse + 204, // 230: cs3.gateway.v1beta1.GatewayAPI.IsProviderAllowed:output_type -> cs3.ocm.provider.v1beta1.IsProviderAllowedResponse + 205, // 231: cs3.gateway.v1beta1.GatewayAPI.GetInfoByDomain:output_type -> cs3.ocm.provider.v1beta1.GetInfoByDomainResponse + 206, // 232: cs3.gateway.v1beta1.GatewayAPI.ListAllProviders:output_type -> cs3.ocm.provider.v1beta1.ListAllProvidersResponse + 207, // 233: cs3.gateway.v1beta1.GatewayAPI.CreateOCMIncomingShare:output_type -> cs3.ocm.incoming.v1beta1.CreateOCMIncomingShareResponse + 208, // 234: cs3.gateway.v1beta1.GatewayAPI.UpdateOCMIncomingShare:output_type -> cs3.ocm.incoming.v1beta1.UpdateOCMIncomingShareResponse + 209, // 235: cs3.gateway.v1beta1.GatewayAPI.DeleteOCMIncomingShare:output_type -> cs3.ocm.incoming.v1beta1.DeleteOCMIncomingShareResponse + 210, // 236: cs3.gateway.v1beta1.GatewayAPI.CreateOCMCoreShare:output_type -> cs3.ocm.core.v1beta1.CreateOCMCoreShareResponse + 211, // 237: cs3.gateway.v1beta1.GatewayAPI.UpdateOCMCoreShare:output_type -> cs3.ocm.core.v1beta1.UpdateOCMCoreShareResponse + 212, // 238: cs3.gateway.v1beta1.GatewayAPI.DeleteOCMCoreShare:output_type -> cs3.ocm.core.v1beta1.DeleteOCMCoreShareResponse + 213, // 239: cs3.gateway.v1beta1.GatewayAPI.CreateTransfer:output_type -> cs3.tx.v1beta1.CreateTransferResponse + 214, // 240: cs3.gateway.v1beta1.GatewayAPI.GetTransferStatus:output_type -> cs3.tx.v1beta1.GetTransferStatusResponse + 215, // 241: cs3.gateway.v1beta1.GatewayAPI.CancelTransfer:output_type -> cs3.tx.v1beta1.CancelTransferResponse + 216, // 242: cs3.gateway.v1beta1.GatewayAPI.ListTransfers:output_type -> cs3.tx.v1beta1.ListTransfersResponse + 217, // 243: cs3.gateway.v1beta1.GatewayAPI.RetryTransfer:output_type -> cs3.tx.v1beta1.RetryTransferResponse + 218, // 244: cs3.gateway.v1beta1.GatewayAPI.CheckPermission:output_type -> cs3.permissions.v1beta1.CheckPermissionResponse + 139, // [139:245] is the sub-list for method output_type + 33, // [33:139] is the sub-list for method input_type 33, // [33:33] is the sub-list for extension type_name 33, // [33:33] is the sub-list for extension extendee 0, // [0:33] is the sub-list for field type_name diff --git a/vendor/github.com/cs3org/go-cs3apis/cs3/gateway/v1beta1/gateway_api_grpc.pb.go b/vendor/github.com/cs3org/go-cs3apis/cs3/gateway/v1beta1/gateway_api_grpc.pb.go index 9858404108..833218205d 100644 --- a/vendor/github.com/cs3org/go-cs3apis/cs3/gateway/v1beta1/gateway_api_grpc.pb.go +++ b/vendor/github.com/cs3org/go-cs3apis/cs3/gateway/v1beta1/gateway_api_grpc.pb.go @@ -89,6 +89,8 @@ const ( GatewayAPI_ListStorageSpaces_FullMethodName = "/cs3.gateway.v1beta1.GatewayAPI/ListStorageSpaces" GatewayAPI_UpdateStorageSpace_FullMethodName = "/cs3.gateway.v1beta1.GatewayAPI/UpdateStorageSpace" GatewayAPI_DeleteStorageSpace_FullMethodName = "/cs3.gateway.v1beta1.GatewayAPI/DeleteStorageSpace" + GatewayAPI_AddFavorite_FullMethodName = "/cs3.gateway.v1beta1.GatewayAPI/AddFavorite" + GatewayAPI_RemoveFavorite_FullMethodName = "/cs3.gateway.v1beta1.GatewayAPI/RemoveFavorite" GatewayAPI_OpenInApp_FullMethodName = "/cs3.gateway.v1beta1.GatewayAPI/OpenInApp" GatewayAPI_CreateShare_FullMethodName = "/cs3.gateway.v1beta1.GatewayAPI/CreateShare" GatewayAPI_RemoveShare_FullMethodName = "/cs3.gateway.v1beta1.GatewayAPI/RemoveShare" @@ -289,6 +291,10 @@ type GatewayAPIClient interface { UpdateStorageSpace(ctx context.Context, in *v1beta11.UpdateStorageSpaceRequest, opts ...grpc.CallOption) (*v1beta11.UpdateStorageSpaceResponse, error) // Deletes a storage space. DeleteStorageSpace(ctx context.Context, in *v1beta11.DeleteStorageSpaceRequest, opts ...grpc.CallOption) (*v1beta11.DeleteStorageSpaceResponse, error) + // Adds a resource as a favorite for a user. + AddFavorite(ctx context.Context, in *v1beta11.AddFavoriteRequest, opts ...grpc.CallOption) (*v1beta11.AddFavoriteResponse, error) + // Removes a resource from favorites for a user. + RemoveFavorite(ctx context.Context, in *v1beta11.RemoveFavoriteRequest, opts ...grpc.CallOption) (*v1beta11.RemoveFavoriteResponse, error) // Returns the App URL and all necessary info to open a resource in an online editor. // MUST return CODE_NOT_FOUND if the resource does not exist. OpenInApp(ctx context.Context, in *OpenInAppRequest, opts ...grpc.CallOption) (*v1beta12.OpenInAppResponse, error) @@ -845,6 +851,24 @@ func (c *gatewayAPIClient) DeleteStorageSpace(ctx context.Context, in *v1beta11. return out, nil } +func (c *gatewayAPIClient) AddFavorite(ctx context.Context, in *v1beta11.AddFavoriteRequest, opts ...grpc.CallOption) (*v1beta11.AddFavoriteResponse, error) { + out := new(v1beta11.AddFavoriteResponse) + err := c.cc.Invoke(ctx, GatewayAPI_AddFavorite_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *gatewayAPIClient) RemoveFavorite(ctx context.Context, in *v1beta11.RemoveFavoriteRequest, opts ...grpc.CallOption) (*v1beta11.RemoveFavoriteResponse, error) { + out := new(v1beta11.RemoveFavoriteResponse) + err := c.cc.Invoke(ctx, GatewayAPI_RemoveFavorite_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + func (c *gatewayAPIClient) OpenInApp(ctx context.Context, in *OpenInAppRequest, opts ...grpc.CallOption) (*v1beta12.OpenInAppResponse, error) { out := new(v1beta12.OpenInAppResponse) err := c.cc.Invoke(ctx, GatewayAPI_OpenInApp_FullMethodName, in, out, opts...) @@ -1595,6 +1619,10 @@ type GatewayAPIServer interface { UpdateStorageSpace(context.Context, *v1beta11.UpdateStorageSpaceRequest) (*v1beta11.UpdateStorageSpaceResponse, error) // Deletes a storage space. DeleteStorageSpace(context.Context, *v1beta11.DeleteStorageSpaceRequest) (*v1beta11.DeleteStorageSpaceResponse, error) + // Adds a resource as a favorite for a user. + AddFavorite(context.Context, *v1beta11.AddFavoriteRequest) (*v1beta11.AddFavoriteResponse, error) + // Removes a resource from favorites for a user. + RemoveFavorite(context.Context, *v1beta11.RemoveFavoriteRequest) (*v1beta11.RemoveFavoriteResponse, error) // Returns the App URL and all necessary info to open a resource in an online editor. // MUST return CODE_NOT_FOUND if the resource does not exist. OpenInApp(context.Context, *OpenInAppRequest) (*v1beta12.OpenInAppResponse, error) @@ -1891,6 +1919,12 @@ func (UnimplementedGatewayAPIServer) UpdateStorageSpace(context.Context, *v1beta func (UnimplementedGatewayAPIServer) DeleteStorageSpace(context.Context, *v1beta11.DeleteStorageSpaceRequest) (*v1beta11.DeleteStorageSpaceResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method DeleteStorageSpace not implemented") } +func (UnimplementedGatewayAPIServer) AddFavorite(context.Context, *v1beta11.AddFavoriteRequest) (*v1beta11.AddFavoriteResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method AddFavorite not implemented") +} +func (UnimplementedGatewayAPIServer) RemoveFavorite(context.Context, *v1beta11.RemoveFavoriteRequest) (*v1beta11.RemoveFavoriteResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method RemoveFavorite not implemented") +} func (UnimplementedGatewayAPIServer) OpenInApp(context.Context, *OpenInAppRequest) (*v1beta12.OpenInAppResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method OpenInApp not implemented") } @@ -2746,6 +2780,42 @@ func _GatewayAPI_DeleteStorageSpace_Handler(srv interface{}, ctx context.Context return interceptor(ctx, in, info, handler) } +func _GatewayAPI_AddFavorite_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(v1beta11.AddFavoriteRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(GatewayAPIServer).AddFavorite(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: GatewayAPI_AddFavorite_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(GatewayAPIServer).AddFavorite(ctx, req.(*v1beta11.AddFavoriteRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _GatewayAPI_RemoveFavorite_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(v1beta11.RemoveFavoriteRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(GatewayAPIServer).RemoveFavorite(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: GatewayAPI_RemoveFavorite_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(GatewayAPIServer).RemoveFavorite(ctx, req.(*v1beta11.RemoveFavoriteRequest)) + } + return interceptor(ctx, in, info, handler) +} + func _GatewayAPI_OpenInApp_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(OpenInAppRequest) if err := dec(in); err != nil { @@ -4127,6 +4197,14 @@ var GatewayAPI_ServiceDesc = grpc.ServiceDesc{ MethodName: "DeleteStorageSpace", Handler: _GatewayAPI_DeleteStorageSpace_Handler, }, + { + MethodName: "AddFavorite", + Handler: _GatewayAPI_AddFavorite_Handler, + }, + { + MethodName: "RemoveFavorite", + Handler: _GatewayAPI_RemoveFavorite_Handler, + }, { MethodName: "OpenInApp", Handler: _GatewayAPI_OpenInApp_Handler, diff --git a/vendor/github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1/provider_api.pb.go b/vendor/github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1/provider_api.pb.go index bc93c7270d..b25fb74edd 100644 --- a/vendor/github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1/provider_api.pb.go +++ b/vendor/github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1/provider_api.pb.go @@ -25,7 +25,7 @@ package providerv1beta1 import ( - _ "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1" + v1beta12 "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1" v1beta11 "github.com/cs3org/go-cs3apis/cs3/rpc/v1beta1" v1beta1 "github.com/cs3org/go-cs3apis/cs3/types/v1beta1" protoreflect "google.golang.org/protobuf/reflect/protoreflect" @@ -4700,6 +4700,262 @@ func (x *CreateHomeResponse) GetOpaque() *v1beta1.Opaque { return nil } +type AddFavoriteRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // OPTIONAL. + // Opaque information. + Opaque *v1beta1.Opaque `protobuf:"bytes,1,opt,name=opaque,proto3" json:"opaque,omitempty"` + // REQUIRED. + // The reference to which the action should be performed. + Ref *Reference `protobuf:"bytes,2,opt,name=ref,proto3" json:"ref,omitempty"` + // REQUIRED. + // The user marking the resource as favorite. + UserId *v1beta12.UserId `protobuf:"bytes,3,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"` +} + +func (x *AddFavoriteRequest) Reset() { + *x = AddFavoriteRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_cs3_storage_provider_v1beta1_provider_api_proto_msgTypes[64] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *AddFavoriteRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AddFavoriteRequest) ProtoMessage() {} + +func (x *AddFavoriteRequest) ProtoReflect() protoreflect.Message { + mi := &file_cs3_storage_provider_v1beta1_provider_api_proto_msgTypes[64] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AddFavoriteRequest.ProtoReflect.Descriptor instead. +func (*AddFavoriteRequest) Descriptor() ([]byte, []int) { + return file_cs3_storage_provider_v1beta1_provider_api_proto_rawDescGZIP(), []int{64} +} + +func (x *AddFavoriteRequest) GetOpaque() *v1beta1.Opaque { + if x != nil { + return x.Opaque + } + return nil +} + +func (x *AddFavoriteRequest) GetRef() *Reference { + if x != nil { + return x.Ref + } + return nil +} + +func (x *AddFavoriteRequest) GetUserId() *v1beta12.UserId { + if x != nil { + return x.UserId + } + return nil +} + +type AddFavoriteResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // REQUIRED. + // The response status. + Status *v1beta11.Status `protobuf:"bytes,1,opt,name=status,proto3" json:"status,omitempty"` + // OPTIONAL. + // Opaque information. + Opaque *v1beta1.Opaque `protobuf:"bytes,2,opt,name=opaque,proto3" json:"opaque,omitempty"` +} + +func (x *AddFavoriteResponse) Reset() { + *x = AddFavoriteResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_cs3_storage_provider_v1beta1_provider_api_proto_msgTypes[65] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *AddFavoriteResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AddFavoriteResponse) ProtoMessage() {} + +func (x *AddFavoriteResponse) ProtoReflect() protoreflect.Message { + mi := &file_cs3_storage_provider_v1beta1_provider_api_proto_msgTypes[65] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AddFavoriteResponse.ProtoReflect.Descriptor instead. +func (*AddFavoriteResponse) Descriptor() ([]byte, []int) { + return file_cs3_storage_provider_v1beta1_provider_api_proto_rawDescGZIP(), []int{65} +} + +func (x *AddFavoriteResponse) GetStatus() *v1beta11.Status { + if x != nil { + return x.Status + } + return nil +} + +func (x *AddFavoriteResponse) GetOpaque() *v1beta1.Opaque { + if x != nil { + return x.Opaque + } + return nil +} + +type RemoveFavoriteRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // OPTIONAL. + // Opaque information. + Opaque *v1beta1.Opaque `protobuf:"bytes,1,opt,name=opaque,proto3" json:"opaque,omitempty"` + // REQUIRED. + // The reference to which the action should be performed. + Ref *Reference `protobuf:"bytes,2,opt,name=ref,proto3" json:"ref,omitempty"` + // REQUIRED. + // The user un-marking the resource as favorite. + UserId *v1beta12.UserId `protobuf:"bytes,3,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"` +} + +func (x *RemoveFavoriteRequest) Reset() { + *x = RemoveFavoriteRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_cs3_storage_provider_v1beta1_provider_api_proto_msgTypes[66] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *RemoveFavoriteRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RemoveFavoriteRequest) ProtoMessage() {} + +func (x *RemoveFavoriteRequest) ProtoReflect() protoreflect.Message { + mi := &file_cs3_storage_provider_v1beta1_provider_api_proto_msgTypes[66] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RemoveFavoriteRequest.ProtoReflect.Descriptor instead. +func (*RemoveFavoriteRequest) Descriptor() ([]byte, []int) { + return file_cs3_storage_provider_v1beta1_provider_api_proto_rawDescGZIP(), []int{66} +} + +func (x *RemoveFavoriteRequest) GetOpaque() *v1beta1.Opaque { + if x != nil { + return x.Opaque + } + return nil +} + +func (x *RemoveFavoriteRequest) GetRef() *Reference { + if x != nil { + return x.Ref + } + return nil +} + +func (x *RemoveFavoriteRequest) GetUserId() *v1beta12.UserId { + if x != nil { + return x.UserId + } + return nil +} + +type RemoveFavoriteResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // REQUIRED. + // The response status. + Status *v1beta11.Status `protobuf:"bytes,1,opt,name=status,proto3" json:"status,omitempty"` + // OPTIONAL. + // Opaque information. + Opaque *v1beta1.Opaque `protobuf:"bytes,2,opt,name=opaque,proto3" json:"opaque,omitempty"` +} + +func (x *RemoveFavoriteResponse) Reset() { + *x = RemoveFavoriteResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_cs3_storage_provider_v1beta1_provider_api_proto_msgTypes[67] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *RemoveFavoriteResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RemoveFavoriteResponse) ProtoMessage() {} + +func (x *RemoveFavoriteResponse) ProtoReflect() protoreflect.Message { + mi := &file_cs3_storage_provider_v1beta1_provider_api_proto_msgTypes[67] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RemoveFavoriteResponse.ProtoReflect.Descriptor instead. +func (*RemoveFavoriteResponse) Descriptor() ([]byte, []int) { + return file_cs3_storage_provider_v1beta1_provider_api_proto_rawDescGZIP(), []int{67} +} + +func (x *RemoveFavoriteResponse) GetStatus() *v1beta11.Status { + if x != nil { + return x.Status + } + return nil +} + +func (x *RemoveFavoriteResponse) GetOpaque() *v1beta1.Opaque { + if x != nil { + return x.Opaque + } + return nil +} + var File_cs3_storage_provider_v1beta1_provider_api_proto protoreflect.FileDescriptor var file_cs3_storage_provider_v1beta1_provider_api_proto_rawDesc = []byte{ @@ -5442,264 +5698,319 @@ var file_cs3_storage_provider_v1beta1_provider_api_proto_rawDesc = []byte{ 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x31, 0x0a, 0x06, 0x6f, 0x70, 0x61, 0x71, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x63, 0x73, 0x33, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4f, 0x70, 0x61, 0x71, - 0x75, 0x65, 0x52, 0x06, 0x6f, 0x70, 0x61, 0x71, 0x75, 0x65, 0x32, 0xf4, 0x1d, 0x0a, 0x0b, 0x50, - 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x41, 0x50, 0x49, 0x12, 0x69, 0x0a, 0x08, 0x41, 0x64, - 0x64, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x12, 0x2d, 0x2e, 0x63, 0x73, 0x33, 0x2e, 0x73, 0x74, 0x6f, - 0x72, 0x61, 0x67, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, - 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x41, 0x64, 0x64, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x63, 0x73, 0x33, 0x2e, 0x73, 0x74, 0x6f, 0x72, - 0x61, 0x67, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, - 0x65, 0x74, 0x61, 0x31, 0x2e, 0x41, 0x64, 0x64, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x7e, 0x0a, 0x0f, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, - 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x12, 0x34, 0x2e, 0x63, 0x73, 0x33, 0x2e, 0x73, - 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, - 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, 0x6f, - 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x35, - 0x2e, 0x63, 0x73, 0x33, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2e, 0x70, 0x72, 0x6f, - 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x43, 0x72, - 0x65, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6c, 0x0a, 0x09, 0x54, 0x6f, 0x75, 0x63, 0x68, 0x46, 0x69, - 0x6c, 0x65, 0x12, 0x2e, 0x2e, 0x63, 0x73, 0x33, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, - 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, - 0x31, 0x2e, 0x54, 0x6f, 0x75, 0x63, 0x68, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x2f, 0x2e, 0x63, 0x73, 0x33, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, - 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, - 0x31, 0x2e, 0x54, 0x6f, 0x75, 0x63, 0x68, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x63, 0x0a, 0x06, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x12, 0x2b, 0x2e, - 0x63, 0x73, 0x33, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x76, - 0x69, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x44, 0x65, 0x6c, - 0x65, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c, 0x2e, 0x63, 0x73, 0x33, - 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, - 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6c, 0x0a, 0x09, 0x44, 0x65, 0x6e, 0x79, - 0x47, 0x72, 0x61, 0x6e, 0x74, 0x12, 0x2e, 0x2e, 0x63, 0x73, 0x33, 0x2e, 0x73, 0x74, 0x6f, 0x72, - 0x61, 0x67, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, - 0x65, 0x74, 0x61, 0x31, 0x2e, 0x44, 0x65, 0x6e, 0x79, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2f, 0x2e, 0x63, 0x73, 0x33, 0x2e, 0x73, 0x74, 0x6f, 0x72, - 0x61, 0x67, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, - 0x65, 0x74, 0x61, 0x31, 0x2e, 0x44, 0x65, 0x6e, 0x79, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x66, 0x0a, 0x07, 0x47, 0x65, 0x74, 0x50, 0x61, 0x74, - 0x68, 0x12, 0x2c, 0x2e, 0x63, 0x73, 0x33, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2e, + 0x75, 0x65, 0x52, 0x06, 0x6f, 0x70, 0x61, 0x71, 0x75, 0x65, 0x22, 0xbe, 0x01, 0x0a, 0x12, 0x41, + 0x64, 0x64, 0x46, 0x61, 0x76, 0x6f, 0x72, 0x69, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x12, 0x31, 0x0a, 0x06, 0x6f, 0x70, 0x61, 0x71, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x19, 0x2e, 0x63, 0x73, 0x33, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x76, 0x31, + 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4f, 0x70, 0x61, 0x71, 0x75, 0x65, 0x52, 0x06, 0x6f, 0x70, + 0x61, 0x71, 0x75, 0x65, 0x12, 0x39, 0x0a, 0x03, 0x72, 0x65, 0x66, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x27, 0x2e, 0x63, 0x73, 0x33, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, - 0x2e, 0x47, 0x65, 0x74, 0x50, 0x61, 0x74, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x2d, 0x2e, 0x63, 0x73, 0x33, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2e, 0x70, 0x72, - 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x47, - 0x65, 0x74, 0x50, 0x61, 0x74, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x69, - 0x0a, 0x08, 0x47, 0x65, 0x74, 0x51, 0x75, 0x6f, 0x74, 0x61, 0x12, 0x2d, 0x2e, 0x63, 0x73, 0x33, - 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, - 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x51, 0x75, 0x6f, - 0x74, 0x61, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x63, 0x73, 0x33, 0x2e, - 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, - 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x51, 0x75, 0x6f, 0x74, - 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x8d, 0x01, 0x0a, 0x14, 0x49, 0x6e, - 0x69, 0x74, 0x69, 0x61, 0x74, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, - 0x61, 0x64, 0x12, 0x39, 0x2e, 0x63, 0x73, 0x33, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, - 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, - 0x31, 0x2e, 0x49, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x74, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x44, 0x6f, - 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x3a, 0x2e, - 0x63, 0x73, 0x33, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x76, - 0x69, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x49, 0x6e, 0x69, - 0x74, 0x69, 0x61, 0x74, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, - 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x87, 0x01, 0x0a, 0x12, 0x49, 0x6e, - 0x69, 0x74, 0x69, 0x61, 0x74, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, - 0x12, 0x37, 0x2e, 0x63, 0x73, 0x33, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2e, 0x70, + 0x2e, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x52, 0x03, 0x72, 0x65, 0x66, 0x12, + 0x3a, 0x0a, 0x07, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x21, 0x2e, 0x63, 0x73, 0x33, 0x2e, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x2e, + 0x75, 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x55, 0x73, 0x65, + 0x72, 0x49, 0x64, 0x52, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x22, 0x79, 0x0a, 0x13, 0x41, + 0x64, 0x64, 0x46, 0x61, 0x76, 0x6f, 0x72, 0x69, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x2f, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x63, 0x73, 0x33, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, 0x62, + 0x65, 0x74, 0x61, 0x31, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, + 0x74, 0x75, 0x73, 0x12, 0x31, 0x0a, 0x06, 0x6f, 0x70, 0x61, 0x71, 0x75, 0x65, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x63, 0x73, 0x33, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, + 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4f, 0x70, 0x61, 0x71, 0x75, 0x65, 0x52, 0x06, + 0x6f, 0x70, 0x61, 0x71, 0x75, 0x65, 0x22, 0xc1, 0x01, 0x0a, 0x15, 0x52, 0x65, 0x6d, 0x6f, 0x76, + 0x65, 0x46, 0x61, 0x76, 0x6f, 0x72, 0x69, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x12, 0x31, 0x0a, 0x06, 0x6f, 0x70, 0x61, 0x71, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x19, 0x2e, 0x63, 0x73, 0x33, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x62, + 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4f, 0x70, 0x61, 0x71, 0x75, 0x65, 0x52, 0x06, 0x6f, 0x70, 0x61, + 0x71, 0x75, 0x65, 0x12, 0x39, 0x0a, 0x03, 0x72, 0x65, 0x66, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x27, 0x2e, 0x63, 0x73, 0x33, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, - 0x49, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x74, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x55, 0x70, 0x6c, 0x6f, - 0x61, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x38, 0x2e, 0x63, 0x73, 0x33, 0x2e, - 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, - 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x49, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x74, - 0x65, 0x46, 0x69, 0x6c, 0x65, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x6f, 0x0a, 0x0a, 0x4c, 0x69, 0x73, 0x74, 0x47, 0x72, 0x61, 0x6e, 0x74, - 0x73, 0x12, 0x2f, 0x2e, 0x63, 0x73, 0x33, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2e, - 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, - 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x30, 0x2e, 0x63, 0x73, 0x33, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, - 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, - 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x8c, 0x01, 0x0a, 0x13, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6f, 0x6e, - 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x12, 0x38, 0x2e, 0x63, - 0x73, 0x33, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, - 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, - 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x39, 0x2e, 0x63, 0x73, 0x33, 0x2e, 0x73, 0x74, 0x6f, + 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x52, 0x03, 0x72, 0x65, 0x66, 0x12, 0x3a, + 0x0a, 0x07, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x21, 0x2e, 0x63, 0x73, 0x33, 0x2e, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x2e, 0x75, + 0x73, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x55, 0x73, 0x65, 0x72, + 0x49, 0x64, 0x52, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x22, 0x7c, 0x0a, 0x16, 0x52, 0x65, + 0x6d, 0x6f, 0x76, 0x65, 0x46, 0x61, 0x76, 0x6f, 0x72, 0x69, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2f, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x63, 0x73, 0x33, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x76, + 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, + 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x31, 0x0a, 0x06, 0x6f, 0x70, 0x61, 0x71, 0x75, 0x65, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x63, 0x73, 0x33, 0x2e, 0x74, 0x79, 0x70, 0x65, + 0x73, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4f, 0x70, 0x61, 0x71, 0x75, 0x65, + 0x52, 0x06, 0x6f, 0x70, 0x61, 0x71, 0x75, 0x65, 0x32, 0xe5, 0x1f, 0x0a, 0x0b, 0x50, 0x72, 0x6f, + 0x76, 0x69, 0x64, 0x65, 0x72, 0x41, 0x50, 0x49, 0x12, 0x69, 0x0a, 0x08, 0x41, 0x64, 0x64, 0x47, + 0x72, 0x61, 0x6e, 0x74, 0x12, 0x2d, 0x2e, 0x63, 0x73, 0x33, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x61, + 0x67, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, + 0x74, 0x61, 0x31, 0x2e, 0x41, 0x64, 0x64, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x63, 0x73, 0x33, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, + 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, + 0x61, 0x31, 0x2e, 0x41, 0x64, 0x64, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x7e, 0x0a, 0x0f, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6e, + 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x12, 0x34, 0x2e, 0x63, 0x73, 0x33, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, - 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, - 0x6e, 0x65, 0x72, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x30, 0x01, 0x12, 0x78, 0x0a, 0x0d, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x61, - 0x69, 0x6e, 0x65, 0x72, 0x12, 0x32, 0x2e, 0x63, 0x73, 0x33, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x61, - 0x67, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, - 0x74, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, - 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x33, 0x2e, 0x63, 0x73, 0x33, 0x2e, 0x73, - 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, - 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6f, 0x6e, 0x74, - 0x61, 0x69, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x81, 0x01, - 0x0a, 0x10, 0x4c, 0x69, 0x73, 0x74, 0x46, 0x69, 0x6c, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, - 0x6e, 0x73, 0x12, 0x35, 0x2e, 0x63, 0x73, 0x33, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, - 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, - 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x46, 0x69, 0x6c, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, - 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x36, 0x2e, 0x63, 0x73, 0x33, 0x2e, - 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, - 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x46, 0x69, 0x6c, - 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x12, 0x86, 0x01, 0x0a, 0x11, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x63, 0x79, 0x63, 0x6c, - 0x65, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x12, 0x36, 0x2e, 0x63, 0x73, 0x33, 0x2e, 0x73, 0x74, - 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, 0x76, - 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x63, 0x79, 0x63, - 0x6c, 0x65, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x37, 0x2e, 0x63, 0x73, 0x33, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2e, 0x70, 0x72, - 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4c, - 0x69, 0x73, 0x74, 0x52, 0x65, 0x63, 0x79, 0x63, 0x6c, 0x65, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x30, 0x01, 0x12, 0x72, 0x0a, 0x0b, 0x4c, 0x69, - 0x73, 0x74, 0x52, 0x65, 0x63, 0x79, 0x63, 0x6c, 0x65, 0x12, 0x30, 0x2e, 0x63, 0x73, 0x33, 0x2e, - 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, - 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x63, - 0x79, 0x63, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x31, 0x2e, 0x63, 0x73, - 0x33, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, - 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, - 0x65, 0x63, 0x79, 0x63, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x5d, - 0x0a, 0x04, 0x4d, 0x6f, 0x76, 0x65, 0x12, 0x29, 0x2e, 0x63, 0x73, 0x33, 0x2e, 0x73, 0x74, 0x6f, - 0x72, 0x61, 0x67, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, - 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4d, 0x6f, 0x76, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x2a, 0x2e, 0x63, 0x73, 0x33, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2e, - 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, - 0x2e, 0x4d, 0x6f, 0x76, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x72, 0x0a, - 0x0b, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x12, 0x30, 0x2e, 0x63, - 0x73, 0x33, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, - 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x6d, 0x6f, - 0x76, 0x65, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x31, - 0x2e, 0x63, 0x73, 0x33, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2e, 0x70, 0x72, 0x6f, - 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x52, 0x65, - 0x6d, 0x6f, 0x76, 0x65, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x12, 0x75, 0x0a, 0x0c, 0x50, 0x75, 0x72, 0x67, 0x65, 0x52, 0x65, 0x63, 0x79, 0x63, 0x6c, - 0x65, 0x12, 0x31, 0x2e, 0x63, 0x73, 0x33, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2e, - 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, - 0x2e, 0x50, 0x75, 0x72, 0x67, 0x65, 0x52, 0x65, 0x63, 0x79, 0x63, 0x6c, 0x65, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x32, 0x2e, 0x63, 0x73, 0x33, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x61, - 0x67, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, - 0x74, 0x61, 0x31, 0x2e, 0x50, 0x75, 0x72, 0x67, 0x65, 0x52, 0x65, 0x63, 0x79, 0x63, 0x6c, 0x65, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x87, 0x01, 0x0a, 0x12, 0x52, 0x65, 0x73, - 0x74, 0x6f, 0x72, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, - 0x37, 0x2e, 0x63, 0x73, 0x33, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2e, 0x70, 0x72, - 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x52, - 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, - 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x38, 0x2e, 0x63, 0x73, 0x33, 0x2e, 0x73, - 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, - 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x46, - 0x69, 0x6c, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x87, 0x01, 0x0a, 0x12, 0x52, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x52, 0x65, - 0x63, 0x79, 0x63, 0x6c, 0x65, 0x49, 0x74, 0x65, 0x6d, 0x12, 0x37, 0x2e, 0x63, 0x73, 0x33, 0x2e, - 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, - 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, - 0x52, 0x65, 0x63, 0x79, 0x63, 0x6c, 0x65, 0x49, 0x74, 0x65, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x38, 0x2e, 0x63, 0x73, 0x33, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, - 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, - 0x31, 0x2e, 0x52, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x52, 0x65, 0x63, 0x79, 0x63, 0x6c, 0x65, - 0x49, 0x74, 0x65, 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x5d, 0x0a, 0x04, - 0x53, 0x74, 0x61, 0x74, 0x12, 0x29, 0x2e, 0x63, 0x73, 0x33, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x61, - 0x67, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, - 0x74, 0x61, 0x31, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x2a, 0x2e, 0x63, 0x73, 0x33, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2e, 0x70, 0x72, - 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x53, - 0x74, 0x61, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x72, 0x0a, 0x0b, 0x55, - 0x70, 0x64, 0x61, 0x74, 0x65, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x12, 0x30, 0x2e, 0x63, 0x73, 0x33, - 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, - 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, - 0x47, 0x72, 0x61, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x31, 0x2e, 0x63, - 0x73, 0x33, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, - 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, - 0x74, 0x65, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, - 0x78, 0x0a, 0x0d, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x79, 0x6d, 0x6c, 0x69, 0x6e, 0x6b, - 0x12, 0x32, 0x2e, 0x63, 0x73, 0x33, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2e, 0x70, - 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, - 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x79, 0x6d, 0x6c, 0x69, 0x6e, 0x6b, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x33, 0x2e, 0x63, 0x73, 0x33, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x61, - 0x67, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, - 0x74, 0x61, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x79, 0x6d, 0x6c, 0x69, 0x6e, - 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x7e, 0x0a, 0x0f, 0x43, 0x72, 0x65, - 0x61, 0x74, 0x65, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x34, 0x2e, 0x63, + 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x74, + 0x61, 0x69, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x35, 0x2e, 0x63, 0x73, 0x33, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, - 0x74, 0x65, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x35, 0x2e, 0x63, 0x73, 0x33, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, - 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, - 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, - 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x8d, 0x01, 0x0a, 0x14, 0x53, 0x65, - 0x74, 0x41, 0x72, 0x62, 0x69, 0x74, 0x72, 0x61, 0x72, 0x79, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, - 0x74, 0x61, 0x12, 0x39, 0x2e, 0x63, 0x73, 0x33, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, - 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, - 0x31, 0x2e, 0x53, 0x65, 0x74, 0x41, 0x72, 0x62, 0x69, 0x74, 0x72, 0x61, 0x72, 0x79, 0x4d, 0x65, - 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x3a, 0x2e, + 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x6c, 0x0a, 0x09, 0x54, 0x6f, 0x75, 0x63, 0x68, 0x46, 0x69, 0x6c, 0x65, + 0x12, 0x2e, 0x2e, 0x63, 0x73, 0x33, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2e, 0x70, + 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, + 0x54, 0x6f, 0x75, 0x63, 0x68, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x2f, 0x2e, 0x63, 0x73, 0x33, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2e, 0x70, + 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, + 0x54, 0x6f, 0x75, 0x63, 0x68, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x63, 0x0a, 0x06, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x12, 0x2b, 0x2e, 0x63, 0x73, + 0x33, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, + 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, + 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c, 0x2e, 0x63, 0x73, 0x33, 0x2e, 0x73, + 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, + 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6c, 0x0a, 0x09, 0x44, 0x65, 0x6e, 0x79, 0x47, 0x72, + 0x61, 0x6e, 0x74, 0x12, 0x2e, 0x2e, 0x63, 0x73, 0x33, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, + 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, + 0x61, 0x31, 0x2e, 0x44, 0x65, 0x6e, 0x79, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x2f, 0x2e, 0x63, 0x73, 0x33, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, + 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, + 0x61, 0x31, 0x2e, 0x44, 0x65, 0x6e, 0x79, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x66, 0x0a, 0x07, 0x47, 0x65, 0x74, 0x50, 0x61, 0x74, 0x68, 0x12, + 0x2c, 0x2e, 0x63, 0x73, 0x33, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2e, 0x70, 0x72, + 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x47, + 0x65, 0x74, 0x50, 0x61, 0x74, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2d, 0x2e, 0x63, 0x73, 0x33, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x76, - 0x69, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x53, 0x65, 0x74, - 0x41, 0x72, 0x62, 0x69, 0x74, 0x72, 0x61, 0x72, 0x79, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, - 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x93, 0x01, 0x0a, 0x16, 0x55, 0x6e, - 0x73, 0x65, 0x74, 0x41, 0x72, 0x62, 0x69, 0x74, 0x72, 0x61, 0x72, 0x79, 0x4d, 0x65, 0x74, 0x61, - 0x64, 0x61, 0x74, 0x61, 0x12, 0x3b, 0x2e, 0x63, 0x73, 0x33, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x61, - 0x67, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, - 0x74, 0x61, 0x31, 0x2e, 0x55, 0x6e, 0x73, 0x65, 0x74, 0x41, 0x72, 0x62, 0x69, 0x74, 0x72, 0x61, - 0x72, 0x79, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x3c, 0x2e, 0x63, 0x73, 0x33, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2e, - 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, - 0x2e, 0x55, 0x6e, 0x73, 0x65, 0x74, 0x41, 0x72, 0x62, 0x69, 0x74, 0x72, 0x61, 0x72, 0x79, 0x4d, - 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, - 0x66, 0x0a, 0x07, 0x53, 0x65, 0x74, 0x4c, 0x6f, 0x63, 0x6b, 0x12, 0x2c, 0x2e, 0x63, 0x73, 0x33, + 0x69, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, + 0x50, 0x61, 0x74, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x69, 0x0a, 0x08, + 0x47, 0x65, 0x74, 0x51, 0x75, 0x6f, 0x74, 0x61, 0x12, 0x2d, 0x2e, 0x63, 0x73, 0x33, 0x2e, 0x73, + 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, + 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x51, 0x75, 0x6f, 0x74, 0x61, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x63, 0x73, 0x33, 0x2e, 0x73, 0x74, + 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, 0x76, + 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x51, 0x75, 0x6f, 0x74, 0x61, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x8d, 0x01, 0x0a, 0x14, 0x49, 0x6e, 0x69, 0x74, + 0x69, 0x61, 0x74, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, + 0x12, 0x39, 0x2e, 0x63, 0x73, 0x33, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2e, 0x70, + 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, + 0x49, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x74, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x44, 0x6f, 0x77, 0x6e, + 0x6c, 0x6f, 0x61, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x3a, 0x2e, 0x63, 0x73, + 0x33, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, + 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x49, 0x6e, 0x69, 0x74, 0x69, + 0x61, 0x74, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x87, 0x01, 0x0a, 0x12, 0x49, 0x6e, 0x69, 0x74, + 0x69, 0x61, 0x74, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x37, + 0x2e, 0x63, 0x73, 0x33, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2e, 0x70, 0x72, 0x6f, + 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x49, 0x6e, + 0x69, 0x74, 0x69, 0x61, 0x74, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x38, 0x2e, 0x63, 0x73, 0x33, 0x2e, 0x73, 0x74, + 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, 0x76, + 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x49, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x74, 0x65, 0x46, + 0x69, 0x6c, 0x65, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x6f, 0x0a, 0x0a, 0x4c, 0x69, 0x73, 0x74, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x12, + 0x2f, 0x2e, 0x63, 0x73, 0x33, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2e, 0x70, 0x72, + 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4c, + 0x69, 0x73, 0x74, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x30, 0x2e, 0x63, 0x73, 0x33, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2e, 0x70, + 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, + 0x4c, 0x69, 0x73, 0x74, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x8c, 0x01, 0x0a, 0x13, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x61, + 0x69, 0x6e, 0x65, 0x72, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x12, 0x38, 0x2e, 0x63, 0x73, 0x33, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, - 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x53, 0x65, 0x74, 0x4c, 0x6f, 0x63, - 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2d, 0x2e, 0x63, 0x73, 0x33, 0x2e, 0x73, + 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6f, + 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x39, 0x2e, 0x63, 0x73, 0x33, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x61, + 0x67, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, + 0x74, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, + 0x72, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x30, + 0x01, 0x12, 0x78, 0x0a, 0x0d, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, + 0x65, 0x72, 0x12, 0x32, 0x2e, 0x63, 0x73, 0x33, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, + 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, + 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x33, 0x2e, 0x63, 0x73, 0x33, 0x2e, 0x73, 0x74, 0x6f, + 0x72, 0x61, 0x67, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, + 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, + 0x6e, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x81, 0x01, 0x0a, 0x10, + 0x4c, 0x69, 0x73, 0x74, 0x46, 0x69, 0x6c, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x73, + 0x12, 0x35, 0x2e, 0x63, 0x73, 0x33, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2e, 0x70, + 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, + 0x4c, 0x69, 0x73, 0x74, 0x46, 0x69, 0x6c, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x73, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x36, 0x2e, 0x63, 0x73, 0x33, 0x2e, 0x73, 0x74, + 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, 0x76, + 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x46, 0x69, 0x6c, 0x65, 0x56, + 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x86, 0x01, 0x0a, 0x11, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x63, 0x79, 0x63, 0x6c, 0x65, 0x53, + 0x74, 0x72, 0x65, 0x61, 0x6d, 0x12, 0x36, 0x2e, 0x63, 0x73, 0x33, 0x2e, 0x73, 0x74, 0x6f, 0x72, + 0x61, 0x67, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, + 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x63, 0x79, 0x63, 0x6c, 0x65, + 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x37, 0x2e, + 0x63, 0x73, 0x33, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x76, + 0x69, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, + 0x74, 0x52, 0x65, 0x63, 0x79, 0x63, 0x6c, 0x65, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x30, 0x01, 0x12, 0x72, 0x0a, 0x0b, 0x4c, 0x69, 0x73, 0x74, + 0x52, 0x65, 0x63, 0x79, 0x63, 0x6c, 0x65, 0x12, 0x30, 0x2e, 0x63, 0x73, 0x33, 0x2e, 0x73, 0x74, + 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, 0x76, + 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x63, 0x79, 0x63, + 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x31, 0x2e, 0x63, 0x73, 0x33, 0x2e, + 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, + 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x63, + 0x79, 0x63, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x5d, 0x0a, 0x04, + 0x4d, 0x6f, 0x76, 0x65, 0x12, 0x29, 0x2e, 0x63, 0x73, 0x33, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x61, + 0x67, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, + 0x74, 0x61, 0x31, 0x2e, 0x4d, 0x6f, 0x76, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x2a, 0x2e, 0x63, 0x73, 0x33, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2e, 0x70, 0x72, + 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4d, + 0x6f, 0x76, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x72, 0x0a, 0x0b, 0x52, + 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x12, 0x30, 0x2e, 0x63, 0x73, 0x33, + 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, + 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, + 0x47, 0x72, 0x61, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x31, 0x2e, 0x63, + 0x73, 0x33, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, + 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x6d, 0x6f, + 0x76, 0x65, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x75, 0x0a, 0x0c, 0x50, 0x75, 0x72, 0x67, 0x65, 0x52, 0x65, 0x63, 0x79, 0x63, 0x6c, 0x65, 0x12, + 0x31, 0x2e, 0x63, 0x73, 0x33, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2e, 0x70, 0x72, + 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x50, + 0x75, 0x72, 0x67, 0x65, 0x52, 0x65, 0x63, 0x79, 0x63, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x32, 0x2e, 0x63, 0x73, 0x33, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, + 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, + 0x31, 0x2e, 0x50, 0x75, 0x72, 0x67, 0x65, 0x52, 0x65, 0x63, 0x79, 0x63, 0x6c, 0x65, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x87, 0x01, 0x0a, 0x12, 0x52, 0x65, 0x73, 0x74, 0x6f, + 0x72, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x37, 0x2e, + 0x63, 0x73, 0x33, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x76, + 0x69, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x73, + 0x74, 0x6f, 0x72, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x38, 0x2e, 0x63, 0x73, 0x33, 0x2e, 0x73, 0x74, 0x6f, + 0x72, 0x61, 0x67, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, + 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x46, 0x69, 0x6c, + 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x87, 0x01, 0x0a, 0x12, 0x52, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x52, 0x65, 0x63, 0x79, + 0x63, 0x6c, 0x65, 0x49, 0x74, 0x65, 0x6d, 0x12, 0x37, 0x2e, 0x63, 0x73, 0x33, 0x2e, 0x73, 0x74, + 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, 0x76, + 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x52, 0x65, + 0x63, 0x79, 0x63, 0x6c, 0x65, 0x49, 0x74, 0x65, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x38, 0x2e, 0x63, 0x73, 0x33, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2e, 0x70, + 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, + 0x52, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x52, 0x65, 0x63, 0x79, 0x63, 0x6c, 0x65, 0x49, 0x74, + 0x65, 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x5d, 0x0a, 0x04, 0x53, 0x74, + 0x61, 0x74, 0x12, 0x29, 0x2e, 0x63, 0x73, 0x33, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, + 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, + 0x31, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2a, 0x2e, + 0x63, 0x73, 0x33, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x76, + 0x69, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x53, 0x74, 0x61, + 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x72, 0x0a, 0x0b, 0x55, 0x70, 0x64, + 0x61, 0x74, 0x65, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x12, 0x30, 0x2e, 0x63, 0x73, 0x33, 0x2e, 0x73, + 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, + 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x47, 0x72, + 0x61, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x31, 0x2e, 0x63, 0x73, 0x33, + 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, + 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, + 0x47, 0x72, 0x61, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x78, 0x0a, + 0x0d, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x79, 0x6d, 0x6c, 0x69, 0x6e, 0x6b, 0x12, 0x32, + 0x2e, 0x63, 0x73, 0x33, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2e, 0x70, 0x72, 0x6f, + 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x43, 0x72, + 0x65, 0x61, 0x74, 0x65, 0x53, 0x79, 0x6d, 0x6c, 0x69, 0x6e, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x33, 0x2e, 0x63, 0x73, 0x33, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, + 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, + 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x79, 0x6d, 0x6c, 0x69, 0x6e, 0x6b, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x7e, 0x0a, 0x0f, 0x43, 0x72, 0x65, 0x61, 0x74, + 0x65, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x34, 0x2e, 0x63, 0x73, 0x33, + 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, + 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, + 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x35, 0x2e, 0x63, 0x73, 0x33, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2e, 0x70, + 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, + 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x8d, 0x01, 0x0a, 0x14, 0x53, 0x65, 0x74, 0x41, + 0x72, 0x62, 0x69, 0x74, 0x72, 0x61, 0x72, 0x79, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, + 0x12, 0x39, 0x2e, 0x63, 0x73, 0x33, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2e, 0x70, + 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, + 0x53, 0x65, 0x74, 0x41, 0x72, 0x62, 0x69, 0x74, 0x72, 0x61, 0x72, 0x79, 0x4d, 0x65, 0x74, 0x61, + 0x64, 0x61, 0x74, 0x61, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x3a, 0x2e, 0x63, 0x73, + 0x33, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, + 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x53, 0x65, 0x74, 0x41, 0x72, + 0x62, 0x69, 0x74, 0x72, 0x61, 0x72, 0x79, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x93, 0x01, 0x0a, 0x16, 0x55, 0x6e, 0x73, 0x65, + 0x74, 0x41, 0x72, 0x62, 0x69, 0x74, 0x72, 0x61, 0x72, 0x79, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, + 0x74, 0x61, 0x12, 0x3b, 0x2e, 0x63, 0x73, 0x33, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, + 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, + 0x31, 0x2e, 0x55, 0x6e, 0x73, 0x65, 0x74, 0x41, 0x72, 0x62, 0x69, 0x74, 0x72, 0x61, 0x72, 0x79, + 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x3c, 0x2e, 0x63, 0x73, 0x33, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2e, 0x70, 0x72, + 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x55, + 0x6e, 0x73, 0x65, 0x74, 0x41, 0x72, 0x62, 0x69, 0x74, 0x72, 0x61, 0x72, 0x79, 0x4d, 0x65, 0x74, + 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x66, 0x0a, + 0x07, 0x53, 0x65, 0x74, 0x4c, 0x6f, 0x63, 0x6b, 0x12, 0x2c, 0x2e, 0x63, 0x73, 0x33, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x53, 0x65, 0x74, 0x4c, 0x6f, 0x63, 0x6b, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x66, 0x0a, 0x07, 0x47, 0x65, 0x74, 0x4c, 0x6f, - 0x63, 0x6b, 0x12, 0x2c, 0x2e, 0x63, 0x73, 0x33, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, - 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, - 0x31, 0x2e, 0x47, 0x65, 0x74, 0x4c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x2d, 0x2e, 0x63, 0x73, 0x33, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2e, 0x70, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2d, 0x2e, 0x63, 0x73, 0x33, 0x2e, 0x73, 0x74, 0x6f, + 0x72, 0x61, 0x67, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, + 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x53, 0x65, 0x74, 0x4c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x66, 0x0a, 0x07, 0x47, 0x65, 0x74, 0x4c, 0x6f, 0x63, 0x6b, + 0x12, 0x2c, 0x2e, 0x63, 0x73, 0x33, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, - 0x47, 0x65, 0x74, 0x4c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, - 0x72, 0x0a, 0x0b, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x4c, 0x6f, 0x63, 0x6b, 0x12, 0x30, + 0x47, 0x65, 0x74, 0x4c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2d, + 0x2e, 0x63, 0x73, 0x33, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2e, 0x70, 0x72, 0x6f, + 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x47, 0x65, + 0x74, 0x4c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x72, 0x0a, + 0x0b, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x4c, 0x6f, 0x63, 0x6b, 0x12, 0x30, 0x2e, 0x63, + 0x73, 0x33, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, + 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x66, 0x72, + 0x65, 0x73, 0x68, 0x4c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x31, 0x2e, 0x63, 0x73, 0x33, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x52, 0x65, - 0x66, 0x72, 0x65, 0x73, 0x68, 0x4c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x66, 0x72, 0x65, 0x73, 0x68, 0x4c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x63, 0x0a, 0x06, 0x55, 0x6e, 0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x2b, 0x2e, 0x63, 0x73, + 0x33, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, + 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x55, 0x6e, 0x6c, 0x6f, 0x63, + 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c, 0x2e, 0x63, 0x73, 0x33, 0x2e, 0x73, + 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, + 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x55, 0x6e, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6f, 0x0a, 0x0a, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, + 0x48, 0x6f, 0x6d, 0x65, 0x12, 0x2f, 0x2e, 0x63, 0x73, 0x33, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x61, + 0x67, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, + 0x74, 0x61, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x48, 0x6f, 0x6d, 0x65, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x30, 0x2e, 0x63, 0x73, 0x33, 0x2e, 0x73, 0x74, 0x6f, 0x72, + 0x61, 0x67, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, + 0x65, 0x74, 0x61, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x48, 0x6f, 0x6d, 0x65, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x66, 0x0a, 0x07, 0x47, 0x65, 0x74, 0x48, 0x6f, + 0x6d, 0x65, 0x12, 0x2c, 0x2e, 0x63, 0x73, 0x33, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, + 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, + 0x31, 0x2e, 0x47, 0x65, 0x74, 0x48, 0x6f, 0x6d, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x2d, 0x2e, 0x63, 0x73, 0x33, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2e, 0x70, + 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, + 0x47, 0x65, 0x74, 0x48, 0x6f, 0x6d, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x72, 0x0a, 0x0b, 0x41, 0x64, 0x64, 0x46, 0x61, 0x76, 0x6f, 0x72, 0x69, 0x74, 0x65, 0x12, 0x30, + 0x2e, 0x63, 0x73, 0x33, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2e, 0x70, 0x72, 0x6f, + 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x41, 0x64, + 0x64, 0x46, 0x61, 0x76, 0x6f, 0x72, 0x69, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x31, 0x2e, 0x63, 0x73, 0x33, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, - 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x4c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x63, 0x0a, 0x06, 0x55, 0x6e, 0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x2b, 0x2e, - 0x63, 0x73, 0x33, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x76, - 0x69, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x55, 0x6e, 0x6c, - 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c, 0x2e, 0x63, 0x73, 0x33, + 0x41, 0x64, 0x64, 0x46, 0x61, 0x76, 0x6f, 0x72, 0x69, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x7b, 0x0a, 0x0e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x46, 0x61, 0x76, + 0x6f, 0x72, 0x69, 0x74, 0x65, 0x12, 0x33, 0x2e, 0x63, 0x73, 0x33, 0x2e, 0x73, 0x74, 0x6f, 0x72, + 0x61, 0x67, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, + 0x65, 0x74, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x46, 0x61, 0x76, 0x6f, 0x72, + 0x69, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x34, 0x2e, 0x63, 0x73, 0x33, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, - 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x55, 0x6e, 0x6c, 0x6f, 0x63, 0x6b, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6f, 0x0a, 0x0a, 0x43, 0x72, 0x65, 0x61, - 0x74, 0x65, 0x48, 0x6f, 0x6d, 0x65, 0x12, 0x2f, 0x2e, 0x63, 0x73, 0x33, 0x2e, 0x73, 0x74, 0x6f, + 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, + 0x46, 0x61, 0x76, 0x6f, 0x72, 0x69, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x42, 0x92, 0x02, 0x0a, 0x20, 0x63, 0x6f, 0x6d, 0x2e, 0x63, 0x73, 0x33, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, - 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x48, 0x6f, 0x6d, 0x65, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x30, 0x2e, 0x63, 0x73, 0x33, 0x2e, 0x73, 0x74, - 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, 0x76, - 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x48, 0x6f, 0x6d, - 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x66, 0x0a, 0x07, 0x47, 0x65, 0x74, - 0x48, 0x6f, 0x6d, 0x65, 0x12, 0x2c, 0x2e, 0x63, 0x73, 0x33, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x61, - 0x67, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, - 0x74, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x48, 0x6f, 0x6d, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x2d, 0x2e, 0x63, 0x73, 0x33, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, - 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, - 0x31, 0x2e, 0x47, 0x65, 0x74, 0x48, 0x6f, 0x6d, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x42, 0x92, 0x02, 0x0a, 0x20, 0x63, 0x6f, 0x6d, 0x2e, 0x63, 0x73, 0x33, 0x2e, 0x73, 0x74, - 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2e, 0x76, - 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x42, 0x10, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, - 0x41, 0x70, 0x69, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x49, 0x67, 0x69, 0x74, 0x68, - 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x73, 0x33, 0x6f, 0x72, 0x67, 0x2f, 0x67, 0x6f, - 0x2d, 0x63, 0x73, 0x33, 0x61, 0x70, 0x69, 0x73, 0x2f, 0x63, 0x73, 0x33, 0x2f, 0x73, 0x74, 0x6f, - 0x72, 0x61, 0x67, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2f, 0x76, 0x31, - 0x62, 0x65, 0x74, 0x61, 0x31, 0x3b, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x76, 0x31, - 0x62, 0x65, 0x74, 0x61, 0x31, 0xa2, 0x02, 0x03, 0x43, 0x53, 0x50, 0xaa, 0x02, 0x1c, 0x43, 0x73, - 0x33, 0x2e, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2e, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, - 0x65, 0x72, 0x2e, 0x56, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0xca, 0x02, 0x1c, 0x43, 0x73, 0x33, - 0x5c, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x5c, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, - 0x72, 0x5c, 0x56, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0xe2, 0x02, 0x28, 0x43, 0x73, 0x33, 0x5c, + 0x62, 0x65, 0x74, 0x61, 0x31, 0x42, 0x10, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x41, + 0x70, 0x69, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x49, 0x67, 0x69, 0x74, 0x68, 0x75, + 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x73, 0x33, 0x6f, 0x72, 0x67, 0x2f, 0x67, 0x6f, 0x2d, + 0x63, 0x73, 0x33, 0x61, 0x70, 0x69, 0x73, 0x2f, 0x63, 0x73, 0x33, 0x2f, 0x73, 0x74, 0x6f, 0x72, + 0x61, 0x67, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x2f, 0x76, 0x31, 0x62, + 0x65, 0x74, 0x61, 0x31, 0x3b, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x76, 0x31, 0x62, + 0x65, 0x74, 0x61, 0x31, 0xa2, 0x02, 0x03, 0x43, 0x53, 0x50, 0xaa, 0x02, 0x1c, 0x43, 0x73, 0x33, + 0x2e, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2e, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, + 0x72, 0x2e, 0x56, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0xca, 0x02, 0x1c, 0x43, 0x73, 0x33, 0x5c, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x5c, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, - 0x5c, 0x56, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, - 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x1f, 0x43, 0x73, 0x33, 0x3a, 0x3a, 0x53, 0x74, 0x6f, 0x72, - 0x61, 0x67, 0x65, 0x3a, 0x3a, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x3a, 0x3a, 0x56, - 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x5c, 0x56, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0xe2, 0x02, 0x28, 0x43, 0x73, 0x33, 0x5c, 0x53, + 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x5c, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x5c, + 0x56, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, + 0x61, 0x74, 0x61, 0xea, 0x02, 0x1f, 0x43, 0x73, 0x33, 0x3a, 0x3a, 0x53, 0x74, 0x6f, 0x72, 0x61, + 0x67, 0x65, 0x3a, 0x3a, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x3a, 0x3a, 0x56, 0x31, + 0x62, 0x65, 0x74, 0x61, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -5714,7 +6025,7 @@ func file_cs3_storage_provider_v1beta1_provider_api_proto_rawDescGZIP() []byte { return file_cs3_storage_provider_v1beta1_provider_api_proto_rawDescData } -var file_cs3_storage_provider_v1beta1_provider_api_proto_msgTypes = make([]protoimpl.MessageInfo, 64) +var file_cs3_storage_provider_v1beta1_provider_api_proto_msgTypes = make([]protoimpl.MessageInfo, 68) var file_cs3_storage_provider_v1beta1_provider_api_proto_goTypes = []interface{}{ (*GetHomeRequest)(nil), // 0: cs3.storage.provider.v1beta1.GetHomeRequest (*GetHomeResponse)(nil), // 1: cs3.storage.provider.v1beta1.GetHomeResponse @@ -5780,248 +6091,267 @@ var file_cs3_storage_provider_v1beta1_provider_api_proto_goTypes = []interface{} (*UnlockResponse)(nil), // 61: cs3.storage.provider.v1beta1.UnlockResponse (*CreateHomeRequest)(nil), // 62: cs3.storage.provider.v1beta1.CreateHomeRequest (*CreateHomeResponse)(nil), // 63: cs3.storage.provider.v1beta1.CreateHomeResponse - (*v1beta1.Opaque)(nil), // 64: cs3.types.v1beta1.Opaque - (*v1beta11.Status)(nil), // 65: cs3.rpc.v1beta1.Status - (*Reference)(nil), // 66: cs3.storage.provider.v1beta1.Reference - (*Grant)(nil), // 67: cs3.storage.provider.v1beta1.Grant - (*Grantee)(nil), // 68: cs3.storage.provider.v1beta1.Grantee - (*ResourceId)(nil), // 69: cs3.storage.provider.v1beta1.ResourceId - (*v1beta1.Timestamp)(nil), // 70: cs3.types.v1beta1.Timestamp - (*FileUploadProtocol)(nil), // 71: cs3.storage.provider.v1beta1.FileUploadProtocol - (*FileDownloadProtocol)(nil), // 72: cs3.storage.provider.v1beta1.FileDownloadProtocol - (*fieldmaskpb.FieldMask)(nil), // 73: google.protobuf.FieldMask - (*ResourceInfo)(nil), // 74: cs3.storage.provider.v1beta1.ResourceInfo - (*FileVersion)(nil), // 75: cs3.storage.provider.v1beta1.FileVersion - (*RecycleItem)(nil), // 76: cs3.storage.provider.v1beta1.RecycleItem - (*ArbitraryMetadata)(nil), // 77: cs3.storage.provider.v1beta1.ArbitraryMetadata - (*Lock)(nil), // 78: cs3.storage.provider.v1beta1.Lock - (*Quota)(nil), // 79: cs3.storage.provider.v1beta1.Quota + (*AddFavoriteRequest)(nil), // 64: cs3.storage.provider.v1beta1.AddFavoriteRequest + (*AddFavoriteResponse)(nil), // 65: cs3.storage.provider.v1beta1.AddFavoriteResponse + (*RemoveFavoriteRequest)(nil), // 66: cs3.storage.provider.v1beta1.RemoveFavoriteRequest + (*RemoveFavoriteResponse)(nil), // 67: cs3.storage.provider.v1beta1.RemoveFavoriteResponse + (*v1beta1.Opaque)(nil), // 68: cs3.types.v1beta1.Opaque + (*v1beta11.Status)(nil), // 69: cs3.rpc.v1beta1.Status + (*Reference)(nil), // 70: cs3.storage.provider.v1beta1.Reference + (*Grant)(nil), // 71: cs3.storage.provider.v1beta1.Grant + (*Grantee)(nil), // 72: cs3.storage.provider.v1beta1.Grantee + (*ResourceId)(nil), // 73: cs3.storage.provider.v1beta1.ResourceId + (*v1beta1.Timestamp)(nil), // 74: cs3.types.v1beta1.Timestamp + (*FileUploadProtocol)(nil), // 75: cs3.storage.provider.v1beta1.FileUploadProtocol + (*FileDownloadProtocol)(nil), // 76: cs3.storage.provider.v1beta1.FileDownloadProtocol + (*fieldmaskpb.FieldMask)(nil), // 77: google.protobuf.FieldMask + (*ResourceInfo)(nil), // 78: cs3.storage.provider.v1beta1.ResourceInfo + (*FileVersion)(nil), // 79: cs3.storage.provider.v1beta1.FileVersion + (*RecycleItem)(nil), // 80: cs3.storage.provider.v1beta1.RecycleItem + (*ArbitraryMetadata)(nil), // 81: cs3.storage.provider.v1beta1.ArbitraryMetadata + (*Lock)(nil), // 82: cs3.storage.provider.v1beta1.Lock + (*Quota)(nil), // 83: cs3.storage.provider.v1beta1.Quota + (*v1beta12.UserId)(nil), // 84: cs3.identity.user.v1beta1.UserId } var file_cs3_storage_provider_v1beta1_provider_api_proto_depIdxs = []int32{ - 64, // 0: cs3.storage.provider.v1beta1.GetHomeRequest.opaque:type_name -> cs3.types.v1beta1.Opaque - 65, // 1: cs3.storage.provider.v1beta1.GetHomeResponse.status:type_name -> cs3.rpc.v1beta1.Status - 64, // 2: cs3.storage.provider.v1beta1.GetHomeResponse.opaque:type_name -> cs3.types.v1beta1.Opaque - 64, // 3: cs3.storage.provider.v1beta1.AddGrantRequest.opaque:type_name -> cs3.types.v1beta1.Opaque - 66, // 4: cs3.storage.provider.v1beta1.AddGrantRequest.ref:type_name -> cs3.storage.provider.v1beta1.Reference - 67, // 5: cs3.storage.provider.v1beta1.AddGrantRequest.grant:type_name -> cs3.storage.provider.v1beta1.Grant - 65, // 6: cs3.storage.provider.v1beta1.AddGrantResponse.status:type_name -> cs3.rpc.v1beta1.Status - 64, // 7: cs3.storage.provider.v1beta1.AddGrantResponse.opaque:type_name -> cs3.types.v1beta1.Opaque - 64, // 8: cs3.storage.provider.v1beta1.DenyGrantRequest.opaque:type_name -> cs3.types.v1beta1.Opaque - 66, // 9: cs3.storage.provider.v1beta1.DenyGrantRequest.ref:type_name -> cs3.storage.provider.v1beta1.Reference - 68, // 10: cs3.storage.provider.v1beta1.DenyGrantRequest.grantee:type_name -> cs3.storage.provider.v1beta1.Grantee - 65, // 11: cs3.storage.provider.v1beta1.DenyGrantResponse.status:type_name -> cs3.rpc.v1beta1.Status - 64, // 12: cs3.storage.provider.v1beta1.DenyGrantResponse.opaque:type_name -> cs3.types.v1beta1.Opaque - 64, // 13: cs3.storage.provider.v1beta1.CreateContainerRequest.opaque:type_name -> cs3.types.v1beta1.Opaque - 66, // 14: cs3.storage.provider.v1beta1.CreateContainerRequest.ref:type_name -> cs3.storage.provider.v1beta1.Reference - 65, // 15: cs3.storage.provider.v1beta1.CreateContainerResponse.status:type_name -> cs3.rpc.v1beta1.Status - 64, // 16: cs3.storage.provider.v1beta1.CreateContainerResponse.opaque:type_name -> cs3.types.v1beta1.Opaque - 64, // 17: cs3.storage.provider.v1beta1.TouchFileRequest.opaque:type_name -> cs3.types.v1beta1.Opaque - 66, // 18: cs3.storage.provider.v1beta1.TouchFileRequest.ref:type_name -> cs3.storage.provider.v1beta1.Reference - 65, // 19: cs3.storage.provider.v1beta1.TouchFileResponse.status:type_name -> cs3.rpc.v1beta1.Status - 64, // 20: cs3.storage.provider.v1beta1.TouchFileResponse.opaque:type_name -> cs3.types.v1beta1.Opaque - 64, // 21: cs3.storage.provider.v1beta1.DeleteRequest.opaque:type_name -> cs3.types.v1beta1.Opaque - 66, // 22: cs3.storage.provider.v1beta1.DeleteRequest.ref:type_name -> cs3.storage.provider.v1beta1.Reference - 65, // 23: cs3.storage.provider.v1beta1.DeleteResponse.status:type_name -> cs3.rpc.v1beta1.Status - 64, // 24: cs3.storage.provider.v1beta1.DeleteResponse.opaque:type_name -> cs3.types.v1beta1.Opaque - 64, // 25: cs3.storage.provider.v1beta1.GetPathRequest.opaque:type_name -> cs3.types.v1beta1.Opaque - 69, // 26: cs3.storage.provider.v1beta1.GetPathRequest.resource_id:type_name -> cs3.storage.provider.v1beta1.ResourceId - 65, // 27: cs3.storage.provider.v1beta1.GetPathResponse.status:type_name -> cs3.rpc.v1beta1.Status - 64, // 28: cs3.storage.provider.v1beta1.GetPathResponse.opaque:type_name -> cs3.types.v1beta1.Opaque - 64, // 29: cs3.storage.provider.v1beta1.GetQuotaRequest.opaque:type_name -> cs3.types.v1beta1.Opaque - 66, // 30: cs3.storage.provider.v1beta1.GetQuotaRequest.ref:type_name -> cs3.storage.provider.v1beta1.Reference - 65, // 31: cs3.storage.provider.v1beta1.GetQuotaResponse.status:type_name -> cs3.rpc.v1beta1.Status - 64, // 32: cs3.storage.provider.v1beta1.GetQuotaResponse.opaque:type_name -> cs3.types.v1beta1.Opaque - 64, // 33: cs3.storage.provider.v1beta1.InitiateFileUploadRequest.opaque:type_name -> cs3.types.v1beta1.Opaque - 66, // 34: cs3.storage.provider.v1beta1.InitiateFileUploadRequest.ref:type_name -> cs3.storage.provider.v1beta1.Reference - 70, // 35: cs3.storage.provider.v1beta1.InitiateFileUploadRequest.if_unmodified_since:type_name -> cs3.types.v1beta1.Timestamp - 65, // 36: cs3.storage.provider.v1beta1.InitiateFileUploadResponse.status:type_name -> cs3.rpc.v1beta1.Status - 64, // 37: cs3.storage.provider.v1beta1.InitiateFileUploadResponse.opaque:type_name -> cs3.types.v1beta1.Opaque - 71, // 38: cs3.storage.provider.v1beta1.InitiateFileUploadResponse.protocols:type_name -> cs3.storage.provider.v1beta1.FileUploadProtocol - 64, // 39: cs3.storage.provider.v1beta1.InitiateFileDownloadRequest.opaque:type_name -> cs3.types.v1beta1.Opaque - 66, // 40: cs3.storage.provider.v1beta1.InitiateFileDownloadRequest.ref:type_name -> cs3.storage.provider.v1beta1.Reference - 65, // 41: cs3.storage.provider.v1beta1.InitiateFileDownloadResponse.status:type_name -> cs3.rpc.v1beta1.Status - 64, // 42: cs3.storage.provider.v1beta1.InitiateFileDownloadResponse.opaque:type_name -> cs3.types.v1beta1.Opaque - 72, // 43: cs3.storage.provider.v1beta1.InitiateFileDownloadResponse.protocols:type_name -> cs3.storage.provider.v1beta1.FileDownloadProtocol - 64, // 44: cs3.storage.provider.v1beta1.ListGrantsRequest.opaque:type_name -> cs3.types.v1beta1.Opaque - 66, // 45: cs3.storage.provider.v1beta1.ListGrantsRequest.ref:type_name -> cs3.storage.provider.v1beta1.Reference - 65, // 46: cs3.storage.provider.v1beta1.ListGrantsResponse.status:type_name -> cs3.rpc.v1beta1.Status - 64, // 47: cs3.storage.provider.v1beta1.ListGrantsResponse.opaque:type_name -> cs3.types.v1beta1.Opaque - 67, // 48: cs3.storage.provider.v1beta1.ListGrantsResponse.grants:type_name -> cs3.storage.provider.v1beta1.Grant - 64, // 49: cs3.storage.provider.v1beta1.ListContainerStreamRequest.opaque:type_name -> cs3.types.v1beta1.Opaque - 66, // 50: cs3.storage.provider.v1beta1.ListContainerStreamRequest.ref:type_name -> cs3.storage.provider.v1beta1.Reference - 73, // 51: cs3.storage.provider.v1beta1.ListContainerStreamRequest.field_mask:type_name -> google.protobuf.FieldMask - 65, // 52: cs3.storage.provider.v1beta1.ListContainerStreamResponse.status:type_name -> cs3.rpc.v1beta1.Status - 64, // 53: cs3.storage.provider.v1beta1.ListContainerStreamResponse.opaque:type_name -> cs3.types.v1beta1.Opaque - 74, // 54: cs3.storage.provider.v1beta1.ListContainerStreamResponse.info:type_name -> cs3.storage.provider.v1beta1.ResourceInfo - 64, // 55: cs3.storage.provider.v1beta1.ListContainerRequest.opaque:type_name -> cs3.types.v1beta1.Opaque - 66, // 56: cs3.storage.provider.v1beta1.ListContainerRequest.ref:type_name -> cs3.storage.provider.v1beta1.Reference - 73, // 57: cs3.storage.provider.v1beta1.ListContainerRequest.field_mask:type_name -> google.protobuf.FieldMask - 65, // 58: cs3.storage.provider.v1beta1.ListContainerResponse.status:type_name -> cs3.rpc.v1beta1.Status - 64, // 59: cs3.storage.provider.v1beta1.ListContainerResponse.opaque:type_name -> cs3.types.v1beta1.Opaque - 74, // 60: cs3.storage.provider.v1beta1.ListContainerResponse.infos:type_name -> cs3.storage.provider.v1beta1.ResourceInfo - 64, // 61: cs3.storage.provider.v1beta1.ListFileVersionsRequest.opaque:type_name -> cs3.types.v1beta1.Opaque - 66, // 62: cs3.storage.provider.v1beta1.ListFileVersionsRequest.ref:type_name -> cs3.storage.provider.v1beta1.Reference - 65, // 63: cs3.storage.provider.v1beta1.ListFileVersionsResponse.status:type_name -> cs3.rpc.v1beta1.Status - 64, // 64: cs3.storage.provider.v1beta1.ListFileVersionsResponse.opaque:type_name -> cs3.types.v1beta1.Opaque - 75, // 65: cs3.storage.provider.v1beta1.ListFileVersionsResponse.versions:type_name -> cs3.storage.provider.v1beta1.FileVersion - 64, // 66: cs3.storage.provider.v1beta1.ListRecycleRequest.opaque:type_name -> cs3.types.v1beta1.Opaque - 70, // 67: cs3.storage.provider.v1beta1.ListRecycleRequest.from_ts:type_name -> cs3.types.v1beta1.Timestamp - 70, // 68: cs3.storage.provider.v1beta1.ListRecycleRequest.to_ts:type_name -> cs3.types.v1beta1.Timestamp - 66, // 69: cs3.storage.provider.v1beta1.ListRecycleRequest.ref:type_name -> cs3.storage.provider.v1beta1.Reference - 65, // 70: cs3.storage.provider.v1beta1.ListRecycleResponse.status:type_name -> cs3.rpc.v1beta1.Status - 64, // 71: cs3.storage.provider.v1beta1.ListRecycleResponse.opaque:type_name -> cs3.types.v1beta1.Opaque - 76, // 72: cs3.storage.provider.v1beta1.ListRecycleResponse.recycle_items:type_name -> cs3.storage.provider.v1beta1.RecycleItem - 64, // 73: cs3.storage.provider.v1beta1.ListRecycleStreamRequest.opaque:type_name -> cs3.types.v1beta1.Opaque - 70, // 74: cs3.storage.provider.v1beta1.ListRecycleStreamRequest.from_ts:type_name -> cs3.types.v1beta1.Timestamp - 70, // 75: cs3.storage.provider.v1beta1.ListRecycleStreamRequest.to_ts:type_name -> cs3.types.v1beta1.Timestamp - 66, // 76: cs3.storage.provider.v1beta1.ListRecycleStreamRequest.ref:type_name -> cs3.storage.provider.v1beta1.Reference - 65, // 77: cs3.storage.provider.v1beta1.ListRecycleStreamResponse.status:type_name -> cs3.rpc.v1beta1.Status - 64, // 78: cs3.storage.provider.v1beta1.ListRecycleStreamResponse.opaque:type_name -> cs3.types.v1beta1.Opaque - 76, // 79: cs3.storage.provider.v1beta1.ListRecycleStreamResponse.recycle_item:type_name -> cs3.storage.provider.v1beta1.RecycleItem - 64, // 80: cs3.storage.provider.v1beta1.MoveRequest.opaque:type_name -> cs3.types.v1beta1.Opaque - 66, // 81: cs3.storage.provider.v1beta1.MoveRequest.source:type_name -> cs3.storage.provider.v1beta1.Reference - 66, // 82: cs3.storage.provider.v1beta1.MoveRequest.destination:type_name -> cs3.storage.provider.v1beta1.Reference - 65, // 83: cs3.storage.provider.v1beta1.MoveResponse.status:type_name -> cs3.rpc.v1beta1.Status - 64, // 84: cs3.storage.provider.v1beta1.MoveResponse.opaque:type_name -> cs3.types.v1beta1.Opaque - 64, // 85: cs3.storage.provider.v1beta1.PurgeRecycleRequest.opaque:type_name -> cs3.types.v1beta1.Opaque - 66, // 86: cs3.storage.provider.v1beta1.PurgeRecycleRequest.ref:type_name -> cs3.storage.provider.v1beta1.Reference - 65, // 87: cs3.storage.provider.v1beta1.PurgeRecycleResponse.status:type_name -> cs3.rpc.v1beta1.Status - 64, // 88: cs3.storage.provider.v1beta1.PurgeRecycleResponse.opaque:type_name -> cs3.types.v1beta1.Opaque - 64, // 89: cs3.storage.provider.v1beta1.RestoreFileVersionRequest.opaque:type_name -> cs3.types.v1beta1.Opaque - 66, // 90: cs3.storage.provider.v1beta1.RestoreFileVersionRequest.ref:type_name -> cs3.storage.provider.v1beta1.Reference - 65, // 91: cs3.storage.provider.v1beta1.RestoreFileVersionResponse.status:type_name -> cs3.rpc.v1beta1.Status - 64, // 92: cs3.storage.provider.v1beta1.RestoreFileVersionResponse.opaque:type_name -> cs3.types.v1beta1.Opaque - 64, // 93: cs3.storage.provider.v1beta1.RestoreRecycleItemRequest.opaque:type_name -> cs3.types.v1beta1.Opaque - 66, // 94: cs3.storage.provider.v1beta1.RestoreRecycleItemRequest.ref:type_name -> cs3.storage.provider.v1beta1.Reference - 66, // 95: cs3.storage.provider.v1beta1.RestoreRecycleItemRequest.restore_ref:type_name -> cs3.storage.provider.v1beta1.Reference - 65, // 96: cs3.storage.provider.v1beta1.RestoreRecycleItemResponse.status:type_name -> cs3.rpc.v1beta1.Status - 64, // 97: cs3.storage.provider.v1beta1.RestoreRecycleItemResponse.opaque:type_name -> cs3.types.v1beta1.Opaque - 64, // 98: cs3.storage.provider.v1beta1.RemoveGrantRequest.opaque:type_name -> cs3.types.v1beta1.Opaque - 66, // 99: cs3.storage.provider.v1beta1.RemoveGrantRequest.ref:type_name -> cs3.storage.provider.v1beta1.Reference - 67, // 100: cs3.storage.provider.v1beta1.RemoveGrantRequest.grant:type_name -> cs3.storage.provider.v1beta1.Grant - 65, // 101: cs3.storage.provider.v1beta1.RemoveGrantResponse.status:type_name -> cs3.rpc.v1beta1.Status - 64, // 102: cs3.storage.provider.v1beta1.RemoveGrantResponse.opaque:type_name -> cs3.types.v1beta1.Opaque - 64, // 103: cs3.storage.provider.v1beta1.StatRequest.opaque:type_name -> cs3.types.v1beta1.Opaque - 66, // 104: cs3.storage.provider.v1beta1.StatRequest.ref:type_name -> cs3.storage.provider.v1beta1.Reference - 73, // 105: cs3.storage.provider.v1beta1.StatRequest.field_mask:type_name -> google.protobuf.FieldMask - 65, // 106: cs3.storage.provider.v1beta1.StatResponse.status:type_name -> cs3.rpc.v1beta1.Status - 64, // 107: cs3.storage.provider.v1beta1.StatResponse.opaque:type_name -> cs3.types.v1beta1.Opaque - 74, // 108: cs3.storage.provider.v1beta1.StatResponse.info:type_name -> cs3.storage.provider.v1beta1.ResourceInfo - 64, // 109: cs3.storage.provider.v1beta1.UpdateGrantRequest.opaque:type_name -> cs3.types.v1beta1.Opaque - 66, // 110: cs3.storage.provider.v1beta1.UpdateGrantRequest.ref:type_name -> cs3.storage.provider.v1beta1.Reference - 67, // 111: cs3.storage.provider.v1beta1.UpdateGrantRequest.grant:type_name -> cs3.storage.provider.v1beta1.Grant - 65, // 112: cs3.storage.provider.v1beta1.UpdateGrantResponse.status:type_name -> cs3.rpc.v1beta1.Status - 64, // 113: cs3.storage.provider.v1beta1.UpdateGrantResponse.opaque:type_name -> cs3.types.v1beta1.Opaque - 64, // 114: cs3.storage.provider.v1beta1.CreateSymlinkRequest.opaque:type_name -> cs3.types.v1beta1.Opaque - 66, // 115: cs3.storage.provider.v1beta1.CreateSymlinkRequest.ref:type_name -> cs3.storage.provider.v1beta1.Reference - 65, // 116: cs3.storage.provider.v1beta1.CreateSymlinkResponse.status:type_name -> cs3.rpc.v1beta1.Status - 64, // 117: cs3.storage.provider.v1beta1.CreateSymlinkResponse.opaque:type_name -> cs3.types.v1beta1.Opaque - 64, // 118: cs3.storage.provider.v1beta1.CreateReferenceRequest.opaque:type_name -> cs3.types.v1beta1.Opaque - 66, // 119: cs3.storage.provider.v1beta1.CreateReferenceRequest.ref:type_name -> cs3.storage.provider.v1beta1.Reference - 65, // 120: cs3.storage.provider.v1beta1.CreateReferenceResponse.status:type_name -> cs3.rpc.v1beta1.Status - 64, // 121: cs3.storage.provider.v1beta1.CreateReferenceResponse.opaque:type_name -> cs3.types.v1beta1.Opaque - 64, // 122: cs3.storage.provider.v1beta1.SetArbitraryMetadataRequest.opaque:type_name -> cs3.types.v1beta1.Opaque - 66, // 123: cs3.storage.provider.v1beta1.SetArbitraryMetadataRequest.ref:type_name -> cs3.storage.provider.v1beta1.Reference - 77, // 124: cs3.storage.provider.v1beta1.SetArbitraryMetadataRequest.arbitrary_metadata:type_name -> cs3.storage.provider.v1beta1.ArbitraryMetadata - 65, // 125: cs3.storage.provider.v1beta1.SetArbitraryMetadataResponse.status:type_name -> cs3.rpc.v1beta1.Status - 64, // 126: cs3.storage.provider.v1beta1.SetArbitraryMetadataResponse.opaque:type_name -> cs3.types.v1beta1.Opaque - 64, // 127: cs3.storage.provider.v1beta1.UnsetArbitraryMetadataRequest.opaque:type_name -> cs3.types.v1beta1.Opaque - 66, // 128: cs3.storage.provider.v1beta1.UnsetArbitraryMetadataRequest.ref:type_name -> cs3.storage.provider.v1beta1.Reference - 65, // 129: cs3.storage.provider.v1beta1.UnsetArbitraryMetadataResponse.status:type_name -> cs3.rpc.v1beta1.Status - 64, // 130: cs3.storage.provider.v1beta1.UnsetArbitraryMetadataResponse.opaque:type_name -> cs3.types.v1beta1.Opaque - 64, // 131: cs3.storage.provider.v1beta1.SetLockRequest.opaque:type_name -> cs3.types.v1beta1.Opaque - 66, // 132: cs3.storage.provider.v1beta1.SetLockRequest.ref:type_name -> cs3.storage.provider.v1beta1.Reference - 78, // 133: cs3.storage.provider.v1beta1.SetLockRequest.lock:type_name -> cs3.storage.provider.v1beta1.Lock - 65, // 134: cs3.storage.provider.v1beta1.SetLockResponse.status:type_name -> cs3.rpc.v1beta1.Status - 64, // 135: cs3.storage.provider.v1beta1.SetLockResponse.opaque:type_name -> cs3.types.v1beta1.Opaque - 64, // 136: cs3.storage.provider.v1beta1.GetLockRequest.opaque:type_name -> cs3.types.v1beta1.Opaque - 66, // 137: cs3.storage.provider.v1beta1.GetLockRequest.ref:type_name -> cs3.storage.provider.v1beta1.Reference - 65, // 138: cs3.storage.provider.v1beta1.GetLockResponse.status:type_name -> cs3.rpc.v1beta1.Status - 64, // 139: cs3.storage.provider.v1beta1.GetLockResponse.opaque:type_name -> cs3.types.v1beta1.Opaque - 78, // 140: cs3.storage.provider.v1beta1.GetLockResponse.lock:type_name -> cs3.storage.provider.v1beta1.Lock - 64, // 141: cs3.storage.provider.v1beta1.RefreshLockRequest.opaque:type_name -> cs3.types.v1beta1.Opaque - 66, // 142: cs3.storage.provider.v1beta1.RefreshLockRequest.ref:type_name -> cs3.storage.provider.v1beta1.Reference - 78, // 143: cs3.storage.provider.v1beta1.RefreshLockRequest.lock:type_name -> cs3.storage.provider.v1beta1.Lock - 65, // 144: cs3.storage.provider.v1beta1.RefreshLockResponse.status:type_name -> cs3.rpc.v1beta1.Status - 64, // 145: cs3.storage.provider.v1beta1.RefreshLockResponse.opaque:type_name -> cs3.types.v1beta1.Opaque - 64, // 146: cs3.storage.provider.v1beta1.UnlockRequest.opaque:type_name -> cs3.types.v1beta1.Opaque - 66, // 147: cs3.storage.provider.v1beta1.UnlockRequest.ref:type_name -> cs3.storage.provider.v1beta1.Reference - 78, // 148: cs3.storage.provider.v1beta1.UnlockRequest.lock:type_name -> cs3.storage.provider.v1beta1.Lock - 65, // 149: cs3.storage.provider.v1beta1.UnlockResponse.status:type_name -> cs3.rpc.v1beta1.Status - 64, // 150: cs3.storage.provider.v1beta1.UnlockResponse.opaque:type_name -> cs3.types.v1beta1.Opaque - 64, // 151: cs3.storage.provider.v1beta1.CreateHomeRequest.opaque:type_name -> cs3.types.v1beta1.Opaque - 79, // 152: cs3.storage.provider.v1beta1.CreateHomeRequest.quota:type_name -> cs3.storage.provider.v1beta1.Quota - 65, // 153: cs3.storage.provider.v1beta1.CreateHomeResponse.status:type_name -> cs3.rpc.v1beta1.Status - 64, // 154: cs3.storage.provider.v1beta1.CreateHomeResponse.opaque:type_name -> cs3.types.v1beta1.Opaque - 2, // 155: cs3.storage.provider.v1beta1.ProviderAPI.AddGrant:input_type -> cs3.storage.provider.v1beta1.AddGrantRequest - 6, // 156: cs3.storage.provider.v1beta1.ProviderAPI.CreateContainer:input_type -> cs3.storage.provider.v1beta1.CreateContainerRequest - 8, // 157: cs3.storage.provider.v1beta1.ProviderAPI.TouchFile:input_type -> cs3.storage.provider.v1beta1.TouchFileRequest - 10, // 158: cs3.storage.provider.v1beta1.ProviderAPI.Delete:input_type -> cs3.storage.provider.v1beta1.DeleteRequest - 4, // 159: cs3.storage.provider.v1beta1.ProviderAPI.DenyGrant:input_type -> cs3.storage.provider.v1beta1.DenyGrantRequest - 12, // 160: cs3.storage.provider.v1beta1.ProviderAPI.GetPath:input_type -> cs3.storage.provider.v1beta1.GetPathRequest - 14, // 161: cs3.storage.provider.v1beta1.ProviderAPI.GetQuota:input_type -> cs3.storage.provider.v1beta1.GetQuotaRequest - 18, // 162: cs3.storage.provider.v1beta1.ProviderAPI.InitiateFileDownload:input_type -> cs3.storage.provider.v1beta1.InitiateFileDownloadRequest - 16, // 163: cs3.storage.provider.v1beta1.ProviderAPI.InitiateFileUpload:input_type -> cs3.storage.provider.v1beta1.InitiateFileUploadRequest - 20, // 164: cs3.storage.provider.v1beta1.ProviderAPI.ListGrants:input_type -> cs3.storage.provider.v1beta1.ListGrantsRequest - 22, // 165: cs3.storage.provider.v1beta1.ProviderAPI.ListContainerStream:input_type -> cs3.storage.provider.v1beta1.ListContainerStreamRequest - 24, // 166: cs3.storage.provider.v1beta1.ProviderAPI.ListContainer:input_type -> cs3.storage.provider.v1beta1.ListContainerRequest - 26, // 167: cs3.storage.provider.v1beta1.ProviderAPI.ListFileVersions:input_type -> cs3.storage.provider.v1beta1.ListFileVersionsRequest - 30, // 168: cs3.storage.provider.v1beta1.ProviderAPI.ListRecycleStream:input_type -> cs3.storage.provider.v1beta1.ListRecycleStreamRequest - 28, // 169: cs3.storage.provider.v1beta1.ProviderAPI.ListRecycle:input_type -> cs3.storage.provider.v1beta1.ListRecycleRequest - 32, // 170: cs3.storage.provider.v1beta1.ProviderAPI.Move:input_type -> cs3.storage.provider.v1beta1.MoveRequest - 40, // 171: cs3.storage.provider.v1beta1.ProviderAPI.RemoveGrant:input_type -> cs3.storage.provider.v1beta1.RemoveGrantRequest - 34, // 172: cs3.storage.provider.v1beta1.ProviderAPI.PurgeRecycle:input_type -> cs3.storage.provider.v1beta1.PurgeRecycleRequest - 36, // 173: cs3.storage.provider.v1beta1.ProviderAPI.RestoreFileVersion:input_type -> cs3.storage.provider.v1beta1.RestoreFileVersionRequest - 38, // 174: cs3.storage.provider.v1beta1.ProviderAPI.RestoreRecycleItem:input_type -> cs3.storage.provider.v1beta1.RestoreRecycleItemRequest - 42, // 175: cs3.storage.provider.v1beta1.ProviderAPI.Stat:input_type -> cs3.storage.provider.v1beta1.StatRequest - 44, // 176: cs3.storage.provider.v1beta1.ProviderAPI.UpdateGrant:input_type -> cs3.storage.provider.v1beta1.UpdateGrantRequest - 46, // 177: cs3.storage.provider.v1beta1.ProviderAPI.CreateSymlink:input_type -> cs3.storage.provider.v1beta1.CreateSymlinkRequest - 48, // 178: cs3.storage.provider.v1beta1.ProviderAPI.CreateReference:input_type -> cs3.storage.provider.v1beta1.CreateReferenceRequest - 50, // 179: cs3.storage.provider.v1beta1.ProviderAPI.SetArbitraryMetadata:input_type -> cs3.storage.provider.v1beta1.SetArbitraryMetadataRequest - 52, // 180: cs3.storage.provider.v1beta1.ProviderAPI.UnsetArbitraryMetadata:input_type -> cs3.storage.provider.v1beta1.UnsetArbitraryMetadataRequest - 54, // 181: cs3.storage.provider.v1beta1.ProviderAPI.SetLock:input_type -> cs3.storage.provider.v1beta1.SetLockRequest - 56, // 182: cs3.storage.provider.v1beta1.ProviderAPI.GetLock:input_type -> cs3.storage.provider.v1beta1.GetLockRequest - 58, // 183: cs3.storage.provider.v1beta1.ProviderAPI.RefreshLock:input_type -> cs3.storage.provider.v1beta1.RefreshLockRequest - 60, // 184: cs3.storage.provider.v1beta1.ProviderAPI.Unlock:input_type -> cs3.storage.provider.v1beta1.UnlockRequest - 62, // 185: cs3.storage.provider.v1beta1.ProviderAPI.CreateHome:input_type -> cs3.storage.provider.v1beta1.CreateHomeRequest - 0, // 186: cs3.storage.provider.v1beta1.ProviderAPI.GetHome:input_type -> cs3.storage.provider.v1beta1.GetHomeRequest - 3, // 187: cs3.storage.provider.v1beta1.ProviderAPI.AddGrant:output_type -> cs3.storage.provider.v1beta1.AddGrantResponse - 7, // 188: cs3.storage.provider.v1beta1.ProviderAPI.CreateContainer:output_type -> cs3.storage.provider.v1beta1.CreateContainerResponse - 9, // 189: cs3.storage.provider.v1beta1.ProviderAPI.TouchFile:output_type -> cs3.storage.provider.v1beta1.TouchFileResponse - 11, // 190: cs3.storage.provider.v1beta1.ProviderAPI.Delete:output_type -> cs3.storage.provider.v1beta1.DeleteResponse - 5, // 191: cs3.storage.provider.v1beta1.ProviderAPI.DenyGrant:output_type -> cs3.storage.provider.v1beta1.DenyGrantResponse - 13, // 192: cs3.storage.provider.v1beta1.ProviderAPI.GetPath:output_type -> cs3.storage.provider.v1beta1.GetPathResponse - 15, // 193: cs3.storage.provider.v1beta1.ProviderAPI.GetQuota:output_type -> cs3.storage.provider.v1beta1.GetQuotaResponse - 19, // 194: cs3.storage.provider.v1beta1.ProviderAPI.InitiateFileDownload:output_type -> cs3.storage.provider.v1beta1.InitiateFileDownloadResponse - 17, // 195: cs3.storage.provider.v1beta1.ProviderAPI.InitiateFileUpload:output_type -> cs3.storage.provider.v1beta1.InitiateFileUploadResponse - 21, // 196: cs3.storage.provider.v1beta1.ProviderAPI.ListGrants:output_type -> cs3.storage.provider.v1beta1.ListGrantsResponse - 23, // 197: cs3.storage.provider.v1beta1.ProviderAPI.ListContainerStream:output_type -> cs3.storage.provider.v1beta1.ListContainerStreamResponse - 25, // 198: cs3.storage.provider.v1beta1.ProviderAPI.ListContainer:output_type -> cs3.storage.provider.v1beta1.ListContainerResponse - 27, // 199: cs3.storage.provider.v1beta1.ProviderAPI.ListFileVersions:output_type -> cs3.storage.provider.v1beta1.ListFileVersionsResponse - 31, // 200: cs3.storage.provider.v1beta1.ProviderAPI.ListRecycleStream:output_type -> cs3.storage.provider.v1beta1.ListRecycleStreamResponse - 29, // 201: cs3.storage.provider.v1beta1.ProviderAPI.ListRecycle:output_type -> cs3.storage.provider.v1beta1.ListRecycleResponse - 33, // 202: cs3.storage.provider.v1beta1.ProviderAPI.Move:output_type -> cs3.storage.provider.v1beta1.MoveResponse - 41, // 203: cs3.storage.provider.v1beta1.ProviderAPI.RemoveGrant:output_type -> cs3.storage.provider.v1beta1.RemoveGrantResponse - 35, // 204: cs3.storage.provider.v1beta1.ProviderAPI.PurgeRecycle:output_type -> cs3.storage.provider.v1beta1.PurgeRecycleResponse - 37, // 205: cs3.storage.provider.v1beta1.ProviderAPI.RestoreFileVersion:output_type -> cs3.storage.provider.v1beta1.RestoreFileVersionResponse - 39, // 206: cs3.storage.provider.v1beta1.ProviderAPI.RestoreRecycleItem:output_type -> cs3.storage.provider.v1beta1.RestoreRecycleItemResponse - 43, // 207: cs3.storage.provider.v1beta1.ProviderAPI.Stat:output_type -> cs3.storage.provider.v1beta1.StatResponse - 45, // 208: cs3.storage.provider.v1beta1.ProviderAPI.UpdateGrant:output_type -> cs3.storage.provider.v1beta1.UpdateGrantResponse - 47, // 209: cs3.storage.provider.v1beta1.ProviderAPI.CreateSymlink:output_type -> cs3.storage.provider.v1beta1.CreateSymlinkResponse - 49, // 210: cs3.storage.provider.v1beta1.ProviderAPI.CreateReference:output_type -> cs3.storage.provider.v1beta1.CreateReferenceResponse - 51, // 211: cs3.storage.provider.v1beta1.ProviderAPI.SetArbitraryMetadata:output_type -> cs3.storage.provider.v1beta1.SetArbitraryMetadataResponse - 53, // 212: cs3.storage.provider.v1beta1.ProviderAPI.UnsetArbitraryMetadata:output_type -> cs3.storage.provider.v1beta1.UnsetArbitraryMetadataResponse - 55, // 213: cs3.storage.provider.v1beta1.ProviderAPI.SetLock:output_type -> cs3.storage.provider.v1beta1.SetLockResponse - 57, // 214: cs3.storage.provider.v1beta1.ProviderAPI.GetLock:output_type -> cs3.storage.provider.v1beta1.GetLockResponse - 59, // 215: cs3.storage.provider.v1beta1.ProviderAPI.RefreshLock:output_type -> cs3.storage.provider.v1beta1.RefreshLockResponse - 61, // 216: cs3.storage.provider.v1beta1.ProviderAPI.Unlock:output_type -> cs3.storage.provider.v1beta1.UnlockResponse - 63, // 217: cs3.storage.provider.v1beta1.ProviderAPI.CreateHome:output_type -> cs3.storage.provider.v1beta1.CreateHomeResponse - 1, // 218: cs3.storage.provider.v1beta1.ProviderAPI.GetHome:output_type -> cs3.storage.provider.v1beta1.GetHomeResponse - 187, // [187:219] is the sub-list for method output_type - 155, // [155:187] is the sub-list for method input_type - 155, // [155:155] is the sub-list for extension type_name - 155, // [155:155] is the sub-list for extension extendee - 0, // [0:155] is the sub-list for field type_name + 68, // 0: cs3.storage.provider.v1beta1.GetHomeRequest.opaque:type_name -> cs3.types.v1beta1.Opaque + 69, // 1: cs3.storage.provider.v1beta1.GetHomeResponse.status:type_name -> cs3.rpc.v1beta1.Status + 68, // 2: cs3.storage.provider.v1beta1.GetHomeResponse.opaque:type_name -> cs3.types.v1beta1.Opaque + 68, // 3: cs3.storage.provider.v1beta1.AddGrantRequest.opaque:type_name -> cs3.types.v1beta1.Opaque + 70, // 4: cs3.storage.provider.v1beta1.AddGrantRequest.ref:type_name -> cs3.storage.provider.v1beta1.Reference + 71, // 5: cs3.storage.provider.v1beta1.AddGrantRequest.grant:type_name -> cs3.storage.provider.v1beta1.Grant + 69, // 6: cs3.storage.provider.v1beta1.AddGrantResponse.status:type_name -> cs3.rpc.v1beta1.Status + 68, // 7: cs3.storage.provider.v1beta1.AddGrantResponse.opaque:type_name -> cs3.types.v1beta1.Opaque + 68, // 8: cs3.storage.provider.v1beta1.DenyGrantRequest.opaque:type_name -> cs3.types.v1beta1.Opaque + 70, // 9: cs3.storage.provider.v1beta1.DenyGrantRequest.ref:type_name -> cs3.storage.provider.v1beta1.Reference + 72, // 10: cs3.storage.provider.v1beta1.DenyGrantRequest.grantee:type_name -> cs3.storage.provider.v1beta1.Grantee + 69, // 11: cs3.storage.provider.v1beta1.DenyGrantResponse.status:type_name -> cs3.rpc.v1beta1.Status + 68, // 12: cs3.storage.provider.v1beta1.DenyGrantResponse.opaque:type_name -> cs3.types.v1beta1.Opaque + 68, // 13: cs3.storage.provider.v1beta1.CreateContainerRequest.opaque:type_name -> cs3.types.v1beta1.Opaque + 70, // 14: cs3.storage.provider.v1beta1.CreateContainerRequest.ref:type_name -> cs3.storage.provider.v1beta1.Reference + 69, // 15: cs3.storage.provider.v1beta1.CreateContainerResponse.status:type_name -> cs3.rpc.v1beta1.Status + 68, // 16: cs3.storage.provider.v1beta1.CreateContainerResponse.opaque:type_name -> cs3.types.v1beta1.Opaque + 68, // 17: cs3.storage.provider.v1beta1.TouchFileRequest.opaque:type_name -> cs3.types.v1beta1.Opaque + 70, // 18: cs3.storage.provider.v1beta1.TouchFileRequest.ref:type_name -> cs3.storage.provider.v1beta1.Reference + 69, // 19: cs3.storage.provider.v1beta1.TouchFileResponse.status:type_name -> cs3.rpc.v1beta1.Status + 68, // 20: cs3.storage.provider.v1beta1.TouchFileResponse.opaque:type_name -> cs3.types.v1beta1.Opaque + 68, // 21: cs3.storage.provider.v1beta1.DeleteRequest.opaque:type_name -> cs3.types.v1beta1.Opaque + 70, // 22: cs3.storage.provider.v1beta1.DeleteRequest.ref:type_name -> cs3.storage.provider.v1beta1.Reference + 69, // 23: cs3.storage.provider.v1beta1.DeleteResponse.status:type_name -> cs3.rpc.v1beta1.Status + 68, // 24: cs3.storage.provider.v1beta1.DeleteResponse.opaque:type_name -> cs3.types.v1beta1.Opaque + 68, // 25: cs3.storage.provider.v1beta1.GetPathRequest.opaque:type_name -> cs3.types.v1beta1.Opaque + 73, // 26: cs3.storage.provider.v1beta1.GetPathRequest.resource_id:type_name -> cs3.storage.provider.v1beta1.ResourceId + 69, // 27: cs3.storage.provider.v1beta1.GetPathResponse.status:type_name -> cs3.rpc.v1beta1.Status + 68, // 28: cs3.storage.provider.v1beta1.GetPathResponse.opaque:type_name -> cs3.types.v1beta1.Opaque + 68, // 29: cs3.storage.provider.v1beta1.GetQuotaRequest.opaque:type_name -> cs3.types.v1beta1.Opaque + 70, // 30: cs3.storage.provider.v1beta1.GetQuotaRequest.ref:type_name -> cs3.storage.provider.v1beta1.Reference + 69, // 31: cs3.storage.provider.v1beta1.GetQuotaResponse.status:type_name -> cs3.rpc.v1beta1.Status + 68, // 32: cs3.storage.provider.v1beta1.GetQuotaResponse.opaque:type_name -> cs3.types.v1beta1.Opaque + 68, // 33: cs3.storage.provider.v1beta1.InitiateFileUploadRequest.opaque:type_name -> cs3.types.v1beta1.Opaque + 70, // 34: cs3.storage.provider.v1beta1.InitiateFileUploadRequest.ref:type_name -> cs3.storage.provider.v1beta1.Reference + 74, // 35: cs3.storage.provider.v1beta1.InitiateFileUploadRequest.if_unmodified_since:type_name -> cs3.types.v1beta1.Timestamp + 69, // 36: cs3.storage.provider.v1beta1.InitiateFileUploadResponse.status:type_name -> cs3.rpc.v1beta1.Status + 68, // 37: cs3.storage.provider.v1beta1.InitiateFileUploadResponse.opaque:type_name -> cs3.types.v1beta1.Opaque + 75, // 38: cs3.storage.provider.v1beta1.InitiateFileUploadResponse.protocols:type_name -> cs3.storage.provider.v1beta1.FileUploadProtocol + 68, // 39: cs3.storage.provider.v1beta1.InitiateFileDownloadRequest.opaque:type_name -> cs3.types.v1beta1.Opaque + 70, // 40: cs3.storage.provider.v1beta1.InitiateFileDownloadRequest.ref:type_name -> cs3.storage.provider.v1beta1.Reference + 69, // 41: cs3.storage.provider.v1beta1.InitiateFileDownloadResponse.status:type_name -> cs3.rpc.v1beta1.Status + 68, // 42: cs3.storage.provider.v1beta1.InitiateFileDownloadResponse.opaque:type_name -> cs3.types.v1beta1.Opaque + 76, // 43: cs3.storage.provider.v1beta1.InitiateFileDownloadResponse.protocols:type_name -> cs3.storage.provider.v1beta1.FileDownloadProtocol + 68, // 44: cs3.storage.provider.v1beta1.ListGrantsRequest.opaque:type_name -> cs3.types.v1beta1.Opaque + 70, // 45: cs3.storage.provider.v1beta1.ListGrantsRequest.ref:type_name -> cs3.storage.provider.v1beta1.Reference + 69, // 46: cs3.storage.provider.v1beta1.ListGrantsResponse.status:type_name -> cs3.rpc.v1beta1.Status + 68, // 47: cs3.storage.provider.v1beta1.ListGrantsResponse.opaque:type_name -> cs3.types.v1beta1.Opaque + 71, // 48: cs3.storage.provider.v1beta1.ListGrantsResponse.grants:type_name -> cs3.storage.provider.v1beta1.Grant + 68, // 49: cs3.storage.provider.v1beta1.ListContainerStreamRequest.opaque:type_name -> cs3.types.v1beta1.Opaque + 70, // 50: cs3.storage.provider.v1beta1.ListContainerStreamRequest.ref:type_name -> cs3.storage.provider.v1beta1.Reference + 77, // 51: cs3.storage.provider.v1beta1.ListContainerStreamRequest.field_mask:type_name -> google.protobuf.FieldMask + 69, // 52: cs3.storage.provider.v1beta1.ListContainerStreamResponse.status:type_name -> cs3.rpc.v1beta1.Status + 68, // 53: cs3.storage.provider.v1beta1.ListContainerStreamResponse.opaque:type_name -> cs3.types.v1beta1.Opaque + 78, // 54: cs3.storage.provider.v1beta1.ListContainerStreamResponse.info:type_name -> cs3.storage.provider.v1beta1.ResourceInfo + 68, // 55: cs3.storage.provider.v1beta1.ListContainerRequest.opaque:type_name -> cs3.types.v1beta1.Opaque + 70, // 56: cs3.storage.provider.v1beta1.ListContainerRequest.ref:type_name -> cs3.storage.provider.v1beta1.Reference + 77, // 57: cs3.storage.provider.v1beta1.ListContainerRequest.field_mask:type_name -> google.protobuf.FieldMask + 69, // 58: cs3.storage.provider.v1beta1.ListContainerResponse.status:type_name -> cs3.rpc.v1beta1.Status + 68, // 59: cs3.storage.provider.v1beta1.ListContainerResponse.opaque:type_name -> cs3.types.v1beta1.Opaque + 78, // 60: cs3.storage.provider.v1beta1.ListContainerResponse.infos:type_name -> cs3.storage.provider.v1beta1.ResourceInfo + 68, // 61: cs3.storage.provider.v1beta1.ListFileVersionsRequest.opaque:type_name -> cs3.types.v1beta1.Opaque + 70, // 62: cs3.storage.provider.v1beta1.ListFileVersionsRequest.ref:type_name -> cs3.storage.provider.v1beta1.Reference + 69, // 63: cs3.storage.provider.v1beta1.ListFileVersionsResponse.status:type_name -> cs3.rpc.v1beta1.Status + 68, // 64: cs3.storage.provider.v1beta1.ListFileVersionsResponse.opaque:type_name -> cs3.types.v1beta1.Opaque + 79, // 65: cs3.storage.provider.v1beta1.ListFileVersionsResponse.versions:type_name -> cs3.storage.provider.v1beta1.FileVersion + 68, // 66: cs3.storage.provider.v1beta1.ListRecycleRequest.opaque:type_name -> cs3.types.v1beta1.Opaque + 74, // 67: cs3.storage.provider.v1beta1.ListRecycleRequest.from_ts:type_name -> cs3.types.v1beta1.Timestamp + 74, // 68: cs3.storage.provider.v1beta1.ListRecycleRequest.to_ts:type_name -> cs3.types.v1beta1.Timestamp + 70, // 69: cs3.storage.provider.v1beta1.ListRecycleRequest.ref:type_name -> cs3.storage.provider.v1beta1.Reference + 69, // 70: cs3.storage.provider.v1beta1.ListRecycleResponse.status:type_name -> cs3.rpc.v1beta1.Status + 68, // 71: cs3.storage.provider.v1beta1.ListRecycleResponse.opaque:type_name -> cs3.types.v1beta1.Opaque + 80, // 72: cs3.storage.provider.v1beta1.ListRecycleResponse.recycle_items:type_name -> cs3.storage.provider.v1beta1.RecycleItem + 68, // 73: cs3.storage.provider.v1beta1.ListRecycleStreamRequest.opaque:type_name -> cs3.types.v1beta1.Opaque + 74, // 74: cs3.storage.provider.v1beta1.ListRecycleStreamRequest.from_ts:type_name -> cs3.types.v1beta1.Timestamp + 74, // 75: cs3.storage.provider.v1beta1.ListRecycleStreamRequest.to_ts:type_name -> cs3.types.v1beta1.Timestamp + 70, // 76: cs3.storage.provider.v1beta1.ListRecycleStreamRequest.ref:type_name -> cs3.storage.provider.v1beta1.Reference + 69, // 77: cs3.storage.provider.v1beta1.ListRecycleStreamResponse.status:type_name -> cs3.rpc.v1beta1.Status + 68, // 78: cs3.storage.provider.v1beta1.ListRecycleStreamResponse.opaque:type_name -> cs3.types.v1beta1.Opaque + 80, // 79: cs3.storage.provider.v1beta1.ListRecycleStreamResponse.recycle_item:type_name -> cs3.storage.provider.v1beta1.RecycleItem + 68, // 80: cs3.storage.provider.v1beta1.MoveRequest.opaque:type_name -> cs3.types.v1beta1.Opaque + 70, // 81: cs3.storage.provider.v1beta1.MoveRequest.source:type_name -> cs3.storage.provider.v1beta1.Reference + 70, // 82: cs3.storage.provider.v1beta1.MoveRequest.destination:type_name -> cs3.storage.provider.v1beta1.Reference + 69, // 83: cs3.storage.provider.v1beta1.MoveResponse.status:type_name -> cs3.rpc.v1beta1.Status + 68, // 84: cs3.storage.provider.v1beta1.MoveResponse.opaque:type_name -> cs3.types.v1beta1.Opaque + 68, // 85: cs3.storage.provider.v1beta1.PurgeRecycleRequest.opaque:type_name -> cs3.types.v1beta1.Opaque + 70, // 86: cs3.storage.provider.v1beta1.PurgeRecycleRequest.ref:type_name -> cs3.storage.provider.v1beta1.Reference + 69, // 87: cs3.storage.provider.v1beta1.PurgeRecycleResponse.status:type_name -> cs3.rpc.v1beta1.Status + 68, // 88: cs3.storage.provider.v1beta1.PurgeRecycleResponse.opaque:type_name -> cs3.types.v1beta1.Opaque + 68, // 89: cs3.storage.provider.v1beta1.RestoreFileVersionRequest.opaque:type_name -> cs3.types.v1beta1.Opaque + 70, // 90: cs3.storage.provider.v1beta1.RestoreFileVersionRequest.ref:type_name -> cs3.storage.provider.v1beta1.Reference + 69, // 91: cs3.storage.provider.v1beta1.RestoreFileVersionResponse.status:type_name -> cs3.rpc.v1beta1.Status + 68, // 92: cs3.storage.provider.v1beta1.RestoreFileVersionResponse.opaque:type_name -> cs3.types.v1beta1.Opaque + 68, // 93: cs3.storage.provider.v1beta1.RestoreRecycleItemRequest.opaque:type_name -> cs3.types.v1beta1.Opaque + 70, // 94: cs3.storage.provider.v1beta1.RestoreRecycleItemRequest.ref:type_name -> cs3.storage.provider.v1beta1.Reference + 70, // 95: cs3.storage.provider.v1beta1.RestoreRecycleItemRequest.restore_ref:type_name -> cs3.storage.provider.v1beta1.Reference + 69, // 96: cs3.storage.provider.v1beta1.RestoreRecycleItemResponse.status:type_name -> cs3.rpc.v1beta1.Status + 68, // 97: cs3.storage.provider.v1beta1.RestoreRecycleItemResponse.opaque:type_name -> cs3.types.v1beta1.Opaque + 68, // 98: cs3.storage.provider.v1beta1.RemoveGrantRequest.opaque:type_name -> cs3.types.v1beta1.Opaque + 70, // 99: cs3.storage.provider.v1beta1.RemoveGrantRequest.ref:type_name -> cs3.storage.provider.v1beta1.Reference + 71, // 100: cs3.storage.provider.v1beta1.RemoveGrantRequest.grant:type_name -> cs3.storage.provider.v1beta1.Grant + 69, // 101: cs3.storage.provider.v1beta1.RemoveGrantResponse.status:type_name -> cs3.rpc.v1beta1.Status + 68, // 102: cs3.storage.provider.v1beta1.RemoveGrantResponse.opaque:type_name -> cs3.types.v1beta1.Opaque + 68, // 103: cs3.storage.provider.v1beta1.StatRequest.opaque:type_name -> cs3.types.v1beta1.Opaque + 70, // 104: cs3.storage.provider.v1beta1.StatRequest.ref:type_name -> cs3.storage.provider.v1beta1.Reference + 77, // 105: cs3.storage.provider.v1beta1.StatRequest.field_mask:type_name -> google.protobuf.FieldMask + 69, // 106: cs3.storage.provider.v1beta1.StatResponse.status:type_name -> cs3.rpc.v1beta1.Status + 68, // 107: cs3.storage.provider.v1beta1.StatResponse.opaque:type_name -> cs3.types.v1beta1.Opaque + 78, // 108: cs3.storage.provider.v1beta1.StatResponse.info:type_name -> cs3.storage.provider.v1beta1.ResourceInfo + 68, // 109: cs3.storage.provider.v1beta1.UpdateGrantRequest.opaque:type_name -> cs3.types.v1beta1.Opaque + 70, // 110: cs3.storage.provider.v1beta1.UpdateGrantRequest.ref:type_name -> cs3.storage.provider.v1beta1.Reference + 71, // 111: cs3.storage.provider.v1beta1.UpdateGrantRequest.grant:type_name -> cs3.storage.provider.v1beta1.Grant + 69, // 112: cs3.storage.provider.v1beta1.UpdateGrantResponse.status:type_name -> cs3.rpc.v1beta1.Status + 68, // 113: cs3.storage.provider.v1beta1.UpdateGrantResponse.opaque:type_name -> cs3.types.v1beta1.Opaque + 68, // 114: cs3.storage.provider.v1beta1.CreateSymlinkRequest.opaque:type_name -> cs3.types.v1beta1.Opaque + 70, // 115: cs3.storage.provider.v1beta1.CreateSymlinkRequest.ref:type_name -> cs3.storage.provider.v1beta1.Reference + 69, // 116: cs3.storage.provider.v1beta1.CreateSymlinkResponse.status:type_name -> cs3.rpc.v1beta1.Status + 68, // 117: cs3.storage.provider.v1beta1.CreateSymlinkResponse.opaque:type_name -> cs3.types.v1beta1.Opaque + 68, // 118: cs3.storage.provider.v1beta1.CreateReferenceRequest.opaque:type_name -> cs3.types.v1beta1.Opaque + 70, // 119: cs3.storage.provider.v1beta1.CreateReferenceRequest.ref:type_name -> cs3.storage.provider.v1beta1.Reference + 69, // 120: cs3.storage.provider.v1beta1.CreateReferenceResponse.status:type_name -> cs3.rpc.v1beta1.Status + 68, // 121: cs3.storage.provider.v1beta1.CreateReferenceResponse.opaque:type_name -> cs3.types.v1beta1.Opaque + 68, // 122: cs3.storage.provider.v1beta1.SetArbitraryMetadataRequest.opaque:type_name -> cs3.types.v1beta1.Opaque + 70, // 123: cs3.storage.provider.v1beta1.SetArbitraryMetadataRequest.ref:type_name -> cs3.storage.provider.v1beta1.Reference + 81, // 124: cs3.storage.provider.v1beta1.SetArbitraryMetadataRequest.arbitrary_metadata:type_name -> cs3.storage.provider.v1beta1.ArbitraryMetadata + 69, // 125: cs3.storage.provider.v1beta1.SetArbitraryMetadataResponse.status:type_name -> cs3.rpc.v1beta1.Status + 68, // 126: cs3.storage.provider.v1beta1.SetArbitraryMetadataResponse.opaque:type_name -> cs3.types.v1beta1.Opaque + 68, // 127: cs3.storage.provider.v1beta1.UnsetArbitraryMetadataRequest.opaque:type_name -> cs3.types.v1beta1.Opaque + 70, // 128: cs3.storage.provider.v1beta1.UnsetArbitraryMetadataRequest.ref:type_name -> cs3.storage.provider.v1beta1.Reference + 69, // 129: cs3.storage.provider.v1beta1.UnsetArbitraryMetadataResponse.status:type_name -> cs3.rpc.v1beta1.Status + 68, // 130: cs3.storage.provider.v1beta1.UnsetArbitraryMetadataResponse.opaque:type_name -> cs3.types.v1beta1.Opaque + 68, // 131: cs3.storage.provider.v1beta1.SetLockRequest.opaque:type_name -> cs3.types.v1beta1.Opaque + 70, // 132: cs3.storage.provider.v1beta1.SetLockRequest.ref:type_name -> cs3.storage.provider.v1beta1.Reference + 82, // 133: cs3.storage.provider.v1beta1.SetLockRequest.lock:type_name -> cs3.storage.provider.v1beta1.Lock + 69, // 134: cs3.storage.provider.v1beta1.SetLockResponse.status:type_name -> cs3.rpc.v1beta1.Status + 68, // 135: cs3.storage.provider.v1beta1.SetLockResponse.opaque:type_name -> cs3.types.v1beta1.Opaque + 68, // 136: cs3.storage.provider.v1beta1.GetLockRequest.opaque:type_name -> cs3.types.v1beta1.Opaque + 70, // 137: cs3.storage.provider.v1beta1.GetLockRequest.ref:type_name -> cs3.storage.provider.v1beta1.Reference + 69, // 138: cs3.storage.provider.v1beta1.GetLockResponse.status:type_name -> cs3.rpc.v1beta1.Status + 68, // 139: cs3.storage.provider.v1beta1.GetLockResponse.opaque:type_name -> cs3.types.v1beta1.Opaque + 82, // 140: cs3.storage.provider.v1beta1.GetLockResponse.lock:type_name -> cs3.storage.provider.v1beta1.Lock + 68, // 141: cs3.storage.provider.v1beta1.RefreshLockRequest.opaque:type_name -> cs3.types.v1beta1.Opaque + 70, // 142: cs3.storage.provider.v1beta1.RefreshLockRequest.ref:type_name -> cs3.storage.provider.v1beta1.Reference + 82, // 143: cs3.storage.provider.v1beta1.RefreshLockRequest.lock:type_name -> cs3.storage.provider.v1beta1.Lock + 69, // 144: cs3.storage.provider.v1beta1.RefreshLockResponse.status:type_name -> cs3.rpc.v1beta1.Status + 68, // 145: cs3.storage.provider.v1beta1.RefreshLockResponse.opaque:type_name -> cs3.types.v1beta1.Opaque + 68, // 146: cs3.storage.provider.v1beta1.UnlockRequest.opaque:type_name -> cs3.types.v1beta1.Opaque + 70, // 147: cs3.storage.provider.v1beta1.UnlockRequest.ref:type_name -> cs3.storage.provider.v1beta1.Reference + 82, // 148: cs3.storage.provider.v1beta1.UnlockRequest.lock:type_name -> cs3.storage.provider.v1beta1.Lock + 69, // 149: cs3.storage.provider.v1beta1.UnlockResponse.status:type_name -> cs3.rpc.v1beta1.Status + 68, // 150: cs3.storage.provider.v1beta1.UnlockResponse.opaque:type_name -> cs3.types.v1beta1.Opaque + 68, // 151: cs3.storage.provider.v1beta1.CreateHomeRequest.opaque:type_name -> cs3.types.v1beta1.Opaque + 83, // 152: cs3.storage.provider.v1beta1.CreateHomeRequest.quota:type_name -> cs3.storage.provider.v1beta1.Quota + 69, // 153: cs3.storage.provider.v1beta1.CreateHomeResponse.status:type_name -> cs3.rpc.v1beta1.Status + 68, // 154: cs3.storage.provider.v1beta1.CreateHomeResponse.opaque:type_name -> cs3.types.v1beta1.Opaque + 68, // 155: cs3.storage.provider.v1beta1.AddFavoriteRequest.opaque:type_name -> cs3.types.v1beta1.Opaque + 70, // 156: cs3.storage.provider.v1beta1.AddFavoriteRequest.ref:type_name -> cs3.storage.provider.v1beta1.Reference + 84, // 157: cs3.storage.provider.v1beta1.AddFavoriteRequest.user_id:type_name -> cs3.identity.user.v1beta1.UserId + 69, // 158: cs3.storage.provider.v1beta1.AddFavoriteResponse.status:type_name -> cs3.rpc.v1beta1.Status + 68, // 159: cs3.storage.provider.v1beta1.AddFavoriteResponse.opaque:type_name -> cs3.types.v1beta1.Opaque + 68, // 160: cs3.storage.provider.v1beta1.RemoveFavoriteRequest.opaque:type_name -> cs3.types.v1beta1.Opaque + 70, // 161: cs3.storage.provider.v1beta1.RemoveFavoriteRequest.ref:type_name -> cs3.storage.provider.v1beta1.Reference + 84, // 162: cs3.storage.provider.v1beta1.RemoveFavoriteRequest.user_id:type_name -> cs3.identity.user.v1beta1.UserId + 69, // 163: cs3.storage.provider.v1beta1.RemoveFavoriteResponse.status:type_name -> cs3.rpc.v1beta1.Status + 68, // 164: cs3.storage.provider.v1beta1.RemoveFavoriteResponse.opaque:type_name -> cs3.types.v1beta1.Opaque + 2, // 165: cs3.storage.provider.v1beta1.ProviderAPI.AddGrant:input_type -> cs3.storage.provider.v1beta1.AddGrantRequest + 6, // 166: cs3.storage.provider.v1beta1.ProviderAPI.CreateContainer:input_type -> cs3.storage.provider.v1beta1.CreateContainerRequest + 8, // 167: cs3.storage.provider.v1beta1.ProviderAPI.TouchFile:input_type -> cs3.storage.provider.v1beta1.TouchFileRequest + 10, // 168: cs3.storage.provider.v1beta1.ProviderAPI.Delete:input_type -> cs3.storage.provider.v1beta1.DeleteRequest + 4, // 169: cs3.storage.provider.v1beta1.ProviderAPI.DenyGrant:input_type -> cs3.storage.provider.v1beta1.DenyGrantRequest + 12, // 170: cs3.storage.provider.v1beta1.ProviderAPI.GetPath:input_type -> cs3.storage.provider.v1beta1.GetPathRequest + 14, // 171: cs3.storage.provider.v1beta1.ProviderAPI.GetQuota:input_type -> cs3.storage.provider.v1beta1.GetQuotaRequest + 18, // 172: cs3.storage.provider.v1beta1.ProviderAPI.InitiateFileDownload:input_type -> cs3.storage.provider.v1beta1.InitiateFileDownloadRequest + 16, // 173: cs3.storage.provider.v1beta1.ProviderAPI.InitiateFileUpload:input_type -> cs3.storage.provider.v1beta1.InitiateFileUploadRequest + 20, // 174: cs3.storage.provider.v1beta1.ProviderAPI.ListGrants:input_type -> cs3.storage.provider.v1beta1.ListGrantsRequest + 22, // 175: cs3.storage.provider.v1beta1.ProviderAPI.ListContainerStream:input_type -> cs3.storage.provider.v1beta1.ListContainerStreamRequest + 24, // 176: cs3.storage.provider.v1beta1.ProviderAPI.ListContainer:input_type -> cs3.storage.provider.v1beta1.ListContainerRequest + 26, // 177: cs3.storage.provider.v1beta1.ProviderAPI.ListFileVersions:input_type -> cs3.storage.provider.v1beta1.ListFileVersionsRequest + 30, // 178: cs3.storage.provider.v1beta1.ProviderAPI.ListRecycleStream:input_type -> cs3.storage.provider.v1beta1.ListRecycleStreamRequest + 28, // 179: cs3.storage.provider.v1beta1.ProviderAPI.ListRecycle:input_type -> cs3.storage.provider.v1beta1.ListRecycleRequest + 32, // 180: cs3.storage.provider.v1beta1.ProviderAPI.Move:input_type -> cs3.storage.provider.v1beta1.MoveRequest + 40, // 181: cs3.storage.provider.v1beta1.ProviderAPI.RemoveGrant:input_type -> cs3.storage.provider.v1beta1.RemoveGrantRequest + 34, // 182: cs3.storage.provider.v1beta1.ProviderAPI.PurgeRecycle:input_type -> cs3.storage.provider.v1beta1.PurgeRecycleRequest + 36, // 183: cs3.storage.provider.v1beta1.ProviderAPI.RestoreFileVersion:input_type -> cs3.storage.provider.v1beta1.RestoreFileVersionRequest + 38, // 184: cs3.storage.provider.v1beta1.ProviderAPI.RestoreRecycleItem:input_type -> cs3.storage.provider.v1beta1.RestoreRecycleItemRequest + 42, // 185: cs3.storage.provider.v1beta1.ProviderAPI.Stat:input_type -> cs3.storage.provider.v1beta1.StatRequest + 44, // 186: cs3.storage.provider.v1beta1.ProviderAPI.UpdateGrant:input_type -> cs3.storage.provider.v1beta1.UpdateGrantRequest + 46, // 187: cs3.storage.provider.v1beta1.ProviderAPI.CreateSymlink:input_type -> cs3.storage.provider.v1beta1.CreateSymlinkRequest + 48, // 188: cs3.storage.provider.v1beta1.ProviderAPI.CreateReference:input_type -> cs3.storage.provider.v1beta1.CreateReferenceRequest + 50, // 189: cs3.storage.provider.v1beta1.ProviderAPI.SetArbitraryMetadata:input_type -> cs3.storage.provider.v1beta1.SetArbitraryMetadataRequest + 52, // 190: cs3.storage.provider.v1beta1.ProviderAPI.UnsetArbitraryMetadata:input_type -> cs3.storage.provider.v1beta1.UnsetArbitraryMetadataRequest + 54, // 191: cs3.storage.provider.v1beta1.ProviderAPI.SetLock:input_type -> cs3.storage.provider.v1beta1.SetLockRequest + 56, // 192: cs3.storage.provider.v1beta1.ProviderAPI.GetLock:input_type -> cs3.storage.provider.v1beta1.GetLockRequest + 58, // 193: cs3.storage.provider.v1beta1.ProviderAPI.RefreshLock:input_type -> cs3.storage.provider.v1beta1.RefreshLockRequest + 60, // 194: cs3.storage.provider.v1beta1.ProviderAPI.Unlock:input_type -> cs3.storage.provider.v1beta1.UnlockRequest + 62, // 195: cs3.storage.provider.v1beta1.ProviderAPI.CreateHome:input_type -> cs3.storage.provider.v1beta1.CreateHomeRequest + 0, // 196: cs3.storage.provider.v1beta1.ProviderAPI.GetHome:input_type -> cs3.storage.provider.v1beta1.GetHomeRequest + 64, // 197: cs3.storage.provider.v1beta1.ProviderAPI.AddFavorite:input_type -> cs3.storage.provider.v1beta1.AddFavoriteRequest + 66, // 198: cs3.storage.provider.v1beta1.ProviderAPI.RemoveFavorite:input_type -> cs3.storage.provider.v1beta1.RemoveFavoriteRequest + 3, // 199: cs3.storage.provider.v1beta1.ProviderAPI.AddGrant:output_type -> cs3.storage.provider.v1beta1.AddGrantResponse + 7, // 200: cs3.storage.provider.v1beta1.ProviderAPI.CreateContainer:output_type -> cs3.storage.provider.v1beta1.CreateContainerResponse + 9, // 201: cs3.storage.provider.v1beta1.ProviderAPI.TouchFile:output_type -> cs3.storage.provider.v1beta1.TouchFileResponse + 11, // 202: cs3.storage.provider.v1beta1.ProviderAPI.Delete:output_type -> cs3.storage.provider.v1beta1.DeleteResponse + 5, // 203: cs3.storage.provider.v1beta1.ProviderAPI.DenyGrant:output_type -> cs3.storage.provider.v1beta1.DenyGrantResponse + 13, // 204: cs3.storage.provider.v1beta1.ProviderAPI.GetPath:output_type -> cs3.storage.provider.v1beta1.GetPathResponse + 15, // 205: cs3.storage.provider.v1beta1.ProviderAPI.GetQuota:output_type -> cs3.storage.provider.v1beta1.GetQuotaResponse + 19, // 206: cs3.storage.provider.v1beta1.ProviderAPI.InitiateFileDownload:output_type -> cs3.storage.provider.v1beta1.InitiateFileDownloadResponse + 17, // 207: cs3.storage.provider.v1beta1.ProviderAPI.InitiateFileUpload:output_type -> cs3.storage.provider.v1beta1.InitiateFileUploadResponse + 21, // 208: cs3.storage.provider.v1beta1.ProviderAPI.ListGrants:output_type -> cs3.storage.provider.v1beta1.ListGrantsResponse + 23, // 209: cs3.storage.provider.v1beta1.ProviderAPI.ListContainerStream:output_type -> cs3.storage.provider.v1beta1.ListContainerStreamResponse + 25, // 210: cs3.storage.provider.v1beta1.ProviderAPI.ListContainer:output_type -> cs3.storage.provider.v1beta1.ListContainerResponse + 27, // 211: cs3.storage.provider.v1beta1.ProviderAPI.ListFileVersions:output_type -> cs3.storage.provider.v1beta1.ListFileVersionsResponse + 31, // 212: cs3.storage.provider.v1beta1.ProviderAPI.ListRecycleStream:output_type -> cs3.storage.provider.v1beta1.ListRecycleStreamResponse + 29, // 213: cs3.storage.provider.v1beta1.ProviderAPI.ListRecycle:output_type -> cs3.storage.provider.v1beta1.ListRecycleResponse + 33, // 214: cs3.storage.provider.v1beta1.ProviderAPI.Move:output_type -> cs3.storage.provider.v1beta1.MoveResponse + 41, // 215: cs3.storage.provider.v1beta1.ProviderAPI.RemoveGrant:output_type -> cs3.storage.provider.v1beta1.RemoveGrantResponse + 35, // 216: cs3.storage.provider.v1beta1.ProviderAPI.PurgeRecycle:output_type -> cs3.storage.provider.v1beta1.PurgeRecycleResponse + 37, // 217: cs3.storage.provider.v1beta1.ProviderAPI.RestoreFileVersion:output_type -> cs3.storage.provider.v1beta1.RestoreFileVersionResponse + 39, // 218: cs3.storage.provider.v1beta1.ProviderAPI.RestoreRecycleItem:output_type -> cs3.storage.provider.v1beta1.RestoreRecycleItemResponse + 43, // 219: cs3.storage.provider.v1beta1.ProviderAPI.Stat:output_type -> cs3.storage.provider.v1beta1.StatResponse + 45, // 220: cs3.storage.provider.v1beta1.ProviderAPI.UpdateGrant:output_type -> cs3.storage.provider.v1beta1.UpdateGrantResponse + 47, // 221: cs3.storage.provider.v1beta1.ProviderAPI.CreateSymlink:output_type -> cs3.storage.provider.v1beta1.CreateSymlinkResponse + 49, // 222: cs3.storage.provider.v1beta1.ProviderAPI.CreateReference:output_type -> cs3.storage.provider.v1beta1.CreateReferenceResponse + 51, // 223: cs3.storage.provider.v1beta1.ProviderAPI.SetArbitraryMetadata:output_type -> cs3.storage.provider.v1beta1.SetArbitraryMetadataResponse + 53, // 224: cs3.storage.provider.v1beta1.ProviderAPI.UnsetArbitraryMetadata:output_type -> cs3.storage.provider.v1beta1.UnsetArbitraryMetadataResponse + 55, // 225: cs3.storage.provider.v1beta1.ProviderAPI.SetLock:output_type -> cs3.storage.provider.v1beta1.SetLockResponse + 57, // 226: cs3.storage.provider.v1beta1.ProviderAPI.GetLock:output_type -> cs3.storage.provider.v1beta1.GetLockResponse + 59, // 227: cs3.storage.provider.v1beta1.ProviderAPI.RefreshLock:output_type -> cs3.storage.provider.v1beta1.RefreshLockResponse + 61, // 228: cs3.storage.provider.v1beta1.ProviderAPI.Unlock:output_type -> cs3.storage.provider.v1beta1.UnlockResponse + 63, // 229: cs3.storage.provider.v1beta1.ProviderAPI.CreateHome:output_type -> cs3.storage.provider.v1beta1.CreateHomeResponse + 1, // 230: cs3.storage.provider.v1beta1.ProviderAPI.GetHome:output_type -> cs3.storage.provider.v1beta1.GetHomeResponse + 65, // 231: cs3.storage.provider.v1beta1.ProviderAPI.AddFavorite:output_type -> cs3.storage.provider.v1beta1.AddFavoriteResponse + 67, // 232: cs3.storage.provider.v1beta1.ProviderAPI.RemoveFavorite:output_type -> cs3.storage.provider.v1beta1.RemoveFavoriteResponse + 199, // [199:233] is the sub-list for method output_type + 165, // [165:199] is the sub-list for method input_type + 165, // [165:165] is the sub-list for extension type_name + 165, // [165:165] is the sub-list for extension extendee + 0, // [0:165] is the sub-list for field type_name } func init() { file_cs3_storage_provider_v1beta1_provider_api_proto_init() } @@ -6799,6 +7129,54 @@ func file_cs3_storage_provider_v1beta1_provider_api_proto_init() { return nil } } + file_cs3_storage_provider_v1beta1_provider_api_proto_msgTypes[64].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*AddFavoriteRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_cs3_storage_provider_v1beta1_provider_api_proto_msgTypes[65].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*AddFavoriteResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_cs3_storage_provider_v1beta1_provider_api_proto_msgTypes[66].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*RemoveFavoriteRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_cs3_storage_provider_v1beta1_provider_api_proto_msgTypes[67].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*RemoveFavoriteResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } } file_cs3_storage_provider_v1beta1_provider_api_proto_msgTypes[16].OneofWrappers = []interface{}{ (*InitiateFileUploadRequest_IfNotExist)(nil), @@ -6811,7 +7189,7 @@ func file_cs3_storage_provider_v1beta1_provider_api_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_cs3_storage_provider_v1beta1_provider_api_proto_rawDesc, NumEnums: 0, - NumMessages: 64, + NumMessages: 68, NumExtensions: 0, NumServices: 1, }, diff --git a/vendor/github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1/provider_api_grpc.pb.go b/vendor/github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1/provider_api_grpc.pb.go index 55b399f8a2..1df73c58df 100644 --- a/vendor/github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1/provider_api_grpc.pb.go +++ b/vendor/github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1/provider_api_grpc.pb.go @@ -69,6 +69,8 @@ const ( ProviderAPI_Unlock_FullMethodName = "/cs3.storage.provider.v1beta1.ProviderAPI/Unlock" ProviderAPI_CreateHome_FullMethodName = "/cs3.storage.provider.v1beta1.ProviderAPI/CreateHome" ProviderAPI_GetHome_FullMethodName = "/cs3.storage.provider.v1beta1.ProviderAPI/GetHome" + ProviderAPI_AddFavorite_FullMethodName = "/cs3.storage.provider.v1beta1.ProviderAPI/AddFavorite" + ProviderAPI_RemoveFavorite_FullMethodName = "/cs3.storage.provider.v1beta1.ProviderAPI/RemoveFavorite" ) // ProviderAPIClient is the client API for ProviderAPI service. @@ -204,6 +206,10 @@ type ProviderAPIClient interface { CreateHome(ctx context.Context, in *CreateHomeRequest, opts ...grpc.CallOption) (*CreateHomeResponse, error) // Gets the home path for the user. GetHome(ctx context.Context, in *GetHomeRequest, opts ...grpc.CallOption) (*GetHomeResponse, error) + // Marks a resource as favorite for a user. + AddFavorite(ctx context.Context, in *AddFavoriteRequest, opts ...grpc.CallOption) (*AddFavoriteResponse, error) + // Unmarks a resource as favorite for a user. + RemoveFavorite(ctx context.Context, in *RemoveFavoriteRequest, opts ...grpc.CallOption) (*RemoveFavoriteResponse, error) } type providerAPIClient struct { @@ -548,6 +554,24 @@ func (c *providerAPIClient) GetHome(ctx context.Context, in *GetHomeRequest, opt return out, nil } +func (c *providerAPIClient) AddFavorite(ctx context.Context, in *AddFavoriteRequest, opts ...grpc.CallOption) (*AddFavoriteResponse, error) { + out := new(AddFavoriteResponse) + err := c.cc.Invoke(ctx, ProviderAPI_AddFavorite_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *providerAPIClient) RemoveFavorite(ctx context.Context, in *RemoveFavoriteRequest, opts ...grpc.CallOption) (*RemoveFavoriteResponse, error) { + out := new(RemoveFavoriteResponse) + err := c.cc.Invoke(ctx, ProviderAPI_RemoveFavorite_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + // ProviderAPIServer is the server API for ProviderAPI service. // All implementations should embed UnimplementedProviderAPIServer // for forward compatibility @@ -681,6 +705,10 @@ type ProviderAPIServer interface { CreateHome(context.Context, *CreateHomeRequest) (*CreateHomeResponse, error) // Gets the home path for the user. GetHome(context.Context, *GetHomeRequest) (*GetHomeResponse, error) + // Marks a resource as favorite for a user. + AddFavorite(context.Context, *AddFavoriteRequest) (*AddFavoriteResponse, error) + // Unmarks a resource as favorite for a user. + RemoveFavorite(context.Context, *RemoveFavoriteRequest) (*RemoveFavoriteResponse, error) } // UnimplementedProviderAPIServer should be embedded to have forward compatible implementations. @@ -783,6 +811,12 @@ func (UnimplementedProviderAPIServer) CreateHome(context.Context, *CreateHomeReq func (UnimplementedProviderAPIServer) GetHome(context.Context, *GetHomeRequest) (*GetHomeResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method GetHome not implemented") } +func (UnimplementedProviderAPIServer) AddFavorite(context.Context, *AddFavoriteRequest) (*AddFavoriteResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method AddFavorite not implemented") +} +func (UnimplementedProviderAPIServer) RemoveFavorite(context.Context, *RemoveFavoriteRequest) (*RemoveFavoriteResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method RemoveFavorite not implemented") +} // UnsafeProviderAPIServer may be embedded to opt out of forward compatibility for this service. // Use of this interface is not recommended, as added methods to ProviderAPIServer will @@ -1377,6 +1411,42 @@ func _ProviderAPI_GetHome_Handler(srv interface{}, ctx context.Context, dec func return interceptor(ctx, in, info, handler) } +func _ProviderAPI_AddFavorite_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(AddFavoriteRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ProviderAPIServer).AddFavorite(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: ProviderAPI_AddFavorite_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ProviderAPIServer).AddFavorite(ctx, req.(*AddFavoriteRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _ProviderAPI_RemoveFavorite_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(RemoveFavoriteRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ProviderAPIServer).RemoveFavorite(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: ProviderAPI_RemoveFavorite_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ProviderAPIServer).RemoveFavorite(ctx, req.(*RemoveFavoriteRequest)) + } + return interceptor(ctx, in, info, handler) +} + // ProviderAPI_ServiceDesc is the grpc.ServiceDesc for ProviderAPI service. // It's only intended for direct use with grpc.RegisterService, // and not to be introspected or modified (even as a copy) @@ -1504,6 +1574,14 @@ var ProviderAPI_ServiceDesc = grpc.ServiceDesc{ MethodName: "GetHome", Handler: _ProviderAPI_GetHome_Handler, }, + { + MethodName: "AddFavorite", + Handler: _ProviderAPI_AddFavorite_Handler, + }, + { + MethodName: "RemoveFavorite", + Handler: _ProviderAPI_RemoveFavorite_Handler, + }, }, Streams: []grpc.StreamDesc{ { diff --git a/vendor/github.com/gomodule/redigo/LICENSE b/vendor/github.com/gomodule/redigo/LICENSE deleted file mode 100644 index f433b1a53f..0000000000 --- a/vendor/github.com/gomodule/redigo/LICENSE +++ /dev/null @@ -1,177 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS diff --git a/vendor/github.com/gomodule/redigo/redis/commandinfo.go b/vendor/github.com/gomodule/redigo/redis/commandinfo.go deleted file mode 100644 index b6df6a25aa..0000000000 --- a/vendor/github.com/gomodule/redigo/redis/commandinfo.go +++ /dev/null @@ -1,55 +0,0 @@ -// Copyright 2014 Gary Burd -// -// 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. - -package redis - -import ( - "strings" -) - -const ( - connectionWatchState = 1 << iota - connectionMultiState - connectionSubscribeState - connectionMonitorState -) - -type commandInfo struct { - // Set or Clear these states on connection. - Set, Clear int -} - -var commandInfos = map[string]commandInfo{ - "WATCH": {Set: connectionWatchState}, - "UNWATCH": {Clear: connectionWatchState}, - "MULTI": {Set: connectionMultiState}, - "EXEC": {Clear: connectionWatchState | connectionMultiState}, - "DISCARD": {Clear: connectionWatchState | connectionMultiState}, - "PSUBSCRIBE": {Set: connectionSubscribeState}, - "SUBSCRIBE": {Set: connectionSubscribeState}, - "MONITOR": {Set: connectionMonitorState}, -} - -func init() { - for n, ci := range commandInfos { - commandInfos[strings.ToLower(n)] = ci - } -} - -func lookupCommandInfo(commandName string) commandInfo { - if ci, ok := commandInfos[commandName]; ok { - return ci - } - return commandInfos[strings.ToUpper(commandName)] -} diff --git a/vendor/github.com/gomodule/redigo/redis/conn.go b/vendor/github.com/gomodule/redigo/redis/conn.go deleted file mode 100644 index dc445a0669..0000000000 --- a/vendor/github.com/gomodule/redigo/redis/conn.go +++ /dev/null @@ -1,868 +0,0 @@ -// Copyright 2012 Gary Burd -// -// 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. - -package redis - -import ( - "bufio" - "bytes" - "context" - "crypto/tls" - "errors" - "fmt" - "io" - "net" - "net/url" - "regexp" - "strconv" - "sync" - "time" -) - -var ( - _ ConnWithTimeout = (*conn)(nil) -) - -// conn is the low-level implementation of Conn -type conn struct { - // Shared - mu sync.Mutex - pending int - err error - conn net.Conn - - // Read - readTimeout time.Duration - br *bufio.Reader - - // Write - writeTimeout time.Duration - bw *bufio.Writer - - // Scratch space for formatting argument length. - // '*' or '$', length, "\r\n" - lenScratch [32]byte - - // Scratch space for formatting integers and floats. - numScratch [40]byte -} - -// DialTimeout acts like Dial but takes timeouts for establishing the -// connection to the server, writing a command and reading a reply. -// -// Deprecated: Use Dial with options instead. -func DialTimeout(network, address string, connectTimeout, readTimeout, writeTimeout time.Duration) (Conn, error) { - return Dial(network, address, - DialConnectTimeout(connectTimeout), - DialReadTimeout(readTimeout), - DialWriteTimeout(writeTimeout)) -} - -// DialOption specifies an option for dialing a Redis server. -type DialOption struct { - f func(*dialOptions) -} - -type dialOptions struct { - readTimeout time.Duration - writeTimeout time.Duration - tlsHandshakeTimeout time.Duration - dialer *net.Dialer - dialContext func(ctx context.Context, network, addr string) (net.Conn, error) - db int - username string - password string - clientName string - useTLS bool - skipVerify bool - tlsConfig *tls.Config -} - -// DialTLSHandshakeTimeout specifies the maximum amount of time waiting to -// wait for a TLS handshake. Zero means no timeout. -// If no DialTLSHandshakeTimeout option is specified then the default is 30 seconds. -func DialTLSHandshakeTimeout(d time.Duration) DialOption { - return DialOption{func(do *dialOptions) { - do.tlsHandshakeTimeout = d - }} -} - -// DialReadTimeout specifies the timeout for reading a single command reply. -func DialReadTimeout(d time.Duration) DialOption { - return DialOption{func(do *dialOptions) { - do.readTimeout = d - }} -} - -// DialWriteTimeout specifies the timeout for writing a single command. -func DialWriteTimeout(d time.Duration) DialOption { - return DialOption{func(do *dialOptions) { - do.writeTimeout = d - }} -} - -// DialConnectTimeout specifies the timeout for connecting to the Redis server when -// no DialNetDial option is specified. -// If no DialConnectTimeout option is specified then the default is 30 seconds. -func DialConnectTimeout(d time.Duration) DialOption { - return DialOption{func(do *dialOptions) { - do.dialer.Timeout = d - }} -} - -// DialKeepAlive specifies the keep-alive period for TCP connections to the Redis server -// when no DialNetDial option is specified. -// If zero, keep-alives are not enabled. If no DialKeepAlive option is specified then -// the default of 5 minutes is used to ensure that half-closed TCP sessions are detected. -func DialKeepAlive(d time.Duration) DialOption { - return DialOption{func(do *dialOptions) { - do.dialer.KeepAlive = d - }} -} - -// DialNetDial specifies a custom dial function for creating TCP -// connections, otherwise a net.Dialer customized via the other options is used. -// DialNetDial overrides DialConnectTimeout and DialKeepAlive. -func DialNetDial(dial func(network, addr string) (net.Conn, error)) DialOption { - return DialOption{func(do *dialOptions) { - do.dialContext = func(ctx context.Context, network, addr string) (net.Conn, error) { - return dial(network, addr) - } - }} -} - -// DialContextFunc specifies a custom dial function with context for creating TCP -// connections, otherwise a net.Dialer customized via the other options is used. -// DialContextFunc overrides DialConnectTimeout and DialKeepAlive. -func DialContextFunc(f func(ctx context.Context, network, addr string) (net.Conn, error)) DialOption { - return DialOption{func(do *dialOptions) { - do.dialContext = f - }} -} - -// DialDatabase specifies the database to select when dialing a connection. -func DialDatabase(db int) DialOption { - return DialOption{func(do *dialOptions) { - do.db = db - }} -} - -// DialPassword specifies the password to use when connecting to -// the Redis server. -func DialPassword(password string) DialOption { - return DialOption{func(do *dialOptions) { - do.password = password - }} -} - -// DialUsername specifies the username to use when connecting to -// the Redis server when Redis ACLs are used. -// A DialPassword must also be passed otherwise this option will have no effect. -func DialUsername(username string) DialOption { - return DialOption{func(do *dialOptions) { - do.username = username - }} -} - -// DialClientName specifies a client name to be used -// by the Redis server connection. -func DialClientName(name string) DialOption { - return DialOption{func(do *dialOptions) { - do.clientName = name - }} -} - -// DialTLSConfig specifies the config to use when a TLS connection is dialed. -// Has no effect when not dialing a TLS connection. -func DialTLSConfig(c *tls.Config) DialOption { - return DialOption{func(do *dialOptions) { - do.tlsConfig = c - }} -} - -// DialTLSSkipVerify disables server name verification when connecting over -// TLS. Has no effect when not dialing a TLS connection. -func DialTLSSkipVerify(skip bool) DialOption { - return DialOption{func(do *dialOptions) { - do.skipVerify = skip - }} -} - -// DialUseTLS specifies whether TLS should be used when connecting to the -// server. This option is ignore by DialURL. -func DialUseTLS(useTLS bool) DialOption { - return DialOption{func(do *dialOptions) { - do.useTLS = useTLS - }} -} - -// Dial connects to the Redis server at the given network and -// address using the specified options. -func Dial(network, address string, options ...DialOption) (Conn, error) { - return DialContext(context.Background(), network, address, options...) -} - -type tlsHandshakeTimeoutError struct{} - -func (tlsHandshakeTimeoutError) Timeout() bool { return true } -func (tlsHandshakeTimeoutError) Temporary() bool { return true } -func (tlsHandshakeTimeoutError) Error() string { return "TLS handshake timeout" } - -// DialContext connects to the Redis server at the given network and -// address using the specified options and context. -func DialContext(ctx context.Context, network, address string, options ...DialOption) (Conn, error) { - do := dialOptions{ - dialer: &net.Dialer{ - Timeout: time.Second * 30, - KeepAlive: time.Minute * 5, - }, - tlsHandshakeTimeout: time.Second * 10, - } - for _, option := range options { - option.f(&do) - } - if do.dialContext == nil { - do.dialContext = do.dialer.DialContext - } - - netConn, err := do.dialContext(ctx, network, address) - if err != nil { - return nil, err - } - - if do.useTLS { - var tlsConfig *tls.Config - if do.tlsConfig == nil { - tlsConfig = &tls.Config{InsecureSkipVerify: do.skipVerify} - } else { - tlsConfig = do.tlsConfig.Clone() - } - if tlsConfig.ServerName == "" { - host, _, err := net.SplitHostPort(address) - if err != nil { - netConn.Close() - return nil, err - } - tlsConfig.ServerName = host - } - - tlsConn := tls.Client(netConn, tlsConfig) - errc := make(chan error, 2) // buffered so we don't block timeout or Handshake - if d := do.tlsHandshakeTimeout; d != 0 { - timer := time.AfterFunc(d, func() { - errc <- tlsHandshakeTimeoutError{} - }) - defer timer.Stop() - } - go func() { - errc <- tlsConn.Handshake() - }() - if err := <-errc; err != nil { - // Timeout or Handshake error. - netConn.Close() // nolint: errcheck - return nil, err - } - - netConn = tlsConn - } - - c := &conn{ - conn: netConn, - bw: bufio.NewWriter(netConn), - br: bufio.NewReader(netConn), - readTimeout: do.readTimeout, - writeTimeout: do.writeTimeout, - } - - if do.password != "" { - authArgs := make([]interface{}, 0, 2) - if do.username != "" { - authArgs = append(authArgs, do.username) - } - authArgs = append(authArgs, do.password) - if _, err := c.DoContext(ctx, "AUTH", authArgs...); err != nil { - netConn.Close() - return nil, err - } - } - - if do.clientName != "" { - if _, err := c.DoContext(ctx, "CLIENT", "SETNAME", do.clientName); err != nil { - netConn.Close() - return nil, err - } - } - - if do.db != 0 { - if _, err := c.DoContext(ctx, "SELECT", do.db); err != nil { - netConn.Close() - return nil, err - } - } - - return c, nil -} - -var pathDBRegexp = regexp.MustCompile(`/(\d*)\z`) - -// DialURL wraps DialURLContext using context.Background. -func DialURL(rawurl string, options ...DialOption) (Conn, error) { - ctx := context.Background() - - return DialURLContext(ctx, rawurl, options...) -} - -// DialURLContext connects to a Redis server at the given URL using the Redis -// URI scheme. URLs should follow the draft IANA specification for the -// scheme (https://www.iana.org/assignments/uri-schemes/prov/redis). -func DialURLContext(ctx context.Context, rawurl string, options ...DialOption) (Conn, error) { - u, err := url.Parse(rawurl) - if err != nil { - return nil, err - } - - switch u.Scheme { - case "redis", "rediss", "valkey", "valkeys": - // valid scheme - default: - return nil, fmt.Errorf("invalid redis URL scheme: %s", u.Scheme) - } - - if u.Opaque != "" { - return nil, fmt.Errorf("invalid redis URL, url is opaque: %s", rawurl) - } - - // As per the IANA draft spec, the host defaults to localhost and - // the port defaults to 6379. - host, port, err := net.SplitHostPort(u.Host) - if err != nil { - // assume port is missing - host = u.Host - port = "6379" - } - if host == "" { - host = "localhost" - } - address := net.JoinHostPort(host, port) - - if u.User != nil { - password, isSet := u.User.Password() - username := u.User.Username() - if isSet { - if username != "" { - // ACL - options = append(options, DialUsername(username), DialPassword(password)) - } else { - // requirepass - user-info username:password with blank username - options = append(options, DialPassword(password)) - } - } else if username != "" { - // requirepass - redis-cli compatibility which treats as single arg in user-info as a password - options = append(options, DialPassword(username)) - } - } - - match := pathDBRegexp.FindStringSubmatch(u.Path) - if len(match) == 2 { - db := 0 - if len(match[1]) > 0 { - db, err = strconv.Atoi(match[1]) - if err != nil { - return nil, fmt.Errorf("invalid database: %s", u.Path[1:]) - } - } - if db != 0 { - options = append(options, DialDatabase(db)) - } - } else if u.Path != "" { - return nil, fmt.Errorf("invalid database: %s", u.Path[1:]) - } - - options = append(options, DialUseTLS(u.Scheme == "rediss" || u.Scheme == "valkeys")) - - return DialContext(ctx, "tcp", address, options...) -} - -// NewConn returns a new Redigo connection for the given net connection. -func NewConn(netConn net.Conn, readTimeout, writeTimeout time.Duration) Conn { - return &conn{ - conn: netConn, - bw: bufio.NewWriter(netConn), - br: bufio.NewReader(netConn), - readTimeout: readTimeout, - writeTimeout: writeTimeout, - } -} - -func (c *conn) Close() error { - c.mu.Lock() - err := c.err - if c.err == nil { - c.err = errors.New("redigo: closed") - err = c.conn.Close() - } - c.mu.Unlock() - return err -} - -func (c *conn) fatal(err error) error { - c.mu.Lock() - if c.err == nil { - c.err = err - // Close connection to force errors on subsequent calls and to unblock - // other reader or writer. - c.conn.Close() - } - c.mu.Unlock() - return err -} - -func (c *conn) Err() error { - c.mu.Lock() - err := c.err - c.mu.Unlock() - return err -} - -func (c *conn) writeLen(prefix byte, n int) error { - c.lenScratch[len(c.lenScratch)-1] = '\n' - c.lenScratch[len(c.lenScratch)-2] = '\r' - i := len(c.lenScratch) - 3 - for { - c.lenScratch[i] = byte('0' + n%10) - i -= 1 - n = n / 10 - if n == 0 { - break - } - } - c.lenScratch[i] = prefix - _, err := c.bw.Write(c.lenScratch[i:]) - return err -} - -func (c *conn) writeString(s string) error { - if err := c.writeLen('$', len(s)); err != nil { - return err - } - if _, err := c.bw.WriteString(s); err != nil { - return err - } - _, err := c.bw.WriteString("\r\n") - return err -} - -func (c *conn) writeBytes(p []byte) error { - if err := c.writeLen('$', len(p)); err != nil { - return err - } - if _, err := c.bw.Write(p); err != nil { - return err - } - _, err := c.bw.WriteString("\r\n") - return err -} - -func (c *conn) writeInt64(n int64) error { - return c.writeBytes(strconv.AppendInt(c.numScratch[:0], n, 10)) -} - -func (c *conn) writeFloat64(n float64) error { - return c.writeBytes(strconv.AppendFloat(c.numScratch[:0], n, 'g', -1, 64)) -} - -func (c *conn) writeCommand(cmd string, args []interface{}) error { - if err := c.writeLen('*', 1+len(args)); err != nil { - return err - } - if err := c.writeString(cmd); err != nil { - return err - } - for _, arg := range args { - if err := c.writeArg(arg, true); err != nil { - return err - } - } - return nil -} - -func (c *conn) writeArg(arg interface{}, argumentTypeOK bool) (err error) { - switch arg := arg.(type) { - case string: - return c.writeString(arg) - case []byte: - return c.writeBytes(arg) - case int: - return c.writeInt64(int64(arg)) - case int64: - return c.writeInt64(arg) - case float64: - return c.writeFloat64(arg) - case bool: - if arg { - return c.writeString("1") - } else { - return c.writeString("0") - } - case nil: - return c.writeString("") - case Argument: - if argumentTypeOK { - return c.writeArg(arg.RedisArg(), false) - } - // See comment in default clause below. - var buf bytes.Buffer - fmt.Fprint(&buf, arg) - return c.writeBytes(buf.Bytes()) - default: - // This default clause is intended to handle builtin numeric types. - // The function should return an error for other types, but this is not - // done for compatibility with previous versions of the package. - var buf bytes.Buffer - fmt.Fprint(&buf, arg) - return c.writeBytes(buf.Bytes()) - } -} - -type protocolError string - -func (pe protocolError) Error() string { - return fmt.Sprintf("redigo: %s (possible server error or unsupported concurrent read by application)", string(pe)) -} - -// readLine reads a line of input from the RESP stream. -func (c *conn) readLine() ([]byte, error) { - // To avoid allocations, attempt to read the line using ReadSlice. This - // call typically succeeds. The known case where the call fails is when - // reading the output from the MONITOR command. - p, err := c.br.ReadSlice('\n') - if err == bufio.ErrBufferFull { - // The line does not fit in the bufio.Reader's buffer. Fall back to - // allocating a buffer for the line. - buf := append([]byte{}, p...) - for err == bufio.ErrBufferFull { - p, err = c.br.ReadSlice('\n') - buf = append(buf, p...) - } - p = buf - } - if err != nil { - return nil, err - } - i := len(p) - 2 - if i < 0 || p[i] != '\r' { - return nil, protocolError("bad response line terminator") - } - return p[:i], nil -} - -// parseLen parses bulk string and array lengths. -func parseLen(p []byte) (int, error) { - if len(p) == 0 { - return -1, protocolError("malformed length") - } - - if p[0] == '-' && len(p) == 2 && p[1] == '1' { - // handle $-1 and $-1 null replies. - return -1, nil - } - - var n int - for _, b := range p { - n *= 10 - if b < '0' || b > '9' { - return -1, protocolError("illegal bytes in length") - } - n += int(b - '0') - } - - return n, nil -} - -// parseInt parses an integer reply. -func parseInt(p []byte) (interface{}, error) { - if len(p) == 0 { - return 0, protocolError("malformed integer") - } - - var negate bool - if p[0] == '-' { - negate = true - p = p[1:] - if len(p) == 0 { - return 0, protocolError("malformed integer") - } - } - - var n int64 - for _, b := range p { - n *= 10 - if b < '0' || b > '9' { - return 0, protocolError("illegal bytes in length") - } - n += int64(b - '0') - } - - if negate { - n = -n - } - return n, nil -} - -var ( - okReply interface{} = "OK" - pongReply interface{} = "PONG" -) - -func (c *conn) readReply() (interface{}, error) { - line, err := c.readLine() - if err != nil { - return nil, err - } - if len(line) == 0 { - return nil, protocolError("short response line") - } - switch line[0] { - case '+': - switch string(line[1:]) { - case "OK": - // Avoid allocation for frequent "+OK" response. - return okReply, nil - case "PONG": - // Avoid allocation in PING command benchmarks :) - return pongReply, nil - default: - return string(line[1:]), nil - } - case '-': - return Error(line[1:]), nil - case ':': - return parseInt(line[1:]) - case '$': - n, err := parseLen(line[1:]) - if n < 0 || err != nil { - return nil, err - } - p := make([]byte, n) - _, err = io.ReadFull(c.br, p) - if err != nil { - return nil, err - } - if line, err := c.readLine(); err != nil { - return nil, err - } else if len(line) != 0 { - return nil, protocolError("bad bulk string format") - } - return p, nil - case '*': - n, err := parseLen(line[1:]) - if n < 0 || err != nil { - return nil, err - } - r := make([]interface{}, n) - for i := range r { - r[i], err = c.readReply() - if err != nil { - return nil, err - } - } - return r, nil - } - return nil, protocolError("unexpected response line") -} - -func (c *conn) Send(cmd string, args ...interface{}) error { - c.mu.Lock() - c.pending += 1 - c.mu.Unlock() - if c.writeTimeout != 0 { - if err := c.conn.SetWriteDeadline(time.Now().Add(c.writeTimeout)); err != nil { - return c.fatal(err) - } - } - if err := c.writeCommand(cmd, args); err != nil { - return c.fatal(err) - } - return nil -} - -func (c *conn) Flush() error { - if c.writeTimeout != 0 { - if err := c.conn.SetWriteDeadline(time.Now().Add(c.writeTimeout)); err != nil { - return c.fatal(err) - } - } - if err := c.bw.Flush(); err != nil { - return c.fatal(err) - } - return nil -} - -func (c *conn) Receive() (interface{}, error) { - return c.ReceiveWithTimeout(c.readTimeout) -} - -func (c *conn) ReceiveContext(ctx context.Context) (interface{}, error) { - var realTimeout time.Duration - if dl, ok := ctx.Deadline(); ok { - timeout := time.Until(dl) - if timeout >= c.readTimeout && c.readTimeout != 0 { - realTimeout = c.readTimeout - } else if timeout <= 0 { - return nil, c.fatal(context.DeadlineExceeded) - } else { - realTimeout = timeout - } - } else { - realTimeout = c.readTimeout - } - endch := make(chan struct{}) - var r interface{} - var e error - go func() { - defer close(endch) - - r, e = c.ReceiveWithTimeout(realTimeout) - }() - select { - case <-ctx.Done(): - return nil, c.fatal(ctx.Err()) - case <-endch: - return r, e - } -} - -func (c *conn) ReceiveWithTimeout(timeout time.Duration) (reply interface{}, err error) { - var deadline time.Time - if timeout != 0 { - deadline = time.Now().Add(timeout) - } - if err := c.conn.SetReadDeadline(deadline); err != nil { - return nil, c.fatal(err) - } - - if reply, err = c.readReply(); err != nil { - return nil, c.fatal(err) - } - // When using pub/sub, the number of receives can be greater than the - // number of sends. To enable normal use of the connection after - // unsubscribing from all channels, we do not decrement pending to a - // negative value. - // - // The pending field is decremented after the reply is read to handle the - // case where Receive is called before Send. - c.mu.Lock() - if c.pending > 0 { - c.pending -= 1 - } - c.mu.Unlock() - if err, ok := reply.(Error); ok { - return nil, err - } - return -} - -func (c *conn) Do(cmd string, args ...interface{}) (interface{}, error) { - return c.DoWithTimeout(c.readTimeout, cmd, args...) -} - -func (c *conn) DoContext(ctx context.Context, cmd string, args ...interface{}) (interface{}, error) { - var realTimeout time.Duration - if dl, ok := ctx.Deadline(); ok { - timeout := time.Until(dl) - if timeout >= c.readTimeout && c.readTimeout != 0 { - realTimeout = c.readTimeout - } else if timeout <= 0 { - return nil, c.fatal(context.DeadlineExceeded) - } else { - realTimeout = timeout - } - } else { - realTimeout = c.readTimeout - } - endch := make(chan struct{}) - var r interface{} - var e error - go func() { - defer close(endch) - - r, e = c.DoWithTimeout(realTimeout, cmd, args...) - }() - select { - case <-ctx.Done(): - return nil, c.fatal(ctx.Err()) - case <-endch: - return r, e - } -} - -func (c *conn) DoWithTimeout(readTimeout time.Duration, cmd string, args ...interface{}) (interface{}, error) { - c.mu.Lock() - pending := c.pending - c.pending = 0 - c.mu.Unlock() - - if cmd == "" && pending == 0 { - return nil, nil - } - - if c.writeTimeout != 0 { - if err := c.conn.SetWriteDeadline(time.Now().Add(c.writeTimeout)); err != nil { - return nil, c.fatal(err) - } - } - - if cmd != "" { - if err := c.writeCommand(cmd, args); err != nil { - return nil, c.fatal(err) - } - } - - if err := c.bw.Flush(); err != nil { - return nil, c.fatal(err) - } - - var deadline time.Time - if readTimeout != 0 { - deadline = time.Now().Add(readTimeout) - } - if err := c.conn.SetReadDeadline(deadline); err != nil { - return nil, c.fatal(err) - } - - if cmd == "" { - reply := make([]interface{}, pending) - for i := range reply { - r, e := c.readReply() - if e != nil { - return nil, c.fatal(e) - } - reply[i] = r - } - return reply, nil - } - - var err error - var reply interface{} - for i := 0; i <= pending; i++ { - var e error - if reply, e = c.readReply(); e != nil { - return nil, c.fatal(e) - } - if e, ok := reply.(Error); ok && err == nil { - err = e - } - } - return reply, err -} diff --git a/vendor/github.com/gomodule/redigo/redis/doc.go b/vendor/github.com/gomodule/redigo/redis/doc.go deleted file mode 100644 index 69ad506cd3..0000000000 --- a/vendor/github.com/gomodule/redigo/redis/doc.go +++ /dev/null @@ -1,177 +0,0 @@ -// Copyright 2012 Gary Burd -// -// 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. - -// Package redis is a client for the Redis database. -// -// The Redigo FAQ (https://github.com/gomodule/redigo/wiki/FAQ) contains more -// documentation about this package. -// -// Connections -// -// The Conn interface is the primary interface for working with Redis. -// Applications create connections by calling the Dial, DialWithTimeout or -// NewConn functions. In the future, functions will be added for creating -// sharded and other types of connections. -// -// The application must call the connection Close method when the application -// is done with the connection. -// -// Executing Commands -// -// The Conn interface has a generic method for executing Redis commands: -// -// Do(commandName string, args ...interface{}) (reply interface{}, err error) -// -// The Redis command reference (http://redis.io/commands) lists the available -// commands. An example of using the Redis APPEND command is: -// -// n, err := conn.Do("APPEND", "key", "value") -// -// The Do method converts command arguments to bulk strings for transmission -// to the server as follows: -// -// Go Type Conversion -// []byte Sent as is -// string Sent as is -// int, int64 strconv.FormatInt(v) -// float64 strconv.FormatFloat(v, 'g', -1, 64) -// bool true -> "1", false -> "0" -// nil "" -// all other types fmt.Fprint(w, v) -// -// Redis command reply types are represented using the following Go types: -// -// Redis type Go type -// error redis.Error -// integer int64 -// simple string string -// bulk string []byte or nil if value not present. -// array []interface{} or nil if value not present. -// -// Use type assertions or the reply helper functions to convert from -// interface{} to the specific Go type for the command result. -// -// Pipelining -// -// Connections support pipelining using the Send, Flush and Receive methods. -// -// Send(commandName string, args ...interface{}) error -// Flush() error -// Receive() (reply interface{}, err error) -// -// Send writes the command to the connection's output buffer. Flush flushes the -// connection's output buffer to the server. Receive reads a single reply from -// the server. The following example shows a simple pipeline. -// -// c.Send("SET", "foo", "bar") -// c.Send("GET", "foo") -// c.Flush() -// c.Receive() // reply from SET -// v, err = c.Receive() // reply from GET -// -// The Do method combines the functionality of the Send, Flush and Receive -// methods. The Do method starts by writing the command and flushing the output -// buffer. Next, the Do method receives all pending replies including the reply -// for the command just sent by Do. If any of the received replies is an error, -// then Do returns the error. If there are no errors, then Do returns the last -// reply. If the command argument to the Do method is "", then the Do method -// will flush the output buffer and receive pending replies without sending a -// command. -// -// Use the Send and Do methods to implement pipelined transactions. -// -// c.Send("MULTI") -// c.Send("INCR", "foo") -// c.Send("INCR", "bar") -// r, err := c.Do("EXEC") -// fmt.Println(r) // prints [1, 1] -// -// Concurrency -// -// Connections support one concurrent caller to the Receive method and one -// concurrent caller to the Send and Flush methods. No other concurrency is -// supported including concurrent calls to the Do and Close methods. -// -// For full concurrent access to Redis, use the thread-safe Pool to get, use -// and release a connection from within a goroutine. Connections returned from -// a Pool have the concurrency restrictions described in the previous -// paragraph. -// -// Publish and Subscribe -// -// Use the Send, Flush and Receive methods to implement Pub/Sub subscribers. -// -// c.Send("SUBSCRIBE", "example") -// c.Flush() -// for { -// reply, err := c.Receive() -// if err != nil { -// return err -// } -// // process pushed message -// } -// -// The PubSubConn type wraps a Conn with convenience methods for implementing -// subscribers. The Subscribe, PSubscribe, Unsubscribe and PUnsubscribe methods -// send and flush a subscription management command. The receive method -// converts a pushed message to convenient types for use in a type switch. -// -// psc := redis.PubSubConn{Conn: c} -// psc.Subscribe("example") -// for { -// switch v := psc.Receive().(type) { -// case redis.Message: -// fmt.Printf("%s: message: %s\n", v.Channel, v.Data) -// case redis.Subscription: -// fmt.Printf("%s: %s %d\n", v.Channel, v.Kind, v.Count) -// case error: -// return v -// } -// } -// -// Reply Helpers -// -// The Bool, Int, Bytes, String, Strings and Values functions convert a reply -// to a value of a specific type. To allow convenient wrapping of calls to the -// connection Do and Receive methods, the functions take a second argument of -// type error. If the error is non-nil, then the helper function returns the -// error. If the error is nil, the function converts the reply to the specified -// type: -// -// exists, err := redis.Bool(c.Do("EXISTS", "foo")) -// if err != nil { -// // handle error return from c.Do or type conversion error. -// } -// -// The Scan function converts elements of a array reply to Go types: -// -// var value1 int -// var value2 string -// reply, err := redis.Values(c.Do("MGET", "key1", "key2")) -// if err != nil { -// // handle error -// } -// if _, err := redis.Scan(reply, &value1, &value2); err != nil { -// // handle error -// } -// -// Errors -// -// Connection methods return error replies from the server as type redis.Error. -// -// Call the connection Err() method to determine if the connection encountered -// non-recoverable error such as a network error or protocol parsing error. If -// Err() returns a non-nil value, then the connection is not usable and should -// be closed. -package redis diff --git a/vendor/github.com/gomodule/redigo/redis/log.go b/vendor/github.com/gomodule/redigo/redis/log.go deleted file mode 100644 index 72e054f0d1..0000000000 --- a/vendor/github.com/gomodule/redigo/redis/log.go +++ /dev/null @@ -1,159 +0,0 @@ -// Copyright 2012 Gary Burd -// -// 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. - -package redis - -import ( - "bytes" - "context" - "fmt" - "log" - "time" -) - -var ( - _ ConnWithTimeout = (*loggingConn)(nil) -) - -// NewLoggingConn returns a logging wrapper around a connection. -func NewLoggingConn(conn Conn, logger *log.Logger, prefix string) Conn { - if prefix != "" { - prefix = prefix + "." - } - return &loggingConn{conn, logger, prefix, nil} -} - -//NewLoggingConnFilter returns a logging wrapper around a connection and a filter function. -func NewLoggingConnFilter(conn Conn, logger *log.Logger, prefix string, skip func(cmdName string) bool) Conn { - if prefix != "" { - prefix = prefix + "." - } - return &loggingConn{conn, logger, prefix, skip} -} - -type loggingConn struct { - Conn - logger *log.Logger - prefix string - skip func(cmdName string) bool -} - -func (c *loggingConn) Close() error { - err := c.Conn.Close() - var buf bytes.Buffer - fmt.Fprintf(&buf, "%sClose() -> (%v)", c.prefix, err) - c.logger.Output(2, buf.String()) // nolint: errcheck - return err -} - -func (c *loggingConn) printValue(buf *bytes.Buffer, v interface{}) { - const chop = 32 - switch v := v.(type) { - case []byte: - if len(v) > chop { - fmt.Fprintf(buf, "%q...", v[:chop]) - } else { - fmt.Fprintf(buf, "%q", v) - } - case string: - if len(v) > chop { - fmt.Fprintf(buf, "%q...", v[:chop]) - } else { - fmt.Fprintf(buf, "%q", v) - } - case []interface{}: - if len(v) == 0 { - buf.WriteString("[]") - } else { - sep := "[" - fin := "]" - if len(v) > chop { - v = v[:chop] - fin = "...]" - } - for _, vv := range v { - buf.WriteString(sep) - c.printValue(buf, vv) - sep = ", " - } - buf.WriteString(fin) - } - default: - fmt.Fprint(buf, v) - } -} - -func (c *loggingConn) print(method, commandName string, args []interface{}, reply interface{}, err error) { - if c.skip != nil && c.skip(commandName) { - return - } - var buf bytes.Buffer - fmt.Fprintf(&buf, "%s%s(", c.prefix, method) - if method != "Receive" { - buf.WriteString(commandName) - for _, arg := range args { - buf.WriteString(", ") - c.printValue(&buf, arg) - } - } - buf.WriteString(") -> (") - if method != "Send" { - c.printValue(&buf, reply) - buf.WriteString(", ") - } - fmt.Fprintf(&buf, "%v)", err) - c.logger.Output(3, buf.String()) // nolint: errcheck -} - -func (c *loggingConn) Do(commandName string, args ...interface{}) (interface{}, error) { - reply, err := c.Conn.Do(commandName, args...) - c.print("Do", commandName, args, reply, err) - return reply, err -} - -func (c *loggingConn) DoContext(ctx context.Context, commandName string, args ...interface{}) (interface{}, error) { - reply, err := DoContext(c.Conn, ctx, commandName, args...) - c.print("DoContext", commandName, args, reply, err) - return reply, err -} - -func (c *loggingConn) DoWithTimeout(timeout time.Duration, commandName string, args ...interface{}) (interface{}, error) { - reply, err := DoWithTimeout(c.Conn, timeout, commandName, args...) - c.print("DoWithTimeout", commandName, args, reply, err) - return reply, err -} - -func (c *loggingConn) Send(commandName string, args ...interface{}) error { - err := c.Conn.Send(commandName, args...) - c.print("Send", commandName, args, nil, err) - return err -} - -func (c *loggingConn) Receive() (interface{}, error) { - reply, err := c.Conn.Receive() - c.print("Receive", "", nil, reply, err) - return reply, err -} - -func (c *loggingConn) ReceiveContext(ctx context.Context) (interface{}, error) { - reply, err := ReceiveContext(c.Conn, ctx) - c.print("ReceiveContext", "", nil, reply, err) - return reply, err -} - -func (c *loggingConn) ReceiveWithTimeout(timeout time.Duration) (interface{}, error) { - reply, err := ReceiveWithTimeout(c.Conn, timeout) - c.print("ReceiveWithTimeout", "", nil, reply, err) - return reply, err -} diff --git a/vendor/github.com/gomodule/redigo/redis/pool.go b/vendor/github.com/gomodule/redigo/redis/pool.go deleted file mode 100644 index 8e22f66b38..0000000000 --- a/vendor/github.com/gomodule/redigo/redis/pool.go +++ /dev/null @@ -1,675 +0,0 @@ -// Copyright 2012 Gary Burd -// -// 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. - -package redis - -import ( - "bytes" - "context" - "crypto/rand" - "crypto/sha1" - "errors" - "io" - "strconv" - "sync" - "time" -) - -var ( - _ ConnWithTimeout = (*activeConn)(nil) - _ ConnWithTimeout = (*errorConn)(nil) -) - -var nowFunc = time.Now // for testing - -// ErrPoolExhausted is returned from a pool connection method (Do, Send, -// Receive, Flush, Err) when the maximum number of database connections in the -// pool has been reached. -var ErrPoolExhausted = errors.New("redigo: connection pool exhausted") - -var ( - errConnClosed = errors.New("redigo: connection closed") -) - -// Pool maintains a pool of connections. The application calls the Get method -// to get a connection from the pool and the connection's Close method to -// return the connection's resources to the pool. -// -// The following example shows how to use a pool in a web application. The -// application creates a pool at application startup and makes it available to -// request handlers using a package level variable. The pool configuration used -// here is an example, not a recommendation. -// -// func newPool(addr string) *redis.Pool { -// return &redis.Pool{ -// MaxIdle: 3, -// IdleTimeout: 240 * time.Second, -// // Dial or DialContext must be set. When both are set, DialContext takes precedence over Dial. -// Dial: func () (redis.Conn, error) { return redis.Dial("tcp", addr) }, -// } -// } -// -// var ( -// pool *redis.Pool -// redisServer = flag.String("redisServer", ":6379", "") -// ) -// -// func main() { -// flag.Parse() -// pool = newPool(*redisServer) -// ... -// } -// -// A request handler gets a connection from the pool and closes the connection -// when the handler is done: -// -// func serveHome(w http.ResponseWriter, r *http.Request) { -// conn := pool.Get() -// defer conn.Close() -// ... -// } -// -// Use the Dial function to authenticate connections with the AUTH command or -// select a database with the SELECT command: -// -// pool := &redis.Pool{ -// // Other pool configuration not shown in this example. -// Dial: func () (redis.Conn, error) { -// c, err := redis.Dial("tcp", server) -// if err != nil { -// return nil, err -// } -// if _, err := c.Do("AUTH", password); err != nil { -// c.Close() -// return nil, err -// } -// if _, err := c.Do("SELECT", db); err != nil { -// c.Close() -// return nil, err -// } -// return c, nil -// }, -// } -// -// Use the TestOnBorrow function to check the health of an idle connection -// before the connection is returned to the application. This example PINGs -// connections that have been idle more than a minute: -// -// pool := &redis.Pool{ -// // Other pool configuration not shown in this example. -// TestOnBorrow: func(c redis.Conn, t time.Time) error { -// if time.Since(t) < time.Minute { -// return nil -// } -// _, err := c.Do("PING") -// return err -// }, -// } -// -type Pool struct { - // Dial is an application supplied function for creating and configuring a - // connection. - // - // The connection returned from Dial must not be in a special state - // (subscribed to pubsub channel, transaction started, ...). - Dial func() (Conn, error) - - // DialContext is an application supplied function for creating and configuring a - // connection with the given context. - // - // The connection returned from DialContext must not be in a special state - // (subscribed to pubsub channel, transaction started, ...). - DialContext func(ctx context.Context) (Conn, error) - - // TestOnBorrow is an optional application supplied function for checking - // the health of an idle connection before the connection is used again by - // the application. Argument lastUsed is the time when the connection was returned - // to the pool. If the function returns an error, then the connection is - // closed. - TestOnBorrow func(c Conn, lastUsed time.Time) error - - // TestOnBorrowContext is an optional application supplied function - // for checking the health of an idle connection with the given context - // before the connection is used again by the application. - // Argument lastUsed is the time when the connection was returned - // to the pool. If the function returns an error, then the connection is - // closed. - TestOnBorrowContext func(ctx context.Context, c Conn, lastUsed time.Time) error - - // Maximum number of idle connections in the pool. - MaxIdle int - - // Maximum number of connections allocated by the pool at a given time. - // When zero, there is no limit on the number of connections in the pool. - MaxActive int - - // Close connections after remaining idle for this duration. If the value - // is zero, then idle connections are not closed. Applications should set - // the timeout to a value less than the server's timeout. - IdleTimeout time.Duration - - // If Wait is true and the pool is at the MaxActive limit, then Get() waits - // for a connection to be returned to the pool before returning. - Wait bool - - // Close connections older than this duration. If the value is zero, then - // the pool does not close connections based on age. - MaxConnLifetime time.Duration - - mu sync.Mutex // mu protects the following fields - closed bool // set to true when the pool is closed. - active int // the number of open connections in the pool - initOnce sync.Once // the init ch once func - ch chan struct{} // limits open connections when p.Wait is true - idle idleList // idle connections - waitCount int64 // total number of connections waited for. - waitDuration time.Duration // total time waited for new connections. -} - -// NewPool creates a new pool. -// -// Deprecated: Initialize the Pool directly as shown in the example. -func NewPool(newFn func() (Conn, error), maxIdle int) *Pool { - return &Pool{Dial: newFn, MaxIdle: maxIdle} -} - -// Get gets a connection. The application must close the returned connection. -// This method always returns a valid connection so that applications can defer -// error handling to the first use of the connection. If there is an error -// getting an underlying connection, then the connection Err, Do, Send, Flush -// and Receive methods return that error. -func (p *Pool) Get() Conn { - // GetContext returns errorConn in the first argument when an error occurs. - c, _ := p.GetContext(context.Background()) - return c -} - -// GetContext gets a connection using the provided context. -// -// The provided Context must be non-nil. If the context expires before the -// connection is complete, an error is returned. Any expiration on the context -// will not affect the returned connection. -// -// If the function completes without error, then the application must close the -// returned connection. -func (p *Pool) GetContext(ctx context.Context) (Conn, error) { - // Wait until there is a vacant connection in the pool. - waited, err := p.waitVacantConn(ctx) - if err != nil { - return errorConn{err}, err - } - - p.mu.Lock() - - if waited > 0 { - p.waitCount++ - p.waitDuration += waited - } - - // Prune stale connections at the back of the idle list. - if p.IdleTimeout > 0 { - n := p.idle.count - for i := 0; i < n && p.idle.back != nil && p.idle.back.t.Add(p.IdleTimeout).Before(nowFunc()); i++ { - pc := p.idle.back - p.idle.popBack() - p.mu.Unlock() - pc.c.Close() - p.mu.Lock() - p.active-- - } - } - - // Get idle connection from the front of idle list. - for p.idle.front != nil { - pc := p.idle.front - p.idle.popFront() - p.mu.Unlock() - if (p.TestOnBorrow == nil || p.TestOnBorrow(pc.c, pc.t) == nil) && - (p.TestOnBorrowContext == nil || p.TestOnBorrowContext(ctx, pc.c, pc.t) == nil) && - (p.MaxConnLifetime == 0 || nowFunc().Sub(pc.created) < p.MaxConnLifetime) { - return &activeConn{p: p, pc: pc}, nil - } - pc.c.Close() - p.mu.Lock() - p.active-- - } - - // Check for pool closed before dialing a new connection. - if p.closed { - p.mu.Unlock() - err := errors.New("redigo: get on closed pool") - return errorConn{err}, err - } - - // Handle limit for p.Wait == false. - if !p.Wait && p.MaxActive > 0 && p.active >= p.MaxActive { - p.mu.Unlock() - return errorConn{ErrPoolExhausted}, ErrPoolExhausted - } - - p.active++ - p.mu.Unlock() - c, err := p.dial(ctx) - if err != nil { - p.mu.Lock() - p.active-- - if p.ch != nil && !p.closed { - p.ch <- struct{}{} - } - p.mu.Unlock() - return errorConn{err}, err - } - return &activeConn{p: p, pc: &poolConn{c: c, created: nowFunc()}}, nil -} - -// PoolStats contains pool statistics. -type PoolStats struct { - // ActiveCount is the number of connections in the pool. The count includes - // idle connections and connections in use. - ActiveCount int - // IdleCount is the number of idle connections in the pool. - IdleCount int - - // WaitCount is the total number of connections waited for. - // This value is currently not guaranteed to be 100% accurate. - WaitCount int64 - - // WaitDuration is the total time blocked waiting for a new connection. - // This value is currently not guaranteed to be 100% accurate. - WaitDuration time.Duration -} - -// Stats returns pool's statistics. -func (p *Pool) Stats() PoolStats { - p.mu.Lock() - stats := PoolStats{ - ActiveCount: p.active, - IdleCount: p.idle.count, - WaitCount: p.waitCount, - WaitDuration: p.waitDuration, - } - p.mu.Unlock() - - return stats -} - -// ActiveCount returns the number of connections in the pool. The count -// includes idle connections and connections in use. -func (p *Pool) ActiveCount() int { - p.mu.Lock() - active := p.active - p.mu.Unlock() - return active -} - -// IdleCount returns the number of idle connections in the pool. -func (p *Pool) IdleCount() int { - p.mu.Lock() - idle := p.idle.count - p.mu.Unlock() - return idle -} - -// Close releases the resources used by the pool. -func (p *Pool) Close() error { - p.mu.Lock() - if p.closed { - p.mu.Unlock() - return nil - } - p.closed = true - p.active -= p.idle.count - pc := p.idle.front - p.idle.count = 0 - p.idle.front, p.idle.back = nil, nil - if p.ch != nil { - close(p.ch) - } - p.mu.Unlock() - for ; pc != nil; pc = pc.next { - pc.c.Close() - } - return nil -} - -func (p *Pool) lazyInit() { - p.initOnce.Do(func() { - p.ch = make(chan struct{}, p.MaxActive) - if p.closed { - close(p.ch) - } else { - for i := 0; i < p.MaxActive; i++ { - p.ch <- struct{}{} - } - } - }) -} - -// waitVacantConn waits for a vacant connection in pool if waiting -// is enabled and pool size is limited, otherwise returns instantly. -// If ctx expires before that, an error is returned. -// -// If there were no vacant connection in the pool right away it returns the time spent waiting -// for that connection to appear in the pool. -func (p *Pool) waitVacantConn(ctx context.Context) (waited time.Duration, err error) { - if !p.Wait || p.MaxActive <= 0 { - // No wait or no connection limit. - return 0, nil - } - - p.lazyInit() - - // wait indicates if we believe it will block so its not 100% accurate - // however for stats it should be good enough. - wait := len(p.ch) == 0 - var start time.Time - if wait { - start = time.Now() - } - - select { - case <-p.ch: - // Additionally check that context hasn't expired while we were waiting, - // because `select` picks a random `case` if several of them are "ready". - select { - case <-ctx.Done(): - p.ch <- struct{}{} - return 0, ctx.Err() - default: - } - case <-ctx.Done(): - return 0, ctx.Err() - } - - if wait { - return time.Since(start), nil - } - return 0, nil -} - -func (p *Pool) dial(ctx context.Context) (Conn, error) { - if p.DialContext != nil { - return p.DialContext(ctx) - } - if p.Dial != nil { - return p.Dial() - } - return nil, errors.New("redigo: must pass Dial or DialContext to pool") -} - -func (p *Pool) put(pc *poolConn, forceClose bool) error { - p.mu.Lock() - if !p.closed && !forceClose { - pc.t = nowFunc() - p.idle.pushFront(pc) - if p.idle.count > p.MaxIdle { - pc = p.idle.back - p.idle.popBack() - } else { - pc = nil - } - } - - if pc != nil { - p.mu.Unlock() - pc.c.Close() - p.mu.Lock() - p.active-- - } - - if p.ch != nil && !p.closed { - p.ch <- struct{}{} - } - p.mu.Unlock() - return nil -} - -type activeConn struct { - p *Pool - pc *poolConn - state int -} - -var ( - sentinel []byte - sentinelOnce sync.Once -) - -func initSentinel() { - p := make([]byte, 64) - if _, err := rand.Read(p); err == nil { - sentinel = p - } else { - h := sha1.New() - io.WriteString(h, "Oops, rand failed. Use time instead.") // nolint: errcheck - io.WriteString(h, strconv.FormatInt(time.Now().UnixNano(), 10)) // nolint: errcheck - sentinel = h.Sum(nil) - } -} - -func (ac *activeConn) firstError(errs ...error) error { - for _, err := range errs[:len(errs)-1] { - if err != nil { - return err - } - } - return errs[len(errs)-1] -} - -func (ac *activeConn) Close() (err error) { - pc := ac.pc - if pc == nil { - return nil - } - ac.pc = nil - - if ac.state&connectionMultiState != 0 { - err = pc.c.Send("DISCARD") - ac.state &^= (connectionMultiState | connectionWatchState) - } else if ac.state&connectionWatchState != 0 { - err = pc.c.Send("UNWATCH") - ac.state &^= connectionWatchState - } - if ac.state&connectionSubscribeState != 0 { - err = ac.firstError(err, - pc.c.Send("UNSUBSCRIBE"), - pc.c.Send("PUNSUBSCRIBE"), - ) - // To detect the end of the message stream, ask the server to echo - // a sentinel value and read until we see that value. - sentinelOnce.Do(initSentinel) - err = ac.firstError(err, - pc.c.Send("ECHO", sentinel), - pc.c.Flush(), - ) - for { - p, err2 := pc.c.Receive() - if err2 != nil { - err = ac.firstError(err, err2) - break - } - if p, ok := p.([]byte); ok && bytes.Equal(p, sentinel) { - ac.state &^= connectionSubscribeState - break - } - } - } - _, err2 := pc.c.Do("") - return ac.firstError( - err, - err2, - ac.p.put(pc, ac.state != 0 || pc.c.Err() != nil), - ) -} - -func (ac *activeConn) Err() error { - pc := ac.pc - if pc == nil { - return errConnClosed - } - return pc.c.Err() -} - -func (ac *activeConn) DoContext(ctx context.Context, commandName string, args ...interface{}) (reply interface{}, err error) { - pc := ac.pc - if pc == nil { - return nil, errConnClosed - } - cwt, ok := pc.c.(ConnWithContext) - if !ok { - return nil, errContextNotSupported - } - ci := lookupCommandInfo(commandName) - ac.state = (ac.state | ci.Set) &^ ci.Clear - return cwt.DoContext(ctx, commandName, args...) -} - -func (ac *activeConn) Do(commandName string, args ...interface{}) (reply interface{}, err error) { - pc := ac.pc - if pc == nil { - return nil, errConnClosed - } - ci := lookupCommandInfo(commandName) - ac.state = (ac.state | ci.Set) &^ ci.Clear - return pc.c.Do(commandName, args...) -} - -func (ac *activeConn) DoWithTimeout(timeout time.Duration, commandName string, args ...interface{}) (reply interface{}, err error) { - pc := ac.pc - if pc == nil { - return nil, errConnClosed - } - cwt, ok := pc.c.(ConnWithTimeout) - if !ok { - return nil, errTimeoutNotSupported - } - ci := lookupCommandInfo(commandName) - ac.state = (ac.state | ci.Set) &^ ci.Clear - return cwt.DoWithTimeout(timeout, commandName, args...) -} - -func (ac *activeConn) Send(commandName string, args ...interface{}) error { - pc := ac.pc - if pc == nil { - return errConnClosed - } - ci := lookupCommandInfo(commandName) - ac.state = (ac.state | ci.Set) &^ ci.Clear - return pc.c.Send(commandName, args...) -} - -func (ac *activeConn) Flush() error { - pc := ac.pc - if pc == nil { - return errConnClosed - } - return pc.c.Flush() -} - -func (ac *activeConn) Receive() (reply interface{}, err error) { - pc := ac.pc - if pc == nil { - return nil, errConnClosed - } - return pc.c.Receive() -} - -func (ac *activeConn) ReceiveContext(ctx context.Context) (reply interface{}, err error) { - pc := ac.pc - if pc == nil { - return nil, errConnClosed - } - cwt, ok := pc.c.(ConnWithContext) - if !ok { - return nil, errContextNotSupported - } - return cwt.ReceiveContext(ctx) -} - -func (ac *activeConn) ReceiveWithTimeout(timeout time.Duration) (reply interface{}, err error) { - pc := ac.pc - if pc == nil { - return nil, errConnClosed - } - cwt, ok := pc.c.(ConnWithTimeout) - if !ok { - return nil, errTimeoutNotSupported - } - return cwt.ReceiveWithTimeout(timeout) -} - -type errorConn struct{ err error } - -func (ec errorConn) Do(string, ...interface{}) (interface{}, error) { return nil, ec.err } -func (ec errorConn) DoContext(context.Context, string, ...interface{}) (interface{}, error) { - return nil, ec.err -} -func (ec errorConn) DoWithTimeout(time.Duration, string, ...interface{}) (interface{}, error) { - return nil, ec.err -} -func (ec errorConn) Send(string, ...interface{}) error { return ec.err } -func (ec errorConn) Err() error { return ec.err } -func (ec errorConn) Close() error { return nil } -func (ec errorConn) Flush() error { return ec.err } -func (ec errorConn) Receive() (interface{}, error) { return nil, ec.err } -func (ec errorConn) ReceiveContext(context.Context) (interface{}, error) { return nil, ec.err } -func (ec errorConn) ReceiveWithTimeout(time.Duration) (interface{}, error) { return nil, ec.err } - -type idleList struct { - count int - front, back *poolConn -} - -type poolConn struct { - c Conn - t time.Time - created time.Time - next, prev *poolConn -} - -func (l *idleList) pushFront(pc *poolConn) { - pc.next = l.front - pc.prev = nil - if l.count == 0 { - l.back = pc - } else { - l.front.prev = pc - } - l.front = pc - l.count++ -} - -func (l *idleList) popFront() { - pc := l.front - l.count-- - if l.count == 0 { - l.front, l.back = nil, nil - } else { - pc.next.prev = nil - l.front = pc.next - } - pc.next, pc.prev = nil, nil -} - -func (l *idleList) popBack() { - pc := l.back - l.count-- - if l.count == 0 { - l.front, l.back = nil, nil - } else { - pc.prev.next = nil - l.back = pc.prev - } - pc.next, pc.prev = nil, nil -} diff --git a/vendor/github.com/gomodule/redigo/redis/pubsub.go b/vendor/github.com/gomodule/redigo/redis/pubsub.go deleted file mode 100644 index 67b885b9d2..0000000000 --- a/vendor/github.com/gomodule/redigo/redis/pubsub.go +++ /dev/null @@ -1,166 +0,0 @@ -// Copyright 2012 Gary Burd -// -// 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. - -package redis - -import ( - "context" - "errors" - "time" -) - -// Subscription represents a subscribe or unsubscribe notification. -type Subscription struct { - // Kind is "subscribe", "unsubscribe", "psubscribe" or "punsubscribe" - Kind string - - // The channel that was changed. - Channel string - - // The current number of subscriptions for connection. - Count int -} - -// Message represents a message notification. -type Message struct { - // The originating channel. - Channel string - - // The matched pattern, if any - Pattern string - - // The message data. - Data []byte -} - -// Pong represents a pubsub pong notification. -type Pong struct { - Data string -} - -// PubSubConn wraps a Conn with convenience methods for subscribers. -type PubSubConn struct { - Conn Conn -} - -// Close closes the connection. -func (c PubSubConn) Close() error { - return c.Conn.Close() -} - -// Subscribe subscribes the connection to the specified channels. -func (c PubSubConn) Subscribe(channel ...interface{}) error { - if err := c.Conn.Send("SUBSCRIBE", channel...); err != nil { - return err - } - return c.Conn.Flush() -} - -// PSubscribe subscribes the connection to the given patterns. -func (c PubSubConn) PSubscribe(channel ...interface{}) error { - if err := c.Conn.Send("PSUBSCRIBE", channel...); err != nil { - return err - } - return c.Conn.Flush() -} - -// Unsubscribe unsubscribes the connection from the given channels, or from all -// of them if none is given. -func (c PubSubConn) Unsubscribe(channel ...interface{}) error { - if err := c.Conn.Send("UNSUBSCRIBE", channel...); err != nil { - return err - } - return c.Conn.Flush() -} - -// PUnsubscribe unsubscribes the connection from the given patterns, or from all -// of them if none is given. -func (c PubSubConn) PUnsubscribe(channel ...interface{}) error { - if err := c.Conn.Send("PUNSUBSCRIBE", channel...); err != nil { - return err - } - return c.Conn.Flush() -} - -// Ping sends a PING to the server with the specified data. -// -// The connection must be subscribed to at least one channel or pattern when -// calling this method. -func (c PubSubConn) Ping(data string) error { - if err := c.Conn.Send("PING", data); err != nil { - return err - } - return c.Conn.Flush() -} - -// Receive returns a pushed message as a Subscription, Message, Pong or error. -// The return value is intended to be used directly in a type switch as -// illustrated in the PubSubConn example. -func (c PubSubConn) Receive() interface{} { - return c.receiveInternal(c.Conn.Receive()) -} - -// ReceiveWithTimeout is like Receive, but it allows the application to -// override the connection's default timeout. -func (c PubSubConn) ReceiveWithTimeout(timeout time.Duration) interface{} { - return c.receiveInternal(ReceiveWithTimeout(c.Conn, timeout)) -} - -// ReceiveContext is like Receive, but it allows termination of the receive -// via a Context. If the call returns due to closure of the context's Done -// channel the underlying Conn will have been closed. -func (c PubSubConn) ReceiveContext(ctx context.Context) interface{} { - return c.receiveInternal(ReceiveContext(c.Conn, ctx)) -} - -func (c PubSubConn) receiveInternal(replyArg interface{}, errArg error) interface{} { - reply, err := Values(replyArg, errArg) - if err != nil { - return err - } - - var kind string - reply, err = Scan(reply, &kind) - if err != nil { - return err - } - - switch kind { - case "message": - var m Message - if _, err := Scan(reply, &m.Channel, &m.Data); err != nil { - return err - } - return m - case "pmessage": - var m Message - if _, err := Scan(reply, &m.Pattern, &m.Channel, &m.Data); err != nil { - return err - } - return m - case "subscribe", "psubscribe", "unsubscribe", "punsubscribe": - s := Subscription{Kind: kind} - if _, err := Scan(reply, &s.Channel, &s.Count); err != nil { - return err - } - return s - case "pong": - var p Pong - if _, err := Scan(reply, &p.Data); err != nil { - return err - } - return p - } - return errors.New("redigo: unknown pubsub notification") -} diff --git a/vendor/github.com/gomodule/redigo/redis/redis.go b/vendor/github.com/gomodule/redigo/redis/redis.go deleted file mode 100644 index e3a3968c20..0000000000 --- a/vendor/github.com/gomodule/redigo/redis/redis.go +++ /dev/null @@ -1,213 +0,0 @@ -// Copyright 2012 Gary Burd -// -// 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. - -package redis - -import ( - "context" - "errors" - "time" -) - -// Error represents an error returned in a command reply. -type Error string - -func (err Error) Error() string { return string(err) } - -// Conn represents a connection to a Redis server. -type Conn interface { - // Close closes the connection. - Close() error - - // Err returns a non-nil value when the connection is not usable. - Err() error - - // Do sends a command to the server and returns the received reply. - // This function will use the timeout which was set when the connection is created - Do(commandName string, args ...interface{}) (reply interface{}, err error) - - // Send writes the command to the client's output buffer. - Send(commandName string, args ...interface{}) error - - // Flush flushes the output buffer to the Redis server. - Flush() error - - // Receive receives a single reply from the Redis server - Receive() (reply interface{}, err error) -} - -// Argument is the interface implemented by an object which wants to control how -// the object is converted to Redis bulk strings. -type Argument interface { - // RedisArg returns a value to be encoded as a bulk string per the - // conversions listed in the section 'Executing Commands'. - // Implementations should typically return a []byte or string. - RedisArg() interface{} -} - -// Scanner is implemented by an object which wants to control its value is -// interpreted when read from Redis. -type Scanner interface { - // RedisScan assigns a value from a Redis value. The argument src is one of - // the reply types listed in the section `Executing Commands`. - // - // An error should be returned if the value cannot be stored without - // loss of information. - RedisScan(src interface{}) error -} - -// ConnWithTimeout is an optional interface that allows the caller to override -// a connection's default read timeout. This interface is useful for executing -// the BLPOP, BRPOP, BRPOPLPUSH, XREAD and other commands that block at the -// server. -// -// A connection's default read timeout is set with the DialReadTimeout dial -// option. Applications should rely on the default timeout for commands that do -// not block at the server. -// -// All of the Conn implementations in this package satisfy the ConnWithTimeout -// interface. -// -// Use the DoWithTimeout and ReceiveWithTimeout helper functions to simplify -// use of this interface. -type ConnWithTimeout interface { - Conn - - // DoWithTimeout sends a command to the server and returns the received reply. - // The timeout overrides the readtimeout set when dialing the connection. - DoWithTimeout(timeout time.Duration, commandName string, args ...interface{}) (reply interface{}, err error) - - // ReceiveWithTimeout receives a single reply from the Redis server. - // The timeout overrides the readtimeout set when dialing the connection. - ReceiveWithTimeout(timeout time.Duration) (reply interface{}, err error) -} - -// ConnWithContext is an optional interface that allows the caller to control the command's life with context. -type ConnWithContext interface { - Conn - - // DoContext sends a command to server and returns the received reply. - // min(ctx,DialReadTimeout()) will be used as the deadline. - // The connection will be closed if DialReadTimeout() timeout or ctx timeout or ctx canceled when this function is running. - // DialReadTimeout() timeout return err can be checked by errors.Is(err, os.ErrDeadlineExceeded). - // ctx timeout return err context.DeadlineExceeded. - // ctx canceled return err context.Canceled. - DoContext(ctx context.Context, commandName string, args ...interface{}) (reply interface{}, err error) - - // ReceiveContext receives a single reply from the Redis server. - // min(ctx,DialReadTimeout()) will be used as the deadline. - // The connection will be closed if DialReadTimeout() timeout or ctx timeout or ctx canceled when this function is running. - // DialReadTimeout() timeout return err can be checked by errors.Is(err, os.ErrDeadlineExceeded). - // ctx timeout return err context.DeadlineExceeded. - // ctx canceled return err context.Canceled. - ReceiveContext(ctx context.Context) (reply interface{}, err error) -} - -var errTimeoutNotSupported = errors.New("redis: connection does not support ConnWithTimeout") -var errContextNotSupported = errors.New("redis: connection does not support ConnWithContext") - -// DoContext sends a command to server and returns the received reply. -// min(ctx,DialReadTimeout()) will be used as the deadline. -// The connection will be closed if DialReadTimeout() timeout or ctx timeout or ctx canceled when this function is running. -// DialReadTimeout() timeout return err can be checked by errors.Is(err, os.ErrDeadlineExceeded). -// ctx timeout return err context.DeadlineExceeded. -// ctx canceled return err context.Canceled. -func DoContext(c Conn, ctx context.Context, cmd string, args ...interface{}) (interface{}, error) { - cwt, ok := c.(ConnWithContext) - if !ok { - return nil, errContextNotSupported - } - return cwt.DoContext(ctx, cmd, args...) -} - -// DoWithTimeout executes a Redis command with the specified read timeout. If -// the connection does not satisfy the ConnWithTimeout interface, then an error -// is returned. -func DoWithTimeout(c Conn, timeout time.Duration, cmd string, args ...interface{}) (interface{}, error) { - cwt, ok := c.(ConnWithTimeout) - if !ok { - return nil, errTimeoutNotSupported - } - return cwt.DoWithTimeout(timeout, cmd, args...) -} - -// ReceiveContext receives a single reply from the Redis server. -// min(ctx,DialReadTimeout()) will be used as the deadline. -// The connection will be closed if DialReadTimeout() timeout or ctx timeout or ctx canceled when this function is running. -// DialReadTimeout() timeout return err can be checked by strings.Contains(e.Error(), "io/timeout"). -// ctx timeout return err context.DeadlineExceeded. -// ctx canceled return err context.Canceled. -func ReceiveContext(c Conn, ctx context.Context) (interface{}, error) { - cwt, ok := c.(ConnWithContext) - if !ok { - return nil, errContextNotSupported - } - return cwt.ReceiveContext(ctx) -} - -// ReceiveWithTimeout receives a reply with the specified read timeout. If the -// connection does not satisfy the ConnWithTimeout interface, then an error is -// returned. -func ReceiveWithTimeout(c Conn, timeout time.Duration) (interface{}, error) { - cwt, ok := c.(ConnWithTimeout) - if !ok { - return nil, errTimeoutNotSupported - } - return cwt.ReceiveWithTimeout(timeout) -} - -// SlowLog represents a redis SlowLog -type SlowLog struct { - // ID is a unique progressive identifier for every slow log entry. - ID int64 - - // Time is the unix timestamp at which the logged command was processed. - Time time.Time - - // ExecutationTime is the amount of time needed for the command execution. - ExecutionTime time.Duration - - // Args is the command name and arguments - Args []string - - // ClientAddr is the client IP address (4.0 only). - ClientAddr string - - // ClientName is the name set via the CLIENT SETNAME command (4.0 only). - ClientName string -} - -// Latency represents a redis LATENCY LATEST. -type Latency struct { - // Name of the latest latency spike event. - Name string - - // Time of the latest latency spike for the event. - Time time.Time - - // Latest is the latest recorded latency for the named event. - Latest time.Duration - - // Max is the maximum latency for the named event. - Max time.Duration -} - -// LatencyHistory represents a redis LATENCY HISTORY. -type LatencyHistory struct { - // Time is the unix timestamp at which the event was processed. - Time time.Time - - // ExecutationTime is the amount of time needed for the command execution. - ExecutionTime time.Duration -} diff --git a/vendor/github.com/gomodule/redigo/redis/reflect.go b/vendor/github.com/gomodule/redigo/redis/reflect.go deleted file mode 100644 index e135aed709..0000000000 --- a/vendor/github.com/gomodule/redigo/redis/reflect.go +++ /dev/null @@ -1,48 +0,0 @@ -package redis - -import ( - "reflect" - "runtime" -) - -// methodName returns the name of the calling method, -// assumed to be two stack frames above. -func methodName() string { - pc, _, _, _ := runtime.Caller(2) - f := runtime.FuncForPC(pc) - if f == nil { - return "unknown method" - } - return f.Name() -} - -// mustBe panics if f's kind is not expected. -func mustBe(v reflect.Value, expected reflect.Kind) { - if v.Kind() != expected { - panic(&reflect.ValueError{Method: methodName(), Kind: v.Kind()}) - } -} - -// fieldByIndexCreate returns the nested field corresponding -// to index creating elements that are nil when stepping through. -// It panics if v is not a struct. -func fieldByIndexCreate(v reflect.Value, index []int) reflect.Value { - if len(index) == 1 { - return v.Field(index[0]) - } - - mustBe(v, reflect.Struct) - for i, x := range index { - if i > 0 { - if v.Kind() == reflect.Ptr && v.Type().Elem().Kind() == reflect.Struct { - if v.IsNil() { - v.Set(reflect.New(v.Type().Elem())) - } - v = v.Elem() - } - } - v = v.Field(x) - } - - return v -} diff --git a/vendor/github.com/gomodule/redigo/redis/reflect_go117.go b/vendor/github.com/gomodule/redigo/redis/reflect_go117.go deleted file mode 100644 index e985192ab8..0000000000 --- a/vendor/github.com/gomodule/redigo/redis/reflect_go117.go +++ /dev/null @@ -1,34 +0,0 @@ -//go:build !go1.18 -// +build !go1.18 - -package redis - -import ( - "errors" - "reflect" -) - -// fieldByIndexErr returns the nested field corresponding to index. -// It returns an error if evaluation requires stepping through a nil -// pointer, but panics if it must step through a field that -// is not a struct. -func fieldByIndexErr(v reflect.Value, index []int) (reflect.Value, error) { - if len(index) == 1 { - return v.Field(index[0]), nil - } - - mustBe(v, reflect.Struct) - for i, x := range index { - if i > 0 { - if v.Kind() == reflect.Ptr && v.Type().Elem().Kind() == reflect.Struct { - if v.IsNil() { - return reflect.Value{}, errors.New("reflect: indirection through nil pointer to embedded struct field " + v.Type().Elem().Name()) - } - v = v.Elem() - } - } - v = v.Field(x) - } - - return v, nil -} diff --git a/vendor/github.com/gomodule/redigo/redis/reflect_go118.go b/vendor/github.com/gomodule/redigo/redis/reflect_go118.go deleted file mode 100644 index 3356e76f3a..0000000000 --- a/vendor/github.com/gomodule/redigo/redis/reflect_go118.go +++ /dev/null @@ -1,16 +0,0 @@ -//go:build go1.18 -// +build go1.18 - -package redis - -import ( - "reflect" -) - -// fieldByIndexErr returns the nested field corresponding to index. -// It returns an error if evaluation requires stepping through a nil -// pointer, but panics if it must step through a field that -// is not a struct. -func fieldByIndexErr(v reflect.Value, index []int) (reflect.Value, error) { - return v.FieldByIndexErr(index) -} diff --git a/vendor/github.com/gomodule/redigo/redis/reply.go b/vendor/github.com/gomodule/redigo/redis/reply.go deleted file mode 100644 index aabf59892c..0000000000 --- a/vendor/github.com/gomodule/redigo/redis/reply.go +++ /dev/null @@ -1,735 +0,0 @@ -// Copyright 2012 Gary Burd -// -// 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. - -package redis - -import ( - "errors" - "fmt" - "strconv" - "time" -) - -// ErrNil indicates that a reply value is nil. -var ErrNil = errors.New("redigo: nil returned") - -// Int is a helper that converts a command reply to an integer. If err is not -// equal to nil, then Int returns 0, err. Otherwise, Int converts the -// reply to an int as follows: -// -// Reply type Result -// integer int(reply), nil -// bulk string parsed reply, nil -// nil 0, ErrNil -// other 0, error -func Int(reply interface{}, err error) (int, error) { - if err != nil { - return 0, err - } - switch reply := reply.(type) { - case int64: - x := int(reply) - if int64(x) != reply { - return 0, strconv.ErrRange - } - return x, nil - case []byte: - n, err := strconv.ParseInt(string(reply), 10, 0) - return int(n), err - case nil: - return 0, ErrNil - case Error: - return 0, reply - } - return 0, fmt.Errorf("redigo: unexpected type for Int, got type %T", reply) -} - -// Int64 is a helper that converts a command reply to 64 bit integer. If err is -// not equal to nil, then Int64 returns 0, err. Otherwise, Int64 converts the -// reply to an int64 as follows: -// -// Reply type Result -// integer reply, nil -// bulk string parsed reply, nil -// nil 0, ErrNil -// other 0, error -func Int64(reply interface{}, err error) (int64, error) { - if err != nil { - return 0, err - } - switch reply := reply.(type) { - case int64: - return reply, nil - case []byte: - n, err := strconv.ParseInt(string(reply), 10, 64) - return n, err - case nil: - return 0, ErrNil - case Error: - return 0, reply - } - return 0, fmt.Errorf("redigo: unexpected type for Int64, got type %T", reply) -} - -func errNegativeInt(v int64) error { - return fmt.Errorf("redigo: unexpected negative value %v for Uint64", v) -} - -// Uint64 is a helper that converts a command reply to 64 bit unsigned integer. -// If err is not equal to nil, then Uint64 returns 0, err. Otherwise, Uint64 converts the -// reply to an uint64 as follows: -// -// Reply type Result -// +integer reply, nil -// bulk string parsed reply, nil -// nil 0, ErrNil -// other 0, error -func Uint64(reply interface{}, err error) (uint64, error) { - if err != nil { - return 0, err - } - switch reply := reply.(type) { - case int64: - if reply < 0 { - return 0, errNegativeInt(reply) - } - return uint64(reply), nil - case []byte: - n, err := strconv.ParseUint(string(reply), 10, 64) - return n, err - case nil: - return 0, ErrNil - case Error: - return 0, reply - } - return 0, fmt.Errorf("redigo: unexpected type for Uint64, got type %T", reply) -} - -// Float64 is a helper that converts a command reply to 64 bit float. If err is -// not equal to nil, then Float64 returns 0, err. Otherwise, Float64 converts -// the reply to a float64 as follows: -// -// Reply type Result -// bulk string parsed reply, nil -// nil 0, ErrNil -// other 0, error -func Float64(reply interface{}, err error) (float64, error) { - if err != nil { - return 0, err - } - switch reply := reply.(type) { - case []byte: - n, err := strconv.ParseFloat(string(reply), 64) - return n, err - case nil: - return 0, ErrNil - case Error: - return 0, reply - } - return 0, fmt.Errorf("redigo: unexpected type for Float64, got type %T", reply) -} - -// String is a helper that converts a command reply to a string. If err is not -// equal to nil, then String returns "", err. Otherwise String converts the -// reply to a string as follows: -// -// Reply type Result -// bulk string string(reply), nil -// simple string reply, nil -// nil "", ErrNil -// other "", error -func String(reply interface{}, err error) (string, error) { - if err != nil { - return "", err - } - switch reply := reply.(type) { - case []byte: - return string(reply), nil - case string: - return reply, nil - case nil: - return "", ErrNil - case Error: - return "", reply - } - return "", fmt.Errorf("redigo: unexpected type for String, got type %T", reply) -} - -// Bytes is a helper that converts a command reply to a slice of bytes. If err -// is not equal to nil, then Bytes returns nil, err. Otherwise Bytes converts -// the reply to a slice of bytes as follows: -// -// Reply type Result -// bulk string reply, nil -// simple string []byte(reply), nil -// nil nil, ErrNil -// other nil, error -func Bytes(reply interface{}, err error) ([]byte, error) { - if err != nil { - return nil, err - } - switch reply := reply.(type) { - case []byte: - return reply, nil - case string: - return []byte(reply), nil - case nil: - return nil, ErrNil - case Error: - return nil, reply - } - return nil, fmt.Errorf("redigo: unexpected type for Bytes, got type %T", reply) -} - -// Bool is a helper that converts a command reply to a boolean. If err is not -// equal to nil, then Bool returns false, err. Otherwise Bool converts the -// reply to boolean as follows: -// -// Reply type Result -// integer value != 0, nil -// bulk string strconv.ParseBool(reply) -// nil false, ErrNil -// other false, error -func Bool(reply interface{}, err error) (bool, error) { - if err != nil { - return false, err - } - switch reply := reply.(type) { - case int64: - return reply != 0, nil - case []byte: - return strconv.ParseBool(string(reply)) - case nil: - return false, ErrNil - case Error: - return false, reply - } - return false, fmt.Errorf("redigo: unexpected type for Bool, got type %T", reply) -} - -// MultiBulk is a helper that converts an array command reply to a []interface{}. -// -// Deprecated: Use Values instead. -func MultiBulk(reply interface{}, err error) ([]interface{}, error) { return Values(reply, err) } - -// Values is a helper that converts an array command reply to a []interface{}. -// If err is not equal to nil, then Values returns nil, err. Otherwise, Values -// converts the reply as follows: -// -// Reply type Result -// array reply, nil -// nil nil, ErrNil -// other nil, error -func Values(reply interface{}, err error) ([]interface{}, error) { - if err != nil { - return nil, err - } - switch reply := reply.(type) { - case []interface{}: - return reply, nil - case nil: - return nil, ErrNil - case Error: - return nil, reply - } - return nil, fmt.Errorf("redigo: unexpected type for Values, got type %T", reply) -} - -func sliceHelper(reply interface{}, err error, name string, makeSlice func(int), assign func(int, interface{}) error) error { - if err != nil { - return err - } - switch reply := reply.(type) { - case []interface{}: - makeSlice(len(reply)) - for i := range reply { - if reply[i] == nil { - continue - } - if err := assign(i, reply[i]); err != nil { - return err - } - } - return nil - case nil: - return ErrNil - case Error: - return reply - } - return fmt.Errorf("redigo: unexpected type for %s, got type %T", name, reply) -} - -// Float64s is a helper that converts an array command reply to a []float64. If -// err is not equal to nil, then Float64s returns nil, err. Nil array items are -// converted to 0 in the output slice. Floats64 returns an error if an array -// item is not a bulk string or nil. -func Float64s(reply interface{}, err error) ([]float64, error) { - var result []float64 - err = sliceHelper(reply, err, "Float64s", func(n int) { result = make([]float64, n) }, func(i int, v interface{}) error { - switch v := v.(type) { - case []byte: - f, err := strconv.ParseFloat(string(v), 64) - result[i] = f - return err - case Error: - return v - default: - return fmt.Errorf("redigo: unexpected element type for Float64s, got type %T", v) - } - }) - return result, err -} - -// Strings is a helper that converts an array command reply to a []string. If -// err is not equal to nil, then Strings returns nil, err. Nil array items are -// converted to "" in the output slice. Strings returns an error if an array -// item is not a bulk string or nil. -func Strings(reply interface{}, err error) ([]string, error) { - var result []string - err = sliceHelper(reply, err, "Strings", func(n int) { result = make([]string, n) }, func(i int, v interface{}) error { - switch v := v.(type) { - case string: - result[i] = v - return nil - case []byte: - result[i] = string(v) - return nil - case Error: - return v - default: - return fmt.Errorf("redigo: unexpected element type for Strings, got type %T", v) - } - }) - return result, err -} - -// ByteSlices is a helper that converts an array command reply to a [][]byte. -// If err is not equal to nil, then ByteSlices returns nil, err. Nil array -// items are stay nil. ByteSlices returns an error if an array item is not a -// bulk string or nil. -func ByteSlices(reply interface{}, err error) ([][]byte, error) { - var result [][]byte - err = sliceHelper(reply, err, "ByteSlices", func(n int) { result = make([][]byte, n) }, func(i int, v interface{}) error { - switch v := v.(type) { - case []byte: - result[i] = v - return nil - case Error: - return v - default: - return fmt.Errorf("redigo: unexpected element type for ByteSlices, got type %T", v) - } - }) - return result, err -} - -// Int64s is a helper that converts an array command reply to a []int64. -// If err is not equal to nil, then Int64s returns nil, err. Nil array -// items are stay nil. Int64s returns an error if an array item is not a -// bulk string or nil. -func Int64s(reply interface{}, err error) ([]int64, error) { - var result []int64 - err = sliceHelper(reply, err, "Int64s", func(n int) { result = make([]int64, n) }, func(i int, v interface{}) error { - switch v := v.(type) { - case int64: - result[i] = v - return nil - case []byte: - n, err := strconv.ParseInt(string(v), 10, 64) - result[i] = n - return err - case Error: - return v - default: - return fmt.Errorf("redigo: unexpected element type for Int64s, got type %T", v) - } - }) - return result, err -} - -// Ints is a helper that converts an array command reply to a []int. -// If err is not equal to nil, then Ints returns nil, err. Nil array -// items are stay nil. Ints returns an error if an array item is not a -// bulk string or nil. -func Ints(reply interface{}, err error) ([]int, error) { - var result []int - err = sliceHelper(reply, err, "Ints", func(n int) { result = make([]int, n) }, func(i int, v interface{}) error { - switch v := v.(type) { - case int64: - n := int(v) - if int64(n) != v { - return strconv.ErrRange - } - result[i] = n - return nil - case []byte: - n, err := strconv.Atoi(string(v)) - result[i] = n - return err - case Error: - return v - default: - return fmt.Errorf("redigo: unexpected element type for Ints, got type %T", v) - } - }) - return result, err -} - -// mapHelper builds a map from the data in reply. -func mapHelper(reply interface{}, err error, name string, makeMap func(int), assign func(key string, value interface{}) error) error { - values, err := Values(reply, err) - if err != nil { - return err - } - - if len(values)%2 != 0 { - return fmt.Errorf("redigo: %s expects even number of values result, got %d", name, len(values)) - } - - makeMap(len(values) / 2) - for i := 0; i < len(values); i += 2 { - key, ok := values[i].([]byte) - if !ok { - return fmt.Errorf("redigo: %s key[%d] not a bulk string value, got %T", name, i, values[i]) - } - - if err := assign(string(key), values[i+1]); err != nil { - return err - } - } - - return nil -} - -// StringMap is a helper that converts an array of strings (alternating key, value) -// into a map[string]string. The HGETALL and CONFIG GET commands return replies in this format. -// Requires an even number of values in result. -func StringMap(reply interface{}, err error) (map[string]string, error) { - var result map[string]string - err = mapHelper(reply, err, "StringMap", - func(n int) { - result = make(map[string]string, n) - }, func(key string, v interface{}) error { - value, ok := v.([]byte) - if !ok { - return fmt.Errorf("redigo: StringMap for %q not a bulk string value, got %T", key, v) - } - - result[key] = string(value) - - return nil - }, - ) - - return result, err -} - -// IntMap is a helper that converts an array of strings (alternating key, value) -// into a map[string]int. The HGETALL commands return replies in this format. -// Requires an even number of values in result. -func IntMap(result interface{}, err error) (map[string]int, error) { - var m map[string]int - err = mapHelper(result, err, "IntMap", - func(n int) { - m = make(map[string]int, n) - }, func(key string, v interface{}) error { - value, err := Int(v, nil) - if err != nil { - return err - } - - m[key] = value - - return nil - }, - ) - - return m, err -} - -// Int64Map is a helper that converts an array of strings (alternating key, value) -// into a map[string]int64. The HGETALL commands return replies in this format. -// Requires an even number of values in result. -func Int64Map(result interface{}, err error) (map[string]int64, error) { - var m map[string]int64 - err = mapHelper(result, err, "Int64Map", - func(n int) { - m = make(map[string]int64, n) - }, func(key string, v interface{}) error { - value, err := Int64(v, nil) - if err != nil { - return err - } - - m[key] = value - - return nil - }, - ) - - return m, err -} - -// Float64Map is a helper that converts an array of strings (alternating key, value) -// into a map[string]float64. The HGETALL commands return replies in this format. -// Requires an even number of values in result. -func Float64Map(result interface{}, err error) (map[string]float64, error) { - var m map[string]float64 - err = mapHelper(result, err, "Float64Map", - func(n int) { - m = make(map[string]float64, n) - }, func(key string, v interface{}) error { - value, err := Float64(v, nil) - if err != nil { - return err - } - - m[key] = value - - return nil - }, - ) - - return m, err -} - -// Positions is a helper that converts an array of positions (lat, long) -// into a [][2]float64. The GEOPOS command returns replies in this format. -func Positions(result interface{}, err error) ([]*[2]float64, error) { - values, err := Values(result, err) - if err != nil { - return nil, err - } - positions := make([]*[2]float64, len(values)) - for i := range values { - if values[i] == nil { - continue - } - - p, ok := values[i].([]interface{}) - if !ok { - return nil, fmt.Errorf("redigo: unexpected element type for interface slice, got type %T", values[i]) - } - - if len(p) != 2 { - return nil, fmt.Errorf("redigo: unexpected number of values for a member position, got %d", len(p)) - } - - lat, err := Float64(p[0], nil) - if err != nil { - return nil, err - } - - long, err := Float64(p[1], nil) - if err != nil { - return nil, err - } - - positions[i] = &[2]float64{lat, long} - } - return positions, nil -} - -// Uint64s is a helper that converts an array command reply to a []uint64. -// If err is not equal to nil, then Uint64s returns nil, err. Nil array -// items are stay nil. Uint64s returns an error if an array item is not a -// bulk string or nil. -func Uint64s(reply interface{}, err error) ([]uint64, error) { - var result []uint64 - err = sliceHelper(reply, err, "Uint64s", func(n int) { result = make([]uint64, n) }, func(i int, v interface{}) error { - switch v := v.(type) { - case uint64: - result[i] = v - return nil - case []byte: - n, err := strconv.ParseUint(string(v), 10, 64) - result[i] = n - return err - case Error: - return v - default: - return fmt.Errorf("redigo: unexpected element type for Uint64s, got type %T", v) - } - }) - return result, err -} - -// Uint64Map is a helper that converts an array of strings (alternating key, value) -// into a map[string]uint64. The HGETALL commands return replies in this format. -// Requires an even number of values in result. -func Uint64Map(result interface{}, err error) (map[string]uint64, error) { - var m map[string]uint64 - err = mapHelper(result, err, "Uint64Map", - func(n int) { - m = make(map[string]uint64, n) - }, func(key string, v interface{}) error { - value, err := Uint64(v, nil) - if err != nil { - return err - } - - m[key] = value - - return nil - }, - ) - - return m, err -} - -// SlowLogs is a helper that parse the SLOWLOG GET command output and -// return the array of SlowLog -func SlowLogs(result interface{}, err error) ([]SlowLog, error) { - rawLogs, err := Values(result, err) - if err != nil { - return nil, err - } - logs := make([]SlowLog, len(rawLogs)) - for i, e := range rawLogs { - rawLog, ok := e.([]interface{}) - if !ok { - return nil, fmt.Errorf("redigo: slowlog element is not an array, got %T", e) - } - - var log SlowLog - if len(rawLog) < 4 { - return nil, fmt.Errorf("redigo: slowlog element has %d elements, expected at least 4", len(rawLog)) - } - - log.ID, ok = rawLog[0].(int64) - if !ok { - return nil, fmt.Errorf("redigo: slowlog element[0] not an int64, got %T", rawLog[0]) - } - - timestamp, ok := rawLog[1].(int64) - if !ok { - return nil, fmt.Errorf("redigo: slowlog element[1] not an int64, got %T", rawLog[1]) - } - - log.Time = time.Unix(timestamp, 0) - duration, ok := rawLog[2].(int64) - if !ok { - return nil, fmt.Errorf("redigo: slowlog element[2] not an int64, got %T", rawLog[2]) - } - - log.ExecutionTime = time.Duration(duration) * time.Microsecond - - log.Args, err = Strings(rawLog[3], nil) - if err != nil { - return nil, fmt.Errorf("redigo: slowlog element[3] is not array of strings: %w", err) - } - - if len(rawLog) >= 6 { - log.ClientAddr, err = String(rawLog[4], nil) - if err != nil { - return nil, fmt.Errorf("redigo: slowlog element[4] is not a string: %w", err) - } - - log.ClientName, err = String(rawLog[5], nil) - if err != nil { - return nil, fmt.Errorf("redigo: slowlog element[5] is not a string: %w", err) - } - } - logs[i] = log - } - return logs, nil -} - -// Latencies is a helper that parses the LATENCY LATEST command output and -// return the slice of Latency values. -func Latencies(result interface{}, err error) ([]Latency, error) { - rawLatencies, err := Values(result, err) - if err != nil { - return nil, err - } - - latencies := make([]Latency, len(rawLatencies)) - for i, e := range rawLatencies { - rawLatency, ok := e.([]interface{}) - if !ok { - return nil, fmt.Errorf("redigo: latencies element is not slice, got %T", e) - } - - var event Latency - if len(rawLatency) != 4 { - return nil, fmt.Errorf("redigo: latencies element has %d elements, expected 4", len(rawLatency)) - } - - event.Name, err = String(rawLatency[0], nil) - if err != nil { - return nil, fmt.Errorf("redigo: latencies element[0] is not a string: %w", err) - } - - timestamp, ok := rawLatency[1].(int64) - if !ok { - return nil, fmt.Errorf("redigo: latencies element[1] not an int64, got %T", rawLatency[1]) - } - - event.Time = time.Unix(timestamp, 0) - - latestDuration, ok := rawLatency[2].(int64) - if !ok { - return nil, fmt.Errorf("redigo: latencies element[2] not an int64, got %T", rawLatency[2]) - } - - event.Latest = time.Duration(latestDuration) * time.Millisecond - - maxDuration, ok := rawLatency[3].(int64) - if !ok { - return nil, fmt.Errorf("redigo: latencies element[3] not an int64, got %T", rawLatency[3]) - } - - event.Max = time.Duration(maxDuration) * time.Millisecond - - latencies[i] = event - } - - return latencies, nil -} - -// LatencyHistories is a helper that parse the LATENCY HISTORY command output and -// returns a LatencyHistory slice. -func LatencyHistories(result interface{}, err error) ([]LatencyHistory, error) { - rawLogs, err := Values(result, err) - if err != nil { - return nil, err - } - - latencyHistories := make([]LatencyHistory, len(rawLogs)) - for i, e := range rawLogs { - rawLog, ok := e.([]interface{}) - if !ok { - return nil, fmt.Errorf("redigo: latency history element is not an slice, got %T", e) - } - - var event LatencyHistory - timestamp, ok := rawLog[0].(int64) - if !ok { - return nil, fmt.Errorf("redigo: latency history element[0] not an int64, got %T", rawLog[0]) - } - - event.Time = time.Unix(timestamp, 0) - - duration, ok := rawLog[1].(int64) - if !ok { - return nil, fmt.Errorf("redigo: latency history element[1] not an int64, got %T", rawLog[1]) - } - - event.ExecutionTime = time.Duration(duration) * time.Millisecond - - latencyHistories[i] = event - } - - return latencyHistories, nil -} diff --git a/vendor/github.com/gomodule/redigo/redis/scan.go b/vendor/github.com/gomodule/redigo/redis/scan.go deleted file mode 100644 index c1fb800d1a..0000000000 --- a/vendor/github.com/gomodule/redigo/redis/scan.go +++ /dev/null @@ -1,729 +0,0 @@ -// Copyright 2012 Gary Burd -// -// 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. - -package redis - -import ( - "errors" - "fmt" - "reflect" - "strconv" - "strings" - "sync" -) - -var ( - scannerType = reflect.TypeOf((*Scanner)(nil)).Elem() -) - -func ensureLen(d reflect.Value, n int) { - if n > d.Cap() { - d.Set(reflect.MakeSlice(d.Type(), n, n)) - } else { - d.SetLen(n) - } -} - -func cannotConvert(d reflect.Value, s interface{}) error { - var sname string - switch s.(type) { - case string: - sname = "Redis simple string" - case Error: - sname = "Redis error" - case int64: - sname = "Redis integer" - case []byte: - sname = "Redis bulk string" - case []interface{}: - sname = "Redis array" - case nil: - sname = "Redis nil" - default: - sname = reflect.TypeOf(s).String() - } - return fmt.Errorf("cannot convert from %s to %s", sname, d.Type()) -} - -func convertAssignNil(d reflect.Value) (err error) { - switch d.Type().Kind() { - case reflect.Slice, reflect.Interface: - d.Set(reflect.Zero(d.Type())) - default: - err = cannotConvert(d, nil) - } - return err -} - -func convertAssignError(d reflect.Value, s Error) (err error) { - if d.Kind() == reflect.String { - d.SetString(string(s)) - } else if d.Kind() == reflect.Slice && d.Type().Elem().Kind() == reflect.Uint8 { - d.SetBytes([]byte(s)) - } else { - err = cannotConvert(d, s) - } - return -} - -func convertAssignString(d reflect.Value, s string) (err error) { - switch d.Type().Kind() { - case reflect.Float32, reflect.Float64: - var x float64 - x, err = strconv.ParseFloat(s, d.Type().Bits()) - d.SetFloat(x) - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: - var x int64 - x, err = strconv.ParseInt(s, 10, d.Type().Bits()) - d.SetInt(x) - case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: - var x uint64 - x, err = strconv.ParseUint(s, 10, d.Type().Bits()) - d.SetUint(x) - case reflect.Bool: - var x bool - x, err = strconv.ParseBool(s) - d.SetBool(x) - case reflect.String: - d.SetString(s) - case reflect.Slice: - if d.Type().Elem().Kind() == reflect.Uint8 { - d.SetBytes([]byte(s)) - } else { - err = cannotConvert(d, s) - } - case reflect.Ptr: - err = convertAssignString(d.Elem(), s) - default: - err = cannotConvert(d, s) - } - return -} - -func convertAssignBulkString(d reflect.Value, s []byte) (err error) { - switch d.Type().Kind() { - case reflect.Slice: - // Handle []byte destination here to avoid unnecessary - // []byte -> string -> []byte converion. - if d.Type().Elem().Kind() == reflect.Uint8 { - d.SetBytes(s) - } else { - err = cannotConvert(d, s) - } - case reflect.Ptr: - if d.CanInterface() && d.CanSet() { - if s == nil { - if d.IsNil() { - return nil - } - - d.Set(reflect.Zero(d.Type())) - return nil - } - - if d.IsNil() { - d.Set(reflect.New(d.Type().Elem())) - } - - if sc, ok := d.Interface().(Scanner); ok { - return sc.RedisScan(s) - } - } - err = convertAssignString(d, string(s)) - default: - err = convertAssignString(d, string(s)) - } - return err -} - -func convertAssignInt(d reflect.Value, s int64) (err error) { - switch d.Type().Kind() { - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: - d.SetInt(s) - if d.Int() != s { - err = strconv.ErrRange - d.SetInt(0) - } - case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: - if s < 0 { - err = strconv.ErrRange - } else { - x := uint64(s) - d.SetUint(x) - if d.Uint() != x { - err = strconv.ErrRange - d.SetUint(0) - } - } - case reflect.Bool: - d.SetBool(s != 0) - default: - err = cannotConvert(d, s) - } - return -} - -func convertAssignValue(d reflect.Value, s interface{}) (err error) { - if d.Kind() != reflect.Ptr { - if d.CanAddr() { - d2 := d.Addr() - if d2.CanInterface() { - if scanner, ok := d2.Interface().(Scanner); ok { - return scanner.RedisScan(s) - } - } - } - } else if d.CanInterface() { - // Already a reflect.Ptr - if d.IsNil() { - d.Set(reflect.New(d.Type().Elem())) - } - if scanner, ok := d.Interface().(Scanner); ok { - return scanner.RedisScan(s) - } - } - - switch s := s.(type) { - case nil: - err = convertAssignNil(d) - case []byte: - err = convertAssignBulkString(d, s) - case int64: - err = convertAssignInt(d, s) - case string: - err = convertAssignString(d, s) - case Error: - err = convertAssignError(d, s) - default: - err = cannotConvert(d, s) - } - return err -} - -func convertAssignArray(d reflect.Value, s []interface{}) error { - if d.Type().Kind() != reflect.Slice { - return cannotConvert(d, s) - } - ensureLen(d, len(s)) - for i := 0; i < len(s); i++ { - if err := convertAssignValue(d.Index(i), s[i]); err != nil { - return err - } - } - return nil -} - -func convertAssign(d interface{}, s interface{}) (err error) { - if scanner, ok := d.(Scanner); ok { - return scanner.RedisScan(s) - } - - // Handle the most common destination types using type switches and - // fall back to reflection for all other types. - switch s := s.(type) { - case nil: - // ignore - case []byte: - switch d := d.(type) { - case *string: - *d = string(s) - case *int: - *d, err = strconv.Atoi(string(s)) - case *bool: - *d, err = strconv.ParseBool(string(s)) - case *[]byte: - *d = s - case *interface{}: - *d = s - case nil: - // skip value - default: - if d := reflect.ValueOf(d); d.Type().Kind() != reflect.Ptr { - err = cannotConvert(d, s) - } else { - err = convertAssignBulkString(d.Elem(), s) - } - } - case int64: - switch d := d.(type) { - case *int: - x := int(s) - if int64(x) != s { - err = strconv.ErrRange - x = 0 - } - *d = x - case *bool: - *d = s != 0 - case *interface{}: - *d = s - case nil: - // skip value - default: - if d := reflect.ValueOf(d); d.Type().Kind() != reflect.Ptr { - err = cannotConvert(d, s) - } else { - err = convertAssignInt(d.Elem(), s) - } - } - case string: - switch d := d.(type) { - case *string: - *d = s - case *interface{}: - *d = s - case nil: - // skip value - default: - err = cannotConvert(reflect.ValueOf(d), s) - } - case []interface{}: - switch d := d.(type) { - case *[]interface{}: - *d = s - case *interface{}: - *d = s - case nil: - // skip value - default: - if d := reflect.ValueOf(d); d.Type().Kind() != reflect.Ptr { - err = cannotConvert(d, s) - } else { - err = convertAssignArray(d.Elem(), s) - } - } - case Error: - err = s - default: - err = cannotConvert(reflect.ValueOf(d), s) - } - return -} - -// Scan copies from src to the values pointed at by dest. -// -// Scan uses RedisScan if available otherwise: -// -// The values pointed at by dest must be an integer, float, boolean, string, -// []byte, interface{} or slices of these types. Scan uses the standard strconv -// package to convert bulk strings to numeric and boolean types. -// -// If a dest value is nil, then the corresponding src value is skipped. -// -// If a src element is nil, then the corresponding dest value is not modified. -// -// To enable easy use of Scan in a loop, Scan returns the slice of src -// following the copied values. -func Scan(src []interface{}, dest ...interface{}) ([]interface{}, error) { - if len(src) < len(dest) { - return nil, errors.New("redigo.Scan: array short") - } - var err error - for i, d := range dest { - err = convertAssign(d, src[i]) - if err != nil { - err = fmt.Errorf("redigo.Scan: cannot assign to dest %d: %v", i, err) - break - } - } - return src[len(dest):], err -} - -type fieldSpec struct { - name string - index []int - omitEmpty bool -} - -type structSpec struct { - m map[string]*fieldSpec - l []*fieldSpec -} - -func (ss *structSpec) fieldSpec(name []byte) *fieldSpec { - return ss.m[string(name)] -} - -func compileStructSpec(t reflect.Type, depth map[string]int, index []int, ss *structSpec, seen map[reflect.Type]struct{}) error { - if _, ok := seen[t]; ok { - // Protect against infinite recursion. - return fmt.Errorf("recursive struct definition for %v", t) - } - - seen[t] = struct{}{} -LOOP: - for i := 0; i < t.NumField(); i++ { - f := t.Field(i) - switch { - case f.PkgPath != "" && !f.Anonymous: - // Ignore unexported fields. - case f.Anonymous: - switch f.Type.Kind() { - case reflect.Struct: - if err := compileStructSpec(f.Type, depth, append(index, i), ss, seen); err != nil { - return err - } - case reflect.Ptr: - if f.Type.Elem().Kind() == reflect.Struct { - if err := compileStructSpec(f.Type.Elem(), depth, append(index, i), ss, seen); err != nil { - return err - } - } - } - default: - fs := &fieldSpec{name: f.Name} - tag := f.Tag.Get("redis") - - var p string - first := true - for len(tag) > 0 { - i := strings.IndexByte(tag, ',') - if i < 0 { - p, tag = tag, "" - } else { - p, tag = tag[:i], tag[i+1:] - } - if p == "-" { - continue LOOP - } - if first && len(p) > 0 { - fs.name = p - first = false - } else { - switch p { - case "omitempty": - fs.omitEmpty = true - default: - panic(fmt.Errorf("redigo: unknown field tag %s for type %s", p, t.Name())) - } - } - } - - d, found := depth[fs.name] - if !found { - d = 1 << 30 - } - - switch { - case len(index) == d: - // At same depth, remove from result. - delete(ss.m, fs.name) - j := 0 - for i := 0; i < len(ss.l); i++ { - if fs.name != ss.l[i].name { - ss.l[j] = ss.l[i] - j += 1 - } - } - ss.l = ss.l[:j] - case len(index) < d: - fs.index = make([]int, len(index)+1) - copy(fs.index, index) - fs.index[len(index)] = i - depth[fs.name] = len(index) - ss.m[fs.name] = fs - ss.l = append(ss.l, fs) - } - } - } - - return nil -} - -var ( - structSpecMutex sync.RWMutex - structSpecCache = make(map[reflect.Type]*structSpec) -) - -func structSpecForType(t reflect.Type) (*structSpec, error) { - structSpecMutex.RLock() - ss, found := structSpecCache[t] - structSpecMutex.RUnlock() - if found { - return ss, nil - } - - structSpecMutex.Lock() - defer structSpecMutex.Unlock() - ss, found = structSpecCache[t] - if found { - return ss, nil - } - - ss = &structSpec{m: make(map[string]*fieldSpec)} - if err := compileStructSpec(t, make(map[string]int), nil, ss, make(map[reflect.Type]struct{})); err != nil { - return nil, fmt.Errorf("compile struct: %s: %w", t, err) - } - structSpecCache[t] = ss - return ss, nil -} - -var errScanStructValue = errors.New("redigo.ScanStruct: value must be non-nil pointer to a struct") - -// ScanStruct scans alternating names and values from src to a struct. The -// HGETALL and CONFIG GET commands return replies in this format. -// -// ScanStruct uses exported field names to match values in the response. Use -// 'redis' field tag to override the name: -// -// Field int `redis:"myName"` -// -// Fields with the tag redis:"-" are ignored. -// -// Each field uses RedisScan if available otherwise: -// Integer, float, boolean, string and []byte fields are supported. Scan uses the -// standard strconv package to convert bulk string values to numeric and -// boolean types. -// -// If a src element is nil, then the corresponding field is not modified. -func ScanStruct(src []interface{}, dest interface{}) error { - d := reflect.ValueOf(dest) - if d.Kind() != reflect.Ptr || d.IsNil() { - return errScanStructValue - } - - d = d.Elem() - if d.Kind() != reflect.Struct { - return errScanStructValue - } - - if len(src)%2 != 0 { - return errors.New("redigo.ScanStruct: number of values not a multiple of 2") - } - - ss, err := structSpecForType(d.Type()) - if err != nil { - return fmt.Errorf("redigo.ScanStruct: %w", err) - } - - for i := 0; i < len(src); i += 2 { - s := src[i+1] - if s == nil { - continue - } - - name, ok := convertToBulk(src[i]) - if !ok { - return fmt.Errorf("redigo.ScanStruct: key %d not a bulk string value got type: %T", i, src[i]) - } - - fs := ss.fieldSpec(name) - if fs == nil { - continue - } - - if err := convertAssignValue(fieldByIndexCreate(d, fs.index), s); err != nil { - return fmt.Errorf("redigo.ScanStruct: cannot assign field %s: %v", fs.name, err) - } - } - return nil -} - -// convertToBulk converts src to a []byte if src is a string or bulk string -// and returns true. Otherwise nil and false is returned. -func convertToBulk(src interface{}) ([]byte, bool) { - switch v := src.(type) { - case []byte: - return v, true - case string: - return []byte(v), true - default: - return nil, false - } -} - -var ( - errScanSliceValue = errors.New("redigo.ScanSlice: dest must be non-nil pointer to a struct") -) - -// ScanSlice scans src to the slice pointed to by dest. -// -// If the target is a slice of types which implement Scanner then the custom -// RedisScan method is used otherwise the following rules apply: -// -// The elements in the dest slice must be integer, float, boolean, string, struct -// or pointer to struct values. -// -// Struct fields must be integer, float, boolean or string values. All struct -// fields are used unless a subset is specified using fieldNames. -func ScanSlice(src []interface{}, dest interface{}, fieldNames ...string) error { - d := reflect.ValueOf(dest) - if d.Kind() != reflect.Ptr || d.IsNil() { - return errScanSliceValue - } - d = d.Elem() - if d.Kind() != reflect.Slice { - return errScanSliceValue - } - - isPtr := false - t := d.Type().Elem() - st := t - if t.Kind() == reflect.Ptr && t.Elem().Kind() == reflect.Struct { - isPtr = true - t = t.Elem() - } - - if t.Kind() != reflect.Struct || st.Implements(scannerType) { - ensureLen(d, len(src)) - for i, s := range src { - if s == nil { - continue - } - if err := convertAssignValue(d.Index(i), s); err != nil { - return fmt.Errorf("redigo.ScanSlice: cannot assign element %d: %v", i, err) - } - } - return nil - } - - ss, err := structSpecForType(t) - if err != nil { - return fmt.Errorf("redigo.ScanSlice: %w", err) - } - - fss := ss.l - if len(fieldNames) > 0 { - fss = make([]*fieldSpec, len(fieldNames)) - for i, name := range fieldNames { - fss[i] = ss.m[name] - if fss[i] == nil { - return fmt.Errorf("redigo.ScanSlice: ScanSlice bad field name %s", name) - } - } - } - - if len(fss) == 0 { - return errors.New("redigo.ScanSlice: no struct fields") - } - - n := len(src) / len(fss) - if n*len(fss) != len(src) { - return errors.New("redigo.ScanSlice: length not a multiple of struct field count") - } - - ensureLen(d, n) - for i := 0; i < n; i++ { - d := d.Index(i) - if isPtr { - if d.IsNil() { - d.Set(reflect.New(t)) - } - d = d.Elem() - } - for j, fs := range fss { - s := src[i*len(fss)+j] - if s == nil { - continue - } - if err := convertAssignValue(d.FieldByIndex(fs.index), s); err != nil { - return fmt.Errorf("redigo.ScanSlice: cannot assign element %d to field %s: %v", i*len(fss)+j, fs.name, err) - } - } - } - return nil -} - -// Args is a helper for constructing command arguments from structured values. -type Args []interface{} - -// Add returns the result of appending value to args. -func (args Args) Add(value ...interface{}) Args { - return append(args, value...) -} - -// AddFlat returns the result of appending the flattened value of v to args. -// -// Maps are flattened by appending the alternating keys and map values to args. -// -// Slices are flattened by appending the slice elements to args. -// -// Structs are flattened by appending the alternating names and values of -// exported fields to args. If v is a nil struct pointer, then nothing is -// appended. The 'redis' field tag overrides struct field names. See ScanStruct -// for more information on the use of the 'redis' field tag. -// -// Other types are appended to args as is. -// panics if v includes a recursive anonymous struct. -func (args Args) AddFlat(v interface{}) Args { - rv := reflect.ValueOf(v) - switch rv.Kind() { - case reflect.Struct: - args = flattenStruct(args, rv) - case reflect.Slice: - for i := 0; i < rv.Len(); i++ { - args = append(args, rv.Index(i).Interface()) - } - case reflect.Map: - for _, k := range rv.MapKeys() { - args = append(args, k.Interface(), rv.MapIndex(k).Interface()) - } - case reflect.Ptr: - if rv.Type().Elem().Kind() == reflect.Struct { - if !rv.IsNil() { - args = flattenStruct(args, rv.Elem()) - } - } else { - args = append(args, v) - } - default: - args = append(args, v) - } - return args -} - -func flattenStruct(args Args, v reflect.Value) Args { - ss, err := structSpecForType(v.Type()) - if err != nil { - panic(fmt.Errorf("redigo.AddFlat: %w", err)) - } - - for _, fs := range ss.l { - fv, err := fieldByIndexErr(v, fs.index) - if err != nil { - // Nil item ignore. - continue - } - if fs.omitEmpty { - var empty = false - switch fv.Kind() { - case reflect.Array, reflect.Map, reflect.Slice, reflect.String: - empty = fv.Len() == 0 - case reflect.Bool: - empty = !fv.Bool() - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: - empty = fv.Int() == 0 - case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: - empty = fv.Uint() == 0 - case reflect.Float32, reflect.Float64: - empty = fv.Float() == 0 - case reflect.Interface, reflect.Ptr: - empty = fv.IsNil() - } - if empty { - continue - } - } - if arg, ok := fv.Interface().(Argument); ok { - args = append(args, fs.name, arg.RedisArg()) - } else if fv.Kind() == reflect.Ptr { - if !fv.IsNil() { - args = append(args, fs.name, fv.Elem().Interface()) - } - } else { - args = append(args, fs.name, fv.Interface()) - } - } - return args -} diff --git a/vendor/github.com/gomodule/redigo/redis/script.go b/vendor/github.com/gomodule/redigo/redis/script.go deleted file mode 100644 index c585518ba8..0000000000 --- a/vendor/github.com/gomodule/redigo/redis/script.go +++ /dev/null @@ -1,104 +0,0 @@ -// Copyright 2012 Gary Burd -// -// 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. - -package redis - -import ( - "context" - "crypto/sha1" - "encoding/hex" - "io" - "strings" -) - -// Script encapsulates the source, hash and key count for a Lua script. See -// http://redis.io/commands/eval for information on scripts in Redis. -type Script struct { - keyCount int - src string - hash string -} - -// NewScript returns a new script object. If keyCount is greater than or equal -// to zero, then the count is automatically inserted in the EVAL command -// argument list. If keyCount is less than zero, then the application supplies -// the count as the first value in the keysAndArgs argument to the Do, Send and -// SendHash methods. -func NewScript(keyCount int, src string) *Script { - h := sha1.New() - io.WriteString(h, src) // nolint: errcheck - return &Script{keyCount, src, hex.EncodeToString(h.Sum(nil))} -} - -func (s *Script) args(spec string, keysAndArgs []interface{}) []interface{} { - var args []interface{} - if s.keyCount < 0 { - args = make([]interface{}, 1+len(keysAndArgs)) - args[0] = spec - copy(args[1:], keysAndArgs) - } else { - args = make([]interface{}, 2+len(keysAndArgs)) - args[0] = spec - args[1] = s.keyCount - copy(args[2:], keysAndArgs) - } - return args -} - -// Hash returns the script hash. -func (s *Script) Hash() string { - return s.hash -} - -func (s *Script) DoContext(ctx context.Context, c Conn, keysAndArgs ...interface{}) (interface{}, error) { - cwt, ok := c.(ConnWithContext) - if !ok { - return nil, errContextNotSupported - } - v, err := cwt.DoContext(ctx, "EVALSHA", s.args(s.hash, keysAndArgs)...) - if e, ok := err.(Error); ok && strings.HasPrefix(string(e), "NOSCRIPT ") { - v, err = cwt.DoContext(ctx, "EVAL", s.args(s.src, keysAndArgs)...) - } - return v, err -} - -// Do evaluates the script. Under the covers, Do optimistically evaluates the -// script using the EVALSHA command. If the command fails because the script is -// not loaded, then Do evaluates the script using the EVAL command (thus -// causing the script to load). -func (s *Script) Do(c Conn, keysAndArgs ...interface{}) (interface{}, error) { - v, err := c.Do("EVALSHA", s.args(s.hash, keysAndArgs)...) - if err != nil && strings.HasPrefix(err.Error(), "NOSCRIPT ") { - v, err = c.Do("EVAL", s.args(s.src, keysAndArgs)...) - } - return v, err -} - -// SendHash evaluates the script without waiting for the reply. The script is -// evaluated with the EVALSHA command. The application must ensure that the -// script is loaded by a previous call to Send, Do or Load methods. -func (s *Script) SendHash(c Conn, keysAndArgs ...interface{}) error { - return c.Send("EVALSHA", s.args(s.hash, keysAndArgs)...) -} - -// Send evaluates the script without waiting for the reply. -func (s *Script) Send(c Conn, keysAndArgs ...interface{}) error { - return c.Send("EVAL", s.args(s.src, keysAndArgs)...) -} - -// Load loads the script without evaluating it. -func (s *Script) Load(c Conn) error { - _, err := c.Do("SCRIPT", "LOAD", s.src) - return err -} diff --git a/vendor/github.com/google/renameio/v2/option.go b/vendor/github.com/google/renameio/v2/option.go index a86906f4cd..39bfe0b859 100644 --- a/vendor/github.com/google/renameio/v2/option.go +++ b/vendor/github.com/google/renameio/v2/option.go @@ -13,7 +13,6 @@ // limitations under the License. //go:build !windows -// +build !windows package renameio @@ -86,3 +85,14 @@ func WithReplaceOnClose() Option { c.renameOnClose = true }) } + +// WithRoot specifies a root directory to use when working with files. +// See [os.Root] and https://go.dev/blog/osroot for more details. +// +// When WithRoot is used, WithTempDir (and the $TMPDIR environment variable) are +// ignored, as temporary files must be created in the specified root directory. +func WithRoot(root *os.Root) Option { + return optionFunc(func(c *config) { + c.root = root + }) +} diff --git a/vendor/github.com/google/renameio/v2/tempfile.go b/vendor/github.com/google/renameio/v2/tempfile.go index 98114e539c..e101e4e704 100644 --- a/vendor/github.com/google/renameio/v2/tempfile.go +++ b/vendor/github.com/google/renameio/v2/tempfile.go @@ -13,13 +13,11 @@ // limitations under the License. //go:build !windows -// +build !windows package renameio import ( - "io/ioutil" - "math/rand" + "math/rand/v2" "os" "path/filepath" "strconv" @@ -29,10 +27,10 @@ import ( const defaultPerm os.FileMode = 0o600 // nextrandom is a function generating a random number. -var nextrandom = rand.Int63 +var nextrandom = rand.Int64 // openTempFile creates a randomly named file and returns an open handle. It is -// similar to ioutil.TempFile except that the directory must be given, the file +// similar to os.CreateTemp except that the directory must be given, the file // permissions can be controlled and patterns in the name are not supported. // The name is always suffixed with a random number. func openTempFile(dir, name string, perm os.FileMode) (*os.File, error) { @@ -58,6 +56,33 @@ func openTempFile(dir, name string, perm os.FileMode) (*os.File, error) { } } +// openTempFileRoot creates a randomly named file in root and returns an open +// handle. It is similar to os.CreateTemp except that the directory must be +// given, the file permissions can be controlled and patterns in the name are +// not supported. The name is always suffixed with a random number. +func openTempFileRoot(root *os.Root, name string, perm os.FileMode) (string, *os.File, error) { + prefix := name + + for attempt := 0; ; { + // Generate a reasonably random name which is unlikely to already + // exist. O_EXCL ensures that existing files generate an error. + name := prefix + strconv.FormatInt(nextrandom(), 10) + + f, err := root.OpenFile(name, os.O_RDWR|os.O_CREATE|os.O_EXCL, perm) + if !os.IsExist(err) { + return name, f, err + } + + if attempt++; attempt > 10000 { + return "", nil, &os.PathError{ + Op: "tempfile", + Path: name, + Err: os.ErrExist, + } + } + } +} + // TempDir checks whether os.TempDir() can be used as a temporary directory for // later atomically replacing files within dest. If no (os.TempDir() resides on // a different mount point), dest is returned. @@ -83,7 +108,7 @@ func tempDir(dir, dest string) string { // the TMPDIR environment variable. tmpdir := os.TempDir() - testsrc, err := ioutil.TempFile(tmpdir, "."+filepath.Base(dest)) + testsrc, err := os.CreateTemp(tmpdir, "."+filepath.Base(dest)) if err != nil { return fallback } @@ -95,7 +120,7 @@ func tempDir(dir, dest string) string { }() testsrc.Close() - testdest, err := ioutil.TempFile(filepath.Dir(dest), "."+filepath.Base(dest)) + testdest, err := os.CreateTemp(filepath.Dir(dest), "."+filepath.Base(dest)) if err != nil { return fallback } @@ -118,6 +143,8 @@ type PendingFile struct { done bool closed bool replaceOnClose bool + root *os.Root + tmpname string } // Cleanup is a no-op if CloseAtomicallyReplace succeeded, and otherwise closes @@ -134,8 +161,14 @@ func (t *PendingFile) Cleanup() error { if !t.closed { closeErr = t.File.Close() } - if err := os.Remove(t.Name()); err != nil { - return err + if t.root != nil { + if err := t.root.Remove(t.tmpname); err != nil { + return err + } + } else { + if err := os.Remove(t.Name()); err != nil { + return err + } } t.done = true return closeErr @@ -163,8 +196,14 @@ func (t *PendingFile) CloseAtomicallyReplace() error { if err := t.File.Close(); err != nil { return err } - if err := os.Rename(t.Name(), t.path); err != nil { - return err + if t.root != nil { + if err := t.root.Rename(t.tmpname, t.path); err != nil { + return err + } + } else { + if err := os.Rename(t.Name(), t.path); err != nil { + return err + } } t.done = true return nil @@ -200,6 +239,7 @@ type config struct { ignoreUmask bool chmod *os.FileMode renameOnClose bool + root *os.Root } // NewPendingFile creates a temporary file destined to atomically creating or @@ -227,8 +267,15 @@ func NewPendingFile(path string, opts ...Option) (*PendingFile, error) { } if cfg.attemptPermCopy { + var existing os.FileInfo + var err error + if cfg.root != nil { + existing, err = cfg.root.Lstat(cfg.path) + } else { + existing, err = os.Lstat(cfg.path) + } // Try to determine permissions from an existing file. - if existing, err := os.Lstat(cfg.path); err == nil && existing.Mode().IsRegular() { + if err == nil && existing.Mode().IsRegular() { perm := existing.Mode() & os.ModePerm cfg.chmod = &perm @@ -240,7 +287,14 @@ func NewPendingFile(path string, opts ...Option) (*PendingFile, error) { } } - f, err := openTempFile(tempDir(cfg.dir, cfg.path), "."+filepath.Base(cfg.path), cfg.createPerm) + var f *os.File + var err error + var tmpname string + if cfg.root != nil { + tmpname, f, err = openTempFileRoot(cfg.root, "."+filepath.Base(cfg.path), cfg.createPerm) + } else { + f, err = openTempFile(tempDir(cfg.dir, cfg.path), "."+filepath.Base(cfg.path), cfg.createPerm) + } if err != nil { return nil, err } @@ -255,7 +309,13 @@ func NewPendingFile(path string, opts ...Option) (*PendingFile, error) { } } - return &PendingFile{File: f, path: cfg.path, replaceOnClose: cfg.renameOnClose}, nil + return &PendingFile{ + File: f, + path: cfg.path, + replaceOnClose: cfg.renameOnClose, + root: cfg.root, + tmpname: tmpname, + }, nil } // Symlink wraps os.Symlink, replacing an existing symlink with the same name @@ -267,9 +327,9 @@ func Symlink(oldname, newname string) error { return err } - // We need to use ioutil.TempDir, as we cannot overwrite a ioutil.TempFile, + // We need to use os.MkdirTemp, as we cannot overwrite a os.CreateTemp file, // and removing+symlinking creates a TOCTOU race. - d, err := ioutil.TempDir(filepath.Dir(newname), "."+filepath.Base(newname)) + d, err := os.MkdirTemp(filepath.Dir(newname), "."+filepath.Base(newname)) if err != nil { return err } @@ -292,3 +352,41 @@ func Symlink(oldname, newname string) error { cleanup = false return os.RemoveAll(d) } + +// SymlinkRoot wraps os.Symlink, replacing an existing symlink with the same +// name atomically (os.Symlink fails when newname already exists, at least on +// Linux). +func SymlinkRoot(root *os.Root, oldname, newname string) error { + // Fast path: if newname does not exist yet, we can skip the whole dance + // below. + if err := root.Symlink(oldname, newname); err == nil || !os.IsExist(err) { + return err + } + + // We need to use os.MkdirTemp, as we cannot overwrite a os.CreateTemp file, + // and removing+symlinking creates a TOCTOU race. + // + // There is no os.Root-compatible os.MkdirTemp, so we use the path directly. + d, err := os.MkdirTemp(root.Name(), "."+filepath.Base(newname)) + if err != nil { + return err + } + cleanup := true + defer func() { + if cleanup { + os.RemoveAll(d) + } + }() + + symlink := filepath.Join(filepath.Base(d), "tmp.symlink") + if err := root.Symlink(oldname, symlink); err != nil { + return err + } + + if err := root.Rename(symlink, newname); err != nil { + return err + } + + cleanup = false + return os.RemoveAll(d) +} diff --git a/vendor/github.com/google/renameio/v2/writefile.go b/vendor/github.com/google/renameio/v2/writefile.go index 545042102b..097817f0e1 100644 --- a/vendor/github.com/google/renameio/v2/writefile.go +++ b/vendor/github.com/google/renameio/v2/writefile.go @@ -13,13 +13,12 @@ // limitations under the License. //go:build !windows -// +build !windows package renameio import "os" -// WriteFile mirrors ioutil.WriteFile, replacing an existing file with the same +// WriteFile mirrors os.WriteFile, replacing an existing file with the same // name atomically. func WriteFile(filename string, data []byte, perm os.FileMode, opts ...Option) error { opts = append([]Option{ diff --git a/vendor/github.com/minio/minio-go/v7/.gitignore b/vendor/github.com/minio/minio-go/v7/.gitignore index 8ae0384ebc..5bb12e74af 100644 --- a/vendor/github.com/minio/minio-go/v7/.gitignore +++ b/vendor/github.com/minio/minio-go/v7/.gitignore @@ -3,4 +3,5 @@ validator golangci-lint functional_tests -.idea \ No newline at end of file +.idea +vendor/ diff --git a/vendor/github.com/minio/minio-go/v7/api-get-object.go b/vendor/github.com/minio/minio-go/v7/api-get-object.go index d3cb6c22a0..a1741b020f 100644 --- a/vendor/github.com/minio/minio-go/v7/api-get-object.go +++ b/vendor/github.com/minio/minio-go/v7/api-get-object.go @@ -458,7 +458,14 @@ func (o *Object) ReadAt(b []byte, offset int64) (n int, err error) { return 0, o.prevErr } - // Set the current offset to ReadAt offset, because the current offset will be shifted at the end of this method. + // Save and restore currOffset so ReadAt doesn't affect sequential Read operations. + // Per io.ReaderAt: "ReadAt should not affect nor be affected by the underlying seek offset." + savedOffset := o.currOffset + defer func() { + o.currOffset = savedOffset + o.seekData = true // Force next Read to re-establish stream at correct position + }() + o.currOffset = offset // Can only compare offsets to size when size has been set. diff --git a/vendor/github.com/minio/minio-go/v7/api-put-object-streaming.go b/vendor/github.com/minio/minio-go/v7/api-put-object-streaming.go index 79d0c1dc1b..70e9af3ad0 100644 --- a/vendor/github.com/minio/minio-go/v7/api-put-object-streaming.go +++ b/vendor/github.com/minio/minio-go/v7/api-put-object-streaming.go @@ -525,7 +525,7 @@ func (c *Client) putObjectMultipartStreamParallel(ctx context.Context, bucketNam break } - if rerr != nil && rerr != io.ErrUnexpectedEOF && err != io.EOF { + if rerr != nil && rerr != io.ErrUnexpectedEOF && rerr != io.EOF { cancel() wg.Wait() return UploadInfo{}, rerr diff --git a/vendor/github.com/minio/minio-go/v7/api-update-object-encryption.go b/vendor/github.com/minio/minio-go/v7/api-update-object-encryption.go new file mode 100644 index 0000000000..b49a5b7276 --- /dev/null +++ b/vendor/github.com/minio/minio-go/v7/api-update-object-encryption.go @@ -0,0 +1,122 @@ +/* + * MinIO Go Library for Amazon S3 Compatible Cloud Storage + * Copyright 2025-2026 MinIO, Inc. + * + * 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. + */ + +package minio + +import ( + "bytes" + "context" + "encoding/xml" + "net/http" + "net/url" + + "github.com/minio/minio-go/v7/pkg/s3utils" +) + +// updateObjectEncryptionSSEKMS represents the SSE-KMS element in the request body. +type updateObjectEncryptionSSEKMS struct { + BucketKeyEnabled bool `xml:"BucketKeyEnabled,omitempty"` + KMSKeyArn string `xml:"KMSKeyArn"` +} + +// updateObjectEncryptionRequest represents the XML request body for UpdateObjectEncryption. +type updateObjectEncryptionRequest struct { + XMLName xml.Name `xml:"ObjectEncryption"` + XMLNS string `xml:"xmlns,attr"` + SSEKMS *updateObjectEncryptionSSEKMS `xml:"SSE-KMS"` +} + +// UpdateObjectEncryptionOptions holds options for the UpdateObjectEncryption call. +type UpdateObjectEncryptionOptions struct { + // KMSKeyArn is the KMS key name or ARN to encrypt the object with. + KMSKeyArn string + + // BucketKeyEnabled enables S3 Bucket Key for KMS encryption. + BucketKeyEnabled bool + + // VersionID targets a specific object version. + VersionID string +} + +// UpdateObjectEncryption changes the encryption configuration of an existing object in-place. +// The object must already be encrypted with SSE-S3 or SSE-KMS. SSE-C objects are not supported. +// This operation rotates the data encryption key envelope without re-reading/re-writing object data. +// +// Parameters: +// - ctx: Context for request cancellation and timeout +// - bucketName: Name of the bucket +// - objectName: Name of the object +// - opts: Options including KMSKeyArn (required), optional BucketKeyEnabled, and optional VersionID +// +// Returns an error if the operation fails. +func (c *Client) UpdateObjectEncryption(ctx context.Context, bucketName, objectName string, opts UpdateObjectEncryptionOptions) error { + // Input validation. + if err := s3utils.CheckValidBucketName(bucketName); err != nil { + return err + } + + if err := s3utils.CheckValidObjectName(objectName); err != nil { + return err + } + + if opts.KMSKeyArn == "" { + return errInvalidArgument("KMSKeyArn is required for UpdateObjectEncryption.") + } + + // Get resources properly escaped and lined up before + // using them in http request. + urlValues := make(url.Values) + urlValues.Set("encryption", "") + + if opts.VersionID != "" { + urlValues.Set("versionId", opts.VersionID) + } + + reqBody := updateObjectEncryptionRequest{ + XMLNS: "http://s3.amazonaws.com/doc/2006-03-01/", + SSEKMS: &updateObjectEncryptionSSEKMS{ + BucketKeyEnabled: opts.BucketKeyEnabled, + KMSKeyArn: opts.KMSKeyArn, + }, + } + + bodyData, err := xml.Marshal(reqBody) + if err != nil { + return err + } + + reqMetadata := requestMetadata{ + bucketName: bucketName, + objectName: objectName, + queryValues: urlValues, + contentBody: bytes.NewReader(bodyData), + contentLength: int64(len(bodyData)), + contentMD5Base64: sumMD5Base64(bodyData), + contentSHA256Hex: sum256Hex(bodyData), + } + + // Execute PUT Object Encryption. + resp, err := c.executeMethod(ctx, http.MethodPut, reqMetadata) + defer closeResponse(resp) + if err != nil { + return err + } + if resp.StatusCode != http.StatusOK { + return httpRespToErrorResponse(resp, bucketName, objectName) + } + return nil +} diff --git a/vendor/github.com/minio/minio-go/v7/functional_tests.go b/vendor/github.com/minio/minio-go/v7/functional_tests.go index 8984d0358b..192beec8e4 100644 --- a/vendor/github.com/minio/minio-go/v7/functional_tests.go +++ b/vendor/github.com/minio/minio-go/v7/functional_tests.go @@ -2004,7 +2004,6 @@ func testPutObjectWithAutoChecksums() { // Save the data objectName := randString(60, rand.NewSource(time.Now().UnixNano()), "") args["objectName"] = objectName - c.TraceOn(os.Stdout) cmpChecksum := func(got, want string) { if want != got { @@ -5285,6 +5284,25 @@ func testGetObjectReadAtFunctional() { } offset += 512 + readOffset := 0 + bufRead := make([]byte, 512) + // Read (again) using the regular read function. + // Should not have been affected by ReadAt. + m, err = io.ReadFull(r, bufRead) + if err != nil { + logError(testName, function, args, startTime, "", "ReadFull failed", err) + return + } + if m != len(bufRead) { + logError(testName, function, args, startTime, "", "ReadFull read shorter bytes before reaching EOF, expected "+string(len(bufRead))+", got "+string(m), err) + return + } + if !bytes.Equal(bufRead, buf[readOffset:readOffset+len(bufRead)]) { + logError(testName, function, args, startTime, "", "Incorrect Read from offset", err) + return + } + readOffset += len(bufRead) + st, err := r.Stat() if err != nil { logError(testName, function, args, startTime, "", "Stat failed", err) @@ -5310,6 +5328,23 @@ func testGetObjectReadAtFunctional() { return } + // Read (again) using the regular read function. + // Should not have been affected by ReadAt. + m, err = io.ReadFull(r, bufRead) + if err != nil { + logError(testName, function, args, startTime, "", "ReadFull (2) failed", err) + return + } + if m != len(bufRead) { + logError(testName, function, args, startTime, "", "ReadFull read shorter bytes before reaching EOF", err) + return + } + if !bytes.Equal(bufRead, buf[readOffset:readOffset+len(bufRead)]) { + logError(testName, function, args, startTime, "", "Incorrect Read from offset", err) + return + } + readOffset += len(bufRead) + offset += 512 m, err = r.ReadAt(buf3, offset) if err != nil { diff --git a/vendor/github.com/opencloud-eu/libre-graph-api-go/README.md b/vendor/github.com/opencloud-eu/libre-graph-api-go/README.md index 71136c7049..353bd46b7a 100644 --- a/vendor/github.com/opencloud-eu/libre-graph-api-go/README.md +++ b/vendor/github.com/opencloud-eu/libre-graph-api-go/README.md @@ -142,9 +142,11 @@ Class | Method | HTTP request | Description *GroupsApi* | [**CreateGroup**](docs/GroupsApi.md#creategroup) | **Post** /v1.0/groups | Add new entity to groups *GroupsApi* | [**ListGroups**](docs/GroupsApi.md#listgroups) | **Get** /v1.0/groups | Get entities from groups *MeChangepasswordApi* | [**ChangeOwnPassword**](docs/MeChangepasswordApi.md#changeownpassword) | **Post** /v1.0/me/changePassword | Change your own password +*MeDriveApi* | [**FollowDriveItem**](docs/MeDriveApi.md#followdriveitem) | **Post** /v1.0/me/drive/items/{item-id}/follow | Follow a DriveItem *MeDriveApi* | [**GetHome**](docs/MeDriveApi.md#gethome) | **Get** /v1.0/me/drive | Get personal space for user *MeDriveApi* | [**ListSharedByMe**](docs/MeDriveApi.md#listsharedbyme) | **Get** /v1beta1/me/drive/sharedByMe | Get a list of driveItem objects shared by the current user. *MeDriveApi* | [**ListSharedWithMe**](docs/MeDriveApi.md#listsharedwithme) | **Get** /v1beta1/me/drive/sharedWithMe | Get a list of driveItem objects shared with the owner of a drive. +*MeDriveApi* | [**UnfollowDriveItem**](docs/MeDriveApi.md#unfollowdriveitem) | **Delete** /v1.0/me/drive/following/{item-id} | Unfollow a DriveItem *MeDriveRootApi* | [**HomeGetRoot**](docs/MeDriveRootApi.md#homegetroot) | **Get** /v1.0/me/drive/root | Get root from personal space *MeDriveRootChildrenApi* | [**HomeGetChildren**](docs/MeDriveRootChildrenApi.md#homegetchildren) | **Get** /v1.0/me/drive/root/children | Get children from drive *MeDrivesApi* | [**ListMyDrives**](docs/MeDrivesApi.md#listmydrives) | **Get** /v1.0/me/drives | Get all drives where the current user is a regular member of diff --git a/vendor/github.com/opencloud-eu/libre-graph-api-go/api_education_school.go b/vendor/github.com/opencloud-eu/libre-graph-api-go/api_education_school.go index 761504d152..0f00b1f6aa 100644 --- a/vendor/github.com/opencloud-eu/libre-graph-api-go/api_education_school.go +++ b/vendor/github.com/opencloud-eu/libre-graph-api-go/api_education_school.go @@ -994,6 +994,13 @@ func (a *EducationSchoolApiService) ListSchoolUsersExecute(r ApiListSchoolUsersR type ApiListSchoolsRequest struct { ctx context.Context ApiService *EducationSchoolApiService + filter *string +} + +// Filter items by property values. Supports a subset of OData filter expressions. **Supported filters:** - By external ID: `externalId eq 'ext_12345'` +func (r ApiListSchoolsRequest) Filter(filter string) ApiListSchoolsRequest { + r.filter = &filter + return r } func (r ApiListSchoolsRequest) Execute() (*CollectionOfSchools, *http.Response, error) { @@ -1003,6 +1010,13 @@ func (r ApiListSchoolsRequest) Execute() (*CollectionOfSchools, *http.Response, /* ListSchools Get a list of schools and their properties +Retrieves a collection of education schools with optional filtering and ordering. + +**Filtering by external ID:** +Use `$filter` to query schools by their external identifier, for example: +`$filter=externalId eq 'EX12345'` + + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). @return ApiListSchoolsRequest */ @@ -1034,6 +1048,9 @@ func (a *EducationSchoolApiService) ListSchoolsExecute(r ApiListSchoolsRequest) localVarQueryParams := url.Values{} localVarFormParams := url.Values{} + if r.filter != nil { + parameterAddToHeaderOrQuery(localVarQueryParams, "$filter", r.filter, "form", "") + } // to determine the Content-Type header localVarHTTPContentTypes := []string{} diff --git a/vendor/github.com/opencloud-eu/libre-graph-api-go/api_education_user.go b/vendor/github.com/opencloud-eu/libre-graph-api-go/api_education_user.go index 37ca4d2bf9..13b1db8540 100644 --- a/vendor/github.com/opencloud-eu/libre-graph-api-go/api_education_user.go +++ b/vendor/github.com/opencloud-eu/libre-graph-api-go/api_education_user.go @@ -165,7 +165,7 @@ See the [ListEducationUsers](#/educationUser/ListEducationUsers) operation for q @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - @param userId key: internal user id (UUID format) or username of user. **Note:** If you only have an external ID, first query the user with `GET /graph/v1.0/education/users?$filter=externalId eq '{value}'` to retrieve the internal ID. + @param userId key: internal user id (UUID format) or username of user. **Note:** If you only have an external ID, first query the user with `GET /graph/v1.0/education/users?$filter=externalId eq '{value}'` to retrieve the internal ID. @return ApiDeleteEducationUserRequest */ func (a *EducationUserApiService) DeleteEducationUser(ctx context.Context, userId string) ApiDeleteEducationUserRequest { diff --git a/vendor/github.com/opencloud-eu/libre-graph-api-go/api_me_drive.go b/vendor/github.com/opencloud-eu/libre-graph-api-go/api_me_drive.go index ef79c7fe47..fb55216429 100644 --- a/vendor/github.com/opencloud-eu/libre-graph-api-go/api_me_drive.go +++ b/vendor/github.com/opencloud-eu/libre-graph-api-go/api_me_drive.go @@ -16,12 +16,124 @@ import ( "io" "net/http" "net/url" + "strings" ) // MeDriveApiService MeDriveApi service type MeDriveApiService service +type ApiFollowDriveItemRequest struct { + ctx context.Context + ApiService *MeDriveApiService + itemId string +} + +func (r ApiFollowDriveItemRequest) Execute() (*DriveItem, *http.Response, error) { + return r.ApiService.FollowDriveItemExecute(r) +} + +/* +FollowDriveItem Follow a DriveItem + +Follow a DriveItem. + + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @param itemId key: id of item + @return ApiFollowDriveItemRequest +*/ +func (a *MeDriveApiService) FollowDriveItem(ctx context.Context, itemId string) ApiFollowDriveItemRequest { + return ApiFollowDriveItemRequest{ + ApiService: a, + ctx: ctx, + itemId: itemId, + } +} + +// Execute executes the request +// @return DriveItem +func (a *MeDriveApiService) FollowDriveItemExecute(r ApiFollowDriveItemRequest) (*DriveItem, *http.Response, error) { + var ( + localVarHTTPMethod = http.MethodPost + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue *DriveItem + ) + + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "MeDriveApiService.FollowDriveItem") + if err != nil { + return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} + } + + localVarPath := localBasePath + "/v1.0/me/drive/items/{item-id}/follow" + localVarPath = strings.Replace(localVarPath, "{"+"item-id"+"}", url.PathEscape(parameterValueToString(r.itemId, "itemId")), -1) + + localVarHeaderParams := make(map[string]string) + localVarQueryParams := url.Values{} + localVarFormParams := url.Values{} + + // to determine the Content-Type header + localVarHTTPContentTypes := []string{} + + // set Content-Type header + localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes) + if localVarHTTPContentType != "" { + localVarHeaderParams["Content-Type"] = localVarHTTPContentType + } + + // to determine the Accept header + localVarHTTPHeaderAccepts := []string{"application/json"} + + // set Accept header + localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) + if localVarHTTPHeaderAccept != "" { + localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept + } + req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles) + if err != nil { + return localVarReturnValue, nil, err + } + + localVarHTTPResponse, err := a.client.callAPI(req) + if err != nil || localVarHTTPResponse == nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + localVarBody, err := io.ReadAll(localVarHTTPResponse.Body) + localVarHTTPResponse.Body.Close() + localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody)) + if err != nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + if localVarHTTPResponse.StatusCode >= 300 { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: localVarHTTPResponse.Status, + } + var v OdataError + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + + err = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: err.Error(), + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + return localVarReturnValue, localVarHTTPResponse, nil +} + type ApiGetHomeRequest struct { ctx context.Context ApiService *MeDriveApiService @@ -362,3 +474,103 @@ func (a *MeDriveApiService) ListSharedWithMeExecute(r ApiListSharedWithMeRequest return localVarReturnValue, localVarHTTPResponse, nil } + +type ApiUnfollowDriveItemRequest struct { + ctx context.Context + ApiService *MeDriveApiService + itemId string +} + +func (r ApiUnfollowDriveItemRequest) Execute() (*http.Response, error) { + return r.ApiService.UnfollowDriveItemExecute(r) +} + +/* +UnfollowDriveItem Unfollow a DriveItem + +Unfollow a DriveItem. + + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @param itemId key: id of item + @return ApiUnfollowDriveItemRequest +*/ +func (a *MeDriveApiService) UnfollowDriveItem(ctx context.Context, itemId string) ApiUnfollowDriveItemRequest { + return ApiUnfollowDriveItemRequest{ + ApiService: a, + ctx: ctx, + itemId: itemId, + } +} + +// Execute executes the request +func (a *MeDriveApiService) UnfollowDriveItemExecute(r ApiUnfollowDriveItemRequest) (*http.Response, error) { + var ( + localVarHTTPMethod = http.MethodDelete + localVarPostBody interface{} + formFiles []formFile + ) + + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "MeDriveApiService.UnfollowDriveItem") + if err != nil { + return nil, &GenericOpenAPIError{error: err.Error()} + } + + localVarPath := localBasePath + "/v1.0/me/drive/following/{item-id}" + localVarPath = strings.Replace(localVarPath, "{"+"item-id"+"}", url.PathEscape(parameterValueToString(r.itemId, "itemId")), -1) + + localVarHeaderParams := make(map[string]string) + localVarQueryParams := url.Values{} + localVarFormParams := url.Values{} + + // to determine the Content-Type header + localVarHTTPContentTypes := []string{} + + // set Content-Type header + localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes) + if localVarHTTPContentType != "" { + localVarHeaderParams["Content-Type"] = localVarHTTPContentType + } + + // to determine the Accept header + localVarHTTPHeaderAccepts := []string{"application/json"} + + // set Accept header + localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) + if localVarHTTPHeaderAccept != "" { + localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept + } + req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles) + if err != nil { + return nil, err + } + + localVarHTTPResponse, err := a.client.callAPI(req) + if err != nil || localVarHTTPResponse == nil { + return localVarHTTPResponse, err + } + + localVarBody, err := io.ReadAll(localVarHTTPResponse.Body) + localVarHTTPResponse.Body.Close() + localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody)) + if err != nil { + return localVarHTTPResponse, err + } + + if localVarHTTPResponse.StatusCode >= 300 { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: localVarHTTPResponse.Status, + } + var v OdataError + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarHTTPResponse, newErr + } + + return localVarHTTPResponse, nil +} diff --git a/vendor/github.com/opencloud-eu/libre-graph-api-go/api_role_management.go b/vendor/github.com/opencloud-eu/libre-graph-api-go/api_role_management.go index 9bda43bcba..3e86c714fa 100644 --- a/vendor/github.com/opencloud-eu/libre-graph-api-go/api_role_management.go +++ b/vendor/github.com/opencloud-eu/libre-graph-api-go/api_role_management.go @@ -140,7 +140,7 @@ type ApiListPermissionRoleDefinitionsRequest struct { ApiService *RoleManagementApiService } -func (r ApiListPermissionRoleDefinitionsRequest) Execute() (*UnifiedRoleDefinition, *http.Response, error) { +func (r ApiListPermissionRoleDefinitionsRequest) Execute() ([]UnifiedRoleDefinition, *http.Response, error) { return r.ApiService.ListPermissionRoleDefinitionsExecute(r) } @@ -161,13 +161,13 @@ func (a *RoleManagementApiService) ListPermissionRoleDefinitions(ctx context.Con } // Execute executes the request -// @return UnifiedRoleDefinition -func (a *RoleManagementApiService) ListPermissionRoleDefinitionsExecute(r ApiListPermissionRoleDefinitionsRequest) (*UnifiedRoleDefinition, *http.Response, error) { +// @return []UnifiedRoleDefinition +func (a *RoleManagementApiService) ListPermissionRoleDefinitionsExecute(r ApiListPermissionRoleDefinitionsRequest) ([]UnifiedRoleDefinition, *http.Response, error) { var ( localVarHTTPMethod = http.MethodGet localVarPostBody interface{} formFiles []formFile - localVarReturnValue *UnifiedRoleDefinition + localVarReturnValue []UnifiedRoleDefinition ) localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "RoleManagementApiService.ListPermissionRoleDefinitions") diff --git a/vendor/github.com/opencloud-eu/reva/v2/cmd/revad/runtime/loader.go b/vendor/github.com/opencloud-eu/reva/v2/cmd/revad/runtime/loader.go index 07a8369f24..197af9c0d8 100644 --- a/vendor/github.com/opencloud-eu/reva/v2/cmd/revad/runtime/loader.go +++ b/vendor/github.com/opencloud-eu/reva/v2/cmd/revad/runtime/loader.go @@ -32,7 +32,6 @@ import ( _ "github.com/opencloud-eu/reva/v2/pkg/appauth/manager/loader" _ "github.com/opencloud-eu/reva/v2/pkg/auth/manager/loader" _ "github.com/opencloud-eu/reva/v2/pkg/auth/registry/loader" - _ "github.com/opencloud-eu/reva/v2/pkg/cbox/loader" _ "github.com/opencloud-eu/reva/v2/pkg/datatx/manager/loader" _ "github.com/opencloud-eu/reva/v2/pkg/group/manager/loader" _ "github.com/opencloud-eu/reva/v2/pkg/metrics/driver/loader" @@ -45,7 +44,6 @@ import ( _ "github.com/opencloud-eu/reva/v2/pkg/rhttp/datatx/manager/loader" _ "github.com/opencloud-eu/reva/v2/pkg/share/cache/warmup/loader" _ "github.com/opencloud-eu/reva/v2/pkg/share/manager/loader" - _ "github.com/opencloud-eu/reva/v2/pkg/storage/favorite/loader" _ "github.com/opencloud-eu/reva/v2/pkg/storage/fs/loader" _ "github.com/opencloud-eu/reva/v2/pkg/storage/registry/loader" _ "github.com/opencloud-eu/reva/v2/pkg/token/manager/loader" diff --git a/vendor/github.com/opencloud-eu/reva/v2/internal/grpc/services/gateway/storageprovider.go b/vendor/github.com/opencloud-eu/reva/v2/internal/grpc/services/gateway/storageprovider.go index ea354f00e8..539f13dadc 100644 --- a/vendor/github.com/opencloud-eu/reva/v2/internal/grpc/services/gateway/storageprovider.go +++ b/vendor/github.com/opencloud-eu/reva/v2/internal/grpc/services/gateway/storageprovider.go @@ -648,6 +648,46 @@ func (s *svc) CreateContainer(ctx context.Context, req *provider.CreateContainer return res, nil } +func (s *svc) AddFavorite(ctx context.Context, req *provider.AddFavoriteRequest) (*provider.AddFavoriteResponse, error) { + var c provider.ProviderAPIClient + var err error + c, _, req.Ref, err = s.findAndUnwrap(ctx, req.Ref) + if err != nil { + return &provider.AddFavoriteResponse{ + Status: status.NewStatusFromErrType(ctx, fmt.Sprintf("gateway could not find space for ref=%+v", req.Ref), err), + }, nil + } + + res, err := c.AddFavorite(ctx, req) + if err != nil { + return &provider.AddFavoriteResponse{ + Status: status.NewStatusFromErrType(ctx, "gateway could not call AddFavorite", err), + }, nil + } + + return res, nil +} + +func (s *svc) RemoveFavorite(ctx context.Context, req *provider.RemoveFavoriteRequest) (*provider.RemoveFavoriteResponse, error) { + var c provider.ProviderAPIClient + var err error + c, _, req.Ref, err = s.findAndUnwrap(ctx, req.Ref) + if err != nil { + return &provider.RemoveFavoriteResponse{ + Status: status.NewStatusFromErrType(ctx, fmt.Sprintf("gateway could not find space for ref=%+v", req.Ref), err), + }, nil + } + + res, err := c.RemoveFavorite(ctx, req) + if err != nil { + return &provider.RemoveFavoriteResponse{ + Status: status.NewStatusFromErrType(ctx, "gateway could not call RemoveFavorite", err), + }, nil + } + + return res, nil +} + func (s *svc) TouchFile(ctx context.Context, req *provider.TouchFileRequest) (*provider.TouchFileResponse, error) { var c provider.ProviderAPIClient var err error diff --git a/vendor/github.com/opencloud-eu/reva/v2/internal/grpc/services/gateway/storageprovidercache.go b/vendor/github.com/opencloud-eu/reva/v2/internal/grpc/services/gateway/storageprovidercache.go index 4419caab87..3c9c8d06fe 100644 --- a/vendor/github.com/opencloud-eu/reva/v2/internal/grpc/services/gateway/storageprovidercache.go +++ b/vendor/github.com/opencloud-eu/reva/v2/internal/grpc/services/gateway/storageprovidercache.go @@ -264,3 +264,9 @@ func (c *cachedAPIClient) GetHome(ctx context.Context, in *provider.GetHomeReque func (c *cachedAPIClient) TouchFile(ctx context.Context, in *provider.TouchFileRequest, opts ...grpc.CallOption) (*provider.TouchFileResponse, error) { return c.c.TouchFile(ctx, in, opts...) } +func (c *cachedAPIClient) AddFavorite(ctx context.Context, in *provider.AddFavoriteRequest, opts ...grpc.CallOption) (*provider.AddFavoriteResponse, error) { + return c.c.AddFavorite(ctx, in, opts...) +} +func (c *cachedAPIClient) RemoveFavorite(ctx context.Context, in *provider.RemoveFavoriteRequest, opts ...grpc.CallOption) (*provider.RemoveFavoriteResponse, error) { + return c.c.RemoveFavorite(ctx, in, opts...) +} diff --git a/vendor/github.com/opencloud-eu/reva/v2/internal/grpc/services/publicstorageprovider/publicstorageprovider.go b/vendor/github.com/opencloud-eu/reva/v2/internal/grpc/services/publicstorageprovider/publicstorageprovider.go index 7e8f65fbc3..a0915e2427 100644 --- a/vendor/github.com/opencloud-eu/reva/v2/internal/grpc/services/publicstorageprovider/publicstorageprovider.go +++ b/vendor/github.com/opencloud-eu/reva/v2/internal/grpc/services/publicstorageprovider/publicstorageprovider.go @@ -929,6 +929,14 @@ func (s *service) GetQuota(ctx context.Context, req *provider.GetQuotaRequest) ( return nil, gstatus.Errorf(codes.Unimplemented, "method not implemented") } +func (s *service) AddFavorite(ctx context.Context, req *provider.AddFavoriteRequest) (*provider.AddFavoriteResponse, error) { + return nil, gstatus.Errorf(codes.Unimplemented, "method not implemented") +} + +func (s *service) RemoveFavorite(ctx context.Context, req *provider.RemoveFavoriteRequest) (*provider.RemoveFavoriteResponse, error) { + return nil, gstatus.Errorf(codes.Unimplemented, "method not implemented") +} + // resolveToken returns the resource info for the publicly shared resource. func (s *service) resolveToken(ctx context.Context, share interface{}) (*provider.ResourceInfo, interface{}, error) { gatewayClient, err := s.gatewaySelector.Next() diff --git a/vendor/github.com/opencloud-eu/reva/v2/internal/grpc/services/sharesstorageprovider/sharesstorageprovider.go b/vendor/github.com/opencloud-eu/reva/v2/internal/grpc/services/sharesstorageprovider/sharesstorageprovider.go index 0d576e4ba4..04c253e824 100644 --- a/vendor/github.com/opencloud-eu/reva/v2/internal/grpc/services/sharesstorageprovider/sharesstorageprovider.go +++ b/vendor/github.com/opencloud-eu/reva/v2/internal/grpc/services/sharesstorageprovider/sharesstorageprovider.go @@ -1035,6 +1035,14 @@ func (s *service) GetQuota(ctx context.Context, req *provider.GetQuotaRequest) ( }, nil } +func (s *service) AddFavorite(ctx context.Context, req *provider.AddFavoriteRequest) (*provider.AddFavoriteResponse, error) { + return nil, gstatus.Errorf(codes.Unimplemented, "method not implemented") +} + +func (s *service) RemoveFavorite(ctx context.Context, req *provider.RemoveFavoriteRequest) (*provider.RemoveFavoriteResponse, error) { + return nil, gstatus.Errorf(codes.Unimplemented, "method not implemented") +} + func (s *service) resolveAcceptedShare(ctx context.Context, ref *provider.Reference) (*collaboration.ReceivedShare, *rpc.Status, error) { // treat absolute id based references as relative ones if ref.Path == "" { diff --git a/vendor/github.com/opencloud-eu/reva/v2/internal/grpc/services/storageprovider/storageprovider.go b/vendor/github.com/opencloud-eu/reva/v2/internal/grpc/services/storageprovider/storageprovider.go index 2208a06b7c..33486559e9 100644 --- a/vendor/github.com/opencloud-eu/reva/v2/internal/grpc/services/storageprovider/storageprovider.go +++ b/vendor/github.com/opencloud-eu/reva/v2/internal/grpc/services/storageprovider/storageprovider.go @@ -706,6 +706,36 @@ func (s *Service) TouchFile(ctx context.Context, req *provider.TouchFileRequest) }, nil } +func (s *Service) AddFavorite(ctx context.Context, req *provider.AddFavoriteRequest) (*provider.AddFavoriteResponse, error) { + appctx.GetLogger(ctx).Debug().Msg("AddFavorite") + + err := s.Storage.AddFavorite(ctx, req.Ref, req.UserId) + if err != nil { + return &provider.AddFavoriteResponse{ + Status: status.NewStatusFromErrType(ctx, "add favorite", err), + }, nil + } + + return &provider.AddFavoriteResponse{ + Status: status.NewOK(ctx), + }, nil +} + +func (s *Service) RemoveFavorite(ctx context.Context, req *provider.RemoveFavoriteRequest) (*provider.RemoveFavoriteResponse, error) { + appctx.GetLogger(ctx).Debug().Msg("RemoveFavorite") + + err := s.Storage.RemoveFavorite(ctx, req.Ref, req.UserId) + if err != nil { + return &provider.RemoveFavoriteResponse{ + Status: status.NewStatusFromErrType(ctx, "remove favorite", err), + }, nil + } + + return &provider.RemoveFavoriteResponse{ + Status: status.NewOK(ctx), + }, nil +} + func (s *Service) Delete(ctx context.Context, req *provider.DeleteRequest) (*provider.DeleteResponse, error) { if req.Ref.GetPath() == "/" { return &provider.DeleteResponse{ diff --git a/vendor/github.com/opencloud-eu/reva/v2/internal/http/services/owncloud/ocdav/config/config.go b/vendor/github.com/opencloud-eu/reva/v2/internal/http/services/owncloud/ocdav/config/config.go index 130383adb1..a0f4f2477a 100644 --- a/vendor/github.com/opencloud-eu/reva/v2/internal/http/services/owncloud/ocdav/config/config.go +++ b/vendor/github.com/opencloud-eu/reva/v2/internal/http/services/owncloud/ocdav/config/config.go @@ -21,17 +21,15 @@ type Config struct { Timeout int64 `mapstructure:"timeout"` Insecure bool `mapstructure:"insecure"` // If true, HTTP COPY will expect the HTTP-TPC (third-party copy) headers - EnableHTTPTpc bool `mapstructure:"enable_http_tpc"` - PublicURL string `mapstructure:"public_url"` - FavoriteStorageDriver string `mapstructure:"favorite_storage_driver"` - FavoriteStorageDrivers map[string]map[string]interface{} `mapstructure:"favorite_storage_drivers"` - Version string `mapstructure:"version"` - VersionString string `mapstructure:"version_string"` - Edition string `mapstructure:"edition"` - Product string `mapstructure:"product"` - ProductName string `mapstructure:"product_name"` - ProductVersion string `mapstructure:"product_version"` - AllowPropfindDepthInfinitiy bool `mapstructure:"allow_depth_infinity"` + EnableHTTPTpc bool `mapstructure:"enable_http_tpc"` + PublicURL string `mapstructure:"public_url"` + Version string `mapstructure:"version"` + VersionString string `mapstructure:"version_string"` + Edition string `mapstructure:"edition"` + Product string `mapstructure:"product"` + ProductName string `mapstructure:"product_name"` + ProductVersion string `mapstructure:"product_version"` + AllowPropfindDepthInfinitiy bool `mapstructure:"allow_depth_infinity"` NameValidation NameValidation `mapstructure:"validation"` @@ -52,10 +50,6 @@ func (c *Config) Init() { // note: default c.Prefix is an empty string c.GatewaySvc = sharedconf.GetGatewaySVC(c.GatewaySvc) - if c.FavoriteStorageDriver == "" { - c.FavoriteStorageDriver = "memory" - } - if c.Version == "" { c.Version = "10.0.11.5" } diff --git a/vendor/github.com/opencloud-eu/reva/v2/internal/http/services/owncloud/ocdav/ocdav.go b/vendor/github.com/opencloud-eu/reva/v2/internal/http/services/owncloud/ocdav/ocdav.go index 8a892d3ade..edc8ce0b34 100644 --- a/vendor/github.com/opencloud-eu/reva/v2/internal/http/services/owncloud/ocdav/ocdav.go +++ b/vendor/github.com/opencloud-eu/reva/v2/internal/http/services/owncloud/ocdav/ocdav.go @@ -43,8 +43,6 @@ import ( "github.com/opencloud-eu/reva/v2/pkg/rhttp/global" "github.com/opencloud-eu/reva/v2/pkg/rhttp/router" "github.com/opencloud-eu/reva/v2/pkg/signedurl" - "github.com/opencloud-eu/reva/v2/pkg/storage/favorite" - "github.com/opencloud-eu/reva/v2/pkg/storage/favorite/registry" "github.com/opencloud-eu/reva/v2/pkg/storage/utils/templates" "github.com/opencloud-eu/reva/v2/pkg/utils" "github.com/rs/zerolog" @@ -61,12 +59,11 @@ func init() { } type svc struct { - c *config.Config - webDavHandler *WebDavHandler - davHandler *DavHandler - favoritesManager favorite.Manager - client *http.Client - gatewaySelector pool.Selectable[gateway.GatewayAPIClient] + c *config.Config + webDavHandler *WebDavHandler + davHandler *DavHandler + client *http.Client + gatewaySelector pool.Selectable[gateway.GatewayAPIClient] // LockSystem is the lock management system. LockSystem LockSystem userIdentifierCache *ttlcache.Cache @@ -78,12 +75,6 @@ func (s *svc) Config() *config.Config { return s.c } -func getFavoritesManager(c *config.Config) (favorite.Manager, error) { - if f, ok := registry.NewFuncs[c.FavoriteStorageDriver]; ok { - return f(c.FavoriteStorageDrivers[c.FavoriteStorageDriver]) - } - return nil, errtypes.NotFound("driver not found: " + c.FavoriteStorageDriver) -} func getLockSystem(c *config.Config) (LockSystem, error) { // TODO in memory implementation selector, err := pool.GatewaySelector(c.GatewaySvc) @@ -102,20 +93,16 @@ func New(m map[string]interface{}, log *zerolog.Logger) (global.Service, error) conf.Init() - fm, err := getFavoritesManager(conf) - if err != nil { - return nil, err - } ls, err := getLockSystem(conf) if err != nil { return nil, err } - return NewWith(conf, fm, ls, log, nil) + return NewWith(conf, ls, log, nil) } // NewWith returns a new ocdav service -func NewWith(conf *config.Config, fm favorite.Manager, ls LockSystem, _ *zerolog.Logger, selector pool.Selectable[gateway.GatewayAPIClient]) (global.Service, error) { +func NewWith(conf *config.Config, ls LockSystem, _ *zerolog.Logger, selector pool.Selectable[gateway.GatewayAPIClient]) (global.Service, error) { // be safe - init the conf again conf.Init() @@ -137,7 +124,6 @@ func NewWith(conf *config.Config, fm favorite.Manager, ls LockSystem, _ *zerolog rhttp.Insecure(conf.Insecure), ), gatewaySelector: selector, - favoritesManager: fm, LockSystem: ls, userIdentifierCache: ttlcache.NewCache(), nameValidators: ValidatorsFromConfig(conf), diff --git a/vendor/github.com/opencloud-eu/reva/v2/internal/http/services/owncloud/ocdav/proppatch.go b/vendor/github.com/opencloud-eu/reva/v2/internal/http/services/owncloud/ocdav/proppatch.go index 3d97d8a461..1c1f9797b9 100644 --- a/vendor/github.com/opencloud-eu/reva/v2/internal/http/services/owncloud/ocdav/proppatch.go +++ b/vendor/github.com/opencloud-eu/reva/v2/internal/http/services/owncloud/ocdav/proppatch.go @@ -36,11 +36,8 @@ import ( "github.com/opencloud-eu/reva/v2/internal/http/services/owncloud/ocdav/propfind" "github.com/opencloud-eu/reva/v2/internal/http/services/owncloud/ocdav/spacelookup" "github.com/opencloud-eu/reva/v2/pkg/appctx" - ctxpkg "github.com/opencloud-eu/reva/v2/pkg/ctx" "github.com/opencloud-eu/reva/v2/pkg/errtypes" - "github.com/opencloud-eu/reva/v2/pkg/permission" rstatus "github.com/opencloud-eu/reva/v2/pkg/rgrpc/status" - "github.com/opencloud-eu/reva/v2/pkg/utils" "github.com/rs/zerolog" ) @@ -214,30 +211,6 @@ func (s *svc) handleProppatch(ctx context.Context, w http.ResponseWriter, r *htt errors.HandleWebdavError(&log, w, b, err) return nil, nil, false } - if key == "http://owncloud.org/ns/favorite" { - statRes, err := client.Stat(ctx, &provider.StatRequest{Ref: ref}) - if err != nil { - w.WriteHeader(http.StatusInternalServerError) - return nil, nil, false - } - currentUser := ctxpkg.ContextMustGetUser(ctx) - ok, err := utils.CheckPermission(ctx, permission.WriteFavorites, client) - if err != nil { - log.Error().Err(err).Msg("error checking permission") - w.WriteHeader(http.StatusInternalServerError) - return nil, nil, false - } - if !ok { - log.Info().Interface("user", currentUser).Msg("user not allowed to unset favorite") - w.WriteHeader(http.StatusForbidden) - return nil, nil, false - } - err = s.favoritesManager.UnsetFavorite(ctx, currentUser.Id, statRes.Info) - if err != nil { - w.WriteHeader(http.StatusInternalServerError) - return nil, nil, false - } - } removedProps = append(removedProps, propNameXML) } else { sreq.ArbitraryMetadata.Metadata[key] = value @@ -282,31 +255,6 @@ func (s *svc) handleProppatch(ctx context.Context, w http.ResponseWriter, r *htt acceptedProps = append(acceptedProps, propNameXML) delete(sreq.ArbitraryMetadata.Metadata, key) - - if key == "http://owncloud.org/ns/favorite" { - statRes, err := client.Stat(ctx, &provider.StatRequest{Ref: ref}) - if err != nil || statRes.Info == nil { - w.WriteHeader(http.StatusInternalServerError) - return nil, nil, false - } - currentUser := ctxpkg.ContextMustGetUser(ctx) - ok, err := utils.CheckPermission(ctx, permission.WriteFavorites, client) - if err != nil { - log.Error().Err(err).Msg("error checking permission") - w.WriteHeader(http.StatusInternalServerError) - return nil, nil, false - } - if !ok { - log.Info().Interface("user", currentUser).Msg("user not allowed to set favorite") - w.WriteHeader(http.StatusForbidden) - return nil, nil, false - } - err = s.favoritesManager.SetFavorite(ctx, currentUser.Id, statRes.Info) - if err != nil { - w.WriteHeader(http.StatusInternalServerError) - return nil, nil, false - } - } } } // FIXME: in case of error, need to set all properties back to the original state, diff --git a/vendor/github.com/opencloud-eu/reva/v2/internal/http/services/owncloud/ocdav/report.go b/vendor/github.com/opencloud-eu/reva/v2/internal/http/services/owncloud/ocdav/report.go index aab369961d..f94be431cf 100644 --- a/vendor/github.com/opencloud-eu/reva/v2/internal/http/services/owncloud/ocdav/report.go +++ b/vendor/github.com/opencloud-eu/reva/v2/internal/http/services/owncloud/ocdav/report.go @@ -23,14 +23,8 @@ import ( "io" "net/http" - rpcv1beta1 "github.com/cs3org/go-cs3apis/cs3/rpc/v1beta1" - providerv1beta1 "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1" - "github.com/opencloud-eu/reva/v2/internal/http/services/owncloud/ocdav/net" "github.com/opencloud-eu/reva/v2/internal/http/services/owncloud/ocdav/propfind" "github.com/opencloud-eu/reva/v2/pkg/appctx" - ctxpkg "github.com/opencloud-eu/reva/v2/pkg/ctx" - "github.com/opencloud-eu/reva/v2/pkg/permission" - "github.com/opencloud-eu/reva/v2/pkg/utils" ) const ( @@ -54,13 +48,6 @@ func (s *svc) handleReport(w http.ResponseWriter, r *http.Request, ns string) { return } - if rep.FilterFiles != nil { - s.doFilterFiles(w, r, rep.FilterFiles, ns) - return - } - - // TODO(jfd): implement report - w.WriteHeader(http.StatusNotImplemented) } @@ -68,73 +55,6 @@ func (s *svc) doSearchFiles(w http.ResponseWriter, r *http.Request, sf *reportSe w.WriteHeader(http.StatusNotImplemented) } -func (s *svc) doFilterFiles(w http.ResponseWriter, r *http.Request, ff *reportFilterFiles, namespace string) { - ctx := r.Context() - log := appctx.GetLogger(ctx) - - if ff.Rules.Favorite { - // List the users favorite resources. - client, err := s.gatewaySelector.Next() - if err != nil { - log.Error().Err(err).Msg("error selecting next gateway client") - w.WriteHeader(http.StatusInternalServerError) - return - } - currentUser := ctxpkg.ContextMustGetUser(ctx) - ok, err := utils.CheckPermission(ctx, permission.ListFavorites, client) - if err != nil { - log.Error().Err(err).Msg("error checking permission") - w.WriteHeader(http.StatusInternalServerError) - return - } - if !ok { - log.Info().Interface("user", currentUser).Msg("user not allowed to list favorites") - w.WriteHeader(http.StatusForbidden) - return - } - favorites, err := s.favoritesManager.ListFavorites(ctx, currentUser.Id) - if err != nil { - log.Error().Err(err).Msg("error getting favorites") - w.WriteHeader(http.StatusInternalServerError) - return - } - - infos := make([]*providerv1beta1.ResourceInfo, 0, len(favorites)) - for i := range favorites { - statRes, err := client.Stat(ctx, &providerv1beta1.StatRequest{Ref: &providerv1beta1.Reference{ResourceId: favorites[i]}}) - if err != nil { - log.Error().Err(err).Msg("error getting resource info") - continue - } - if statRes.Status.Code != rpcv1beta1.Code_CODE_OK { - log.Error().Interface("stat_response", statRes).Msg("error getting resource info") - continue - } - infos = append(infos, statRes.Info) - } - - prefer := net.ParsePrefer(r.Header.Get("prefer")) - returnMinimal := prefer[net.HeaderPreferReturn] == "minimal" - - responsesXML, err := propfind.MultistatusResponse(ctx, &propfind.XML{Prop: ff.Prop}, infos, s.c.PublicURL, namespace, nil, returnMinimal, nil) - if err != nil { - log.Error().Err(err).Msg("error formatting propfind") - w.WriteHeader(http.StatusInternalServerError) - return - } - w.Header().Set(net.HeaderDav, "1, 3, extended-mkcol") - w.Header().Set(net.HeaderContentType, "application/xml; charset=utf-8") - w.Header().Set(net.HeaderVary, net.HeaderPrefer) - if returnMinimal { - w.Header().Set(net.HeaderPreferenceApplied, "return=minimal") - } - w.WriteHeader(http.StatusMultiStatus) - if _, err := w.Write(responsesXML); err != nil { - log.Err(err).Msg("error writing response") - } - } -} - type report struct { SearchFiles *reportSearchFiles // FilterFiles TODO add this for tag based search diff --git a/vendor/github.com/opencloud-eu/reva/v2/pkg/cbox/favorite/sql/sql.go b/vendor/github.com/opencloud-eu/reva/v2/pkg/cbox/favorite/sql/sql.go deleted file mode 100644 index cbbada4a29..0000000000 --- a/vendor/github.com/opencloud-eu/reva/v2/pkg/cbox/favorite/sql/sql.go +++ /dev/null @@ -1,139 +0,0 @@ -// 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 cbox - -import ( - "context" - "database/sql" - "fmt" - - user "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1" - provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1" - "github.com/mitchellh/mapstructure" - "github.com/opencloud-eu/reva/v2/pkg/cbox/utils" - ctxpkg "github.com/opencloud-eu/reva/v2/pkg/ctx" - "github.com/opencloud-eu/reva/v2/pkg/storage/favorite" - "github.com/opencloud-eu/reva/v2/pkg/storage/favorite/registry" -) - -func init() { - registry.Register("sql", New) -} - -type config struct { - DbUsername string `mapstructure:"db_username"` - DbPassword string `mapstructure:"db_password"` - DbHost string `mapstructure:"db_host"` - DbPort int `mapstructure:"db_port"` - DbName string `mapstructure:"db_name"` -} - -type mgr struct { - c *config - db *sql.DB -} - -// New returns an instance of the cbox sql favorites manager. -func New(m map[string]interface{}) (favorite.Manager, error) { - c := &config{} - if err := mapstructure.Decode(m, c); err != nil { - return nil, err - } - - db, err := sql.Open("mysql", fmt.Sprintf("%s:%s@tcp(%s:%d)/%s", c.DbUsername, c.DbPassword, c.DbHost, c.DbPort, c.DbName)) - if err != nil { - return nil, err - } - - return &mgr{ - c: c, - db: db, - }, nil -} - -func (m *mgr) ListFavorites(ctx context.Context, userID *user.UserId) ([]*provider.ResourceId, error) { - user := ctxpkg.ContextMustGetUser(ctx) - infos := []*provider.ResourceId{} - query := `SELECT fileid_prefix, fileid FROM cbox_metadata WHERE uid=? AND tag_key="fav"` - rows, err := m.db.Query(query, user.Id.OpaqueId) - if err != nil { - return nil, err - } - defer rows.Close() - - for rows.Next() { - var info provider.ResourceId - if err := rows.Scan(&info.SpaceId, &info.OpaqueId); err != nil { - return nil, err - } - infos = append(infos, &info) - } - - if err = rows.Err(); err != nil { - return nil, err - } - return infos, nil -} - -func (m *mgr) SetFavorite(ctx context.Context, userID *user.UserId, resourceInfo *provider.ResourceInfo) error { - user := ctxpkg.ContextMustGetUser(ctx) - spaceID := resourceInfo.Id.SpaceId - - // The primary key is just the ID in the table, it should ideally be (uid, fileid_prefix, fileid, tag_key) - // For the time being, just check if the favorite already exists. If it does, return early - var id int - query := `SELECT id FROM cbox_metadata WHERE uid=? AND fileid_prefix=? AND fileid=? AND tag_key="fav"` - if err := m.db.QueryRow(query, user.Id.OpaqueId, spaceID, resourceInfo.Id.OpaqueId).Scan(&id); err == nil { - // Favorite is already set, return - return nil - } - - query = `INSERT INTO cbox_metadata SET item_type=?, uid=?, fileid_prefix=?, fileid=?, tag_key="fav"` - vals := []interface{}{utils.ResourceTypeToItemInt(resourceInfo.Type), user.Id.OpaqueId, spaceID, resourceInfo.Id.OpaqueId} - stmt, err := m.db.Prepare(query) - if err != nil { - return err - } - - if _, err = stmt.Exec(vals...); err != nil { - return err - } - return nil -} - -func (m *mgr) UnsetFavorite(ctx context.Context, userID *user.UserId, resourceInfo *provider.ResourceInfo) error { - user := ctxpkg.ContextMustGetUser(ctx) - spaceID := resourceInfo.Id.SpaceId - - stmt, err := m.db.Prepare(`DELETE FROM cbox_metadata WHERE uid=? AND fileid_prefix=? AND fileid=? AND tag_key="fav"`) - if err != nil { - return err - } - - res, err := stmt.Exec(user.Id.OpaqueId, spaceID, resourceInfo.Id.OpaqueId) - if err != nil { - return err - } - - _, err = res.RowsAffected() - if err != nil { - return err - } - return nil -} diff --git a/vendor/github.com/opencloud-eu/reva/v2/pkg/cbox/group/rest/cache.go b/vendor/github.com/opencloud-eu/reva/v2/pkg/cbox/group/rest/cache.go deleted file mode 100644 index cd4110fd65..0000000000 --- a/vendor/github.com/opencloud-eu/reva/v2/pkg/cbox/group/rest/cache.go +++ /dev/null @@ -1,221 +0,0 @@ -// 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 rest - -import ( - "encoding/json" - "errors" - "fmt" - "strconv" - "strings" - "time" - - grouppb "github.com/cs3org/go-cs3apis/cs3/identity/group/v1beta1" - userpb "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1" - "github.com/gomodule/redigo/redis" -) - -const ( - groupPrefix = "group:" - idPrefix = "id:" - namePrefix = "name:" - gidPrefix = "gid:" - groupMembersPrefix = "members:" - groupInternalIDPrefix = "internal:" -) - -func initRedisPool(address, username, password string) *redis.Pool { - return &redis.Pool{ - - MaxIdle: 50, - MaxActive: 1000, - IdleTimeout: 240 * time.Second, - - Dial: func() (redis.Conn, error) { - var c redis.Conn - var err error - switch { - case username != "": - c, err = redis.Dial("tcp", address, - redis.DialUsername(username), - redis.DialPassword(password), - ) - case password != "": - c, err = redis.Dial("tcp", address, - redis.DialPassword(password), - ) - default: - c, err = redis.Dial("tcp", address) - } - - if err != nil { - return nil, err - } - return c, err - }, - - TestOnBorrow: func(c redis.Conn, t time.Time) error { - _, err := c.Do("PING") - return err - }, - } -} - -func (m *manager) setVal(key, val string, expiration int) error { - conn := m.redisPool.Get() - defer conn.Close() - if conn != nil { - args := []interface{}{key, val} - if expiration != -1 { - args = append(args, "EX", expiration) - } - if _, err := conn.Do("SET", args...); err != nil { - return err - } - return nil - } - return errors.New("rest: unable to get connection from redis pool") -} - -func (m *manager) getVal(key string) (string, error) { - conn := m.redisPool.Get() - defer conn.Close() - if conn != nil { - val, err := redis.String(conn.Do("GET", key)) - if err != nil { - return "", err - } - return val, nil - } - return "", errors.New("rest: unable to get connection from redis pool") -} - -func (m *manager) fetchCachedInternalID(gid *grouppb.GroupId) (string, error) { - return m.getVal(groupPrefix + groupInternalIDPrefix + gid.OpaqueId) -} - -func (m *manager) cacheInternalID(gid *grouppb.GroupId, internalID string) error { - return m.setVal(groupPrefix+groupInternalIDPrefix+gid.OpaqueId, internalID, -1) -} - -func (m *manager) findCachedGroups(query string) ([]*grouppb.Group, error) { - conn := m.redisPool.Get() - defer conn.Close() - if conn != nil { - query = fmt.Sprintf("%s*%s*", groupPrefix, strings.ReplaceAll(strings.ToLower(query), " ", "_")) - keys, err := redis.Strings(conn.Do("KEYS", query)) - if err != nil { - return nil, err - } - var args []interface{} - for _, k := range keys { - args = append(args, k) - } - - // Fetch the groups for all these keys - groupStrings, err := redis.Strings(conn.Do("MGET", args...)) - if err != nil { - return nil, err - } - groupMap := make(map[string]*grouppb.Group) - for _, group := range groupStrings { - g := grouppb.Group{} - if err = json.Unmarshal([]byte(group), &g); err == nil { - groupMap[g.Id.OpaqueId] = &g - } - } - - var groups []*grouppb.Group - for _, g := range groupMap { - groups = append(groups, g) - } - - return groups, nil - } - - return nil, errors.New("rest: unable to get connection from redis pool") -} - -func (m *manager) fetchCachedGroupDetails(gid *grouppb.GroupId) (*grouppb.Group, error) { - group, err := m.getVal(groupPrefix + idPrefix + gid.OpaqueId) - if err != nil { - return nil, err - } - - g := grouppb.Group{} - if err = json.Unmarshal([]byte(group), &g); err != nil { - return nil, err - } - return &g, nil -} - -func (m *manager) cacheGroupDetails(g *grouppb.Group) error { - encodedGroup, err := json.Marshal(&g) - if err != nil { - return err - } - if err = m.setVal(groupPrefix+idPrefix+strings.ToLower(g.Id.OpaqueId), string(encodedGroup), -1); err != nil { - return err - } - - if g.GidNumber != 0 { - if err = m.setVal(groupPrefix+gidPrefix+strconv.FormatInt(g.GidNumber, 10), g.Id.OpaqueId, -1); err != nil { - return err - } - } - if g.DisplayName != "" { - if err = m.setVal(groupPrefix+namePrefix+g.Id.OpaqueId+"_"+strings.ToLower(g.DisplayName), g.Id.OpaqueId, -1); err != nil { - return err - } - } - return nil -} - -func (m *manager) fetchCachedGroupByParam(field, claim string) (*grouppb.Group, error) { - group, err := m.getVal(groupPrefix + field + ":" + strings.ToLower(claim)) - if err != nil { - return nil, err - } - - g := grouppb.Group{} - if err = json.Unmarshal([]byte(group), &g); err != nil { - return nil, err - } - return &g, nil -} - -func (m *manager) fetchCachedGroupMembers(gid *grouppb.GroupId) ([]*userpb.UserId, error) { - members, err := m.getVal(groupPrefix + groupMembersPrefix + strings.ToLower(gid.OpaqueId)) - if err != nil { - return nil, err - } - u := []*userpb.UserId{} - if err = json.Unmarshal([]byte(members), &u); err != nil { - return nil, err - } - return u, nil -} - -func (m *manager) cacheGroupMembers(gid *grouppb.GroupId, members []*userpb.UserId) error { - u, err := json.Marshal(&members) - if err != nil { - return err - } - return m.setVal(groupPrefix+groupMembersPrefix+strings.ToLower(gid.OpaqueId), string(u), m.conf.GroupMembersCacheExpiration*60) -} diff --git a/vendor/github.com/opencloud-eu/reva/v2/pkg/cbox/group/rest/rest.go b/vendor/github.com/opencloud-eu/reva/v2/pkg/cbox/group/rest/rest.go deleted file mode 100644 index 7464b10bf2..0000000000 --- a/vendor/github.com/opencloud-eu/reva/v2/pkg/cbox/group/rest/rest.go +++ /dev/null @@ -1,329 +0,0 @@ -// 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 rest - -import ( - "context" - "errors" - "fmt" - "os" - "os/signal" - "strings" - "syscall" - "time" - - grouppb "github.com/cs3org/go-cs3apis/cs3/identity/group/v1beta1" - userpb "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1" - "github.com/gomodule/redigo/redis" - "github.com/mitchellh/mapstructure" - "github.com/opencloud-eu/reva/v2/pkg/appctx" - utils "github.com/opencloud-eu/reva/v2/pkg/cbox/utils" - "github.com/opencloud-eu/reva/v2/pkg/group" - "github.com/opencloud-eu/reva/v2/pkg/group/manager/registry" - "github.com/rs/zerolog/log" -) - -func init() { - registry.Register("rest", New) -} - -type manager struct { - conf *config - redisPool *redis.Pool - apiTokenManager *utils.APITokenManager -} - -type config struct { - // The address at which the redis server is running - RedisAddress string `mapstructure:"redis_address" docs:"localhost:6379"` - // The username for connecting to the redis server - RedisUsername string `mapstructure:"redis_username" docs:""` - // The password for connecting to the redis server - RedisPassword string `mapstructure:"redis_password" docs:""` - // The time in minutes for which the members of a group would be cached - GroupMembersCacheExpiration int `mapstructure:"group_members_cache_expiration" docs:"5"` - // The OIDC Provider - IDProvider string `mapstructure:"id_provider" docs:"http://cernbox.cern.ch"` - // Base API Endpoint - APIBaseURL string `mapstructure:"api_base_url" docs:"https://authorization-service-api-dev.web.cern.ch"` - // Client ID needed to authenticate - ClientID string `mapstructure:"client_id" docs:"-"` - // Client Secret - ClientSecret string `mapstructure:"client_secret" docs:"-"` - - // Endpoint to generate token to access the API - OIDCTokenEndpoint string `mapstructure:"oidc_token_endpoint" docs:"https://keycloak-dev.cern.ch/auth/realms/cern/api-access/token"` - // The target application for which token needs to be generated - TargetAPI string `mapstructure:"target_api" docs:"authorization-service-api"` - // The time in seconds between bulk fetch of groups - GroupFetchInterval int `mapstructure:"group_fetch_interval" docs:"3600"` -} - -func (c *config) init() { - if c.GroupMembersCacheExpiration == 0 { - c.GroupMembersCacheExpiration = 5 - } - if c.RedisAddress == "" { - c.RedisAddress = ":6379" - } - if c.APIBaseURL == "" { - c.APIBaseURL = "https://authorization-service-api-dev.web.cern.ch" - } - if c.TargetAPI == "" { - c.TargetAPI = "authorization-service-api" - } - if c.OIDCTokenEndpoint == "" { - c.OIDCTokenEndpoint = "https://keycloak-dev.cern.ch/auth/realms/cern/api-access/token" - } - if c.IDProvider == "" { - c.IDProvider = "http://cernbox.cern.ch" - } - if c.GroupFetchInterval == 0 { - c.GroupFetchInterval = 3600 - } -} - -func parseConfig(m map[string]interface{}) (*config, error) { - c := &config{} - if err := mapstructure.Decode(m, c); err != nil { - return nil, err - } - return c, nil -} - -// New returns a user manager implementation that makes calls to the GRAPPA API. -func New(m map[string]interface{}) (group.Manager, error) { - c, err := parseConfig(m) - if err != nil { - return nil, err - } - c.init() - - redisPool := initRedisPool(c.RedisAddress, c.RedisUsername, c.RedisPassword) - apiTokenManager := utils.InitAPITokenManager(c.TargetAPI, c.OIDCTokenEndpoint, c.ClientID, c.ClientSecret) - - mgr := &manager{ - conf: c, - redisPool: redisPool, - apiTokenManager: apiTokenManager, - } - go mgr.fetchAllGroups() - return mgr, nil -} - -func (m *manager) fetchAllGroups() { - _ = m.fetchAllGroupAccounts() - ticker := time.NewTicker(time.Duration(m.conf.GroupFetchInterval) * time.Second) - work := make(chan os.Signal, 1) - signal.Notify(work, syscall.SIGHUP, syscall.SIGINT, syscall.SIGQUIT) - - for { - select { - case <-work: - return - case <-ticker.C: - _ = m.fetchAllGroupAccounts() - } - } -} - -func (m *manager) fetchAllGroupAccounts() error { - ctx := context.Background() - url := fmt.Sprintf("%s/api/v1.0/Group?field=groupIdentifier&field=displayName&field=gid", m.conf.APIBaseURL) - - for url != "" { - result, err := m.apiTokenManager.SendAPIGetRequest(ctx, url, false) - if err != nil { - return err - } - - responseData, ok := result["data"].([]interface{}) - if !ok { - return errors.New("rest: error in type assertion") - } - for _, usr := range responseData { - groupData, ok := usr.(map[string]interface{}) - if !ok { - continue - } - - _, err = m.parseAndCacheGroup(ctx, groupData) - if err != nil { - continue - } - } - - url = "" - if pagination, ok := result["pagination"].(map[string]interface{}); ok { - if links, ok := pagination["links"].(map[string]interface{}); ok { - if next, ok := links["next"].(string); ok { - url = fmt.Sprintf("%s%s", m.conf.APIBaseURL, next) - } - } - } - } - - return nil -} - -func (m *manager) parseAndCacheGroup(ctx context.Context, groupData map[string]interface{}) (*grouppb.Group, error) { - id, ok := groupData["groupIdentifier"].(string) - if !ok { - return nil, errors.New("rest: missing upn in user data") - } - - name, _ := groupData["displayName"].(string) - groupID := &grouppb.GroupId{ - OpaqueId: id, - Idp: m.conf.IDProvider, - } - gid, ok := groupData["gid"].(int64) - if !ok { - gid = 0 - } - g := &grouppb.Group{ - Id: groupID, - GroupName: id, - Mail: id + "@cern.ch", - DisplayName: name, - GidNumber: gid, - } - - if err := m.cacheGroupDetails(g); err != nil { - log.Error().Err(err).Msg("rest: error caching group details") - } - - if internalID, ok := groupData["id"].(string); ok { - if err := m.cacheInternalID(groupID, internalID); err != nil { - log.Error().Err(err).Msg("rest: error caching group details") - } - } - - return g, nil - -} - -func (m *manager) GetGroup(ctx context.Context, gid *grouppb.GroupId, skipFetchingMembers bool) (*grouppb.Group, error) { - g, err := m.fetchCachedGroupDetails(gid) - if err != nil { - return nil, err - } - - if !skipFetchingMembers { - groupMembers, err := m.GetMembers(ctx, gid) - if err != nil { - return nil, err - } - g.Members = groupMembers - } - - return g, nil -} - -func (m *manager) GetGroupByClaim(ctx context.Context, claim, value string, skipFetchingMembers bool) (*grouppb.Group, error) { - if claim == "group_name" { - return m.GetGroup(ctx, &grouppb.GroupId{OpaqueId: value}, skipFetchingMembers) - } - - g, err := m.fetchCachedGroupByParam(claim, value) - if err != nil { - return nil, err - } - - if !skipFetchingMembers { - groupMembers, err := m.GetMembers(ctx, g.Id) - if err != nil { - return nil, err - } - g.Members = groupMembers - } - - return g, nil -} - -func (m *manager) FindGroups(ctx context.Context, query string, skipFetchingMembers bool) ([]*grouppb.Group, error) { - - // Look at namespaces filters. If the query starts with: - // "a" or none => get egroups - // other filters => get empty list - - parts := strings.SplitN(query, ":", 2) - - if len(parts) == 2 { - if parts[0] == "a" { - query = parts[1] - } else { - return []*grouppb.Group{}, nil - } - } - - return m.findCachedGroups(query) -} - -func (m *manager) GetMembers(ctx context.Context, gid *grouppb.GroupId) ([]*userpb.UserId, error) { - - users, err := m.fetchCachedGroupMembers(gid) - if err == nil { - return users, nil - } - - internalID, err := m.fetchCachedInternalID(gid) - if err != nil { - return nil, err - } - url := fmt.Sprintf("%s/api/v1.0/Group/%s/memberidentities/precomputed", m.conf.APIBaseURL, internalID) - result, err := m.apiTokenManager.SendAPIGetRequest(ctx, url, false) - if err != nil { - return nil, err - } - - userData := result["data"].([]interface{}) - users = []*userpb.UserId{} - - for _, u := range userData { - userInfo, ok := u.(map[string]interface{}) - if !ok { - return nil, errors.New("rest: error in type assertion") - } - if id, ok := userInfo["upn"].(string); ok { - users = append(users, &userpb.UserId{OpaqueId: id, Idp: m.conf.IDProvider}) - } - } - - if err = m.cacheGroupMembers(gid, users); err != nil { - log := appctx.GetLogger(ctx) - log.Error().Err(err).Msg("rest: error caching group members") - } - - return users, nil -} - -func (m *manager) HasMember(ctx context.Context, gid *grouppb.GroupId, uid *userpb.UserId) (bool, error) { - groupMemers, err := m.GetMembers(ctx, gid) - if err != nil { - return false, err - } - - for _, u := range groupMemers { - if uid.OpaqueId == u.OpaqueId { - return true, nil - } - } - return false, nil -} diff --git a/vendor/github.com/opencloud-eu/reva/v2/pkg/cbox/loader/loader.go b/vendor/github.com/opencloud-eu/reva/v2/pkg/cbox/loader/loader.go deleted file mode 100644 index 59e0eb5406..0000000000 --- a/vendor/github.com/opencloud-eu/reva/v2/pkg/cbox/loader/loader.go +++ /dev/null @@ -1,31 +0,0 @@ -// 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 loader - -import ( - // Load cbox specific drivers. - _ "github.com/opencloud-eu/reva/v2/pkg/cbox/favorite/sql" - _ "github.com/opencloud-eu/reva/v2/pkg/cbox/group/rest" - _ "github.com/opencloud-eu/reva/v2/pkg/cbox/preferences/sql" - _ "github.com/opencloud-eu/reva/v2/pkg/cbox/publicshare/sql" - _ "github.com/opencloud-eu/reva/v2/pkg/cbox/share/sql" - _ "github.com/opencloud-eu/reva/v2/pkg/cbox/storage/eoshomewrapper" - _ "github.com/opencloud-eu/reva/v2/pkg/cbox/storage/eoswrapper" - _ "github.com/opencloud-eu/reva/v2/pkg/cbox/user/rest" -) diff --git a/vendor/github.com/opencloud-eu/reva/v2/pkg/cbox/preferences/sql/sql.go b/vendor/github.com/opencloud-eu/reva/v2/pkg/cbox/preferences/sql/sql.go deleted file mode 100644 index 0d5acffe1c..0000000000 --- a/vendor/github.com/opencloud-eu/reva/v2/pkg/cbox/preferences/sql/sql.go +++ /dev/null @@ -1,100 +0,0 @@ -// 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 sql - -import ( - "context" - "database/sql" - "fmt" - - "github.com/mitchellh/mapstructure" - ctxpkg "github.com/opencloud-eu/reva/v2/pkg/ctx" - "github.com/opencloud-eu/reva/v2/pkg/errtypes" - "github.com/opencloud-eu/reva/v2/pkg/preferences" - "github.com/opencloud-eu/reva/v2/pkg/preferences/registry" -) - -func init() { - registry.Register("sql", New) -} - -type config struct { - DbUsername string `mapstructure:"db_username"` - DbPassword string `mapstructure:"db_password"` - DbHost string `mapstructure:"db_host"` - DbPort int `mapstructure:"db_port"` - DbName string `mapstructure:"db_name"` -} - -type mgr struct { - c *config - db *sql.DB -} - -// New returns an instance of the cbox sql preferences manager. -func New(m map[string]interface{}) (preferences.Manager, error) { - c := &config{} - if err := mapstructure.Decode(m, c); err != nil { - return nil, err - } - - db, err := sql.Open("mysql", fmt.Sprintf("%s:%s@tcp(%s:%d)/%s", c.DbUsername, c.DbPassword, c.DbHost, c.DbPort, c.DbName)) - if err != nil { - return nil, err - } - - return &mgr{ - c: c, - db: db, - }, nil -} - -func (m *mgr) SetKey(ctx context.Context, key, namespace, value string) error { - user, ok := ctxpkg.ContextGetUser(ctx) - if !ok { - return errtypes.UserRequired("preferences: error getting user from ctx") - } - query := `INSERT INTO oc_preferences(userid, appid, configkey, configvalue) values(?, ?, ?, ?) ON DUPLICATE KEY UPDATE configvalue = ?` - params := []interface{}{user.Id.OpaqueId, namespace, key, value, value} - stmt, err := m.db.Prepare(query) - if err != nil { - return err - } - - if _, err = stmt.Exec(params...); err != nil { - return err - } - return nil -} - -func (m *mgr) GetKey(ctx context.Context, key, namespace string) (string, error) { - user, ok := ctxpkg.ContextGetUser(ctx) - if !ok { - return "", errtypes.UserRequired("preferences: error getting user from ctx") - } - query := `SELECT configvalue FROM oc_preferences WHERE userid=? AND appid=? AND configkey=?` - var val string - if err := m.db.QueryRow(query, user.Id.OpaqueId, namespace, key).Scan(&val); err != nil { - if err == sql.ErrNoRows { - return "", errtypes.NotFound(namespace + ":" + key) - } - return "", err - } - return val, nil -} diff --git a/vendor/github.com/opencloud-eu/reva/v2/pkg/cbox/publicshare/sql/sql.go b/vendor/github.com/opencloud-eu/reva/v2/pkg/cbox/publicshare/sql/sql.go deleted file mode 100644 index ce55d383f8..0000000000 --- a/vendor/github.com/opencloud-eu/reva/v2/pkg/cbox/publicshare/sql/sql.go +++ /dev/null @@ -1,533 +0,0 @@ -// 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 sql - -import ( - "context" - "database/sql" - "fmt" - "os" - "os/signal" - "strconv" - "strings" - "syscall" - "time" - - "golang.org/x/crypto/bcrypt" - - gatewayv1beta1 "github.com/cs3org/go-cs3apis/cs3/gateway/v1beta1" - user "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1" - 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/mitchellh/mapstructure" - conversions "github.com/opencloud-eu/reva/v2/pkg/cbox/utils" - "github.com/opencloud-eu/reva/v2/pkg/errtypes" - "github.com/opencloud-eu/reva/v2/pkg/publicshare" - "github.com/opencloud-eu/reva/v2/pkg/publicshare/manager/registry" - "github.com/opencloud-eu/reva/v2/pkg/rgrpc/todo/pool" - "github.com/opencloud-eu/reva/v2/pkg/utils" - "github.com/pkg/errors" -) - -const publicShareType = 3 - -func init() { - registry.Register("sql", New) -} - -type config struct { - SharePasswordHashCost int `mapstructure:"password_hash_cost"` - JanitorRunInterval int `mapstructure:"janitor_run_interval"` - EnableExpiredSharesCleanup bool `mapstructure:"enable_expired_shares_cleanup"` - DbUsername string `mapstructure:"db_username"` - DbPassword string `mapstructure:"db_password"` - DbHost string `mapstructure:"db_host"` - DbPort int `mapstructure:"db_port"` - DbName string `mapstructure:"db_name"` - GatewaySvc string `mapstructure:"gatewaysvc"` -} - -type manager struct { - c *config - db *sql.DB - client gatewayv1beta1.GatewayAPIClient -} - -func (c *config) init() { - if c.SharePasswordHashCost == 0 { - c.SharePasswordHashCost = 11 - } - if c.JanitorRunInterval == 0 { - c.JanitorRunInterval = 3600 - } -} - -func (m *manager) startJanitorRun() { - if !m.c.EnableExpiredSharesCleanup { - return - } - - ticker := time.NewTicker(time.Duration(m.c.JanitorRunInterval) * time.Second) - work := make(chan os.Signal, 1) - signal.Notify(work, syscall.SIGHUP, syscall.SIGINT, syscall.SIGQUIT) - - for { - select { - case <-work: - return - case <-ticker.C: - _ = m.cleanupExpiredShares() - } - } -} - -// New returns a new public share manager. -func New(m map[string]interface{}) (publicshare.Manager, error) { - c := &config{} - if err := mapstructure.Decode(m, c); err != nil { - return nil, err - } - c.init() - - db, err := sql.Open("mysql", fmt.Sprintf("%s:%s@tcp(%s:%d)/%s", c.DbUsername, c.DbPassword, c.DbHost, c.DbPort, c.DbName)) - if err != nil { - return nil, err - } - - gw, err := pool.GetGatewayServiceClient(c.GatewaySvc) - if err != nil { - return nil, err - } - - mgr := manager{ - c: c, - db: db, - client: gw, - } - go mgr.startJanitorRun() - - return &mgr, nil -} - -func (m *manager) CreatePublicShare(ctx context.Context, u *user.User, rInfo *provider.ResourceInfo, g *link.Grant) (*link.PublicShare, error) { - - tkn := utils.RandString(15) - now := time.Now().Unix() - - displayName, ok := rInfo.ArbitraryMetadata.Metadata["name"] - if !ok { - displayName = tkn - } - createdAt := &typespb.Timestamp{ - Seconds: uint64(now), - } - - creator := conversions.FormatUserID(u.Id) - owner := conversions.FormatUserID(rInfo.Owner) - permissions := conversions.SharePermToInt(g.Permissions.Permissions) - itemType := conversions.ResourceTypeToItem(rInfo.Type) - prefix := rInfo.Id.SpaceId - itemSource := rInfo.Id.OpaqueId - fileSource, err := strconv.ParseUint(itemSource, 10, 64) - if err != nil { - // it can be the case that the item source may be a character string - // we leave fileSource blank in that case - fileSource = 0 - } - - query := "insert into oc_share set share_type=?,uid_owner=?,uid_initiator=?,item_type=?,fileid_prefix=?,item_source=?,file_source=?,permissions=?,stime=?,token=?,share_name=?" - params := []interface{}{publicShareType, owner, creator, itemType, prefix, itemSource, fileSource, permissions, now, tkn, displayName} - - var passwordProtected bool - password := g.Password - if password != "" { - password, err = hashPassword(password, m.c.SharePasswordHashCost) - if err != nil { - return nil, errors.Wrap(err, "could not hash share password") - } - passwordProtected = true - - query += ",share_with=?" - params = append(params, password) - } - - if g.Expiration != nil && g.Expiration.Seconds != 0 { - t := time.Unix(int64(g.Expiration.Seconds), 0) - query += ",expiration=?" - params = append(params, t) - } - - stmt, err := m.db.Prepare(query) - if err != nil { - return nil, err - } - result, err := stmt.Exec(params...) - if err != nil { - return nil, err - } - lastID, err := result.LastInsertId() - if err != nil { - return nil, err - } - - return &link.PublicShare{ - Id: &link.PublicShareId{ - OpaqueId: strconv.FormatInt(lastID, 10), - }, - Owner: rInfo.GetOwner(), - Creator: u.Id, - ResourceId: rInfo.Id, - Token: tkn, - Permissions: g.Permissions, - Ctime: createdAt, - Mtime: createdAt, - PasswordProtected: passwordProtected, - Expiration: g.Expiration, - DisplayName: displayName, - }, nil -} - -func (m *manager) UpdatePublicShare(ctx context.Context, u *user.User, req *link.UpdatePublicShareRequest) (*link.PublicShare, error) { - query := "update oc_share set " - paramsMap := map[string]interface{}{} - params := []interface{}{} - - now := time.Now().Unix() - uid := conversions.FormatUserID(u.Id) - - switch req.GetUpdate().GetType() { - case link.UpdatePublicShareRequest_Update_TYPE_DISPLAYNAME: - paramsMap["share_name"] = req.Update.GetDisplayName() - case link.UpdatePublicShareRequest_Update_TYPE_PERMISSIONS: - paramsMap["permissions"] = conversions.SharePermToInt(req.Update.GetGrant().GetPermissions().Permissions) - case link.UpdatePublicShareRequest_Update_TYPE_EXPIRATION: - paramsMap["expiration"] = time.Unix(int64(req.Update.GetGrant().Expiration.Seconds), 0) - case link.UpdatePublicShareRequest_Update_TYPE_PASSWORD: - if req.Update.GetGrant().Password == "" { - paramsMap["share_with"] = "" - } else { - h, err := hashPassword(req.Update.GetGrant().Password, m.c.SharePasswordHashCost) - if err != nil { - return nil, errors.Wrap(err, "could not hash share password") - } - paramsMap["share_with"] = h - } - default: - return nil, fmt.Errorf("invalid update type: %v", req.GetUpdate().GetType()) - } - - for k, v := range paramsMap { - query += k + "=?" - params = append(params, v) - } - - switch { - case req.Ref.GetId() != nil: - query += ",stime=? where id=? AND (uid_owner=? or uid_initiator=?)" - params = append(params, now, req.Ref.GetId().OpaqueId, uid, uid) - case req.Ref.GetToken() != "": - query += ",stime=? where token=? AND (uid_owner=? or uid_initiator=?)" - params = append(params, now, req.Ref.GetToken(), uid, uid) - default: - return nil, errtypes.NotFound(req.Ref.String()) - } - - stmt, err := m.db.Prepare(query) - if err != nil { - return nil, err - } - if _, err = stmt.Exec(params...); err != nil { - return nil, err - } - - return m.GetPublicShare(ctx, u, req.Ref, false) -} - -func (m *manager) getByToken(ctx context.Context, token string, u *user.User) (*link.PublicShare, string, error) { - s := conversions.DBShare{Token: token} - query := "select coalesce(uid_owner, '') as uid_owner, coalesce(uid_initiator, '') as uid_initiator, coalesce(share_with, '') as share_with, coalesce(fileid_prefix, '') as fileid_prefix, coalesce(item_source, '') as item_source, coalesce(item_type, '') as item_type, coalesce(expiration, '') as expiration, coalesce(share_name, '') as share_name, id, stime, permissions FROM oc_share WHERE (orphan = 0 or orphan IS NULL) AND share_type=? AND token=?" - if err := m.db.QueryRow(query, publicShareType, token).Scan(&s.UIDOwner, &s.UIDInitiator, &s.ShareWith, &s.Prefix, &s.ItemSource, &s.ItemType, &s.Expiration, &s.ShareName, &s.ID, &s.STime, &s.Permissions); err != nil { - if err == sql.ErrNoRows { - return nil, "", errtypes.NotFound(token) - } - return nil, "", err - } - share, err := conversions.ConvertToCS3PublicShare(ctx, m.client, s) - if err != nil { - return nil, "", err - } - return share, s.ShareWith, nil -} - -func (m *manager) getByID(ctx context.Context, id *link.PublicShareId, u *user.User) (*link.PublicShare, string, error) { - uid := conversions.FormatUserID(u.Id) - s := conversions.DBShare{ID: id.OpaqueId} - query := "select coalesce(uid_owner, '') as uid_owner, coalesce(uid_initiator, '') as uid_initiator, coalesce(share_with, '') as share_with, coalesce(fileid_prefix, '') as fileid_prefix, coalesce(item_source, '') as item_source, coalesce(item_type, '') as item_type, coalesce(token,'') as token, coalesce(expiration, '') as expiration, coalesce(share_name, '') as share_name, stime, permissions FROM oc_share WHERE (orphan = 0 or orphan IS NULL) AND share_type=? AND id=? AND (uid_owner=? OR uid_initiator=?)" - if err := m.db.QueryRow(query, publicShareType, id.OpaqueId, uid, uid).Scan(&s.UIDOwner, &s.UIDInitiator, &s.ShareWith, &s.Prefix, &s.ItemSource, &s.ItemType, &s.Token, &s.Expiration, &s.ShareName, &s.STime, &s.Permissions); err != nil { - if err == sql.ErrNoRows { - return nil, "", errtypes.NotFound(id.OpaqueId) - } - return nil, "", err - } - share, err := conversions.ConvertToCS3PublicShare(ctx, m.client, s) - if err != nil { - return nil, "", err - } - return share, s.ShareWith, nil -} - -func (m *manager) GetPublicShare(ctx context.Context, u *user.User, ref *link.PublicShareReference, sign bool) (*link.PublicShare, error) { - var s *link.PublicShare - var pw string - var err error - switch { - case ref.GetId() != nil: - s, pw, err = m.getByID(ctx, ref.GetId(), u) - case ref.GetToken() != "": - s, pw, err = m.getByToken(ctx, ref.GetToken(), u) - default: - err = errtypes.NotFound(ref.String()) - } - if err != nil { - return nil, err - } - - if expired(s) { - if err := m.cleanupExpiredShares(); err != nil { - return nil, err - } - return nil, errtypes.NotFound(ref.String()) - } - - if s.PasswordProtected && sign { - if err := publicshare.AddSignature(s, pw); err != nil { - return nil, err - } - - } - - return s, nil -} - -func (m *manager) ListPublicShares(ctx context.Context, u *user.User, filters []*link.ListPublicSharesRequest_Filter, sign bool) ([]*link.PublicShare, error) { - uid := conversions.FormatUserID(u.Id) - query := "select coalesce(uid_owner, '') as uid_owner, coalesce(uid_initiator, '') as uid_initiator, coalesce(share_with, '') as share_with, coalesce(fileid_prefix, '') as fileid_prefix, coalesce(item_source, '') as item_source, coalesce(item_type, '') as item_type, coalesce(token,'') as token, coalesce(expiration, '') as expiration, coalesce(share_name, '') as share_name, id, stime, permissions FROM oc_share WHERE (orphan = 0 or orphan IS NULL) AND (uid_owner=? or uid_initiator=?) AND (share_type=?)" - var resourceFilters, ownerFilters, creatorFilters string - var resourceParams, ownerParams, creatorParams []interface{} - params := []interface{}{uid, uid, publicShareType} - - for _, f := range filters { - switch f.Type { - case link.ListPublicSharesRequest_Filter_TYPE_RESOURCE_ID: - if len(resourceFilters) != 0 { - resourceFilters += " OR " - } - resourceFilters += "(fileid_prefix=? AND item_source=?)" - resourceParams = append(resourceParams, f.GetResourceId().SpaceId, f.GetResourceId().OpaqueId) - case link.ListPublicSharesRequest_Filter_TYPE_OWNER: - if len(ownerFilters) != 0 { - ownerFilters += " OR " - } - ownerFilters += "(uid_owner=?)" - ownerParams = append(ownerParams, conversions.FormatUserID(f.GetOwner())) - case link.ListPublicSharesRequest_Filter_TYPE_CREATOR: - if len(creatorFilters) != 0 { - creatorFilters += " OR " - } - creatorFilters += "(uid_initiator=?)" - creatorParams = append(creatorParams, conversions.FormatUserID(f.GetCreator())) - } - } - if resourceFilters != "" { - query = fmt.Sprintf("%s AND (%s)", query, resourceFilters) - params = append(params, resourceParams...) - } - if ownerFilters != "" { - query = fmt.Sprintf("%s AND (%s)", query, ownerFilters) - params = append(params, ownerParams...) - } - if creatorFilters != "" { - query = fmt.Sprintf("%s AND (%s)", query, creatorFilters) - params = append(params, creatorParams...) - } - - rows, err := m.db.Query(query, params...) - if err != nil { - return nil, err - } - defer rows.Close() - - var s conversions.DBShare - shares := []*link.PublicShare{} - for rows.Next() { - if err := rows.Scan(&s.UIDOwner, &s.UIDInitiator, &s.ShareWith, &s.Prefix, &s.ItemSource, &s.ItemType, &s.Token, &s.Expiration, &s.ShareName, &s.ID, &s.STime, &s.Permissions); err != nil { - continue - } - cs3Share, err := conversions.ConvertToCS3PublicShare(ctx, m.client, s) - if err != nil { - return nil, err - } - if expired(cs3Share) { - _ = m.cleanupExpiredShares() - } else { - if cs3Share.PasswordProtected && sign { - if err := publicshare.AddSignature(cs3Share, s.ShareWith); err != nil { - return nil, err - } - } - shares = append(shares, cs3Share) - } - } - if err = rows.Err(); err != nil { - return nil, err - } - - return shares, nil -} - -func (m *manager) RevokePublicShare(ctx context.Context, u *user.User, ref *link.PublicShareReference) error { - uid := conversions.FormatUserID(u.Id) - query := "delete from oc_share where " - params := []interface{}{} - - switch { - case ref.GetId() != nil && ref.GetId().OpaqueId != "": - query += "id=? AND (uid_owner=? or uid_initiator=?)" - params = append(params, ref.GetId().OpaqueId, uid, uid) - case ref.GetToken() != "": - query += "token=? AND (uid_owner=? or uid_initiator=?)" - params = append(params, ref.GetToken(), uid, uid) - default: - return errtypes.NotFound(ref.String()) - } - - stmt, err := m.db.Prepare(query) - if err != nil { - return err - } - res, err := stmt.Exec(params...) - if err != nil { - return err - } - - rowCnt, err := res.RowsAffected() - if err != nil { - return err - } - if rowCnt == 0 { - return errtypes.NotFound(ref.String()) - } - return nil -} - -func (m *manager) GetPublicShareByToken(ctx context.Context, token string, auth *link.PublicShareAuthentication, sign bool) (*link.PublicShare, error) { - s := conversions.DBShare{Token: token} - query := "select coalesce(uid_owner, '') as uid_owner, coalesce(uid_initiator, '') as uid_initiator, coalesce(share_with, '') as share_with, coalesce(fileid_prefix, '') as fileid_prefix, coalesce(item_source, '') as item_source, coalesce(item_type, '') as item_type, coalesce(expiration, '') as expiration, coalesce(share_name, '') as share_name, id, stime, permissions FROM oc_share WHERE share_type=? AND token=?" - if err := m.db.QueryRow(query, publicShareType, token).Scan(&s.UIDOwner, &s.UIDInitiator, &s.ShareWith, &s.Prefix, &s.ItemSource, &s.ItemType, &s.Expiration, &s.ShareName, &s.ID, &s.STime, &s.Permissions); err != nil { - if err == sql.ErrNoRows { - return nil, errtypes.NotFound(token) - } - return nil, err - } - cs3Share, err := conversions.ConvertToCS3PublicShare(ctx, m.client, s) - if err != nil { - return nil, err - } - if s.ShareWith != "" { - if !authenticate(cs3Share, s.ShareWith, auth) { - // if check := checkPasswordHash(auth.Password, s.ShareWith); !check { - return nil, errtypes.InvalidCredentials(token) - } - - if sign { - if err := publicshare.AddSignature(cs3Share, s.ShareWith); err != nil { - return nil, err - } - } - } - - if expired(cs3Share) { - if err := m.cleanupExpiredShares(); err != nil { - return nil, err - } - return nil, errtypes.NotFound(token) - } - - return cs3Share, nil -} - -func (m *manager) cleanupExpiredShares() error { - if !m.c.EnableExpiredSharesCleanup { - return nil - } - - query := "update oc_share set orphan = 1 where expiration IS NOT NULL AND expiration < ?" - params := []interface{}{time.Now().Format("2006-01-02 03:04:05")} - - stmt, err := m.db.Prepare(query) - if err != nil { - return err - } - if _, err = stmt.Exec(params...); err != nil { - return err - } - return nil -} - -func expired(s *link.PublicShare) bool { - if s.Expiration != nil { - if t := time.Unix(int64(s.Expiration.GetSeconds()), int64(s.Expiration.GetNanos())); t.Before(time.Now()) { - return true - } - } - return false -} - -func hashPassword(password string, cost int) (string, error) { - bytes, err := bcrypt.GenerateFromPassword([]byte(password), cost) - return "1|" + string(bytes), err -} - -func checkPasswordHash(password, hash string) bool { - err := bcrypt.CompareHashAndPassword([]byte(strings.TrimPrefix(hash, "1|")), []byte(password)) - return err == nil -} - -func authenticate(share *link.PublicShare, pw string, auth *link.PublicShareAuthentication) bool { - switch { - case auth.GetPassword() != "": - return checkPasswordHash(auth.GetPassword(), pw) - case auth.GetSignature() != nil: - sig := auth.GetSignature() - now := time.Now() - expiration := time.Unix(int64(sig.GetSignatureExpiration().GetSeconds()), int64(sig.GetSignatureExpiration().GetNanos())) - if now.After(expiration) { - return false - } - s, err := publicshare.CreateSignature(share.Token, pw, expiration) - if err != nil { - // TODO(labkode): pass context to call to log err. - // No we are blind - return false - } - return sig.GetSignature() == s - } - return false -} diff --git a/vendor/github.com/opencloud-eu/reva/v2/pkg/cbox/share/sql/sql.go b/vendor/github.com/opencloud-eu/reva/v2/pkg/cbox/share/sql/sql.go deleted file mode 100644 index 1d81cf1a2c..0000000000 --- a/vendor/github.com/opencloud-eu/reva/v2/pkg/cbox/share/sql/sql.go +++ /dev/null @@ -1,592 +0,0 @@ -// 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 sql - -import ( - "context" - "database/sql" - "fmt" - "path" - "strconv" - "strings" - "time" - - gatewayv1beta1 "github.com/cs3org/go-cs3apis/cs3/gateway/v1beta1" - userpb "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1" - collaboration "github.com/cs3org/go-cs3apis/cs3/sharing/collaboration/v1beta1" - provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1" - typespb "github.com/cs3org/go-cs3apis/cs3/types/v1beta1" - "github.com/mitchellh/mapstructure" - conversions "github.com/opencloud-eu/reva/v2/pkg/cbox/utils" - ctxpkg "github.com/opencloud-eu/reva/v2/pkg/ctx" - "github.com/opencloud-eu/reva/v2/pkg/errtypes" - "github.com/opencloud-eu/reva/v2/pkg/rgrpc/todo/pool" - "github.com/opencloud-eu/reva/v2/pkg/share" - "github.com/opencloud-eu/reva/v2/pkg/share/manager/registry" - "github.com/opencloud-eu/reva/v2/pkg/utils" - "github.com/pkg/errors" - "google.golang.org/genproto/protobuf/field_mask" - - // Provides mysql drivers - _ "github.com/go-sql-driver/mysql" -) - -const ( - shareTypeUser = 0 - shareTypeGroup = 1 -) - -func init() { - registry.Register("sql", New) -} - -type config struct { - DbUsername string `mapstructure:"db_username"` - DbPassword string `mapstructure:"db_password"` - DbHost string `mapstructure:"db_host"` - DbPort int `mapstructure:"db_port"` - DbName string `mapstructure:"db_name"` - GatewaySvc string `mapstructure:"gatewaysvc"` -} - -type mgr struct { - c *config - db *sql.DB - client gatewayv1beta1.GatewayAPIClient -} - -// New returns a new share manager. -func New(m map[string]interface{}) (share.Manager, error) { - c, err := parseConfig(m) - if err != nil { - err = errors.Wrap(err, "error creating a new manager") - return nil, err - } - - db, err := sql.Open("mysql", fmt.Sprintf("%s:%s@tcp(%s:%d)/%s", c.DbUsername, c.DbPassword, c.DbHost, c.DbPort, c.DbName)) - if err != nil { - return nil, err - } - - gw, err := pool.GetGatewayServiceClient(c.GatewaySvc) - if err != nil { - return nil, err - } - - return &mgr{ - c: c, - db: db, - client: gw, - }, nil -} - -func parseConfig(m map[string]interface{}) (*config, error) { - c := &config{} - if err := mapstructure.Decode(m, c); err != nil { - return nil, err - } - return c, nil -} - -func (m *mgr) Share(ctx context.Context, md *provider.ResourceInfo, g *collaboration.ShareGrant) (*collaboration.Share, error) { - user := ctxpkg.ContextMustGetUser(ctx) - - // do not allow share to myself or the owner if share is for a user - // TODO(labkode): should not this be caught already at the gw level? - if g.Grantee.Type == provider.GranteeType_GRANTEE_TYPE_USER && - (utils.UserEqual(g.Grantee.GetUserId(), user.Id) || utils.UserEqual(g.Grantee.GetUserId(), md.Owner)) { - return nil, errors.New("sql: owner/creator and grantee are the same") - } - - // check if share already exists. - key := &collaboration.ShareKey{ - Owner: md.Owner, - ResourceId: md.Id, - Grantee: g.Grantee, - } - _, err := m.getByKey(ctx, key) - - // share already exists - if err == nil { - return nil, errtypes.AlreadyExists(key.String()) - } - - now := time.Now().Unix() - ts := &typespb.Timestamp{ - Seconds: uint64(now), - } - - shareType, shareWith := conversions.FormatGrantee(g.Grantee) - itemType := conversions.ResourceTypeToItem(md.Type) - targetPath := path.Join("/", path.Base(md.Path)) - permissions := conversions.SharePermToInt(g.Permissions.Permissions) - prefix := md.Id.SpaceId - itemSource := md.Id.OpaqueId - fileSource, err := strconv.ParseUint(itemSource, 10, 64) - if err != nil { - // it can be the case that the item source may be a character string - // we leave fileSource blank in that case - fileSource = 0 - } - - stmtString := "insert into oc_share set share_type=?,uid_owner=?,uid_initiator=?,item_type=?,fileid_prefix=?,item_source=?,file_source=?,permissions=?,stime=?,share_with=?,file_target=?" - stmtValues := []interface{}{shareType, conversions.FormatUserID(md.Owner), conversions.FormatUserID(user.Id), itemType, prefix, itemSource, fileSource, permissions, now, shareWith, targetPath} - - stmt, err := m.db.Prepare(stmtString) - if err != nil { - return nil, err - } - result, err := stmt.Exec(stmtValues...) - if err != nil { - return nil, err - } - lastID, err := result.LastInsertId() - if err != nil { - return nil, err - } - - return &collaboration.Share{ - Id: &collaboration.ShareId{ - OpaqueId: strconv.FormatInt(lastID, 10), - }, - ResourceId: md.Id, - Permissions: g.Permissions, - Grantee: g.Grantee, - Owner: md.Owner, - Creator: user.Id, - Ctime: ts, - Mtime: ts, - }, nil -} - -func (m *mgr) getByID(ctx context.Context, id *collaboration.ShareId) (*collaboration.Share, error) { - uid := conversions.FormatUserID(ctxpkg.ContextMustGetUser(ctx).Id) - s := conversions.DBShare{ID: id.OpaqueId} - query := "select coalesce(uid_owner, '') as uid_owner, coalesce(uid_initiator, '') as uid_initiator, coalesce(share_with, '') as share_with, coalesce(fileid_prefix, '') as fileid_prefix, coalesce(item_source, '') as item_source, coalesce(item_type, '') as item_type, stime, permissions, share_type FROM oc_share WHERE (orphan = 0 or orphan IS NULL) AND id=? AND (uid_owner=? or uid_initiator=?)" - if err := m.db.QueryRow(query, id.OpaqueId, uid, uid).Scan(&s.UIDOwner, &s.UIDInitiator, &s.ShareWith, &s.Prefix, &s.ItemSource, &s.ItemType, &s.STime, &s.Permissions, &s.ShareType); err != nil { - if err == sql.ErrNoRows { - return nil, errtypes.NotFound(id.OpaqueId) - } - return nil, err - } - share, err := conversions.ConvertToCS3Share(ctx, m.client, s) - if err != nil { - return nil, err - } - return share, nil -} - -func (m *mgr) getByKey(ctx context.Context, key *collaboration.ShareKey) (*collaboration.Share, error) { - owner := conversions.FormatUserID(key.Owner) - uid := conversions.FormatUserID(ctxpkg.ContextMustGetUser(ctx).Id) - - s := conversions.DBShare{} - shareType, shareWith := conversions.FormatGrantee(key.Grantee) - query := "select coalesce(uid_owner, '') as uid_owner, coalesce(uid_initiator, '') as uid_initiator, coalesce(share_with, '') as share_with, coalesce(fileid_prefix, '') as fileid_prefix, coalesce(item_source, '') as item_source, coalesce(item_type, '') as item_type, id, stime, permissions, share_type FROM oc_share WHERE (orphan = 0 or orphan IS NULL) AND uid_owner=? AND fileid_prefix=? AND item_source=? AND share_type=? AND share_with=? AND (uid_owner=? or uid_initiator=?)" - if err := m.db.QueryRow(query, owner, key.ResourceId.SpaceId, key.ResourceId.OpaqueId, shareType, shareWith, uid, uid).Scan(&s.UIDOwner, &s.UIDInitiator, &s.ShareWith, &s.Prefix, &s.ItemSource, &s.ItemType, &s.ID, &s.STime, &s.Permissions, &s.ShareType); err != nil { - if err == sql.ErrNoRows { - return nil, errtypes.NotFound(key.String()) - } - return nil, err - } - share, err := conversions.ConvertToCS3Share(ctx, m.client, s) - if err != nil { - return nil, err - } - return share, nil -} - -func (m *mgr) GetShare(ctx context.Context, ref *collaboration.ShareReference) (*collaboration.Share, error) { - var s *collaboration.Share - var err error - switch { - case ref.GetId() != nil: - s, err = m.getByID(ctx, ref.GetId()) - case ref.GetKey() != nil: - s, err = m.getByKey(ctx, ref.GetKey()) - default: - err = errtypes.NotFound(ref.String()) - } - - if err != nil { - return nil, err - } - - return s, nil -} - -func (m *mgr) Unshare(ctx context.Context, ref *collaboration.ShareReference) error { - uid := conversions.FormatUserID(ctxpkg.ContextMustGetUser(ctx).Id) - var query string - params := []interface{}{} - switch { - case ref.GetId() != nil: - query = "delete from oc_share where id=? AND (uid_owner=? or uid_initiator=?)" - params = append(params, ref.GetId().OpaqueId, uid, uid) - case ref.GetKey() != nil: - key := ref.GetKey() - shareType, shareWith := conversions.FormatGrantee(key.Grantee) - owner := conversions.FormatUserID(key.Owner) - query = "delete from oc_share where uid_owner=? AND fileid_prefix=? AND item_source=? AND share_type=? AND share_with=? AND (uid_owner=? or uid_initiator=?)" - params = append(params, owner, key.ResourceId.SpaceId, key.ResourceId.OpaqueId, shareType, shareWith, uid, uid) - default: - return errtypes.NotFound(ref.String()) - } - - stmt, err := m.db.Prepare(query) - if err != nil { - return err - } - res, err := stmt.Exec(params...) - if err != nil { - return err - } - - rowCnt, err := res.RowsAffected() - if err != nil { - return err - } - if rowCnt == 0 { - return errtypes.NotFound(ref.String()) - } - return nil -} - -func (m *mgr) UpdateShare(ctx context.Context, ref *collaboration.ShareReference, p *collaboration.SharePermissions, updated *collaboration.Share, fieldMask *field_mask.FieldMask) (*collaboration.Share, error) { - permissions := conversions.SharePermToInt(p.Permissions) - uid := conversions.FormatUserID(ctxpkg.ContextMustGetUser(ctx).Id) - - var query string - params := []interface{}{} - switch { - case ref.GetId() != nil: - query = "update oc_share set permissions=?,stime=? where id=? AND (uid_owner=? or uid_initiator=?)" - params = append(params, permissions, time.Now().Unix(), ref.GetId().OpaqueId, uid, uid) - case ref.GetKey() != nil: - key := ref.GetKey() - shareType, shareWith := conversions.FormatGrantee(key.Grantee) - owner := conversions.FormatUserID(key.Owner) - query = "update oc_share set permissions=?,stime=? where (uid_owner=? or uid_initiator=?) AND fileid_prefix=? AND item_source=? AND share_type=? AND share_with=? AND (uid_owner=? or uid_initiator=?)" - params = append(params, permissions, time.Now().Unix(), owner, owner, key.ResourceId.SpaceId, key.ResourceId.OpaqueId, shareType, shareWith, uid, uid) - default: - return nil, errtypes.NotFound(ref.String()) - } - - stmt, err := m.db.Prepare(query) - if err != nil { - return nil, err - } - if _, err = stmt.Exec(params...); err != nil { - return nil, err - } - - return m.GetShare(ctx, ref) -} - -func (m *mgr) ListShares(ctx context.Context, filters []*collaboration.Filter) ([]*collaboration.Share, error) { - uid := conversions.FormatUserID(ctxpkg.ContextMustGetUser(ctx).Id) - query := `select coalesce(uid_owner, '') as uid_owner, coalesce(uid_initiator, '') as uid_initiator, coalesce(share_with, '') as share_with, - coalesce(fileid_prefix, '') as fileid_prefix, coalesce(item_source, '') as item_source, coalesce(item_type, '') as item_type, - id, stime, permissions, share_type - FROM oc_share - WHERE (orphan = 0 or orphan IS NULL) AND (uid_owner=? or uid_initiator=?) AND (share_type=? OR share_type=?)` - params := []interface{}{uid, uid, shareTypeUser, shareTypeGroup} - - if len(filters) > 0 { - filterQuery, filterParams, err := translateFilters(filters) - if err != nil { - return nil, err - } - params = append(params, filterParams...) - if filterQuery != "" { - query = fmt.Sprintf("%s AND (%s)", query, filterQuery) - } - } - - rows, err := m.db.Query(query, params...) - if err != nil { - return nil, err - } - defer rows.Close() - - var s conversions.DBShare - shares := []*collaboration.Share{} - for rows.Next() { - if err := rows.Scan(&s.UIDOwner, &s.UIDInitiator, &s.ShareWith, &s.Prefix, &s.ItemSource, &s.ItemType, &s.ID, &s.STime, &s.Permissions, &s.ShareType); err != nil { - continue - } - share, err := conversions.ConvertToCS3Share(ctx, m.client, s) - if err != nil { - continue - } - shares = append(shares, share) - } - if err = rows.Err(); err != nil { - return nil, err - } - - return shares, nil -} - -// we list the shares that are targeted to the user in context or to the user groups. -func (m *mgr) ListReceivedShares(ctx context.Context, filters []*collaboration.Filter, _ *userpb.UserId) ([]*collaboration.ReceivedShare, error) { - user := ctxpkg.ContextMustGetUser(ctx) - uid := conversions.FormatUserID(user.Id) - - params := []interface{}{uid, uid, uid, uid} - for _, v := range user.Groups { - params = append(params, v) - } - - query := `SELECT coalesce(uid_owner, '') as uid_owner, coalesce(uid_initiator, '') as uid_initiator, coalesce(share_with, '') as share_with, - coalesce(fileid_prefix, '') as fileid_prefix, coalesce(item_source, '') as item_source, coalesce(item_type, '') as item_type, coalesce(file_target, '') as file_target, - ts.id, stime, permissions, share_type, coalesce(tr.state, 0) as state - FROM oc_share ts LEFT JOIN oc_share_status tr ON (ts.id = tr.id AND tr.recipient = ?) - WHERE (orphan = 0 or orphan IS NULL) AND (uid_owner != ? AND uid_initiator != ?)` - if len(user.Groups) > 0 { - query += " AND ((share_with=? AND share_type = 0) OR (share_type = 1 AND share_with in (?" + strings.Repeat(",?", len(user.Groups)-1) + ")))" - } else { - query += " AND (share_with=? AND share_type = 0)" - } - - filterQuery, filterParams, err := translateFilters(filters) - if err != nil { - return nil, err - } - params = append(params, filterParams...) - - if filterQuery != "" { - query = fmt.Sprintf("%s AND (%s)", query, filterQuery) - } - - rows, err := m.db.Query(query, params...) - if err != nil { - return nil, err - } - defer rows.Close() - - var s conversions.DBShare - shares := []*collaboration.ReceivedShare{} - for rows.Next() { - if err := rows.Scan(&s.UIDOwner, &s.UIDInitiator, &s.ShareWith, &s.Prefix, &s.ItemSource, &s.ItemType, &s.FileTarget, &s.ID, &s.STime, &s.Permissions, &s.ShareType, &s.State); err != nil { - continue - } - share, err := conversions.ConvertToCS3ReceivedShare(ctx, m.client, s) - if err != nil { - continue - } - shares = append(shares, share) - } - if err = rows.Err(); err != nil { - return nil, err - } - - return shares, nil -} - -func (m *mgr) getReceivedByID(ctx context.Context, id *collaboration.ShareId) (*collaboration.ReceivedShare, error) { - user := ctxpkg.ContextMustGetUser(ctx) - uid := conversions.FormatUserID(user.Id) - - params := []interface{}{uid, id.OpaqueId, uid} // nolint:prealloc - for _, v := range user.Groups { - params = append(params, v) - } - - s := conversions.DBShare{ID: id.OpaqueId} - query := `select coalesce(uid_owner, '') as uid_owner, coalesce(uid_initiator, '') as uid_initiator, coalesce(share_with, '') as share_with, - coalesce(fileid_prefix, '') as fileid_prefix, coalesce(item_source, '') as item_source, coalesce(item_type, '') as item_type, coalesce(file_target, '') as file_target, - stime, permissions, share_type, coalesce(tr.state, 0) as state - FROM oc_share ts LEFT JOIN oc_share_status tr ON (ts.id = tr.id AND tr.recipient = ?) - WHERE (orphan = 0 or orphan IS NULL) AND ts.id=?` - if len(user.Groups) > 0 { - query += " AND ((share_with=? AND share_type = 0) OR (share_type = 1 AND share_with in (?" + strings.Repeat(",?", len(user.Groups)-1) + ")))" - } else { - query += " AND (share_with=? AND share_type = 0)" - } - if err := m.db.QueryRow(query, params...).Scan(&s.UIDOwner, &s.UIDInitiator, &s.ShareWith, &s.Prefix, &s.ItemSource, &s.ItemType, &s.FileTarget, &s.STime, &s.Permissions, &s.ShareType, &s.State); err != nil { - if err == sql.ErrNoRows { - return nil, errtypes.NotFound(id.OpaqueId) - } - return nil, err - } - share, err := conversions.ConvertToCS3ReceivedShare(ctx, m.client, s) - if err != nil { - return nil, err - } - return share, nil -} - -func (m *mgr) getReceivedByKey(ctx context.Context, key *collaboration.ShareKey) (*collaboration.ReceivedShare, error) { - user := ctxpkg.ContextMustGetUser(ctx) - uid := conversions.FormatUserID(user.Id) - - shareType, shareWith := conversions.FormatGrantee(key.Grantee) - params := []interface{}{uid, conversions.FormatUserID(key.Owner), key.GetResourceId().SpaceId, key.ResourceId.OpaqueId, shareType, shareWith, shareWith} // nolint:prealloc - for _, v := range user.Groups { - params = append(params, v) - } - - s := conversions.DBShare{} - query := `select coalesce(uid_owner, '') as uid_owner, coalesce(uid_initiator, '') as uid_initiator, coalesce(share_with, '') as share_with, - coalesce(fileid_prefix, '') as fileid_prefix, coalesce(item_source, '') as item_source, coalesce(item_type, '') as item_type, coalesce(file_target, '') as file_target, - ts.id, stime, permissions, share_type, coalesce(tr.state, 0) as state - FROM oc_share ts LEFT JOIN oc_share_status tr ON (ts.id = tr.id AND tr.recipient = ?) - WHERE (orphan = 0 or orphan IS NULL) AND uid_owner=? AND fileid_prefix=? AND item_source=? AND share_type=? AND share_with=?` - if len(user.Groups) > 0 { - query += " AND ((share_with=? AND share_type = 0) OR (share_type = 1 AND share_with in (?" + strings.Repeat(",?", len(user.Groups)-1) + ")))" - } else { - query += " AND (share_with=? AND share_type = 0)" - } - - if err := m.db.QueryRow(query, params...).Scan(&s.UIDOwner, &s.UIDInitiator, &s.ShareWith, &s.Prefix, &s.ItemSource, &s.ItemType, &s.FileTarget, &s.ID, &s.STime, &s.Permissions, &s.ShareType, &s.State); err != nil { - if err == sql.ErrNoRows { - return nil, errtypes.NotFound(key.String()) - } - return nil, err - } - share, err := conversions.ConvertToCS3ReceivedShare(ctx, m.client, s) - if err != nil { - return nil, err - } - return share, nil -} - -func (m *mgr) GetReceivedShare(ctx context.Context, ref *collaboration.ShareReference) (*collaboration.ReceivedShare, error) { - var s *collaboration.ReceivedShare - var err error - switch { - case ref.GetId() != nil: - s, err = m.getReceivedByID(ctx, ref.GetId()) - case ref.GetKey() != nil: - s, err = m.getReceivedByKey(ctx, ref.GetKey()) - default: - err = errtypes.NotFound(ref.String()) - } - - if err != nil { - return nil, err - } - - return s, nil - -} - -func (m *mgr) UpdateReceivedShare(ctx context.Context, share *collaboration.ReceivedShare, fieldMask *field_mask.FieldMask, _ *userpb.UserId) (*collaboration.ReceivedShare, error) { - user := ctxpkg.ContextMustGetUser(ctx) - - rs, err := m.GetReceivedShare(ctx, &collaboration.ShareReference{Spec: &collaboration.ShareReference_Id{Id: share.Share.Id}}) - if err != nil { - return nil, err - } - - for i := range fieldMask.Paths { - switch fieldMask.Paths[i] { - case "state": - rs.State = share.State - case "mount_point": - rs.MountPoint = share.MountPoint - default: - return nil, errtypes.NotSupported("updating " + fieldMask.Paths[i] + " is not supported") - } - } - - state := 0 - switch rs.GetState() { - case collaboration.ShareState_SHARE_STATE_REJECTED: - state = -1 - case collaboration.ShareState_SHARE_STATE_ACCEPTED: - state = 1 - } - - params := []interface{}{rs.Share.Id.OpaqueId, conversions.FormatUserID(user.Id), state, state} - query := "insert into oc_share_status(id, recipient, state) values(?, ?, ?) ON DUPLICATE KEY UPDATE state = ?" - - stmt, err := m.db.Prepare(query) - if err != nil { - return nil, err - } - _, err = stmt.Exec(params...) - if err != nil { - return nil, err - } - - return rs, nil -} - -func granteeTypeToShareType(granteeType provider.GranteeType) int { - switch granteeType { - case provider.GranteeType_GRANTEE_TYPE_USER: - return shareTypeUser - case provider.GranteeType_GRANTEE_TYPE_GROUP: - return shareTypeGroup - } - return -1 -} - -// translateFilters translates the filters to sql queries -func translateFilters(filters []*collaboration.Filter) (string, []interface{}, error) { - var ( - filterQuery string - params []interface{} - ) - - groupedFilters := share.GroupFiltersByType(filters) - // If multiple filters of the same type are passed to this function, they need to be combined with the `OR` operator. - // That is why the filters got grouped by type. - // For every given filter type, iterate over the filters and if there are more than one combine them. - // Combine the different filter types using `AND` - var filterCounter = 0 - for filterType, filters := range groupedFilters { - switch filterType { - case collaboration.Filter_TYPE_RESOURCE_ID: - filterQuery += "(" - for i, f := range filters { - filterQuery += "(fileid_prefix =? AND item_source=?)" - params = append(params, f.GetResourceId().SpaceId, f.GetResourceId().OpaqueId) - - if i != len(filters)-1 { - filterQuery += " OR " - } - } - filterQuery += ")" - case collaboration.Filter_TYPE_GRANTEE_TYPE: - filterQuery += "(" - for i, f := range filters { - filterQuery += "share_type=?" - params = append(params, granteeTypeToShareType(f.GetGranteeType())) - - if i != len(filters)-1 { - filterQuery += " OR " - } - } - filterQuery += ")" - case collaboration.Filter_TYPE_EXCLUDE_DENIALS: - // TODO this may change once the mapping of permission to share types is completed (cf. pkg/cbox/utils/conversions.go) - filterQuery += "(permissions > 0)" - default: - return "", nil, fmt.Errorf("filter type is not supported") - } - if filterCounter != len(groupedFilters)-1 { - filterQuery += " AND " - } - filterCounter++ - } - return filterQuery, params, nil -} diff --git a/vendor/github.com/opencloud-eu/reva/v2/pkg/cbox/storage/eoshomewrapper/eoshomewrapper.go b/vendor/github.com/opencloud-eu/reva/v2/pkg/cbox/storage/eoshomewrapper/eoshomewrapper.go deleted file mode 100644 index 6df8cd089e..0000000000 --- a/vendor/github.com/opencloud-eu/reva/v2/pkg/cbox/storage/eoshomewrapper/eoshomewrapper.go +++ /dev/null @@ -1,129 +0,0 @@ -// 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 eoshomewrapper - -import ( - "bytes" - "context" - "text/template" - - "github.com/Masterminds/sprig" - provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1" - "github.com/mitchellh/mapstructure" - ctxpkg "github.com/opencloud-eu/reva/v2/pkg/ctx" - "github.com/opencloud-eu/reva/v2/pkg/errtypes" - "github.com/opencloud-eu/reva/v2/pkg/events" - "github.com/opencloud-eu/reva/v2/pkg/storage" - "github.com/opencloud-eu/reva/v2/pkg/storage/fs/registry" - "github.com/opencloud-eu/reva/v2/pkg/storage/utils/eosfs" - "github.com/pkg/errors" - "github.com/rs/zerolog" -) - -func init() { - registry.Register("eoshomewrapper", New) -} - -type wrapper struct { - storage.FS - mountIDTemplate *template.Template -} - -func parseConfig(m map[string]interface{}) (*eosfs.Config, string, error) { - c := &eosfs.Config{} - if err := mapstructure.Decode(m, c); err != nil { - err = errors.Wrap(err, "error decoding conf") - return nil, "", err - } - - // default to version invariance if not configured - if _, ok := m["version_invariant"]; !ok { - c.VersionInvariant = true - } - - t, ok := m["mount_id_template"].(string) - if !ok || t == "" { - t = "eoshome-{{substr 0 1 .Username}}" - } - - return c, t, nil -} - -// New returns an implementation of the storage.FS interface that forms a wrapper -// around separate connections to EOS. -func New(m map[string]interface{}, _ events.Stream, _ *zerolog.Logger) (storage.FS, error) { - c, t, err := parseConfig(m) - if err != nil { - return nil, err - } - c.EnableHome = true - - eos, err := eosfs.NewEOSFS(c) - if err != nil { - return nil, err - } - - mountIDTemplate, err := template.New("mountID").Funcs(sprig.TxtFuncMap()).Parse(t) - if err != nil { - return nil, err - } - - return &wrapper{FS: eos, mountIDTemplate: mountIDTemplate}, nil -} - -// We need to override the two methods, GetMD and ListFolder to fill the -// StorageId in the ResourceInfo objects. - -func (w *wrapper) GetMD(ctx context.Context, ref *provider.Reference, mdKeys []string, fieldMask []string) (*provider.ResourceInfo, error) { - res, err := w.FS.GetMD(ctx, ref, mdKeys, fieldMask) - if err != nil { - return nil, err - } - - // We need to extract the mount ID based on the mapping template. - // - // Take the first letter of the username of the logged-in user, as the home - // storage provider restricts requests only to the home namespace. - res.Id.StorageId = w.getMountID(ctx, res) - return res, nil -} - -func (w *wrapper) ListFolder(ctx context.Context, ref *provider.Reference, mdKeys, fieldMask []string) ([]*provider.ResourceInfo, error) { - res, err := w.FS.ListFolder(ctx, ref, mdKeys, fieldMask) - if err != nil { - return nil, err - } - for _, r := range res { - r.Id.StorageId = w.getMountID(ctx, r) - } - return res, nil -} - -func (w *wrapper) DenyGrant(ctx context.Context, ref *provider.Reference, g *provider.Grantee) error { - return errtypes.NotSupported("eos: deny grant is only enabled for project spaces") -} - -func (w *wrapper) getMountID(ctx context.Context, r *provider.ResourceInfo) string { - u := ctxpkg.ContextMustGetUser(ctx) - b := bytes.Buffer{} - if err := w.mountIDTemplate.Execute(&b, u); err != nil { - return "" - } - return b.String() -} diff --git a/vendor/github.com/opencloud-eu/reva/v2/pkg/cbox/storage/eoswrapper/eoswrapper.go b/vendor/github.com/opencloud-eu/reva/v2/pkg/cbox/storage/eoswrapper/eoswrapper.go deleted file mode 100644 index 315d73352f..0000000000 --- a/vendor/github.com/opencloud-eu/reva/v2/pkg/cbox/storage/eoswrapper/eoswrapper.go +++ /dev/null @@ -1,296 +0,0 @@ -// 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 eoswrapper - -import ( - "bytes" - "context" - "io" - "path" - "strings" - "text/template" - - "github.com/Masterminds/sprig" - provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1" - "github.com/mitchellh/mapstructure" - "github.com/pkg/errors" - "github.com/rs/zerolog" - - ctxpkg "github.com/opencloud-eu/reva/v2/pkg/ctx" - "github.com/opencloud-eu/reva/v2/pkg/errtypes" - "github.com/opencloud-eu/reva/v2/pkg/events" - "github.com/opencloud-eu/reva/v2/pkg/storage" - "github.com/opencloud-eu/reva/v2/pkg/storage/fs/registry" - "github.com/opencloud-eu/reva/v2/pkg/storage/utils/eosfs" - "github.com/opencloud-eu/reva/v2/pkg/storagespace" - "github.com/opencloud-eu/reva/v2/pkg/utils" -) - -func init() { - registry.Register("eoswrapper", New) -} - -const ( - eosProjectsNamespace = "/eos/project" - - // We can use a regex for these, but that might have inferior performance - projectSpaceGroupsPrefix = "cernbox-project-" - projectSpaceAdminGroupsSuffix = "-admins" -) - -type wrapper struct { - storage.FS - conf *eosfs.Config - mountIDTemplate *template.Template -} - -func parseConfig(m map[string]interface{}) (*eosfs.Config, string, error) { - c := &eosfs.Config{} - if err := mapstructure.Decode(m, c); err != nil { - err = errors.Wrap(err, "error decoding conf") - return nil, "", err - } - - // default to version invariance if not configured - if _, ok := m["version_invariant"]; !ok { - c.VersionInvariant = true - } - - // allow recycle operations for project spaces - if !c.EnableHome && strings.HasPrefix(c.Namespace, eosProjectsNamespace) { - c.AllowPathRecycleOperations = true - c.ImpersonateOwnerforRevisions = true - } - - t, ok := m["mount_id_template"].(string) - if !ok || t == "" { - t = "eoshome-{{ trimAll \"/\" .Path | substr 0 1 }}" - } - - return c, t, nil -} - -// New returns an implementation of the storage.FS interface that forms a wrapper -// around separate connections to EOS. -func New(m map[string]interface{}, _ events.Stream, _ *zerolog.Logger) (storage.FS, error) { - c, t, err := parseConfig(m) - if err != nil { - return nil, err - } - - eos, err := eosfs.NewEOSFS(c) - if err != nil { - return nil, err - } - - mountIDTemplate, err := template.New("mountID").Funcs(sprig.TxtFuncMap()).Parse(t) - if err != nil { - return nil, err - } - - return &wrapper{FS: eos, conf: c, mountIDTemplate: mountIDTemplate}, nil -} - -// We need to override the methods, GetMD, GetPathByID and ListFolder to fill the -// StorageId in the ResourceInfo objects. - -func (w *wrapper) GetMD(ctx context.Context, ref *provider.Reference, mdKeys []string, fieldMask []string) (*provider.ResourceInfo, error) { - res, err := w.FS.GetMD(ctx, ref, mdKeys, fieldMask) - if err != nil { - return nil, err - } - - // We need to extract the mount ID based on the mapping template. - // - // Take the first letter of the resource path after the namespace has been removed. - // If it's empty, leave it empty to be filled by storageprovider. - res.Id.StorageId = w.getMountID(ctx, res) - - if err = w.setProjectSharingPermissions(ctx, res); err != nil { - return nil, err - } - - // If the request contains a relative reference, we also need to return the base path instead of the full one - if utils.IsRelativeReference(ref) { - res.Path = path.Base(res.Path) - } - - return res, nil -} - -func (w *wrapper) ListFolder(ctx context.Context, ref *provider.Reference, mdKeys, fieldMask []string) ([]*provider.ResourceInfo, error) { - res, err := w.FS.ListFolder(ctx, ref, mdKeys, fieldMask) - if err != nil { - return nil, err - } - for _, r := range res { - r.Id.StorageId = w.getMountID(ctx, r) - - // If the request contains a relative reference, we also need to return the base path instead of the full one - if utils.IsRelativeReference(ref) { - r.Path = path.Base(r.Path) - } - - if err = w.setProjectSharingPermissions(ctx, r); err != nil { - continue - } - } - return res, nil -} - -func (w *wrapper) ListRecycle(ctx context.Context, ref *provider.Reference, key, relativePath string) ([]*provider.RecycleItem, error) { - res, err := w.FS.ListRecycle(ctx, ref, key, relativePath) - if err != nil { - return nil, err - } - - // If the request contains a relative reference, we also need to return the base path instead of the full one - if utils.IsRelativeReference(ref) { - for _, info := range res { - info.Ref.Path = path.Base(info.Ref.Path) - } - } - - return res, nil - -} - -func (w *wrapper) ListStorageSpaces(ctx context.Context, filter []*provider.ListStorageSpacesRequest_Filter, unrestricted bool) ([]*provider.StorageSpace, error) { - res, err := w.FS.ListStorageSpaces(ctx, filter, unrestricted) - if err != nil { - return nil, err - } - - for _, r := range res { - if mountID, _, _, _ := storagespace.SplitID(r.Id.OpaqueId); mountID == "" { - mountID = w.getMountID(ctx, &provider.ResourceInfo{Path: r.Name}) - r.Root.StorageId = mountID - } - } - return res, nil - -} - -func (w *wrapper) ListRevisions(ctx context.Context, ref *provider.Reference) ([]*provider.FileVersion, error) { - if err := w.userIsProjectAdmin(ctx, ref); err != nil { - return nil, err - } - - return w.FS.ListRevisions(ctx, ref) -} - -func (w *wrapper) DownloadRevision(ctx context.Context, ref *provider.Reference, revisionKey string, openReaderfunc func(*provider.ResourceInfo) bool) (*provider.ResourceInfo, io.ReadCloser, error) { - if err := w.userIsProjectAdmin(ctx, ref); err != nil { - return nil, nil, err - } - - return w.FS.DownloadRevision(ctx, ref, revisionKey, openReaderfunc) -} - -func (w *wrapper) RestoreRevision(ctx context.Context, ref *provider.Reference, revisionKey string) error { - if err := w.userIsProjectAdmin(ctx, ref); err != nil { - return err - } - - return w.FS.RestoreRevision(ctx, ref, revisionKey) -} - -func (w *wrapper) DenyGrant(ctx context.Context, ref *provider.Reference, g *provider.Grantee) error { - // This is only allowed for project space admins - if strings.HasPrefix(w.conf.Namespace, eosProjectsNamespace) { - if err := w.userIsProjectAdmin(ctx, ref); err != nil { - return err - } - return w.FS.DenyGrant(ctx, ref, g) - } - - return errtypes.NotSupported("eos: deny grant is only enabled for project spaces") -} - -func (w *wrapper) getMountID(ctx context.Context, r *provider.ResourceInfo) string { - if r == nil { - return "" - } - r.Path = strings.TrimPrefix(r.Path, w.conf.MountPath) - b := bytes.Buffer{} - if err := w.mountIDTemplate.Execute(&b, r); err != nil { - return "" - } - r.Path = path.Join(w.conf.MountPath, r.Path) - return b.String() -} - -func (w *wrapper) setProjectSharingPermissions(ctx context.Context, r *provider.ResourceInfo) error { - // Check if this storage provider corresponds to a project spaces instance - if strings.HasPrefix(w.conf.Namespace, eosProjectsNamespace) { - - // Extract project name from the path resembling /c/cernbox or /c/cernbox/minutes/.. - parts := strings.SplitN(r.Path, "/", 4) - if len(parts) != 4 && len(parts) != 3 { - // The request might be for / or /$letter - // Nothing to do in that case - return nil - } - adminGroup := projectSpaceGroupsPrefix + parts[2] + projectSpaceAdminGroupsSuffix - user := ctxpkg.ContextMustGetUser(ctx) - - for _, g := range user.Groups { - if g == adminGroup { - r.PermissionSet.AddGrant = true - r.PermissionSet.RemoveGrant = true - r.PermissionSet.UpdateGrant = true - r.PermissionSet.ListGrants = true - r.PermissionSet.GetQuota = true - r.PermissionSet.DenyGrant = true - return nil - } - } - } - return nil -} - -func (w *wrapper) userIsProjectAdmin(ctx context.Context, ref *provider.Reference) error { - // Check if this storage provider corresponds to a project spaces instance - if !strings.HasPrefix(w.conf.Namespace, eosProjectsNamespace) { - return nil - } - - res, err := w.FS.GetMD(ctx, ref, nil, nil) - if err != nil { - return err - } - - // Extract project name from the path resembling /c/cernbox or /c/cernbox/minutes/.. - parts := strings.SplitN(res.Path, "/", 4) - if len(parts) != 4 && len(parts) != 3 { - // The request might be for / or /$letter - // Nothing to do in that case - return nil - } - adminGroup := projectSpaceGroupsPrefix + parts[2] + projectSpaceAdminGroupsSuffix - user := ctxpkg.ContextMustGetUser(ctx) - - for _, g := range user.Groups { - if g == adminGroup { - return nil - } - } - - return errtypes.PermissionDenied("eosfs: project spaces revisions can only be accessed by admins") -} diff --git a/vendor/github.com/opencloud-eu/reva/v2/pkg/cbox/user/rest/cache.go b/vendor/github.com/opencloud-eu/reva/v2/pkg/cbox/user/rest/cache.go deleted file mode 100644 index d15995aa0d..0000000000 --- a/vendor/github.com/opencloud-eu/reva/v2/pkg/cbox/user/rest/cache.go +++ /dev/null @@ -1,214 +0,0 @@ -// 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 rest - -import ( - "encoding/json" - "errors" - "fmt" - "strconv" - "strings" - "time" - - userpb "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1" - "github.com/gomodule/redigo/redis" -) - -const ( - userPrefix = "user:" - usernamePrefix = "username:" - userIDPrefix = "userid:" - namePrefix = "name:" - mailPrefix = "mail:" - uidPrefix = "uid:" - userGroupsPrefix = "groups:" -) - -func initRedisPool(address, username, password string) *redis.Pool { - return &redis.Pool{ - - MaxIdle: 50, - MaxActive: 1000, - IdleTimeout: 240 * time.Second, - - Dial: func() (redis.Conn, error) { - var opts []redis.DialOption - if username != "" { - opts = append(opts, redis.DialUsername(username)) - } - if password != "" { - opts = append(opts, redis.DialPassword(password)) - } - - c, err := redis.Dial("tcp", address, opts...) - if err != nil { - return nil, err - } - return c, err - }, - - TestOnBorrow: func(c redis.Conn, t time.Time) error { - _, err := c.Do("PING") - return err - }, - } -} - -func (m *manager) setVal(key, val string, expiration int) error { - conn := m.redisPool.Get() - defer conn.Close() - if conn != nil { - args := []interface{}{key, val} - if expiration != -1 { - args = append(args, "EX", expiration) - } - if _, err := conn.Do("SET", args...); err != nil { - return err - } - return nil - } - return errors.New("rest: unable to get connection from redis pool") -} - -func (m *manager) getVal(key string) (string, error) { - conn := m.redisPool.Get() - defer conn.Close() - if conn != nil { - val, err := redis.String(conn.Do("GET", key)) - if err != nil { - return "", err - } - return val, nil - } - return "", errors.New("rest: unable to get connection from redis pool") -} - -func (m *manager) findCachedUsers(query string) ([]*userpb.User, error) { - conn := m.redisPool.Get() - defer conn.Close() - if conn != nil { - query = fmt.Sprintf("%s*%s*", userPrefix, strings.ReplaceAll(strings.ToLower(query), " ", "_")) - keys, err := redis.Strings(conn.Do("KEYS", query)) - if err != nil { - return nil, err - } - var args []interface{} - for _, k := range keys { - args = append(args, k) - } - - // Fetch the users for all these keys - userStrings, err := redis.Strings(conn.Do("MGET", args...)) - if err != nil { - return nil, err - } - userMap := make(map[string]*userpb.User) - for _, user := range userStrings { - u := userpb.User{} - if err = json.Unmarshal([]byte(user), &u); err == nil { - userMap[u.Id.OpaqueId] = &u - } - } - - var users []*userpb.User - for _, u := range userMap { - users = append(users, u) - } - - return users, nil - } - - return nil, errors.New("rest: unable to get connection from redis pool") -} - -func (m *manager) fetchCachedUserDetails(uid *userpb.UserId) (*userpb.User, error) { - user, err := m.getVal(userPrefix + usernamePrefix + strings.ToLower(uid.OpaqueId)) - if err != nil { - return nil, err - } - - u := userpb.User{} - if err = json.Unmarshal([]byte(user), &u); err != nil { - return nil, err - } - return &u, nil -} - -func (m *manager) cacheUserDetails(u *userpb.User) error { - encodedUser, err := json.Marshal(&u) - if err != nil { - return err - } - if err = m.setVal(userPrefix+usernamePrefix+strings.ToLower(u.Id.OpaqueId), string(encodedUser), -1); err != nil { - return err - } - if err = m.setVal(userPrefix+userIDPrefix+strings.ToLower(u.Id.OpaqueId), string(encodedUser), -1); err != nil { - return err - } - - if u.Mail != "" { - if err = m.setVal(userPrefix+mailPrefix+strings.ToLower(u.Mail), string(encodedUser), -1); err != nil { - return err - } - } - if u.DisplayName != "" { - if err = m.setVal(userPrefix+namePrefix+u.Id.OpaqueId+"_"+strings.ReplaceAll(strings.ToLower(u.DisplayName), " ", "_"), string(encodedUser), -1); err != nil { - return err - } - } - if u.UidNumber != 0 { - if err = m.setVal(userPrefix+uidPrefix+strconv.FormatInt(u.UidNumber, 10), string(encodedUser), -1); err != nil { - return err - } - } - return nil -} - -func (m *manager) fetchCachedUserByParam(field, claim string) (*userpb.User, error) { - user, err := m.getVal(userPrefix + field + ":" + strings.ToLower(claim)) - if err != nil { - return nil, err - } - - u := userpb.User{} - if err = json.Unmarshal([]byte(user), &u); err != nil { - return nil, err - } - return &u, nil -} - -func (m *manager) fetchCachedUserGroups(uid *userpb.UserId) ([]string, error) { - groups, err := m.getVal(userPrefix + userGroupsPrefix + strings.ToLower(uid.OpaqueId)) - if err != nil { - return nil, err - } - g := []string{} - if err = json.Unmarshal([]byte(groups), &g); err != nil { - return nil, err - } - return g, nil -} - -func (m *manager) cacheUserGroups(uid *userpb.UserId, groups []string) error { - g, err := json.Marshal(&groups) - if err != nil { - return err - } - return m.setVal(userPrefix+userGroupsPrefix+strings.ToLower(uid.OpaqueId), string(g), m.conf.UserGroupsCacheExpiration*60) -} diff --git a/vendor/github.com/opencloud-eu/reva/v2/pkg/cbox/user/rest/rest.go b/vendor/github.com/opencloud-eu/reva/v2/pkg/cbox/user/rest/rest.go deleted file mode 100644 index 5433433e38..0000000000 --- a/vendor/github.com/opencloud-eu/reva/v2/pkg/cbox/user/rest/rest.go +++ /dev/null @@ -1,391 +0,0 @@ -// 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 rest - -import ( - "context" - "fmt" - "os" - "os/signal" - "strings" - "syscall" - "time" - - userpb "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1" - "github.com/gomodule/redigo/redis" - "github.com/mitchellh/mapstructure" - "github.com/opencloud-eu/reva/v2/pkg/appctx" - utils "github.com/opencloud-eu/reva/v2/pkg/cbox/utils" - "github.com/opencloud-eu/reva/v2/pkg/errtypes" - "github.com/opencloud-eu/reva/v2/pkg/user" - "github.com/opencloud-eu/reva/v2/pkg/user/manager/registry" - "github.com/pkg/errors" - "github.com/rs/zerolog/log" -) - -func init() { - registry.Register("rest", New) -} - -type manager struct { - conf *config - redisPool *redis.Pool - apiTokenManager *utils.APITokenManager -} - -type config struct { - // The address at which the redis server is running - RedisAddress string `mapstructure:"redis_address" docs:"localhost:6379"` - // The username for connecting to the redis server - RedisUsername string `mapstructure:"redis_username" docs:""` - // The password for connecting to the redis server - RedisPassword string `mapstructure:"redis_password" docs:""` - // The time in minutes for which the groups to which a user belongs would be cached - UserGroupsCacheExpiration int `mapstructure:"user_groups_cache_expiration" docs:"5"` - // The OIDC Provider - IDProvider string `mapstructure:"id_provider" docs:"http://cernbox.cern.ch"` - // Base API Endpoint - APIBaseURL string `mapstructure:"api_base_url" docs:"https://authorization-service-api-dev.web.cern.ch"` - // Client ID needed to authenticate - ClientID string `mapstructure:"client_id" docs:"-"` - // Client Secret - ClientSecret string `mapstructure:"client_secret" docs:"-"` - - // Endpoint to generate token to access the API - OIDCTokenEndpoint string `mapstructure:"oidc_token_endpoint" docs:"https://keycloak-dev.cern.ch/auth/realms/cern/api-access/token"` - // The target application for which token needs to be generated - TargetAPI string `mapstructure:"target_api" docs:"authorization-service-api"` - // The time in seconds between bulk fetch of user accounts - UserFetchInterval int `mapstructure:"user_fetch_interval" docs:"3600"` -} - -func (c *config) init() { - if c.UserGroupsCacheExpiration == 0 { - c.UserGroupsCacheExpiration = 5 - } - if c.RedisAddress == "" { - c.RedisAddress = ":6379" - } - if c.APIBaseURL == "" { - c.APIBaseURL = "https://authorization-service-api-dev.web.cern.ch" - } - if c.TargetAPI == "" { - c.TargetAPI = "authorization-service-api" - } - if c.OIDCTokenEndpoint == "" { - c.OIDCTokenEndpoint = "https://keycloak-dev.cern.ch/auth/realms/cern/api-access/token" - } - if c.IDProvider == "" { - c.IDProvider = "http://cernbox.cern.ch" - } - if c.UserFetchInterval == 0 { - c.UserFetchInterval = 3600 - } -} - -func parseConfig(m map[string]interface{}) (*config, error) { - c := &config{} - if err := mapstructure.Decode(m, c); err != nil { - return nil, err - } - return c, nil -} - -// New returns a user manager implementation that makes calls to the GRAPPA API. -func New(m map[string]interface{}) (user.Manager, error) { - mgr := &manager{} - err := mgr.Configure(m) - if err != nil { - return nil, err - } - return mgr, err -} - -func (m *manager) Configure(ml map[string]interface{}) error { - c, err := parseConfig(ml) - if err != nil { - return err - } - c.init() - redisPool := initRedisPool(c.RedisAddress, c.RedisUsername, c.RedisPassword) - apiTokenManager := utils.InitAPITokenManager(c.TargetAPI, c.OIDCTokenEndpoint, c.ClientID, c.ClientSecret) - m.conf = c - m.redisPool = redisPool - m.apiTokenManager = apiTokenManager - - // Since we're starting a subroutine which would take some time to execute, - // we can't wait to see if it works before returning the user.Manager object - // TODO: return err if the fetch fails - go m.fetchAllUsers() - return nil -} - -func (m *manager) fetchAllUsers() { - _ = m.fetchAllUserAccounts() - ticker := time.NewTicker(time.Duration(m.conf.UserFetchInterval) * time.Second) - work := make(chan os.Signal, 1) - signal.Notify(work, syscall.SIGHUP, syscall.SIGINT, syscall.SIGQUIT) - - for { - select { - case <-work: - return - case <-ticker.C: - _ = m.fetchAllUserAccounts() - } - } -} - -func (m *manager) fetchAllUserAccounts() error { - ctx := context.Background() - url := fmt.Sprintf("%s/api/v1.0/Identity?field=upn&field=primaryAccountEmail&field=displayName&field=uid&field=gid&field=type", m.conf.APIBaseURL) - - for url != "" { - result, err := m.apiTokenManager.SendAPIGetRequest(ctx, url, false) - if err != nil { - return err - } - - responseData, ok := result["data"].([]interface{}) - if !ok { - return errors.New("rest: error in type assertion") - } - for _, usr := range responseData { - userData, ok := usr.(map[string]interface{}) - if !ok { - continue - } - - _, err = m.parseAndCacheUser(ctx, userData) - if err != nil { - continue - } - } - - url = "" - if pagination, ok := result["pagination"].(map[string]interface{}); ok { - if links, ok := pagination["links"].(map[string]interface{}); ok { - if next, ok := links["next"].(string); ok { - url = fmt.Sprintf("%s%s", m.conf.APIBaseURL, next) - } - } - } - } - - return nil -} - -func (m *manager) parseAndCacheUser(ctx context.Context, userData map[string]interface{}) (*userpb.User, error) { - upn, ok := userData["upn"].(string) - if !ok { - return nil, errors.New("rest: missing upn in user data") - } - mail, _ := userData["primaryAccountEmail"].(string) - name, _ := userData["displayName"].(string) - uidNumber, _ := userData["uid"].(float64) - gidNumber, _ := userData["gid"].(float64) - t, _ := userData["type"].(string) - userType := getUserType(t, upn) - - userID := &userpb.UserId{ - OpaqueId: upn, - Idp: m.conf.IDProvider, - Type: userType, - } - u := &userpb.User{ - Id: userID, - Username: upn, - Mail: mail, - DisplayName: name, - UidNumber: int64(uidNumber), - GidNumber: int64(gidNumber), - } - - if err := m.cacheUserDetails(u); err != nil { - log.Error().Err(err).Msg("rest: error caching user details") - } - return u, nil -} - -func (m *manager) GetUser(ctx context.Context, uid *userpb.UserId, skipFetchingGroups bool) (*userpb.User, error) { - if uid.GetTenantId() != "" { - return nil, errtypes.NotSupported("tenant filter not supported in rest user manager") - } - u, err := m.fetchCachedUserDetails(uid) - if err != nil { - return nil, err - } - - if !skipFetchingGroups { - userGroups, err := m.GetUserGroups(ctx, uid) - if err != nil { - return nil, err - } - u.Groups = userGroups - } - - return u, nil -} - -func (m *manager) GetUserByClaim(ctx context.Context, claim, value, tenantID string, skipFetchingGroups bool) (*userpb.User, error) { - if tenantID != "" { - return nil, errtypes.NotSupported("tenant filter not supported in rest user manager") - } - u, err := m.fetchCachedUserByParam(claim, value) - if err != nil { - return nil, err - } - - if !skipFetchingGroups { - userGroups, err := m.GetUserGroups(ctx, u.Id) - if err != nil { - return nil, err - } - u.Groups = userGroups - } - - return u, nil -} - -func (m *manager) FindUsers(ctx context.Context, query, tenantID string, skipFetchingGroups bool) ([]*userpb.User, error) { - if tenantID != "" { - return nil, errtypes.NotSupported("tenant filter not supported in rest user manager") - } - - // Look at namespaces filters. If the query starts with: - // "a" => look into primary/secondary/service accounts - // "l" => look into lightweight/federated accounts - // none => look into primary - - parts := strings.SplitN(query, ":", 2) - - var namespace string - if len(parts) == 2 { - // the query contains a namespace filter - namespace, query = parts[0], parts[1] - } - - users, err := m.findCachedUsers(query) - if err != nil { - return nil, err - } - - userSlice := []*userpb.User{} - - var accountsFilters []userpb.UserType - switch namespace { - case "": - accountsFilters = []userpb.UserType{userpb.UserType_USER_TYPE_PRIMARY} - case "a": - accountsFilters = []userpb.UserType{userpb.UserType_USER_TYPE_PRIMARY, userpb.UserType_USER_TYPE_SECONDARY, userpb.UserType_USER_TYPE_SERVICE} - case "l": - accountsFilters = []userpb.UserType{userpb.UserType_USER_TYPE_LIGHTWEIGHT, userpb.UserType_USER_TYPE_FEDERATED} - } - - for _, u := range users { - if isUserAnyType(u, accountsFilters) { - userSlice = append(userSlice, u) - } - } - - return userSlice, nil -} - -// isUserAnyType returns true if the user's type is one of types list -func isUserAnyType(user *userpb.User, types []userpb.UserType) bool { - for _, t := range types { - if user.GetId().Type == t { - return true - } - } - return false -} - -func (m *manager) GetUserGroups(ctx context.Context, uid *userpb.UserId) ([]string, error) { - groups, err := m.fetchCachedUserGroups(uid) - if err == nil { - return groups, nil - } - - url := fmt.Sprintf("%s/api/v1.0/Identity/%s/groups?recursive=true", m.conf.APIBaseURL, uid.OpaqueId) - result, err := m.apiTokenManager.SendAPIGetRequest(ctx, url, false) - if err != nil { - return nil, err - } - - groupData := result["data"].([]interface{}) - groups = []string{} - - for _, g := range groupData { - groupInfo, ok := g.(map[string]interface{}) - if !ok { - return nil, errors.New("rest: error in type assertion") - } - name, ok := groupInfo["displayName"].(string) - if ok { - groups = append(groups, name) - } - } - - if err = m.cacheUserGroups(uid, groups); err != nil { - log := appctx.GetLogger(ctx) - log.Error().Err(err).Msg("rest: error caching user groups") - } - - return groups, nil -} - -func (m *manager) IsInGroup(ctx context.Context, uid *userpb.UserId, group string) (bool, error) { - userGroups, err := m.GetUserGroups(ctx, uid) - if err != nil { - return false, err - } - - for _, g := range userGroups { - if group == g { - return true, nil - } - } - return false, nil -} - -func getUserType(userType, upn string) userpb.UserType { - var t userpb.UserType - switch userType { - case "Application": - t = userpb.UserType_USER_TYPE_APPLICATION - case "Service": - t = userpb.UserType_USER_TYPE_SERVICE - case "Secondary": - t = userpb.UserType_USER_TYPE_SECONDARY - case "Person": - switch { - case strings.HasPrefix(upn, "guest"): - t = userpb.UserType_USER_TYPE_LIGHTWEIGHT - case strings.Contains(upn, "@"): - t = userpb.UserType_USER_TYPE_FEDERATED - default: - t = userpb.UserType_USER_TYPE_PRIMARY - } - default: - t = userpb.UserType_USER_TYPE_INVALID - } - return t - -} diff --git a/vendor/github.com/opencloud-eu/reva/v2/pkg/cbox/utils/conversions.go b/vendor/github.com/opencloud-eu/reva/v2/pkg/cbox/utils/conversions.go deleted file mode 100644 index 03e0193536..0000000000 --- a/vendor/github.com/opencloud-eu/reva/v2/pkg/cbox/utils/conversions.go +++ /dev/null @@ -1,308 +0,0 @@ -// 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 utils - -import ( - "context" - "errors" - "time" - - gatewayv1beta1 "github.com/cs3org/go-cs3apis/cs3/gateway/v1beta1" - grouppb "github.com/cs3org/go-cs3apis/cs3/identity/group/v1beta1" - userpb "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1" - rpcv1beta1 "github.com/cs3org/go-cs3apis/cs3/rpc/v1beta1" - collaboration "github.com/cs3org/go-cs3apis/cs3/sharing/collaboration/v1beta1" - 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/opencloud-eu/reva/v2/pkg/conversions" -) - -// DBShare stores information about user and public shares. -type DBShare struct { - ID string - UIDOwner string - UIDInitiator string - Prefix string - ItemSource string - ItemType string - ShareWith string - Token string - Expiration string - Permissions int - ShareType int - ShareName string - STime int - FileTarget string - State int - Quicklink bool - Description string - NotifyUploads bool - NotifyUploadsExtraRecipients string -} - -// FormatGrantee formats a CS3API grantee to a string. -func FormatGrantee(g *provider.Grantee) (int, string) { - var granteeType int - var formattedID string - switch g.Type { - case provider.GranteeType_GRANTEE_TYPE_USER: - granteeType = 0 - formattedID = FormatUserID(g.GetUserId()) - case provider.GranteeType_GRANTEE_TYPE_GROUP: - granteeType = 1 - formattedID = FormatGroupID(g.GetGroupId()) - default: - granteeType = -1 - } - return granteeType, formattedID -} - -// ExtractGrantee retrieves the CS3API grantee from a formatted string. -func ExtractGrantee(ctx context.Context, gateway gatewayv1beta1.GatewayAPIClient, t int, g string) (*provider.Grantee, error) { - var grantee provider.Grantee - switch t { - case 0: - grantee.Type = provider.GranteeType_GRANTEE_TYPE_USER - user, err := ExtractUserID(ctx, gateway, g) - if err != nil { - return nil, err - } - grantee.Id = &provider.Grantee_UserId{UserId: user} - case 1: - grantee.Type = provider.GranteeType_GRANTEE_TYPE_GROUP - group, err := ExtractGroupID(ctx, gateway, g) - if err != nil { - return nil, err - } - grantee.Id = &provider.Grantee_GroupId{GroupId: group} - default: - grantee.Type = provider.GranteeType_GRANTEE_TYPE_INVALID - } - return &grantee, nil -} - -// ResourceTypeToItem maps a resource type to a string. -func ResourceTypeToItem(r provider.ResourceType) string { - switch r { - case provider.ResourceType_RESOURCE_TYPE_FILE: - return "file" - case provider.ResourceType_RESOURCE_TYPE_CONTAINER: - return "folder" - case provider.ResourceType_RESOURCE_TYPE_REFERENCE: - return "reference" - case provider.ResourceType_RESOURCE_TYPE_SYMLINK: - return "symlink" - default: - return "" - } -} - -// ResourceTypeToItemInt maps a resource type to an integer. -func ResourceTypeToItemInt(r provider.ResourceType) int { - switch r { - case provider.ResourceType_RESOURCE_TYPE_CONTAINER: - return 0 - case provider.ResourceType_RESOURCE_TYPE_FILE: - return 1 - default: - return -1 - } -} - -// SharePermToInt maps read/write permissions to an integer. -func SharePermToInt(p *provider.ResourcePermissions) int { - var perm int - switch { - case p.InitiateFileUpload && !p.InitiateFileDownload: - perm = 4 - case p.InitiateFileUpload: - perm = 15 - case p.InitiateFileDownload: - perm = 1 - } - // TODO map denials and resharing; currently, denials are mapped to 0 - return perm -} - -// IntTosharePerm retrieves read/write permissions from an integer. -func IntTosharePerm(p int, itemType string) *provider.ResourcePermissions { - switch p { - case 1: - return conversions.NewViewerRole().CS3ResourcePermissions() - case 15: - if itemType == "folder" { - return conversions.NewEditorRole().CS3ResourcePermissions() - } - return conversions.NewFileEditorRole().CS3ResourcePermissions() - case 4: - return conversions.NewUploaderRole().CS3ResourcePermissions() - default: - // TODO we may have other options, for now this is a denial - return &provider.ResourcePermissions{} - } -} - -// IntToShareState retrieves the received share state from an integer. -func IntToShareState(g int) collaboration.ShareState { - switch g { - case 0: - return collaboration.ShareState_SHARE_STATE_PENDING - case 1: - return collaboration.ShareState_SHARE_STATE_ACCEPTED - case -1: - return collaboration.ShareState_SHARE_STATE_REJECTED - default: - return collaboration.ShareState_SHARE_STATE_INVALID - } -} - -// FormatUserID formats a CS3API user ID to a string. -func FormatUserID(u *userpb.UserId) string { - return u.OpaqueId -} - -// ExtractUserID retrieves a CS3API user ID from a string. -func ExtractUserID(ctx context.Context, gateway gatewayv1beta1.GatewayAPIClient, u string) (*userpb.UserId, error) { - userRes, err := gateway.GetUser(ctx, &userpb.GetUserRequest{ - UserId: &userpb.UserId{OpaqueId: u}, - }) - if err != nil { - return nil, err - } - if userRes.Status.Code != rpcv1beta1.Code_CODE_OK { - return nil, errors.New(userRes.Status.Message) - } - - return userRes.User.Id, nil -} - -// FormatGroupID formats a CS3API group ID to a string. -func FormatGroupID(u *grouppb.GroupId) string { - return u.OpaqueId -} - -// ExtractGroupID retrieves a CS3API group ID from a string. -func ExtractGroupID(ctx context.Context, gateway gatewayv1beta1.GatewayAPIClient, u string) (*grouppb.GroupId, error) { - groupRes, err := gateway.GetGroup(ctx, &grouppb.GetGroupRequest{ - GroupId: &grouppb.GroupId{OpaqueId: u}, - }) - if err != nil { - return nil, err - } - if groupRes.Status.Code != rpcv1beta1.Code_CODE_OK { - return nil, errors.New(groupRes.Status.Message) - } - return groupRes.Group.Id, nil -} - -// ConvertToCS3Share converts a DBShare to a CS3API collaboration share. -func ConvertToCS3Share(ctx context.Context, gateway gatewayv1beta1.GatewayAPIClient, s DBShare) (*collaboration.Share, error) { - ts := &typespb.Timestamp{ - Seconds: uint64(s.STime), - } - owner, err := ExtractUserID(ctx, gateway, s.UIDOwner) - if err != nil { - return nil, err - } - creator, err := ExtractUserID(ctx, gateway, s.UIDInitiator) - if err != nil { - return nil, err - } - grantee, err := ExtractGrantee(ctx, gateway, s.ShareType, s.ShareWith) - if err != nil { - return nil, err - } - - return &collaboration.Share{ - Id: &collaboration.ShareId{ - OpaqueId: s.ID, - }, - //ResourceId: &provider.Reference{StorageId: s.Prefix, NodeId: s.ItemSource}, - ResourceId: &provider.ResourceId{ - StorageId: s.Prefix, - OpaqueId: s.ItemSource, - }, - Permissions: &collaboration.SharePermissions{Permissions: IntTosharePerm(s.Permissions, s.ItemType)}, - Grantee: grantee, - Owner: owner, - Creator: creator, - Ctime: ts, - Mtime: ts, - }, nil -} - -// ConvertToCS3ReceivedShare converts a DBShare to a CS3API collaboration received share. -func ConvertToCS3ReceivedShare(ctx context.Context, gateway gatewayv1beta1.GatewayAPIClient, s DBShare) (*collaboration.ReceivedShare, error) { - share, err := ConvertToCS3Share(ctx, gateway, s) - if err != nil { - return nil, err - } - return &collaboration.ReceivedShare{ - Share: share, - State: IntToShareState(s.State), - }, nil -} - -// ConvertToCS3PublicShare converts a DBShare to a CS3API public share. -func ConvertToCS3PublicShare(ctx context.Context, gateway gatewayv1beta1.GatewayAPIClient, s DBShare) (*link.PublicShare, error) { - ts := &typespb.Timestamp{ - Seconds: uint64(s.STime), - } - pwd := s.ShareWith != "" - var expires *typespb.Timestamp - if s.Expiration != "" { - t, err := time.Parse("2006-01-02 15:04:05", s.Expiration) - if err == nil { - expires = &typespb.Timestamp{ - Seconds: uint64(t.Unix()), - } - } - } - owner, err := ExtractUserID(ctx, gateway, s.UIDOwner) - if err != nil { - return nil, err - } - creator, err := ExtractUserID(ctx, gateway, s.UIDInitiator) - if err != nil { - return nil, err - } - return &link.PublicShare{ - Id: &link.PublicShareId{ - OpaqueId: s.ID, - }, - ResourceId: &provider.ResourceId{ - StorageId: s.Prefix, - OpaqueId: s.ItemSource, - }, - Permissions: &link.PublicSharePermissions{Permissions: IntTosharePerm(s.Permissions, s.ItemType)}, - Owner: owner, - Creator: creator, - Token: s.Token, - DisplayName: s.ShareName, - PasswordProtected: pwd, - Expiration: expires, - Ctime: ts, - Mtime: ts, - Quicklink: s.Quicklink, - Description: s.Description, - NotifyUploads: s.NotifyUploads, - NotifyUploadsExtraRecipients: s.NotifyUploadsExtraRecipients, - }, nil -} diff --git a/vendor/github.com/opencloud-eu/reva/v2/pkg/cbox/utils/tokenmanagement.go b/vendor/github.com/opencloud-eu/reva/v2/pkg/cbox/utils/tokenmanagement.go deleted file mode 100644 index a1091298e1..0000000000 --- a/vendor/github.com/opencloud-eu/reva/v2/pkg/cbox/utils/tokenmanagement.go +++ /dev/null @@ -1,172 +0,0 @@ -// 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 utils - -import ( - "context" - "encoding/json" - "errors" - "io" - "net/http" - "net/url" - "strings" - "sync" - "time" - - "github.com/opencloud-eu/reva/v2/pkg/rhttp" -) - -// APITokenManager stores config related to api management -type APITokenManager struct { - oidcToken OIDCToken - conf *config - client *http.Client -} - -// OIDCToken stores the OIDC token used to authenticate requests to the REST API service -type OIDCToken struct { - sync.Mutex // concurrent access to apiToken and tokenExpirationTime - apiToken string - tokenExpirationTime time.Time -} - -type config struct { - TargetAPI string - OIDCTokenEndpoint string - ClientID string - ClientSecret string -} - -// InitAPITokenManager initializes a new APITokenManager -func InitAPITokenManager(targetAPI, oidcTokenEndpoint, clientID, clientSecret string) *APITokenManager { - return &APITokenManager{ - conf: &config{ - TargetAPI: targetAPI, - OIDCTokenEndpoint: oidcTokenEndpoint, - ClientID: clientID, - ClientSecret: clientSecret, - }, - client: rhttp.GetHTTPClient( - rhttp.Timeout(10*time.Second), - rhttp.Insecure(true), - ), - } -} - -func (a *APITokenManager) renewAPIToken(ctx context.Context, forceRenewal bool) error { - // Received tokens have an expiration time of 20 minutes. - // Take a couple of seconds as buffer time for the API call to complete - if forceRenewal || a.oidcToken.tokenExpirationTime.Before(time.Now().Add(time.Second*time.Duration(2))) { - token, expiration, err := a.getAPIToken(ctx) - if err != nil { - return err - } - - a.oidcToken.Lock() - defer a.oidcToken.Unlock() - - a.oidcToken.apiToken = token - a.oidcToken.tokenExpirationTime = expiration - } - return nil -} - -func (a *APITokenManager) getAPIToken(ctx context.Context) (string, time.Time, error) { - - params := url.Values{ - "grant_type": {"client_credentials"}, - "audience": {a.conf.TargetAPI}, - } - - httpReq, err := http.NewRequest("POST", a.conf.OIDCTokenEndpoint, strings.NewReader(params.Encode())) - if err != nil { - return "", time.Time{}, err - } - httpReq.SetBasicAuth(a.conf.ClientID, a.conf.ClientSecret) - httpReq.Header.Set("Content-Type", "application/x-www-form-urlencoded; param=value") - - httpRes, err := a.client.Do(httpReq) - if err != nil { - return "", time.Time{}, err - } - defer httpRes.Body.Close() - - body, err := io.ReadAll(httpRes.Body) - if err != nil { - return "", time.Time{}, err - } - if httpRes.StatusCode < 200 || httpRes.StatusCode > 299 { - return "", time.Time{}, errors.New("rest: get token endpoint returned " + httpRes.Status) - } - - var result map[string]interface{} - err = json.Unmarshal(body, &result) - if err != nil { - return "", time.Time{}, err - } - - expirationSecs := result["expires_in"].(float64) - expirationTime := time.Now().Add(time.Second * time.Duration(expirationSecs)) - return result["access_token"].(string), expirationTime, nil -} - -// SendAPIGetRequest makes an API GET Request to the passed URL -func (a *APITokenManager) SendAPIGetRequest(ctx context.Context, url string, forceRenewal bool) (map[string]interface{}, error) { - err := a.renewAPIToken(ctx, forceRenewal) - if err != nil { - return nil, err - } - - httpReq, err := http.NewRequest("GET", url, nil) - if err != nil { - return nil, err - } - - // We don't need to take the lock when reading apiToken, because if we reach here, - // the token is valid at least for a couple of seconds. Even if another request modifies - // the token and expiration time while this request is in progress, the current token will still be valid. - httpReq.Header.Set("Authorization", "Bearer "+a.oidcToken.apiToken) - - httpRes, err := a.client.Do(httpReq) - if err != nil { - return nil, err - } - defer httpRes.Body.Close() - - if httpRes.StatusCode == http.StatusUnauthorized { - // The token is no longer valid, try renewing it - return a.SendAPIGetRequest(ctx, url, true) - } - if httpRes.StatusCode < 200 || httpRes.StatusCode > 299 { - return nil, errors.New("rest: API request returned " + httpRes.Status) - } - - body, err := io.ReadAll(httpRes.Body) - if err != nil { - return nil, err - } - - var result map[string]interface{} - err = json.Unmarshal(body, &result) - if err != nil { - return nil, err - } - - return result, nil -} diff --git a/vendor/github.com/opencloud-eu/reva/v2/pkg/events/favorites.go b/vendor/github.com/opencloud-eu/reva/v2/pkg/events/favorites.go new file mode 100644 index 0000000000..619aa6c63a --- /dev/null +++ b/vendor/github.com/opencloud-eu/reva/v2/pkg/events/favorites.go @@ -0,0 +1,42 @@ +// Copyright 2026 OpenCloud GmbH +// SPDX-License-Identifier: Apache-2.0 + +package events + +import ( + "encoding/json" + + user "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1" + provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1" + types "github.com/cs3org/go-cs3apis/cs3/types/v1beta1" +) + +// FavoriteAdded is emitted when a user added a resource to their favorites +type FavoriteAdded struct { + Ref *provider.Reference + Executant *user.UserId + UserID *user.UserId + Timestamp *types.Timestamp +} + +// Unmarshal to fulfill umarshaller interface +func (FavoriteAdded) Unmarshal(v []byte) (interface{}, error) { + e := FavoriteAdded{} + err := json.Unmarshal(v, &e) + return e, err +} + +// FavoriteRemoved is emitted when a user removed a resource from their favorites +type FavoriteRemoved struct { + Ref *provider.Reference + Executant *user.UserId + UserID *user.UserId + Timestamp *types.Timestamp +} + +// Unmarshal to fulfill umarshaller interface +func (FavoriteRemoved) Unmarshal(v []byte) (interface{}, error) { + e := FavoriteRemoved{} + err := json.Unmarshal(v, &e) + return e, err +} diff --git a/vendor/github.com/opencloud-eu/reva/v2/pkg/ocm/invite/repository/loader/loader.go b/vendor/github.com/opencloud-eu/reva/v2/pkg/ocm/invite/repository/loader/loader.go index b5aebac9ba..e5d7b55b28 100644 --- a/vendor/github.com/opencloud-eu/reva/v2/pkg/ocm/invite/repository/loader/loader.go +++ b/vendor/github.com/opencloud-eu/reva/v2/pkg/ocm/invite/repository/loader/loader.go @@ -22,6 +22,5 @@ import ( // Load core share manager drivers. _ "github.com/opencloud-eu/reva/v2/pkg/ocm/invite/repository/json" _ "github.com/opencloud-eu/reva/v2/pkg/ocm/invite/repository/memory" - _ "github.com/opencloud-eu/reva/v2/pkg/ocm/invite/repository/sql" // Add your own here. ) diff --git a/vendor/github.com/opencloud-eu/reva/v2/pkg/ocm/invite/repository/sql/sql.go b/vendor/github.com/opencloud-eu/reva/v2/pkg/ocm/invite/repository/sql/sql.go deleted file mode 100644 index ac3e16595e..0000000000 --- a/vendor/github.com/opencloud-eu/reva/v2/pkg/ocm/invite/repository/sql/sql.go +++ /dev/null @@ -1,251 +0,0 @@ -// 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 sql - -import ( - "context" - "database/sql" - "fmt" - "time" - - gatewayv1beta1 "github.com/cs3org/go-cs3apis/cs3/gateway/v1beta1" - userpb "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1" - invitepb "github.com/cs3org/go-cs3apis/cs3/ocm/invite/v1beta1" - types "github.com/cs3org/go-cs3apis/cs3/types/v1beta1" - "github.com/go-sql-driver/mysql" - conversions "github.com/opencloud-eu/reva/v2/pkg/cbox/utils" - "github.com/opencloud-eu/reva/v2/pkg/errtypes" - "github.com/opencloud-eu/reva/v2/pkg/ocm/invite" - "github.com/opencloud-eu/reva/v2/pkg/rgrpc/todo/pool" - "github.com/opencloud-eu/reva/v2/pkg/utils/cfg" - - "github.com/opencloud-eu/reva/v2/pkg/ocm/invite/repository/registry" - "github.com/opencloud-eu/reva/v2/pkg/sharedconf" - "github.com/pkg/errors" -) - -// This module implement the invite.Repository interface as a mysql driver. -// -// The OCM Invitation tokens are saved in the table: -// ocm_tokens(*token*, initiator, expiration, description) -// -// The OCM remote user are saved in the table: -// ocm_remote_users(*initiator*, *opaque_user_id*, *idp*, email, display_name) - -func init() { - registry.Register("sql", New) -} - -type mgr struct { - c *config - db *sql.DB - client gatewayv1beta1.GatewayAPIClient -} - -type config struct { - DBUsername string `mapstructure:"db_username"` - DBPassword string `mapstructure:"db_password"` - DBAddress string `mapstructure:"db_address"` - DBName string `mapstructure:"db_name"` - GatewaySvc string `mapstructure:"gatewaysvc"` -} - -func (c *config) ApplyDefaults() { - c.GatewaySvc = sharedconf.GetGatewaySVC(c.GatewaySvc) -} - -// New creates a sql repository for ocm tokens and users. -func New(m map[string]interface{}) (invite.Repository, error) { - var c config - if err := cfg.Decode(m, &c); err != nil { - return nil, err - } - - db, err := sql.Open("mysql", fmt.Sprintf("%s:%s@tcp(%s)/%s?parseTime=true", c.DBUsername, c.DBPassword, c.DBAddress, c.DBName)) - if err != nil { - return nil, errors.Wrap(err, "sql: error opening connection to mysql database") - } - - gw, err := pool.GetGatewayServiceClient(c.GatewaySvc) - if err != nil { - return nil, err - } - - mgr := mgr{ - c: &c, - db: db, - client: gw, - } - return &mgr, nil -} - -// AddToken stores the token in the repository. -func (m *mgr) AddToken(ctx context.Context, token *invitepb.InviteToken) error { - query := "INSERT INTO ocm_tokens SET token=?,initiator=?,expiration=?,description=?" - _, err := m.db.ExecContext(ctx, query, token.Token, conversions.FormatUserID(token.UserId), timestampToTime(token.Expiration), token.Description) - return err -} - -func timestampToTime(t *types.Timestamp) time.Time { - return time.Unix(int64(t.Seconds), int64(t.Nanos)) -} - -type dbToken struct { - Token string - Initiator string - Expiration time.Time - Description string -} - -// GetToken gets the token from the repository. -func (m *mgr) GetToken(ctx context.Context, token string) (*invitepb.InviteToken, error) { - query := "SELECT token, initiator, expiration, description FROM ocm_tokens where token=?" - - var tkn dbToken - if err := m.db.QueryRowContext(ctx, query, token).Scan(&tkn.Token, &tkn.Initiator, &tkn.Expiration, &tkn.Description); err != nil { - if errors.Is(err, sql.ErrNoRows) { - return nil, invite.ErrTokenNotFound - } - return nil, err - } - return m.convertToInviteToken(ctx, tkn) -} - -func (m *mgr) convertToInviteToken(ctx context.Context, tkn dbToken) (*invitepb.InviteToken, error) { - user, err := conversions.ExtractUserID(ctx, m.client, tkn.Initiator) - if err != nil { - return nil, err - } - return &invitepb.InviteToken{ - Token: tkn.Token, - UserId: user, - Expiration: &types.Timestamp{ - Seconds: uint64(tkn.Expiration.Unix()), - }, - Description: tkn.Description, - }, nil -} - -func (m *mgr) ListTokens(ctx context.Context, initiator *userpb.UserId) ([]*invitepb.InviteToken, error) { - query := "SELECT token, initiator, expiration, description FROM ocm_tokens WHERE initiator=? AND expiration > NOW()" - - tokens := []*invitepb.InviteToken{} - rows, err := m.db.QueryContext(ctx, query, conversions.FormatUserID(initiator)) - if err != nil { - return nil, err - } - - var tkn dbToken - for rows.Next() { - if err := rows.Scan(&tkn.Token, &tkn.Initiator, &tkn.Expiration, &tkn.Description); err != nil { - continue - } - token, err := m.convertToInviteToken(ctx, tkn) - if err != nil { - return nil, err - } - tokens = append(tokens, token) - } - - return tokens, nil -} - -// AddRemoteUser stores the remote user. -func (m *mgr) AddRemoteUser(ctx context.Context, initiator *userpb.UserId, remoteUser *userpb.User) error { - query := "INSERT INTO ocm_remote_users SET initiator=?, opaque_user_id=?, idp=?, email=?, display_name=?" - if _, err := m.db.ExecContext(ctx, query, conversions.FormatUserID(initiator), conversions.FormatUserID(remoteUser.Id), remoteUser.Id.Idp, remoteUser.Mail, remoteUser.DisplayName); err != nil { - // check if the user already exist in the db - // https://dev.mysql.com/doc/mysql-errors/8.0/en/server-error-reference.html#error_er_dup_entry - var e *mysql.MySQLError - if errors.As(err, &e) && e.Number == 1062 { - return invite.ErrUserAlreadyAccepted - } - return err - } - return nil -} - -type dbOCMUser struct { - OpaqueUserID string - Idp string - Email string - DisplayName string -} - -// GetRemoteUser retrieves details about a remote user who has accepted an invite to share. -func (m *mgr) GetRemoteUser(ctx context.Context, initiator *userpb.UserId, remoteUserID *userpb.UserId) (*userpb.User, error) { - query := "SELECT opaque_user_id, idp, email, display_name FROM ocm_remote_users WHERE initiator=? AND opaque_user_id=? AND idp=?" - - var user dbOCMUser - if err := m.db.QueryRowContext(ctx, query, conversions.FormatUserID(initiator), conversions.FormatUserID(remoteUserID), remoteUserID.Idp). - Scan(&user.OpaqueUserID, &user.Idp, &user.Email, &user.DisplayName); err != nil { - if errors.Is(err, sql.ErrNoRows) { - return nil, errtypes.NotFound(remoteUserID.OpaqueId) - } - return nil, err - } - return user.toCS3User(), nil -} - -func (u *dbOCMUser) toCS3User() *userpb.User { - return &userpb.User{ - Id: &userpb.UserId{ - Idp: u.Idp, - OpaqueId: u.OpaqueUserID, - Type: userpb.UserType_USER_TYPE_FEDERATED, - }, - Mail: u.Email, - DisplayName: u.DisplayName, - } -} - -// FindRemoteUsers finds remote users who have accepted invites based on their attributes. -func (m *mgr) FindRemoteUsers(ctx context.Context, initiator *userpb.UserId, attr string) ([]*userpb.User, error) { - // TODO: (gdelmont) this query can get really slow in case the number of rows is too high. - // For the time being this is not expected, but if in future this happens, consider to add - // a fulltext index. - query := "SELECT opaque_user_id, idp, email, display_name FROM ocm_remote_users WHERE initiator=? AND (opaque_user_id LIKE ? OR idp LIKE ? OR email LIKE ? OR display_name LIKE ?)" - s := "%" + attr + "%" - params := []any{conversions.FormatUserID(initiator), s, s, s, s} - - rows, err := m.db.QueryContext(ctx, query, params...) - if err != nil { - return nil, err - } - - var u dbOCMUser - var users []*userpb.User - for rows.Next() { - if err := rows.Scan(&u.OpaqueUserID, &u.Idp, &u.Email, &u.DisplayName); err != nil { - continue - } - users = append(users, u.toCS3User()) - } - if err := rows.Err(); err != nil { - return nil, err - } - - return users, nil -} - -func (m *mgr) DeleteRemoteUser(ctx context.Context, initiator *userpb.UserId, remoteUser *userpb.UserId) error { - query := "DELETE FROM ocm_remote_users WHERE initiator=? AND opaque_user_id=? AND idp=?" - _, err := m.db.ExecContext(ctx, query, conversions.FormatUserID(initiator), conversions.FormatUserID(remoteUser), remoteUser.Idp) - return err -} diff --git a/vendor/github.com/opencloud-eu/reva/v2/pkg/ocm/storage/received/ocm.go b/vendor/github.com/opencloud-eu/reva/v2/pkg/ocm/storage/received/ocm.go index c019ec94eb..6b11463fd9 100644 --- a/vendor/github.com/opencloud-eu/reva/v2/pkg/ocm/storage/received/ocm.go +++ b/vendor/github.com/opencloud-eu/reva/v2/pkg/ocm/storage/received/ocm.go @@ -609,3 +609,11 @@ func (d *driver) UpdateStorageSpace(ctx context.Context, req *provider.UpdateSto func (d *driver) DeleteStorageSpace(ctx context.Context, req *provider.DeleteStorageSpaceRequest) error { return errtypes.NotSupported("operation not supported") } + +func (d *driver) AddFavorite(ctx context.Context, ref *provider.Reference, userID *userpb.UserId) error { + return errtypes.NotSupported("AddFavorite not implemented") +} + +func (d *driver) RemoveFavorite(ctx context.Context, ref *provider.Reference, userID *userpb.UserId) error { + return errtypes.NotSupported("RemoveFavorite not implemented") +} diff --git a/vendor/github.com/opencloud-eu/reva/v2/pkg/publicshare/manager/loader/loader.go b/vendor/github.com/opencloud-eu/reva/v2/pkg/publicshare/manager/loader/loader.go index b1b208551f..a7cc27c24e 100644 --- a/vendor/github.com/opencloud-eu/reva/v2/pkg/publicshare/manager/loader/loader.go +++ b/vendor/github.com/opencloud-eu/reva/v2/pkg/publicshare/manager/loader/loader.go @@ -22,6 +22,5 @@ import ( // Load core share manager drivers. _ "github.com/opencloud-eu/reva/v2/pkg/publicshare/manager/json" _ "github.com/opencloud-eu/reva/v2/pkg/publicshare/manager/memory" - _ "github.com/opencloud-eu/reva/v2/pkg/publicshare/manager/owncloudsql" // Add your own here ) diff --git a/vendor/github.com/opencloud-eu/reva/v2/pkg/publicshare/manager/owncloudsql/conversions.go b/vendor/github.com/opencloud-eu/reva/v2/pkg/publicshare/manager/owncloudsql/conversions.go deleted file mode 100644 index 7b19014e8e..0000000000 --- a/vendor/github.com/opencloud-eu/reva/v2/pkg/publicshare/manager/owncloudsql/conversions.go +++ /dev/null @@ -1,223 +0,0 @@ -// 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 owncloudsql - -import ( - "context" - "time" - - userpb "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1" - rpc "github.com/cs3org/go-cs3apis/cs3/rpc/v1beta1" - 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/jellydator/ttlcache/v2" - "github.com/opencloud-eu/reva/v2/pkg/conversions" - "github.com/opencloud-eu/reva/v2/pkg/rgrpc/status" - "github.com/opencloud-eu/reva/v2/pkg/rgrpc/todo/pool" -) - -// DBShare stores information about user and public shares. -type DBShare struct { - ID string - UIDOwner string - UIDInitiator string - ItemStorage string - FileSource string - ItemType string // 'file' or 'folder' - ShareWith string - Token string - Expiration string - Permissions int - ShareType int - ShareName string - STime int - FileTarget string - RejectedBy string - State int - Parent int -} - -// UserConverter describes an interface for converting user ids to names and back -type UserConverter interface { - UserNameToUserID(ctx context.Context, username string) (*userpb.UserId, error) - UserIDToUserName(ctx context.Context, userid *userpb.UserId) (string, error) -} - -// GatewayUserConverter converts usernames and ids using the gateway -type GatewayUserConverter struct { - gwAddr string - - IDCache *ttlcache.Cache - NameCache *ttlcache.Cache -} - -// NewGatewayUserConverter returns a instance of GatewayUserConverter -func NewGatewayUserConverter(gwAddr string) *GatewayUserConverter { - IDCache := ttlcache.NewCache() - _ = IDCache.SetTTL(30 * time.Second) - IDCache.SkipTTLExtensionOnHit(true) - NameCache := ttlcache.NewCache() - _ = NameCache.SetTTL(30 * time.Second) - NameCache.SkipTTLExtensionOnHit(true) - - return &GatewayUserConverter{ - gwAddr: gwAddr, - IDCache: IDCache, - NameCache: NameCache, - } -} - -// UserIDToUserName converts a user ID to an username -func (c *GatewayUserConverter) UserIDToUserName(ctx context.Context, userid *userpb.UserId) (string, error) { - username, err := c.NameCache.Get(userid.String()) - if err == nil { - return username.(string), nil - } - - gwConn, err := pool.GetGatewayServiceClient(c.gwAddr) - if err != nil { - return "", err - } - getUserResponse, err := gwConn.GetUser(ctx, &userpb.GetUserRequest{ - UserId: userid, - SkipFetchingUserGroups: true, - }) - if err != nil { - return "", err - } - if getUserResponse.Status.Code != rpc.Code_CODE_OK { - return "", status.NewErrorFromCode(getUserResponse.Status.Code, "gateway") - } - _ = c.NameCache.Set(userid.String(), getUserResponse.User.Username) - return getUserResponse.User.Username, nil -} - -// UserNameToUserID converts a username to an user ID -func (c *GatewayUserConverter) UserNameToUserID(ctx context.Context, username string) (*userpb.UserId, error) { - id, err := c.IDCache.Get(username) - if err == nil { - return id.(*userpb.UserId), nil - } - - gwConn, err := pool.GetGatewayServiceClient(c.gwAddr) - if err != nil { - return nil, err - } - getUserResponse, err := gwConn.GetUserByClaim(ctx, &userpb.GetUserByClaimRequest{ - Claim: "username", - Value: username, - SkipFetchingUserGroups: true, - }) - if err != nil { - return nil, err - } - if getUserResponse.Status.Code != rpc.Code_CODE_OK { - return nil, status.NewErrorFromCode(getUserResponse.Status.Code, "gateway") - } - _ = c.IDCache.Set(username, getUserResponse.User.Id) - return getUserResponse.User.Id, nil -} - -func resourceTypeToItem(r provider.ResourceType) string { - switch r { - case provider.ResourceType_RESOURCE_TYPE_FILE: - return "file" - case provider.ResourceType_RESOURCE_TYPE_CONTAINER: - return "folder" - case provider.ResourceType_RESOURCE_TYPE_REFERENCE: - return "reference" - case provider.ResourceType_RESOURCE_TYPE_SYMLINK: - return "symlink" - default: - return "" - } -} - -func sharePermToInt(p *provider.ResourcePermissions) int { - return int(conversions.RoleFromResourcePermissions(p, true).OCSPermissions()) -} - -func intTosharePerm(p int) (*provider.ResourcePermissions, error) { - perms, err := conversions.NewPermissions(p) - if err != nil { - return nil, err - } - - return conversions.RoleFromOCSPermissions(perms, nil).CS3ResourcePermissions(), nil -} - -func formatUserID(u *userpb.UserId) string { - return u.OpaqueId -} - -// ConvertToCS3PublicShare converts a DBShare to a CS3API public share -func (m *mgr) ConvertToCS3PublicShare(ctx context.Context, s DBShare) (*link.PublicShare, error) { - ts := &typespb.Timestamp{ - Seconds: uint64(s.STime), - } - permissions, err := intTosharePerm(s.Permissions) - if err != nil { - return nil, err - } - owner, err := m.userConverter.UserNameToUserID(ctx, s.UIDOwner) - if err != nil { - return nil, err - } - var creator *userpb.UserId - if s.UIDOwner == s.UIDInitiator { - creator = owner - } else { - creator, err = m.userConverter.UserNameToUserID(ctx, s.UIDOwner) - if err != nil { - return nil, err - } - } - pwd := s.ShareWith != "" - var expires *typespb.Timestamp - if s.Expiration != "" { - t, err := time.Parse("2006-01-02 15:04:05", s.Expiration) - if err != nil { - t, err = time.Parse("2006-01-02 15:04:05-07:00", s.Expiration) - } - if err == nil { - expires = &typespb.Timestamp{ - Seconds: uint64(t.Unix()), - } - } - } - return &link.PublicShare{ - Id: &link.PublicShareId{ - OpaqueId: s.ID, - }, - ResourceId: &provider.ResourceId{ - SpaceId: s.ItemStorage, - OpaqueId: s.FileSource, - }, - Permissions: &link.PublicSharePermissions{Permissions: permissions}, - Owner: owner, - Creator: creator, - Token: s.Token, - DisplayName: s.ShareName, - PasswordProtected: pwd, - Expiration: expires, - Ctime: ts, - Mtime: ts, - }, nil -} diff --git a/vendor/github.com/opencloud-eu/reva/v2/pkg/publicshare/manager/owncloudsql/owncloudsql.go b/vendor/github.com/opencloud-eu/reva/v2/pkg/publicshare/manager/owncloudsql/owncloudsql.go deleted file mode 100644 index 37dea4565c..0000000000 --- a/vendor/github.com/opencloud-eu/reva/v2/pkg/publicshare/manager/owncloudsql/owncloudsql.go +++ /dev/null @@ -1,533 +0,0 @@ -// 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 owncloudsql implements a publiclink share manager backed by an existing ownCloud 10 database -// -// The SQL queries use `coalesce({column_identifier}, ”) as {column_identifier}` to read an emptystring -// instead of null values, which better fits the golang default values. -package owncloudsql - -import ( - "context" - "database/sql" - "fmt" - "strconv" - "strings" - "time" - - user "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1" - 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/mitchellh/mapstructure" - "github.com/opencloud-eu/reva/v2/pkg/errtypes" - "github.com/opencloud-eu/reva/v2/pkg/publicshare" - "github.com/opencloud-eu/reva/v2/pkg/publicshare/manager/registry" - "github.com/opencloud-eu/reva/v2/pkg/sharedconf" - "github.com/opencloud-eu/reva/v2/pkg/utils" - "github.com/pkg/errors" - "golang.org/x/crypto/bcrypt" - "google.golang.org/protobuf/proto" - - // Provides mysql drivers - _ "github.com/go-sql-driver/mysql" -) - -const ( - publicShareType = 3 -) - -func init() { - registry.Register("owncloudsql", NewMysql) -} - -// Config configures an owncloudsql publicshare manager -type Config struct { - GatewayAddr string `mapstructure:"gateway_addr"` - DbUsername string `mapstructure:"db_username"` - DbPassword string `mapstructure:"db_password"` - DbHost string `mapstructure:"db_host"` - DbPort int `mapstructure:"db_port"` - DbName string `mapstructure:"db_name"` - EnableExpiredSharesCleanup bool `mapstructure:"enable_expired_shares_cleanup"` - SharePasswordHashCost int `mapstructure:"password_hash_cost"` -} - -type mgr struct { - driver string - db *sql.DB - c Config - userConverter UserConverter -} - -// NewMysql returns a new publicshare manager connection to a mysql database -func NewMysql(m map[string]interface{}) (publicshare.Manager, error) { - c, err := parseConfig(m) - if err != nil { - err = errors.Wrap(err, "error creating a new manager") - return nil, err - } - - db, err := sql.Open("mysql", fmt.Sprintf("%s:%s@tcp(%s:%d)/%s", c.DbUsername, c.DbPassword, c.DbHost, c.DbPort, c.DbName)) - if err != nil { - return nil, err - } - - userConverter := NewGatewayUserConverter(sharedconf.GetGatewaySVC(c.GatewayAddr)) - - return New("mysql", db, *c, userConverter) -} - -// New returns a new Cache instance connecting to the given sql.DB -func New(driver string, db *sql.DB, c Config, userConverter UserConverter) (publicshare.Manager, error) { - if c.SharePasswordHashCost == 0 { - c.SharePasswordHashCost = bcrypt.DefaultCost - } - return &mgr{ - driver: driver, - db: db, - c: c, - userConverter: userConverter, - }, nil -} - -func parseConfig(m map[string]interface{}) (*Config, error) { - c := &Config{} - if err := mapstructure.Decode(m, c); err != nil { - return nil, err - } - return c, nil -} - -func (m *mgr) CreatePublicShare(ctx context.Context, u *user.User, rInfo *provider.ResourceInfo, g *link.Grant) (*link.PublicShare, error) { - - tkn := utils.RandString(15) - now := time.Now().Unix() - - displayName := tkn - if rInfo.ArbitraryMetadata != nil && rInfo.ArbitraryMetadata.Metadata["name"] != "" { - displayName = rInfo.ArbitraryMetadata.Metadata["name"] - } - createdAt := &typespb.Timestamp{ - Seconds: uint64(now), - } - - creator := u.Username - owner, err := m.userConverter.UserIDToUserName(ctx, rInfo.Owner) - if err != nil { - return nil, err - } - permissions := sharePermToInt(g.Permissions.Permissions) - itemType := resourceTypeToItem(rInfo.Type) - - itemSource := rInfo.Id.OpaqueId - fileSource, err := strconv.ParseUint(itemSource, 10, 64) - if err != nil { - // it can be the case that the item source may be a character string - // we leave fileSource blank in that case - fileSource = 0 - } - - columns := "share_type,uid_owner,uid_initiator,item_type,item_source,file_source,permissions,stime,token,share_name" - placeholders := "?,?,?,?,?,?,?,?,?,?" - params := []interface{}{publicShareType, owner, creator, itemType, itemSource, fileSource, permissions, now, tkn, displayName} - - var passwordProtected bool - password := g.Password - if password != "" { - password, err = hashPassword(password, m.c.SharePasswordHashCost) - if err != nil { - return nil, errors.Wrap(err, "could not hash share password") - } - passwordProtected = true - - columns += ",share_with" - placeholders += ",?" - params = append(params, password) - } - - if g.Expiration != nil && g.Expiration.Seconds != 0 { - t := time.Unix(int64(g.Expiration.Seconds), 0) - columns += ",expiration" - placeholders += ",?" - params = append(params, t) - } - - query := "INSERT INTO oc_share (" + columns + ") VALUES (" + placeholders + ")" - stmt, err := m.db.Prepare(query) - if err != nil { - return nil, err - } - result, err := stmt.Exec(params...) - if err != nil { - return nil, err - } - lastID, err := result.LastInsertId() - if err != nil { - return nil, err - } - - return &link.PublicShare{ - Id: &link.PublicShareId{ - OpaqueId: strconv.FormatInt(lastID, 10), - }, - Owner: rInfo.GetOwner(), - Creator: u.Id, - ResourceId: rInfo.Id, - Token: tkn, - Permissions: g.Permissions, - Ctime: createdAt, - Mtime: createdAt, - PasswordProtected: passwordProtected, - Expiration: g.Expiration, - DisplayName: displayName, - }, nil -} - -// owncloud 10 prefixes the hash with `1|` -func hashPassword(password string, cost int) (string, error) { - bytes, err := bcrypt.GenerateFromPassword([]byte(password), cost) - return "1|" + string(bytes), err -} - -// UpdatePublicShare updates the expiration date, permissions and Mtime -func (m *mgr) UpdatePublicShare(ctx context.Context, u *user.User, req *link.UpdatePublicShareRequest) (*link.PublicShare, error) { - query := "update oc_share set " - paramsMap := map[string]interface{}{} - params := []interface{}{} - - now := time.Now().Unix() - uid := u.Username - - switch req.GetUpdate().GetType() { - case link.UpdatePublicShareRequest_Update_TYPE_DISPLAYNAME: - paramsMap["share_name"] = req.Update.GetDisplayName() - case link.UpdatePublicShareRequest_Update_TYPE_PERMISSIONS: - paramsMap["permissions"] = sharePermToInt(req.Update.GetGrant().GetPermissions().Permissions) - case link.UpdatePublicShareRequest_Update_TYPE_EXPIRATION: - paramsMap["expiration"] = time.Unix(int64(req.Update.GetGrant().Expiration.Seconds), 0) - case link.UpdatePublicShareRequest_Update_TYPE_PASSWORD: - if req.Update.GetGrant().Password == "" { - paramsMap["share_with"] = "" - } else { - h, err := hashPassword(req.Update.GetGrant().Password, m.c.SharePasswordHashCost) - if err != nil { - return nil, errors.Wrap(err, "could not hash share password") - } - paramsMap["share_with"] = h - } - default: - return nil, fmt.Errorf("invalid update type: %v", req.GetUpdate().GetType()) - } - - for k, v := range paramsMap { - query += k + "=?" - params = append(params, v) - } - - switch { - case req.Ref.GetId() != nil: - query += ",stime=? where id=? AND (uid_owner=? or uid_initiator=?)" - params = append(params, now, req.Ref.GetId().OpaqueId, uid, uid) - case req.Ref.GetToken() != "": - query += ",stime=? where token=? AND (uid_owner=? or uid_initiator=?)" - params = append(params, now, req.Ref.GetToken(), uid, uid) - default: - return nil, errtypes.NotFound(req.Ref.String()) - } - - stmt, err := m.db.Prepare(query) - if err != nil { - return nil, err - } - if _, err = stmt.Exec(params...); err != nil { - return nil, err - } - - return m.GetPublicShare(ctx, u, req.Ref, false) -} - -func (m *mgr) GetPublicShare(ctx context.Context, u *user.User, ref *link.PublicShareReference, sign bool) (share *link.PublicShare, err error) { - - ps, err := m.getWithPassword(ctx, ref) - if err != nil { - return nil, err - } - - if publicshare.IsExpired(&ps.PublicShare) { - if err := m.cleanupExpiredShares(); err != nil { - return nil, err - } - return nil, errtypes.NotFound("public share has expired") - } - - if ps.PublicShare.PasswordProtected && sign { - err = publicshare.AddSignature(&ps.PublicShare, ps.Password) - if err != nil { - return nil, err - } - } - - return &ps.PublicShare, nil -} - -func (m *mgr) getWithPassword(ctx context.Context, ref *link.PublicShareReference) (*publicshare.WithPassword, error) { - switch { - case ref.GetToken() != "": - return m.getByToken(ctx, ref.GetToken()) - case ref.GetId().GetOpaqueId() != "": - return m.getByID(ctx, ref.GetId().GetOpaqueId()) - default: - return nil, errtypes.BadRequest("neither id nor token given") - } -} - -func (m *mgr) getByToken(ctx context.Context, token string) (*publicshare.WithPassword, error) { - s, err := getByToken(m.db, token) - if err != nil { - return nil, err - } - ps, err := m.ConvertToCS3PublicShare(ctx, s) - if err != nil { - return nil, err - } - ret := &publicshare.WithPassword{ - Password: strings.TrimPrefix(s.ShareWith, "1|"), - } - proto.Merge(&ret.PublicShare, ps) - return ret, nil -} - -func getByToken(db *sql.DB, token string) (DBShare, error) { - s := DBShare{Token: token} - query := `SELECT - coalesce(uid_owner, '') as uid_owner, coalesce(uid_initiator, '') as uid_initiator, - coalesce(share_with, '') as share_with, coalesce(file_source, '') as file_source, - coalesce(item_type, '') as item_type, - coalesce(expiration, '') as expiration, coalesce(share_name, '') as share_name, - s.id, s.stime, s.permissions, fc.storage as storage - FROM oc_share s - LEFT JOIN oc_filecache fc ON fc.fileid = file_source - WHERE share_type=? AND token=?` - if err := db.QueryRow(query, publicShareType, token).Scan(&s.UIDOwner, &s.UIDInitiator, &s.ShareWith, &s.FileSource, &s.ItemType, &s.Expiration, &s.ShareName, &s.ID, &s.STime, &s.Permissions, &s.ItemStorage); err != nil { - if err == sql.ErrNoRows { - return s, errtypes.NotFound(token) - } - return s, err - } - return s, nil -} - -func (m *mgr) getByID(ctx context.Context, id string) (*publicshare.WithPassword, error) { - s := DBShare{ID: id} - query := `SELECT - coalesce(uid_owner, '') as uid_owner, coalesce(uid_initiator, '') as uid_initiator, - coalesce(share_with, '') as share_with, coalesce(file_source, '') as file_source, - coalesce(item_type, '') as item_type, coalesce(token,'') as token, - coalesce(expiration, '') as expiration, coalesce(share_name, '') as share_name, - s.stime, s.permissions, fc.storage as storage - FROM oc_share s - LEFT JOIN oc_filecache fc ON fc.fileid = file_source - WHERE share_type=? AND id=?` - if err := m.db.QueryRow(query, publicShareType, id).Scan(&s.UIDOwner, &s.UIDInitiator, &s.ShareWith, &s.FileSource, &s.ItemType, &s.Token, &s.Expiration, &s.ShareName, &s.STime, &s.Permissions, &s.ItemStorage); err != nil { - if err == sql.ErrNoRows { - return nil, errtypes.NotFound(id) - } - return nil, err - } - ps, err := m.ConvertToCS3PublicShare(ctx, s) - if err != nil { - return nil, err - } - ret := &publicshare.WithPassword{ - Password: strings.TrimPrefix(s.ShareWith, "1|"), - } - proto.Merge(&ret.PublicShare, ps) - return ret, nil -} - -func (m *mgr) ListPublicShares(ctx context.Context, u *user.User, filters []*link.ListPublicSharesRequest_Filter, sign bool) ([]*link.PublicShare, error) { - uid := u.Username - // FIXME instead of joining we may want to have to do a stat call ... if we want to store shares from other providers? or just Dump()? and be done with migration? - query := `SELECT - coalesce(uid_owner, '') as uid_owner, coalesce(uid_initiator, '') as uid_initiator, - coalesce(share_with, '') as share_with, coalesce(file_source, '') as file_source, - coalesce(item_type, '') as item_type, coalesce(token,'') as token, - coalesce(expiration, '') as expiration, coalesce(share_name, '') as share_name, - s.id, s.stime, s.permissions, fc.storage as storage - FROM oc_share s - LEFT JOIN oc_filecache fc ON fc.fileid = file_source - WHERE (uid_owner=? or uid_initiator=?) - AND (share_type=?)` - var resourceFilters, ownerFilters, creatorFilters, storageFilters string - var resourceParams, ownerParams, creatorParams, storageParams []interface{} - params := []interface{}{uid, uid, publicShareType} - - for _, f := range filters { - switch f.Type { - case link.ListPublicSharesRequest_Filter_TYPE_RESOURCE_ID: - if len(resourceFilters) != 0 { - resourceFilters += " OR " - } - resourceFilters += "item_source=?" - resourceParams = append(resourceParams, f.GetResourceId().GetOpaqueId()) - case link.ListPublicSharesRequest_Filter_TYPE_OWNER: - if len(ownerFilters) != 0 { - ownerFilters += " OR " - } - ownerFilters += "(uid_owner=?)" - ownerParams = append(ownerParams, formatUserID(f.GetOwner())) - case link.ListPublicSharesRequest_Filter_TYPE_CREATOR: - if len(creatorFilters) != 0 { - creatorFilters += " OR " - } - creatorFilters += "(uid_initiator=?)" - creatorParams = append(creatorParams, formatUserID(f.GetCreator())) - case publicshare.StorageIDFilterType: - if len(storageFilters) != 0 { - storageFilters += " OR " - } - storageFilters += "(storage=?)" - storageParams = append(storageParams, f.GetResourceId().GetStorageId()) - } - } - if resourceFilters != "" { - query = fmt.Sprintf("%s AND (%s)", query, resourceFilters) - params = append(params, resourceParams...) - } - if ownerFilters != "" { - query = fmt.Sprintf("%s AND (%s)", query, ownerFilters) - params = append(params, ownerParams...) - } - if creatorFilters != "" { - query = fmt.Sprintf("%s AND (%s)", query, creatorFilters) - params = append(params, creatorParams...) - } - if storageFilters != "" { - query = fmt.Sprintf("%s AND (%s)", query, storageFilters) - params = append(params, storageParams...) - } - - rows, err := m.db.Query(query, params...) - if err != nil { - return nil, err - } - defer rows.Close() - - var s DBShare - shares := []*link.PublicShare{} - for rows.Next() { - if err := rows.Scan(&s.UIDOwner, &s.UIDInitiator, &s.ShareWith, &s.FileSource, &s.ItemType, &s.Token, &s.Expiration, &s.ShareName, &s.ID, &s.STime, &s.Permissions, &s.ItemStorage); err != nil { - continue - } - var cs3Share *link.PublicShare - if cs3Share, err = m.ConvertToCS3PublicShare(ctx, s); err != nil { - return nil, err - } - if publicshare.IsExpired(cs3Share) { - _ = m.cleanupExpiredShares() - } else { - if cs3Share.PasswordProtected && sign { - if err := publicshare.AddSignature(cs3Share, strings.TrimPrefix(s.ShareWith, "1|")); err != nil { - return nil, err - } - } - shares = append(shares, cs3Share) - } - } - if err = rows.Err(); err != nil { - return nil, err - } - - return shares, nil -} - -func (m *mgr) RevokePublicShare(ctx context.Context, u *user.User, ref *link.PublicShareReference) error { - uid := u.Username - query := "delete from oc_share where " - params := []interface{}{} - - switch { - case ref.GetId() != nil && ref.GetId().OpaqueId != "": - query += "id=? AND (uid_owner=? or uid_initiator=?)" - params = append(params, ref.GetId().OpaqueId, uid, uid) - case ref.GetToken() != "": - query += "token=? AND (uid_owner=? or uid_initiator=?)" - params = append(params, ref.GetToken(), uid, uid) - default: - return errtypes.NotFound(ref.String()) - } - - stmt, err := m.db.Prepare(query) - if err != nil { - return err - } - res, err := stmt.Exec(params...) - if err != nil { - return err - } - - rowCnt, err := res.RowsAffected() - if err != nil { - return err - } - if rowCnt == 0 { - return errtypes.NotFound(ref.String()) - } - return nil -} - -func (m *mgr) GetPublicShareByToken(ctx context.Context, token string, auth *link.PublicShareAuthentication, sign bool) (*link.PublicShare, error) { - ps, err := m.getByToken(ctx, token) - if err != nil { - return nil, err - } - - if publicshare.IsExpired(&ps.PublicShare) { - if err := m.cleanupExpiredShares(); err != nil { - return nil, err - } - return nil, errtypes.NotFound("public share has expired") - } - - if ps.PublicShare.PasswordProtected { - if !publicshare.Authenticate(&ps.PublicShare, ps.Password, auth) { - return nil, errtypes.InvalidCredentials("access denied") - } - } - - return &ps.PublicShare, nil -} - -func (m *mgr) cleanupExpiredShares() error { - if !m.c.EnableExpiredSharesCleanup { - return nil - } - - query := "DELETE FROM oc_share WHERE expiration IS NOT NULL AND expiration < ?" - params := []interface{}{time.Now().Format("2006-01-02 03:04:05")} - - stmt, err := m.db.Prepare(query) - if err != nil { - return err - } - if _, err = stmt.Exec(params...); err != nil { - return err - } - return nil -} diff --git a/vendor/github.com/opencloud-eu/reva/v2/pkg/publicshare/manager/owncloudsql/test.db b/vendor/github.com/opencloud-eu/reva/v2/pkg/publicshare/manager/owncloudsql/test.db deleted file mode 100644 index fba76fdcc4..0000000000 Binary files a/vendor/github.com/opencloud-eu/reva/v2/pkg/publicshare/manager/owncloudsql/test.db and /dev/null differ diff --git a/vendor/github.com/opencloud-eu/reva/v2/pkg/share/cache/warmup/cbox/cbox.go b/vendor/github.com/opencloud-eu/reva/v2/pkg/share/cache/warmup/cbox/cbox.go deleted file mode 100644 index 74c18c4039..0000000000 --- a/vendor/github.com/opencloud-eu/reva/v2/pkg/share/cache/warmup/cbox/cbox.go +++ /dev/null @@ -1,155 +0,0 @@ -// 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 cbox - -import ( - "context" - "database/sql" - "fmt" - - userpb "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" - "github.com/mitchellh/mapstructure" - "github.com/opencloud-eu/reva/v2/pkg/auth/scope" - ctxpkg "github.com/opencloud-eu/reva/v2/pkg/ctx" - "github.com/opencloud-eu/reva/v2/pkg/rgrpc/todo/pool" - "github.com/opencloud-eu/reva/v2/pkg/share/cache" - "github.com/opencloud-eu/reva/v2/pkg/share/cache/warmup/registry" - "github.com/opencloud-eu/reva/v2/pkg/token/manager/jwt" - "github.com/pkg/errors" - "google.golang.org/grpc/metadata" - - // Provides mysql drivers - _ "github.com/go-sql-driver/mysql" -) - -func init() { - registry.Register("cbox", New) -} - -type config struct { - DbUsername string `mapstructure:"db_username"` - DbPassword string `mapstructure:"db_password"` - DbHost string `mapstructure:"db_host"` - DbPort int `mapstructure:"db_port"` - DbName string `mapstructure:"db_name"` - EOSNamespace string `mapstructure:"namespace"` - GatewaySvc string `mapstructure:"gatewaysvc"` - JWTSecret string `mapstructure:"jwt_secret"` -} - -type manager struct { - conf *config - db *sql.DB -} - -func parseConfig(m map[string]interface{}) (*config, error) { - c := &config{} - if err := mapstructure.Decode(m, c); err != nil { - err = errors.Wrap(err, "error decoding conf") - return nil, err - } - return c, nil -} - -// New returns an implementation of cache warmup that connects to the cbox share db and stats resources on EOS -func New(m map[string]interface{}) (cache.Warmup, error) { - c, err := parseConfig(m) - if err != nil { - return nil, err - } - db, err := sql.Open("mysql", fmt.Sprintf("%s:%s@tcp(%s:%d)/%s", c.DbUsername, c.DbPassword, c.DbHost, c.DbPort, c.DbName)) - if err != nil { - return nil, err - } - - return &manager{ - conf: c, - db: db, - }, nil -} - -func (m *manager) GetResourceInfos() ([]*provider.ResourceInfo, error) { - query := "select coalesce(fileid_prefix, '') as fileid_prefix, coalesce(item_source, '') as item_source FROM oc_share WHERE (orphan = 0 or orphan IS NULL)" - rows, err := m.db.Query(query) - if err != nil { - return nil, err - } - defer rows.Close() - - tokenManager, err := jwt.New(map[string]interface{}{ - "secret": m.conf.JWTSecret, - }) - if err != nil { - return nil, err - } - - u := &userpb.User{ - Id: &userpb.UserId{ - OpaqueId: "root", - }, - UidNumber: 0, - GidNumber: 0, - } - scope, err := scope.AddOwnerScope(nil) - if err != nil { - return nil, err - } - - tkn, err := tokenManager.MintToken(context.Background(), u, scope) - if err != nil { - return nil, err - } - ctx := metadata.AppendToOutgoingContext(context.Background(), ctxpkg.TokenHeader, tkn) - - client, err := pool.GetGatewayServiceClient(m.conf.GatewaySvc) - if err != nil { - return nil, err - } - - infos := []*provider.ResourceInfo{} - for rows.Next() { - var spaceID, nodeID string - if err := rows.Scan(&spaceID, &nodeID); err != nil { - continue - } - - statReq := provider.StatRequest{Ref: &provider.Reference{ - ResourceId: &provider.ResourceId{ - SpaceId: spaceID, - OpaqueId: nodeID, - }, - }} - - statRes, err := client.Stat(ctx, &statReq) - if err != nil || statRes.Status.Code != rpc.Code_CODE_OK { - continue - } - - infos = append(infos, statRes.Info) - } - - if err = rows.Err(); err != nil { - return nil, err - } - - return infos, nil - -} diff --git a/vendor/github.com/opencloud-eu/reva/v2/pkg/share/cache/warmup/loader/loader.go b/vendor/github.com/opencloud-eu/reva/v2/pkg/share/cache/warmup/loader/loader.go index ac6e685114..5bd3e4ae6e 100644 --- a/vendor/github.com/opencloud-eu/reva/v2/pkg/share/cache/warmup/loader/loader.go +++ b/vendor/github.com/opencloud-eu/reva/v2/pkg/share/cache/warmup/loader/loader.go @@ -18,8 +18,5 @@ package loader -import ( - // Load share cache drivers. - _ "github.com/opencloud-eu/reva/v2/pkg/share/cache/warmup/cbox" - // Add your own here -) +// Load share cache drivers. +// Add your own here diff --git a/vendor/github.com/opencloud-eu/reva/v2/pkg/share/manager/json/json.go b/vendor/github.com/opencloud-eu/reva/v2/pkg/share/manager/json/json.go deleted file mode 100644 index f17a34a02b..0000000000 --- a/vendor/github.com/opencloud-eu/reva/v2/pkg/share/manager/json/json.go +++ /dev/null @@ -1,617 +0,0 @@ -// 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 json - -import ( - "context" - "encoding/json" - "io" - "io/fs" - "os" - "strings" - "sync" - "time" - - userv1beta1 "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1" - rpcv1beta1 "github.com/cs3org/go-cs3apis/cs3/rpc/v1beta1" - collaboration "github.com/cs3org/go-cs3apis/cs3/sharing/collaboration/v1beta1" - provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1" - typespb "github.com/cs3org/go-cs3apis/cs3/types/v1beta1" - "github.com/golang/protobuf/proto" // nolint:staticcheck // we need the legacy package to convert V1 to V2 messages - "github.com/google/uuid" - "github.com/mitchellh/mapstructure" - "github.com/opencloud-eu/reva/v2/pkg/appctx" - ctxpkg "github.com/opencloud-eu/reva/v2/pkg/ctx" - "github.com/opencloud-eu/reva/v2/pkg/errtypes" - "github.com/opencloud-eu/reva/v2/pkg/rgrpc/todo/pool" - "github.com/opencloud-eu/reva/v2/pkg/share" - "github.com/pkg/errors" - "google.golang.org/genproto/protobuf/field_mask" - "google.golang.org/protobuf/encoding/prototext" - - "github.com/opencloud-eu/reva/v2/pkg/share/manager/registry" - "github.com/opencloud-eu/reva/v2/pkg/utils" -) - -func init() { - registry.Register("json", New) -} - -// New returns a new mgr. -func New(m map[string]interface{}) (share.Manager, error) { - c, err := parseConfig(m) - if err != nil { - err = errors.Wrap(err, "error creating a new manager") - return nil, err - } - - if c.GatewayAddr == "" { - return nil, errors.New("share manager config is missing gateway address") - } - - c.init() - - // load or create file - model, err := loadOrCreate(c.File) - if err != nil { - err = errors.Wrap(err, "error loading the file containing the shares") - return nil, err - } - - return &mgr{ - c: c, - model: model, - }, nil -} - -func loadOrCreate(file string) (*shareModel, error) { - if info, err := os.Stat(file); errors.Is(err, fs.ErrNotExist) || info.Size() == 0 { - if err := os.WriteFile(file, []byte("{}"), 0700); err != nil { - err = errors.Wrap(err, "error opening/creating the file: "+file) - return nil, err - } - } - - fd, err := os.OpenFile(file, os.O_CREATE, 0644) - if err != nil { - err = errors.Wrap(err, "error opening/creating the file: "+file) - return nil, err - } - defer fd.Close() - - data, err := io.ReadAll(fd) - if err != nil { - err = errors.Wrap(err, "error reading the data") - return nil, err - } - - j := &jsonEncoding{} - if err := json.Unmarshal(data, j); err != nil { - err = errors.Wrap(err, "error decoding data from json") - return nil, err - } - - m := &shareModel{State: j.State, MountPoint: j.MountPoint} - for _, s := range j.Shares { - var decShare collaboration.Share - if err = utils.UnmarshalJSONToProtoV1([]byte(s), &decShare); err != nil { - return nil, errors.Wrap(err, "error decoding share from json") - } - m.Shares = append(m.Shares, &decShare) - } - - if m.State == nil { - m.State = map[string]map[string]collaboration.ShareState{} - } - if m.MountPoint == nil { - m.MountPoint = map[string]map[string]*provider.Reference{} - } - - m.file = file - return m, nil -} - -type shareModel struct { - file string - State map[string]map[string]collaboration.ShareState `json:"state"` // map[username]map[share_id]ShareState - MountPoint map[string]map[string]*provider.Reference `json:"mount_point"` // map[username]map[share_id]MountPoint - Shares []*collaboration.Share `json:"shares"` -} - -type jsonEncoding struct { - State map[string]map[string]collaboration.ShareState `json:"state"` // map[username]map[share_id]ShareState - MountPoint map[string]map[string]*provider.Reference `json:"mount_point"` // map[username]map[share_id]MountPoint - Shares []string `json:"shares"` -} - -func (m *shareModel) Save() error { - j := &jsonEncoding{State: m.State, MountPoint: m.MountPoint} - for _, s := range m.Shares { - encShare, err := utils.MarshalProtoV1ToJSON(s) - if err != nil { - return errors.Wrap(err, "error encoding to json") - } - j.Shares = append(j.Shares, string(encShare)) - } - - data, err := json.Marshal(j) - if err != nil { - err = errors.Wrap(err, "error encoding to json") - return err - } - - if err := os.WriteFile(m.file, data, 0644); err != nil { - err = errors.Wrap(err, "error writing to file: "+m.file) - return err - } - - return nil -} - -type mgr struct { - c *config - sync.Mutex // concurrent access to the file - model *shareModel -} - -type config struct { - File string `mapstructure:"file"` - GatewayAddr string `mapstructure:"gateway_addr"` -} - -func (c *config) init() { - if c.File == "" { - c.File = "/var/tmp/reva/shares.json" - } -} - -func parseConfig(m map[string]interface{}) (*config, error) { - c := &config{} - if err := mapstructure.Decode(m, c); err != nil { - return nil, err - } - return c, nil -} - -// Dump exports shares and received shares to channels (e.g. during migration) -func (m *mgr) Dump(ctx context.Context, shareChan chan<- *collaboration.Share, receivedShareChan chan<- share.ReceivedShareWithUser) error { - log := appctx.GetLogger(ctx) - for _, s := range m.model.Shares { - shareChan <- s - } - - for userIDString, states := range m.model.State { - userMountPoints := m.model.MountPoint[userIDString] - id := &userv1beta1.UserId{} - mV2 := proto.MessageV2(id) - if err := prototext.Unmarshal([]byte(userIDString), mV2); err != nil { - log.Error().Err(err).Msg("error unmarshalling the user id") - continue - } - - for shareIDString, state := range states { - sid := &collaboration.ShareId{} - mV2 := proto.MessageV2(sid) - if err := prototext.Unmarshal([]byte(shareIDString), mV2); err != nil { - log.Error().Err(err).Msg("error unmarshalling the user id") - continue - } - - var s *collaboration.Share - for _, is := range m.model.Shares { - if is.Id.OpaqueId == sid.OpaqueId { - s = is - break - } - } - if s == nil { - log.Warn().Str("share id", sid.OpaqueId).Msg("Share not found") - continue - } - - var mp *provider.Reference - if userMountPoints != nil { - mp = userMountPoints[shareIDString] - } - - receivedShareChan <- share.ReceivedShareWithUser{ - UserID: id, - ReceivedShare: &collaboration.ReceivedShare{ - Share: s, - State: state, - MountPoint: mp, - }, - } - } - } - - return nil -} - -func (m *mgr) Share(ctx context.Context, md *provider.ResourceInfo, g *collaboration.ShareGrant) (*collaboration.Share, error) { - id := uuid.NewString() - user := ctxpkg.ContextMustGetUser(ctx) - now := time.Now().UnixNano() - ts := &typespb.Timestamp{ - Seconds: uint64(now / int64(time.Second)), - Nanos: uint32(now % int64(time.Second)), - } - - // do not allow share to myself or the owner if share is for a user - // TODO(labkode): should not this be caught already at the gw level? - if g.Grantee.Type == provider.GranteeType_GRANTEE_TYPE_USER && - (utils.UserEqual(g.Grantee.GetUserId(), user.Id) || utils.UserEqual(g.Grantee.GetUserId(), md.Owner)) { - return nil, errtypes.BadRequest("json: owner/creator and grantee are the same") - } - - // check if share already exists. - key := &collaboration.ShareKey{ - Owner: md.Owner, - ResourceId: md.Id, - Grantee: g.Grantee, - } - - m.Lock() - defer m.Unlock() - _, _, err := m.getByKey(key) - if err == nil { - // share already exists - return nil, errtypes.AlreadyExists(key.String()) - } - - s := &collaboration.Share{ - Id: &collaboration.ShareId{ - OpaqueId: id, - }, - ResourceId: md.Id, - Permissions: g.Permissions, - Grantee: g.Grantee, - Owner: md.Owner, - Creator: user.Id, - Ctime: ts, - Mtime: ts, - } - - m.model.Shares = append(m.model.Shares, s) - if err := m.model.Save(); err != nil { - err = errors.Wrap(err, "error saving model") - return nil, err - } - - return s, nil -} - -// getByID must be called in a lock-controlled block. -func (m *mgr) getByID(id *collaboration.ShareId) (int, *collaboration.Share, error) { - for i, s := range m.model.Shares { - if s.GetId().OpaqueId == id.OpaqueId { - return i, s, nil - } - } - return -1, nil, errtypes.NotFound(id.String()) -} - -// getByKey must be called in a lock-controlled block. -func (m *mgr) getByKey(key *collaboration.ShareKey) (int, *collaboration.Share, error) { - for i, s := range m.model.Shares { - if (utils.UserEqual(key.Owner, s.Owner) || utils.UserEqual(key.Owner, s.Creator)) && - utils.ResourceIDEqual(key.ResourceId, s.ResourceId) && utils.GranteeEqual(key.Grantee, s.Grantee) { - return i, s, nil - } - } - return -1, nil, errtypes.NotFound(key.String()) -} - -// get must be called in a lock-controlled block. -func (m *mgr) get(ref *collaboration.ShareReference) (idx int, s *collaboration.Share, err error) { - switch { - case ref.GetId() != nil: - idx, s, err = m.getByID(ref.GetId()) - case ref.GetKey() != nil: - idx, s, err = m.getByKey(ref.GetKey()) - default: - err = errtypes.NotFound(ref.String()) - } - return -} - -func (m *mgr) GetShare(ctx context.Context, ref *collaboration.ShareReference) (*collaboration.Share, error) { - m.Lock() - defer m.Unlock() - _, s, err := m.get(ref) - if err != nil { - return nil, err - } - // check if we are the owner or the grantee - user := ctxpkg.ContextMustGetUser(ctx) - if share.IsCreatedByUser(s, user) || share.IsGrantedToUser(s, user) { - return s, nil - } - // we return not found to not disclose information - return nil, errtypes.NotFound(ref.String()) -} - -func (m *mgr) Unshare(ctx context.Context, ref *collaboration.ShareReference) error { - m.Lock() - defer m.Unlock() - user := ctxpkg.ContextMustGetUser(ctx) - - idx, s, err := m.get(ref) - if err != nil { - return err - } - if !share.IsCreatedByUser(s, user) { - return errtypes.NotFound(ref.String()) - } - - last := len(m.model.Shares) - 1 - m.model.Shares[idx] = m.model.Shares[last] - // explicitly nil the reference to prevent memory leaks - // https://github.com/golang/go/wiki/SliceTricks#delete-without-preserving-order - m.model.Shares[last] = nil - m.model.Shares = m.model.Shares[:last] - if err := m.model.Save(); err != nil { - err = errors.Wrap(err, "error saving model") - return err - } - return nil -} - -func (m *mgr) UpdateShare(ctx context.Context, ref *collaboration.ShareReference, p *collaboration.SharePermissions, updated *collaboration.Share, fieldMask *field_mask.FieldMask) (*collaboration.Share, error) { - m.Lock() - defer m.Unlock() - - var ( - idx int - toUpdate *collaboration.Share - ) - - if ref != nil { - var err error - idx, toUpdate, err = m.get(ref) - if err != nil { - return nil, err - } - } else if updated != nil { - var err error - idx, toUpdate, err = m.getByID(updated.Id) - if err != nil { - return nil, err - } - } - - if fieldMask != nil { - for i := range fieldMask.Paths { - switch fieldMask.Paths[i] { - case "permissions": - m.model.Shares[idx].Permissions = updated.Permissions - case "expiration": - m.model.Shares[idx].Expiration = updated.Expiration - case "hidden": - continue - default: - return nil, errtypes.NotSupported("updating " + fieldMask.Paths[i] + " is not supported") - } - } - } - - user := ctxpkg.ContextMustGetUser(ctx) - if !share.IsCreatedByUser(toUpdate, user) { - return nil, errtypes.NotFound(ref.String()) - } - - now := time.Now().UnixNano() - if p != nil { - m.model.Shares[idx].Permissions = p - } - m.model.Shares[idx].Mtime = &typespb.Timestamp{ - Seconds: uint64(now / int64(time.Second)), - Nanos: uint32(now % int64(time.Second)), - } - - if err := m.model.Save(); err != nil { - err = errors.Wrap(err, "error saving model") - return nil, err - } - return m.model.Shares[idx], nil -} - -func (m *mgr) ListShares(ctx context.Context, filters []*collaboration.Filter) ([]*collaboration.Share, error) { - m.Lock() - defer m.Unlock() - log := appctx.GetLogger(ctx) - user := ctxpkg.ContextMustGetUser(ctx) - - client, err := pool.GetGatewayServiceClient(m.c.GatewayAddr) - if err != nil { - return nil, errors.Wrap(err, "failed to list shares") - } - cache := make(map[string]struct{}) - var ss []*collaboration.Share - for _, s := range m.model.Shares { - if share.MatchesFilters(s, filters) { - // Only add the share if the share was created by the user or if - // the user has ListGrants permissions on the shared resource. - // The ListGrants check is necessary when a space member wants - // to list shares in a space. - // We are using a cache here so that we don't have to stat a - // resource multiple times. - key := strings.Join([]string{s.ResourceId.StorageId, s.ResourceId.OpaqueId}, "!") - if _, hit := cache[key]; !hit && !share.IsCreatedByUser(s, user) { - sRes, err := client.Stat(ctx, &provider.StatRequest{Ref: &provider.Reference{ResourceId: s.ResourceId}}) - if err != nil || sRes.Status.Code != rpcv1beta1.Code_CODE_OK { - log.Error(). - Err(err). - Interface("status", sRes.Status). - Interface("resource_id", s.ResourceId). - Msg("ListShares: could not stat resource") - continue - } - if !sRes.Info.PermissionSet.ListGrants { - continue - } - cache[key] = struct{}{} - } - ss = append(ss, s) - } - } - return ss, nil -} - -// we list the shares that are targeted to the user in context or to the user groups. -func (m *mgr) ListReceivedShares(ctx context.Context, filters []*collaboration.Filter, forUser *userv1beta1.UserId) ([]*collaboration.ReceivedShare, error) { - m.Lock() - defer m.Unlock() - - user := ctxpkg.ContextMustGetUser(ctx) - if user.GetId().GetType() == userv1beta1.UserType_USER_TYPE_SERVICE { - gwc, err := pool.GetGatewayServiceClient(m.c.GatewayAddr) - if err != nil { - return nil, errors.Wrap(err, "failed to list shares") - } - u, err := utils.GetUser(ctx, forUser, gwc) - if err != nil { - return nil, errtypes.BadRequest("user not found") - } - user = u - } - mem := make(map[string]int) - var rss []*collaboration.ReceivedShare - for _, s := range m.model.Shares { - if !share.IsCreatedByUser(s, user) && - share.IsGrantedToUser(s, user) && - share.MatchesFilters(s, filters) { - - rs := m.convert(user.Id, s) - idx, seen := mem[s.ResourceId.OpaqueId] - if !seen { - rss = append(rss, rs) - mem[s.ResourceId.OpaqueId] = len(rss) - 1 - continue - } - - // When we arrive here there was already a share for this resource. - // if there is a mix-up of shares of type group and shares of type user we need to deduplicate them, since it points - // to the same resource. Leave the more explicit and hide the less explicit. In this case we hide the group shares - // and return the user share to the user. - other := rss[idx] - if other.Share.Grantee.Type == provider.GranteeType_GRANTEE_TYPE_GROUP && s.Grantee.Type == provider.GranteeType_GRANTEE_TYPE_USER { - if other.State == rs.State { - rss[idx] = rs - } else { - rss = append(rss, rs) - } - } - } - } - - return rss, nil -} - -// convert must be called in a lock-controlled block. -func (m *mgr) convert(currentUser *userv1beta1.UserId, s *collaboration.Share) *collaboration.ReceivedShare { - rs := &collaboration.ReceivedShare{ - Share: s, - State: collaboration.ShareState_SHARE_STATE_PENDING, - } - if v, ok := m.model.State[currentUser.String()]; ok { - if state, ok := v[s.Id.String()]; ok { - rs.State = state - } - } - if v, ok := m.model.MountPoint[currentUser.String()]; ok { - if mp, ok := v[s.Id.String()]; ok { - rs.MountPoint = mp - } - } - return rs -} - -func (m *mgr) GetReceivedShare(ctx context.Context, ref *collaboration.ShareReference) (*collaboration.ReceivedShare, error) { - return m.getReceived(ctx, ref) -} - -func (m *mgr) getReceived(ctx context.Context, ref *collaboration.ShareReference) (*collaboration.ReceivedShare, error) { - m.Lock() - defer m.Unlock() - _, s, err := m.get(ref) - if err != nil { - return nil, err - } - user := ctxpkg.ContextMustGetUser(ctx) - if user.GetId().GetType() != userv1beta1.UserType_USER_TYPE_SERVICE && !share.IsGrantedToUser(s, user) { - return nil, errtypes.NotFound(ref.String()) - } - return m.convert(user.Id, s), nil -} - -func (m *mgr) UpdateReceivedShare(ctx context.Context, receivedShare *collaboration.ReceivedShare, fieldMask *field_mask.FieldMask, forUser *userv1beta1.UserId) (*collaboration.ReceivedShare, error) { - rs, err := m.getReceived(ctx, &collaboration.ShareReference{Spec: &collaboration.ShareReference_Id{Id: receivedShare.Share.Id}}) - if err != nil { - return nil, err - } - - m.Lock() - defer m.Unlock() - - for i := range fieldMask.Paths { - switch fieldMask.Paths[i] { - case "state": - rs.State = receivedShare.State - case "mount_point": - rs.MountPoint = receivedShare.MountPoint - default: - return nil, errtypes.NotSupported("updating " + fieldMask.Paths[i] + " is not supported") - } - } - - u := ctxpkg.ContextMustGetUser(ctx) - uid := u.GetId().String() - if u.GetId().GetType() == userv1beta1.UserType_USER_TYPE_SERVICE { - uid = forUser.String() - } - // Persist state - if v, ok := m.model.State[uid]; ok { - v[rs.Share.Id.String()] = rs.State - m.model.State[uid] = v - } else { - a := map[string]collaboration.ShareState{ - rs.Share.Id.String(): rs.State, - } - m.model.State[uid] = a - } - - // Persist mount point - if v, ok := m.model.MountPoint[uid]; ok { - v[rs.Share.Id.String()] = rs.MountPoint - m.model.MountPoint[uid] = v - } else { - a := map[string]*provider.Reference{ - rs.Share.Id.String(): rs.MountPoint, - } - m.model.MountPoint[uid] = a - } - - if err := m.model.Save(); err != nil { - err = errors.Wrap(err, "error saving model") - return nil, err - } - - return rs, nil -} diff --git a/vendor/github.com/opencloud-eu/reva/v2/pkg/share/manager/loader/loader.go b/vendor/github.com/opencloud-eu/reva/v2/pkg/share/manager/loader/loader.go index c6ef3e18bd..e5b7c425be 100644 --- a/vendor/github.com/opencloud-eu/reva/v2/pkg/share/manager/loader/loader.go +++ b/vendor/github.com/opencloud-eu/reva/v2/pkg/share/manager/loader/loader.go @@ -20,9 +20,7 @@ package loader import ( // Load core share manager drivers. - _ "github.com/opencloud-eu/reva/v2/pkg/share/manager/json" _ "github.com/opencloud-eu/reva/v2/pkg/share/manager/jsoncs3" _ "github.com/opencloud-eu/reva/v2/pkg/share/manager/memory" - _ "github.com/opencloud-eu/reva/v2/pkg/share/manager/owncloudsql" // Add your own here ) diff --git a/vendor/github.com/opencloud-eu/reva/v2/pkg/share/manager/owncloudsql/conversions.go b/vendor/github.com/opencloud-eu/reva/v2/pkg/share/manager/owncloudsql/conversions.go deleted file mode 100644 index 7fc7a78123..0000000000 --- a/vendor/github.com/opencloud-eu/reva/v2/pkg/share/manager/owncloudsql/conversions.go +++ /dev/null @@ -1,300 +0,0 @@ -// 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 owncloudsql - -import ( - "context" - "strings" - "time" - - grouppb "github.com/cs3org/go-cs3apis/cs3/identity/group/v1beta1" - userpb "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1" - rpc "github.com/cs3org/go-cs3apis/cs3/rpc/v1beta1" - collaboration "github.com/cs3org/go-cs3apis/cs3/sharing/collaboration/v1beta1" - provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1" - typespb "github.com/cs3org/go-cs3apis/cs3/types/v1beta1" - "github.com/jellydator/ttlcache/v2" - "github.com/opencloud-eu/reva/v2/pkg/conversions" - "github.com/opencloud-eu/reva/v2/pkg/rgrpc/status" - "github.com/opencloud-eu/reva/v2/pkg/rgrpc/todo/pool" - "github.com/opencloud-eu/reva/v2/pkg/utils" -) - -// DBShare stores information about user and public shares. -type DBShare struct { - ID string - UIDOwner string - UIDInitiator string - ItemStorage string - FileSource string - ShareWith string - Token string - Expiration string - Permissions int - ShareType int - ShareName string - STime int - FileTarget string - RejectedBy string - State int - Parent int -} - -// UserConverter describes an interface for converting user ids to names and back -type UserConverter interface { - UserNameToUserID(ctx context.Context, username string) (*userpb.UserId, error) - UserIDToUserName(ctx context.Context, userid *userpb.UserId) (string, error) - GetUser(ctx context.Context, userid *userpb.UserId) (*userpb.User, error) -} - -// GatewayUserConverter converts usernames and ids using the gateway -type GatewayUserConverter struct { - gwAddr string - - IDCache *ttlcache.Cache - NameCache *ttlcache.Cache -} - -// NewGatewayUserConverter returns a instance of GatewayUserConverter -func NewGatewayUserConverter(gwAddr string) *GatewayUserConverter { - IDCache := ttlcache.NewCache() - _ = IDCache.SetTTL(30 * time.Second) - IDCache.SkipTTLExtensionOnHit(true) - NameCache := ttlcache.NewCache() - _ = NameCache.SetTTL(30 * time.Second) - NameCache.SkipTTLExtensionOnHit(true) - - return &GatewayUserConverter{ - gwAddr: gwAddr, - IDCache: IDCache, - NameCache: NameCache, - } -} - -// UserIDToUserName converts a user ID to an username -func (c *GatewayUserConverter) UserIDToUserName(ctx context.Context, userid *userpb.UserId) (string, error) { - username, err := c.NameCache.Get(userid.String()) - if err == nil { - return username.(string), nil - } - - gwConn, err := pool.GetGatewayServiceClient(c.gwAddr) - if err != nil { - return "", err - } - getUserResponse, err := gwConn.GetUser(ctx, &userpb.GetUserRequest{ - UserId: userid, - SkipFetchingUserGroups: true, - }) - if err != nil { - return "", err - } - if getUserResponse.Status.Code != rpc.Code_CODE_OK { - return "", status.NewErrorFromCode(getUserResponse.Status.Code, "gateway") - } - _ = c.NameCache.Set(userid.String(), getUserResponse.User.Username) - return getUserResponse.User.Username, nil -} - -// UserNameToUserID converts a username to an user ID -func (c *GatewayUserConverter) UserNameToUserID(ctx context.Context, username string) (*userpb.UserId, error) { - id, err := c.IDCache.Get(username) - if err == nil { - return id.(*userpb.UserId), nil - } - - gwConn, err := pool.GetGatewayServiceClient(c.gwAddr) - if err != nil { - return nil, err - } - getUserResponse, err := gwConn.GetUserByClaim(ctx, &userpb.GetUserByClaimRequest{ - Claim: "username", - Value: username, - SkipFetchingUserGroups: true, - }) - if err != nil { - return nil, err - } - if getUserResponse.Status.Code != rpc.Code_CODE_OK { - return nil, status.NewErrorFromCode(getUserResponse.Status.Code, "gateway") - } - _ = c.IDCache.Set(username, getUserResponse.User.Id) - return getUserResponse.User.Id, nil -} - -// GetUser gets the user -func (c *GatewayUserConverter) GetUser(ctx context.Context, userid *userpb.UserId) (*userpb.User, error) { - gwc, err := pool.GetGatewayServiceClient(c.gwAddr) - if err != nil { - return nil, err - } - return utils.GetUser(ctx, userid, gwc) -} - -func (m *mgr) formatGrantee(ctx context.Context, g *provider.Grantee) (int, string, error) { - var granteeType int - var formattedID string - switch g.Type { - case provider.GranteeType_GRANTEE_TYPE_USER: - granteeType = 0 - var err error - formattedID, err = m.userConverter.UserIDToUserName(ctx, g.GetUserId()) - if err != nil { - return 0, "", err - } - case provider.GranteeType_GRANTEE_TYPE_GROUP: - granteeType = 1 - formattedID = formatGroupID(g.GetGroupId()) - default: - granteeType = -1 - } - return granteeType, formattedID, nil -} - -func (m *mgr) extractGrantee(ctx context.Context, t int, g string) (*provider.Grantee, error) { - var grantee provider.Grantee - switch t { - case 0: - userid, err := m.userConverter.UserNameToUserID(ctx, g) - if err != nil { - return nil, err - } - grantee.Type = provider.GranteeType_GRANTEE_TYPE_USER - grantee.Id = &provider.Grantee_UserId{UserId: userid} - case 1, 2: - grantee.Type = provider.GranteeType_GRANTEE_TYPE_GROUP - grantee.Id = &provider.Grantee_GroupId{GroupId: extractGroupID(g)} - default: - grantee.Type = provider.GranteeType_GRANTEE_TYPE_INVALID - } - return &grantee, nil -} - -func resourceTypeToItem(r provider.ResourceType) string { - switch r { - case provider.ResourceType_RESOURCE_TYPE_FILE: - return "file" - case provider.ResourceType_RESOURCE_TYPE_CONTAINER: - return "folder" - case provider.ResourceType_RESOURCE_TYPE_REFERENCE: - return "reference" - case provider.ResourceType_RESOURCE_TYPE_SYMLINK: - return "symlink" - default: - return "" - } -} - -func sharePermToInt(p *provider.ResourcePermissions) int { - return int(conversions.RoleFromResourcePermissions(p, false).OCSPermissions()) -} - -func intTosharePerm(p int) (*provider.ResourcePermissions, error) { - perms, err := conversions.NewPermissions(p) - if err != nil { - return nil, err - } - - return conversions.RoleFromOCSPermissions(perms, nil).CS3ResourcePermissions(), nil -} - -func intToShareState(g int) collaboration.ShareState { - switch g { - case 0: - return collaboration.ShareState_SHARE_STATE_ACCEPTED - case 1: - return collaboration.ShareState_SHARE_STATE_PENDING - case 2: - return collaboration.ShareState_SHARE_STATE_REJECTED - default: - return collaboration.ShareState_SHARE_STATE_INVALID - } -} - -func formatUserID(u *userpb.UserId) string { - return u.OpaqueId -} - -func formatGroupID(u *grouppb.GroupId) string { - return u.OpaqueId -} - -func extractGroupID(u string) *grouppb.GroupId { - return &grouppb.GroupId{OpaqueId: u} -} - -func (m *mgr) convertToCS3Share(ctx context.Context, s DBShare, storageMountID string) (*collaboration.Share, error) { - ts := &typespb.Timestamp{ - Seconds: uint64(s.STime), - } - permissions, err := intTosharePerm(s.Permissions) - if err != nil { - return nil, err - } - grantee, err := m.extractGrantee(ctx, s.ShareType, s.ShareWith) - if err != nil { - return nil, err - } - owner, err := m.userConverter.UserNameToUserID(ctx, s.UIDOwner) - if err != nil { - return nil, err - } - var creator *userpb.UserId - if s.UIDOwner == s.UIDInitiator { - creator = owner - } else { - creator, err = m.userConverter.UserNameToUserID(ctx, s.UIDOwner) - if err != nil { - return nil, err - } - } - return &collaboration.Share{ - Id: &collaboration.ShareId{ - OpaqueId: s.ID, - }, - ResourceId: &provider.ResourceId{ - SpaceId: s.ItemStorage, - OpaqueId: s.FileSource, - }, - Permissions: &collaboration.SharePermissions{Permissions: permissions}, - Grantee: grantee, - Owner: owner, - Creator: creator, - Ctime: ts, - Mtime: ts, - }, nil -} - -func (m *mgr) convertToCS3ReceivedShare(ctx context.Context, s DBShare, storageMountID string) (*collaboration.ReceivedShare, error) { - share, err := m.convertToCS3Share(ctx, s, storageMountID) - if err != nil { - return nil, err - } - var state collaboration.ShareState - if s.RejectedBy != "" { - state = collaboration.ShareState_SHARE_STATE_REJECTED - } else { - state = intToShareState(s.State) - } - return &collaboration.ReceivedShare{ - Share: share, - State: state, - MountPoint: &provider.Reference{Path: strings.TrimLeft(s.FileTarget, "/")}, - }, nil -} diff --git a/vendor/github.com/opencloud-eu/reva/v2/pkg/share/manager/owncloudsql/owncloudsql.go b/vendor/github.com/opencloud-eu/reva/v2/pkg/share/manager/owncloudsql/owncloudsql.go deleted file mode 100644 index f836c6ba7f..0000000000 --- a/vendor/github.com/opencloud-eu/reva/v2/pkg/share/manager/owncloudsql/owncloudsql.go +++ /dev/null @@ -1,674 +0,0 @@ -// 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 owncloudsql - -import ( - "context" - "database/sql" - "fmt" - "path" - "strconv" - "strings" - "time" - - userpb "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1" - collaboration "github.com/cs3org/go-cs3apis/cs3/sharing/collaboration/v1beta1" - provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1" - typespb "github.com/cs3org/go-cs3apis/cs3/types/v1beta1" - "github.com/mitchellh/mapstructure" - ctxpkg "github.com/opencloud-eu/reva/v2/pkg/ctx" - "github.com/opencloud-eu/reva/v2/pkg/errtypes" - "github.com/opencloud-eu/reva/v2/pkg/share" - "github.com/opencloud-eu/reva/v2/pkg/share/manager/registry" - "github.com/opencloud-eu/reva/v2/pkg/utils" - "github.com/pkg/errors" - "google.golang.org/genproto/protobuf/field_mask" - - // Provides mysql drivers - _ "github.com/go-sql-driver/mysql" -) - -const ( - shareTypeUser = 0 - shareTypeGroup = 1 -) - -func init() { - registry.Register("owncloudsql", NewMysql) -} - -type config struct { - GatewayAddr string `mapstructure:"gateway_addr"` - StorageMountID string `mapstructure:"storage_mount_id"` - DbUsername string `mapstructure:"db_username"` - DbPassword string `mapstructure:"db_password"` - DbHost string `mapstructure:"db_host"` - DbPort int `mapstructure:"db_port"` - DbName string `mapstructure:"db_name"` -} - -type mgr struct { - driver string - db *sql.DB - storageMountID string - userConverter UserConverter -} - -// NewMysql returns a new share manager connection to a mysql database -func NewMysql(m map[string]interface{}) (share.Manager, error) { - c, err := parseConfig(m) - if err != nil { - err = errors.Wrap(err, "error creating a new manager") - return nil, err - } - - db, err := sql.Open("mysql", fmt.Sprintf("%s:%s@tcp(%s:%d)/%s", c.DbUsername, c.DbPassword, c.DbHost, c.DbPort, c.DbName)) - if err != nil { - return nil, err - } - - userConverter := NewGatewayUserConverter(c.GatewayAddr) - - return New("mysql", db, c.StorageMountID, userConverter) -} - -// New returns a new Cache instance connecting to the given sql.DB -func New(driver string, db *sql.DB, storageMountID string, userConverter UserConverter) (share.Manager, error) { - return &mgr{ - driver: driver, - db: db, - storageMountID: storageMountID, - userConverter: userConverter, - }, nil -} - -func parseConfig(m map[string]interface{}) (*config, error) { - c := &config{} - if err := mapstructure.Decode(m, c); err != nil { - return nil, err - } - return c, nil -} - -func (m *mgr) Share(ctx context.Context, md *provider.ResourceInfo, g *collaboration.ShareGrant) (*collaboration.Share, error) { - user := ctxpkg.ContextMustGetUser(ctx) - - // do not allow share to myself or the owner if share is for a user - // TODO(labkode): should not this be caught already at the gw level? - if g.Grantee.Type == provider.GranteeType_GRANTEE_TYPE_USER && - (utils.UserEqual(g.Grantee.GetUserId(), user.Id) || utils.UserEqual(g.Grantee.GetUserId(), md.Owner)) { - return nil, errtypes.BadRequest("owncloudsql: owner/creator and grantee are the same") - } - - // check if share already exists. - key := &collaboration.ShareKey{ - Owner: md.Owner, - ResourceId: md.Id, - Grantee: g.Grantee, - } - _, err := m.getByKey(ctx, key) - - // share already exists - if err == nil { - return nil, errtypes.AlreadyExists(key.String()) - } - - now := time.Now().Unix() - ts := &typespb.Timestamp{ - Seconds: uint64(now), - } - - owner, err := m.userConverter.UserIDToUserName(ctx, md.Owner) - if err != nil { - return nil, err - } - shareType, shareWith, err := m.formatGrantee(ctx, g.Grantee) - if err != nil { - return nil, err - } - itemType := resourceTypeToItem(md.Type) - targetPath := path.Join("/", path.Base(md.Path)) - permissions := sharePermToInt(g.Permissions.Permissions) - itemSource := md.Id.OpaqueId - fileSource, err := strconv.ParseUint(itemSource, 10, 64) - if err != nil { - // it can be the case that the item source may be a character string - // we leave fileSource blank in that case - fileSource = 0 - } - - stmtString := "INSERT INTO oc_share (share_type,uid_owner,uid_initiator,item_type,item_source,file_source,permissions,stime,share_with,file_target) VALUES (?,?,?,?,?,?,?,?,?,?)" - stmtValues := []interface{}{shareType, owner, user.Username, itemType, itemSource, fileSource, permissions, now, shareWith, targetPath} - - stmt, err := m.db.Prepare(stmtString) - if err != nil { - return nil, err - } - result, err := stmt.ExecContext(ctx, stmtValues...) - if err != nil { - return nil, err - } - lastID, err := result.LastInsertId() - if err != nil { - return nil, err - } - - return &collaboration.Share{ - Id: &collaboration.ShareId{ - OpaqueId: strconv.FormatInt(lastID, 10), - }, - ResourceId: md.Id, - Permissions: g.Permissions, - Grantee: g.Grantee, - Owner: md.Owner, - Creator: user.Id, - Ctime: ts, - Mtime: ts, - }, nil -} - -func (m *mgr) GetShare(ctx context.Context, ref *collaboration.ShareReference) (*collaboration.Share, error) { - var s *collaboration.Share - var err error - switch { - case ref.GetId() != nil: - s, err = m.getByID(ctx, ref.GetId()) - case ref.GetKey() != nil: - s, err = m.getByKey(ctx, ref.GetKey()) - default: - err = errtypes.NotFound(ref.String()) - } - - if err != nil { - return nil, err - } - - return s, nil -} - -func (m *mgr) Unshare(ctx context.Context, ref *collaboration.ShareReference) error { - uid := ctxpkg.ContextMustGetUser(ctx).Username - var query string - params := []interface{}{} - switch { - case ref.GetId() != nil: - query = "DELETE FROM oc_share where id=? AND (uid_owner=? or uid_initiator=?)" - params = append(params, ref.GetId().OpaqueId, uid, uid) - case ref.GetKey() != nil: - key := ref.GetKey() - shareType, shareWith, err := m.formatGrantee(ctx, key.Grantee) - if err != nil { - return err - } - owner := formatUserID(key.Owner) - query = "DELETE FROM oc_share WHERE uid_owner=? AND file_source=? AND share_type=? AND share_with=? AND (uid_owner=? or uid_initiator=?)" - params = append(params, owner, key.ResourceId.OpaqueId, shareType, shareWith, uid, uid) - default: - return errtypes.NotFound(ref.String()) - } - - stmt, err := m.db.Prepare(query) - if err != nil { - return err - } - res, err := stmt.ExecContext(ctx, params...) - if err != nil { - return err - } - - rowCnt, err := res.RowsAffected() - if err != nil { - return err - } - if rowCnt == 0 { - return errtypes.NotFound(ref.String()) - } - return nil -} - -func (m *mgr) UpdateShare(ctx context.Context, ref *collaboration.ShareReference, p *collaboration.SharePermissions, updated *collaboration.Share, fieldMask *field_mask.FieldMask) (*collaboration.Share, error) { - permissions := sharePermToInt(p.Permissions) - uid := ctxpkg.ContextMustGetUser(ctx).Username - - var query string - params := []interface{}{} - switch { - case ref.GetId() != nil: - query = "update oc_share set permissions=?,stime=? where id=? AND (uid_owner=? or uid_initiator=?)" - params = append(params, permissions, time.Now().Unix(), ref.GetId().OpaqueId, uid, uid) - case ref.GetKey() != nil: - key := ref.GetKey() - shareType, shareWith, err := m.formatGrantee(ctx, key.Grantee) - if err != nil { - return nil, err - } - owner := formatUserID(key.Owner) - query = "update oc_share set permissions=?,stime=? where (uid_owner=? or uid_initiator=?) AND file_source=? AND share_type=? AND share_with=? AND (uid_owner=? or uid_initiator=?)" - params = append(params, permissions, time.Now().Unix(), owner, owner, key.ResourceId.OpaqueId, shareType, shareWith, uid, uid) - default: - return nil, errtypes.NotFound(ref.String()) - } - - stmt, err := m.db.Prepare(query) - if err != nil { - return nil, err - } - if _, err = stmt.ExecContext(ctx, params...); err != nil { - return nil, err - } - - return m.GetShare(ctx, ref) -} - -func (m *mgr) ListShares(ctx context.Context, filters []*collaboration.Filter) ([]*collaboration.Share, error) { - uid := ctxpkg.ContextMustGetUser(ctx).Username - query := ` - SELECT - coalesce(s.uid_owner, '') as uid_owner, coalesce(s.uid_initiator, '') as uid_initiator, - coalesce(s.share_with, '') as share_with, coalesce(s.file_source, '') as file_source, - s.file_target, s.id, s.stime, s.permissions, s.share_type, fc.storage as storage - FROM oc_share s - LEFT JOIN oc_filecache fc ON fc.fileid = file_source - WHERE (uid_owner=? or uid_initiator=?) - ` - params := []interface{}{uid, uid} - - var ( - filterQuery string - filterParams []interface{} - err error - ) - if len(filters) == 0 { - filterQuery += "(share_type=? OR share_type=?)" - params = append(params, shareTypeUser) - params = append(params, shareTypeGroup) - } else { - filterQuery, filterParams, err = translateFilters(filters) - if err != nil { - return nil, err - } - params = append(params, filterParams...) - } - - if filterQuery != "" { - query = fmt.Sprintf("%s AND (%s)", query, filterQuery) - } - - rows, err := m.db.QueryContext(ctx, query, params...) - if err != nil { - return nil, err - } - defer rows.Close() - - var s DBShare - shares := []*collaboration.Share{} - for rows.Next() { - if err := rows.Scan(&s.UIDOwner, &s.UIDInitiator, &s.ShareWith, &s.FileSource, &s.FileTarget, &s.ID, &s.STime, &s.Permissions, &s.ShareType, &s.ItemStorage); err != nil { - continue - } - share, err := m.convertToCS3Share(ctx, s, m.storageMountID) - if err != nil { - return nil, err - } - shares = append(shares, share) - } - if err = rows.Err(); err != nil { - return nil, err - } - - return shares, nil -} - -// we list the shares that are targeted to the user in context or to the user groups. -func (m *mgr) ListReceivedShares(ctx context.Context, filters []*collaboration.Filter, forUser *userpb.UserId) ([]*collaboration.ReceivedShare, error) { - user := ctxpkg.ContextMustGetUser(ctx) - if user.GetId().GetType() == userpb.UserType_USER_TYPE_SERVICE { - u, err := m.userConverter.GetUser(ctx, forUser) - if err != nil { - return nil, errtypes.BadRequest("user not found") - } - user = u - } - uid := user.Username - - params := []interface{}{uid, uid, uid} - for _, v := range user.Groups { - params = append(params, v) - } - - homeConcat := "" - if m.driver == "mysql" { // mysql concat - homeConcat = "storages.id = CONCAT('home::', s.uid_owner)" - } else { // sqlite3 concat - homeConcat = "storages.id = 'home::' || s.uid_owner" - } - userSelect := "" - if len(user.Groups) > 0 { - userSelect = "AND ((share_type != 1 AND share_with=?) OR (share_type = 1 AND share_with in (?" + strings.Repeat(",?", len(user.Groups)-1) + ")))" - } else { - userSelect = "AND (share_type != 1 AND share_with=?)" - } - query := ` - WITH results AS - ( - SELECT s.*, storages.numeric_id FROM oc_share s - LEFT JOIN oc_storages storages ON ` + homeConcat + ` - WHERE (uid_owner != ? AND uid_initiator != ?) ` + userSelect + ` - ) - SELECT COALESCE(r.uid_owner, '') AS uid_owner, COALESCE(r.uid_initiator, '') AS uid_initiator, COALESCE(r.share_with, '') - AS share_with, COALESCE(r.file_source, '') AS file_source, COALESCE(r2.file_target, r.file_target), r.id, r.stime, r.permissions, r.share_type, COALESCE(r2.accepted, r.accepted), - r.numeric_id, COALESCE(r.parent, -1) AS parent FROM results r LEFT JOIN results r2 ON r.id = r2.parent WHERE r.parent IS NULL` - - filterQuery, filterParams, err := translateFilters(filters) - if err != nil { - return nil, err - } - params = append(params, filterParams...) - - if filterQuery != "" { - query = fmt.Sprintf("%s AND (%s)", query, filterQuery) - } - query += ";" - rows, err := m.db.QueryContext(ctx, query, params...) - if err != nil { - return nil, err - } - defer rows.Close() - - var s DBShare - shares := []*collaboration.ReceivedShare{} - for rows.Next() { - if err := rows.Scan(&s.UIDOwner, &s.UIDInitiator, &s.ShareWith, &s.FileSource, &s.FileTarget, &s.ID, &s.STime, &s.Permissions, &s.ShareType, &s.State, &s.ItemStorage, &s.Parent); err != nil { - continue - } - share, err := m.convertToCS3ReceivedShare(ctx, s, m.storageMountID) - if err != nil { - return nil, err - } - shares = append(shares, share) - } - if err = rows.Err(); err != nil { - return nil, err - } - - return shares, nil -} - -func (m *mgr) GetReceivedShare(ctx context.Context, ref *collaboration.ShareReference) (*collaboration.ReceivedShare, error) { - var s *collaboration.ReceivedShare - var err error - switch { - case ref.GetId() != nil: - s, err = m.getReceivedByID(ctx, ref.GetId()) - case ref.GetKey() != nil: - s, err = m.getReceivedByKey(ctx, ref.GetKey()) - default: - err = errtypes.NotFound(ref.String()) - } - - if err != nil { - return nil, err - } - - return s, nil - -} - -func (m *mgr) UpdateReceivedShare(ctx context.Context, receivedShare *collaboration.ReceivedShare, fieldMask *field_mask.FieldMask, _ *userpb.UserId) (*collaboration.ReceivedShare, error) { - // TODO: How to inject the uid when a UserId is set? override it in the ctx? Add parameter to GetReceivedShare? - rs, err := m.GetReceivedShare(ctx, &collaboration.ShareReference{Spec: &collaboration.ShareReference_Id{Id: receivedShare.Share.Id}}) - if err != nil { - return nil, err - } - - fields := []string{} - params := []interface{}{} - for i := range fieldMask.Paths { - switch fieldMask.Paths[i] { - case "state": - rs.State = receivedShare.State - fields = append(fields, "accepted=?") - switch rs.State { - case collaboration.ShareState_SHARE_STATE_REJECTED: - params = append(params, 2) - case collaboration.ShareState_SHARE_STATE_ACCEPTED: - params = append(params, 0) - } - case "mount_point": - fields = append(fields, "file_target=?") - rs.MountPoint = receivedShare.MountPoint - params = append(params, rs.MountPoint.Path) - case "hidden": - continue - default: - return nil, errtypes.NotSupported("updating " + fieldMask.Paths[i] + " is not supported") - } - } - - if len(fields) == 0 { - return nil, fmt.Errorf("no valid field provided in the fieldmask") - } - - updateReceivedShare := func(column string) error { - query := "update oc_share set " - query += strings.Join(fields, ",") - query += fmt.Sprintf(" where %s=?", column) - params := append(params, rs.Share.Id.OpaqueId) - - stmt, err := m.db.Prepare(query) - if err != nil { - return err - } - res, err := stmt.ExecContext(ctx, params...) - if err != nil { - return err - } - affected, err := res.RowsAffected() - if err != nil { - return err - } - if affected < 1 { - return fmt.Errorf("no rows updated") - } - return nil - } - err = updateReceivedShare("parent") // Try to update the child state in case of group shares first - if err != nil { - err = updateReceivedShare("id") - } - if err != nil { - return nil, err - } - - return rs, nil -} - -func (m *mgr) getByID(ctx context.Context, id *collaboration.ShareId) (*collaboration.Share, error) { - uid := ctxpkg.ContextMustGetUser(ctx).Username - s := DBShare{ID: id.OpaqueId} - query := "select coalesce(uid_owner, '') as uid_owner, coalesce(uid_initiator, '') as uid_initiator, coalesce(share_with, '') as share_with, coalesce(file_source, '') as file_source, file_target, stime, permissions, share_type FROM oc_share WHERE id=? AND (uid_owner=? or uid_initiator=?)" - if err := m.db.QueryRowContext(ctx, query, id.OpaqueId, uid, uid).Scan(&s.UIDOwner, &s.UIDInitiator, &s.ShareWith, &s.FileSource, &s.FileTarget, &s.STime, &s.Permissions, &s.ShareType); err != nil { - if err == sql.ErrNoRows { - return nil, errtypes.NotFound(id.OpaqueId) - } - return nil, err - } - return m.convertToCS3Share(ctx, s, m.storageMountID) -} - -func (m *mgr) getByKey(ctx context.Context, key *collaboration.ShareKey) (*collaboration.Share, error) { - owner, err := m.userConverter.UserIDToUserName(ctx, key.Owner) - if err != nil { - return nil, err - } - uid := ctxpkg.ContextMustGetUser(ctx).Username - - s := DBShare{} - shareType, shareWith, err := m.formatGrantee(ctx, key.Grantee) - if err != nil { - return nil, err - } - query := "select coalesce(uid_owner, '') as uid_owner, coalesce(uid_initiator, '') as uid_initiator, coalesce(share_with, '') as share_with, coalesce(file_source, '') as file_source, file_target, id, stime, permissions, share_type FROM oc_share WHERE uid_owner=? AND file_source=? AND share_type=? AND share_with=? AND (uid_owner=? or uid_initiator=?)" - if err = m.db.QueryRowContext(ctx, query, owner, key.ResourceId.StorageId, shareType, shareWith, uid, uid).Scan(&s.UIDOwner, &s.UIDInitiator, &s.ShareWith, &s.FileSource, &s.FileTarget, &s.ID, &s.STime, &s.Permissions, &s.ShareType); err != nil { - if err == sql.ErrNoRows { - return nil, errtypes.NotFound(key.String()) - } - return nil, err - } - return m.convertToCS3Share(ctx, s, m.storageMountID) -} - -func (m *mgr) getReceivedByID(ctx context.Context, id *collaboration.ShareId) (*collaboration.ReceivedShare, error) { - user := ctxpkg.ContextMustGetUser(ctx) - uid := user.Username - - params := []interface{}{id.OpaqueId, id.OpaqueId, uid} //nolint:prealloc - for _, v := range user.Groups { - params = append(params, v) - } - - homeConcat := "" - if m.driver == "mysql" { // mysql concat - homeConcat = "storages.id = CONCAT('home::', s.uid_owner)" - } else { // sqlite3 concat - homeConcat = "storages.id = 'home::' || s.uid_owner" - } - userSelect := "" - if len(user.Groups) > 0 { - userSelect = "AND ((share_type != 1 AND share_with=?) OR (share_type = 1 AND share_with in (?" + strings.Repeat(",?", len(user.Groups)-1) + ")))" - } else { - userSelect = "AND (share_type != 1 AND share_with=?)" - } - - query := ` - WITH results AS - ( - SELECT s.*, storages.numeric_id - FROM oc_share s - LEFT JOIN oc_storages storages ON ` + homeConcat + ` - WHERE s.id=? OR s.parent=? ` + userSelect + ` - ) - SELECT COALESCE(r.uid_owner, '') AS uid_owner, COALESCE(r.uid_initiator, '') AS uid_initiator, COALESCE(r.share_with, '') - AS share_with, COALESCE(r.file_source, '') AS file_source, COALESCE(r2.file_target, r.file_target), r.id, r.stime, r.permissions, r.share_type, COALESCE(r2.accepted, r.accepted), - r.numeric_id, COALESCE(r.parent, -1) AS parent - FROM results r - LEFT JOIN results r2 ON r.id = r2.parent - WHERE r.parent IS NULL; - ` - - s := DBShare{} - if err := m.db.QueryRowContext(ctx, query, params...).Scan(&s.UIDOwner, &s.UIDInitiator, &s.ShareWith, &s.FileSource, &s.FileTarget, &s.ID, &s.STime, &s.Permissions, &s.ShareType, &s.State, &s.ItemStorage, &s.Parent); err != nil { - if err == sql.ErrNoRows { - return nil, errtypes.NotFound(id.OpaqueId) - } - return nil, err - } - return m.convertToCS3ReceivedShare(ctx, s, m.storageMountID) -} - -func (m *mgr) getReceivedByKey(ctx context.Context, key *collaboration.ShareKey) (*collaboration.ReceivedShare, error) { - user := ctxpkg.ContextMustGetUser(ctx) - uid := user.Username - - shareType, shareWith, err := m.formatGrantee(ctx, key.Grantee) - if err != nil { - return nil, err - } - params := []interface{}{uid, formatUserID(key.Owner), key.ResourceId.StorageId, key.ResourceId.OpaqueId, shareType, shareWith, shareWith} - for _, v := range user.Groups { - params = append(params, v) - } - - s := DBShare{} - query := "select coalesce(uid_owner, '') as uid_owner, coalesce(uid_initiator, '') as uid_initiator, coalesce(share_with, '') as share_with, coalesce(file_source, '') as file_source, file_target, ts.id, stime, permissions, share_type, accepted FROM oc_share ts WHERE uid_owner=? AND file_source=? AND share_type=? AND share_with=? " - if len(user.Groups) > 0 { - query += "AND (share_with=? OR share_with in (?" + strings.Repeat(",?", len(user.Groups)-1) + "))" - } else { - query += "AND (share_with=?)" - } - - if err := m.db.QueryRowContext(ctx, query, params...).Scan(&s.UIDOwner, &s.UIDInitiator, &s.ShareWith, &s.FileSource, &s.FileTarget, &s.ID, &s.STime, &s.Permissions, &s.ShareType, &s.State); err != nil { - if err == sql.ErrNoRows { - return nil, errtypes.NotFound(key.String()) - } - return nil, err - } - return m.convertToCS3ReceivedShare(ctx, s, m.storageMountID) -} - -func granteeTypeToShareType(granteeType provider.GranteeType) int { - switch granteeType { - case provider.GranteeType_GRANTEE_TYPE_USER: - return shareTypeUser - case provider.GranteeType_GRANTEE_TYPE_GROUP: - return shareTypeGroup - } - return -1 -} - -// translateFilters translates the filters to sql queries -func translateFilters(filters []*collaboration.Filter) (string, []interface{}, error) { - var ( - filterQuery string - params []interface{} - ) - - groupedFilters := share.GroupFiltersByType(filters) - // If multiple filters of the same type are passed to this function, they need to be combined with the `OR` operator. - // That is why the filters got grouped by type. - // For every given filter type, iterate over the filters and if there are more than one combine them. - // Combine the different filter types using `AND` - var filterCounter = 0 - for filterType, filters := range groupedFilters { - switch filterType { - case collaboration.Filter_TYPE_RESOURCE_ID: - filterQuery += "(" - for i, f := range filters { - filterQuery += "file_source=?" - params = append(params, f.GetResourceId().OpaqueId) - - if i != len(filters)-1 { - filterQuery += " OR " - } - } - filterQuery += ")" - case collaboration.Filter_TYPE_GRANTEE_TYPE: - filterQuery += "(" - for i, f := range filters { - filterQuery += "r.share_type=?" - params = append(params, granteeTypeToShareType(f.GetGranteeType())) - - if i != len(filters)-1 { - filterQuery += " OR " - } - } - filterQuery += ")" - case collaboration.Filter_TYPE_EXCLUDE_DENIALS: - // TODO this may change once the mapping of permission to share types is completed (cf. pkg/cbox/utils/conversions.go) - filterQuery += "r.permissions > 0" - default: - return "", nil, fmt.Errorf("filter type is not supported") - } - if filterCounter != len(groupedFilters)-1 { - filterQuery += " AND " - } - filterCounter++ - } - return filterQuery, params, nil -} diff --git a/vendor/github.com/opencloud-eu/reva/v2/pkg/share/manager/owncloudsql/test.db b/vendor/github.com/opencloud-eu/reva/v2/pkg/share/manager/owncloudsql/test.db deleted file mode 100644 index fba76fdcc4..0000000000 Binary files a/vendor/github.com/opencloud-eu/reva/v2/pkg/share/manager/owncloudsql/test.db and /dev/null differ diff --git a/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/favorite/favorite.go b/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/favorite/favorite.go deleted file mode 100644 index 73a8bebd8a..0000000000 --- a/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/favorite/favorite.go +++ /dev/null @@ -1,36 +0,0 @@ -// 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 favorite - -import ( - "context" - - user "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1" - provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1" -) - -// Manager defines an interface for a favorites manager. -type Manager interface { - // ListFavorites returns all resources that were favorited by a user. - ListFavorites(ctx context.Context, userID *user.UserId) ([]*provider.ResourceId, error) - // SetFavorite marks a resource as favorited by a user. - SetFavorite(ctx context.Context, userID *user.UserId, resourceInfo *provider.ResourceInfo) error - // UnsetFavorite unmarks a resource as favorited by a user. - UnsetFavorite(ctx context.Context, userID *user.UserId, resourceInfo *provider.ResourceInfo) error -} diff --git a/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/favorite/loader/loader.go b/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/favorite/loader/loader.go deleted file mode 100644 index e9e6c59a78..0000000000 --- a/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/favorite/loader/loader.go +++ /dev/null @@ -1,25 +0,0 @@ -// 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 loader - -import ( - // Load share cache drivers. - _ "github.com/opencloud-eu/reva/v2/pkg/storage/favorite/memory" - // Add your own here -) diff --git a/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/favorite/memory/memory.go b/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/favorite/memory/memory.go deleted file mode 100644 index d0ffb4358b..0000000000 --- a/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/favorite/memory/memory.go +++ /dev/null @@ -1,70 +0,0 @@ -// 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 memory - -import ( - "context" - "sync" - - user "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1" - provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1" - "github.com/opencloud-eu/reva/v2/pkg/storage/favorite" - "github.com/opencloud-eu/reva/v2/pkg/storage/favorite/registry" -) - -func init() { - registry.Register("memory", New) -} - -type mgr struct { - sync.RWMutex - favorites map[string]map[string]*provider.ResourceId -} - -// New returns an instance of the in-memory favorites manager. -func New(m map[string]interface{}) (favorite.Manager, error) { - return &mgr{favorites: make(map[string]map[string]*provider.ResourceId)}, nil -} - -func (m *mgr) ListFavorites(_ context.Context, userID *user.UserId) ([]*provider.ResourceId, error) { - m.RLock() - defer m.RUnlock() - favorites := make([]*provider.ResourceId, 0, len(m.favorites[userID.OpaqueId])) - for _, id := range m.favorites[userID.OpaqueId] { - favorites = append(favorites, id) - } - return favorites, nil -} - -func (m *mgr) SetFavorite(_ context.Context, userID *user.UserId, resourceInfo *provider.ResourceInfo) error { - m.Lock() - defer m.Unlock() - if m.favorites[userID.OpaqueId] == nil { - m.favorites[userID.OpaqueId] = make(map[string]*provider.ResourceId) - } - m.favorites[userID.OpaqueId][resourceInfo.Id.OpaqueId] = resourceInfo.Id - return nil -} - -func (m *mgr) UnsetFavorite(_ context.Context, userID *user.UserId, resourceInfo *provider.ResourceInfo) error { - m.Lock() - defer m.Unlock() - delete(m.favorites[userID.OpaqueId], resourceInfo.Id.OpaqueId) - return nil -} diff --git a/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/favorite/registry/registry.go b/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/favorite/registry/registry.go deleted file mode 100644 index be4e9ae37d..0000000000 --- a/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/favorite/registry/registry.go +++ /dev/null @@ -1,34 +0,0 @@ -// 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 registry - -import "github.com/opencloud-eu/reva/v2/pkg/storage/favorite" - -// NewFunc is the function that favorite storage implementations -// should register at init time. -type NewFunc func(map[string]interface{}) (favorite.Manager, error) - -// NewFuncs is a map containing all the registered favorite storage implementations. -var NewFuncs = map[string]NewFunc{} - -// Register registers a new favorite storage function. -// Not safe for concurrent use. Safe for use from package init. -func Register(name string, f NewFunc) { - NewFuncs[name] = f -} diff --git a/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/fs/cephfs/cephfs.go b/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/fs/cephfs/cephfs.go index 22e1e9c1bd..5622836151 100644 --- a/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/fs/cephfs/cephfs.go +++ b/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/fs/cephfs/cephfs.go @@ -32,6 +32,7 @@ import ( "strings" cephfs2 "github.com/ceph/go-ceph/cephfs" + user "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1" provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1" "github.com/mitchellh/mapstructure" "github.com/pkg/errors" @@ -602,6 +603,14 @@ func (fs *cephfs) UnsetArbitraryMetadata(ctx context.Context, ref *provider.Refe return getRevaError(err) } +func (fs *cephfs) AddFavorite(ctx context.Context, ref *provider.Reference, userID *user.UserId) error { + return errtypes.NotSupported("AddFavorite not implemented") +} + +func (fs *cephfs) RemoveFavorite(ctx context.Context, ref *provider.Reference, userID *user.UserId) error { + return errtypes.NotSupported("RemoveFavorite not implemented") +} + func (fs *cephfs) EmptyRecycle(ctx context.Context, ref *provider.Reference) error { return errtypes.NotSupported("cephfs: empty recycle not supported") } diff --git a/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/fs/hello/unimplemented.go b/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/fs/hello/unimplemented.go index 6509ce5d3c..fec192d046 100644 --- a/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/fs/hello/unimplemented.go +++ b/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/fs/hello/unimplemented.go @@ -23,6 +23,7 @@ import ( "io" "net/url" + user "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1" provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1" "github.com/opencloud-eu/reva/v2/pkg/errtypes" @@ -124,6 +125,14 @@ func (fs *hellofs) UnsetArbitraryMetadata(ctx context.Context, ref *provider.Ref return errtypes.NotSupported("unimplemented") } +func (fs *hellofs) AddFavorite(ctx context.Context, ref *provider.Reference, userID *user.UserId) error { + return errtypes.NotSupported("AddFavorite not implemented") +} + +func (fs *hellofs) RemoveFavorite(ctx context.Context, ref *provider.Reference, userID *user.UserId) error { + return errtypes.NotSupported("RemoveFavorite not implemented") +} + // locks // GetLock returns an existing lock on the given reference diff --git a/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/fs/nextcloud/nextcloud.go b/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/fs/nextcloud/nextcloud.go index 1be26fe116..d71c370f72 100644 --- a/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/fs/nextcloud/nextcloud.go +++ b/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/fs/nextcloud/nextcloud.go @@ -862,6 +862,16 @@ func (nc *StorageDriver) Unlock(ctx context.Context, ref *provider.Reference, lo return errtypes.NotSupported("unimplemented") } +// AddFavorite adds a favourite to a resource +func (nc *StorageDriver) AddFavorite(ctx context.Context, ref *provider.Reference, userID *user.UserId) error { + return errtypes.NotSupported("AddFavorite not implemented") +} + +// RemoveFavorite removes a favourite from a resource +func (nc *StorageDriver) RemoveFavorite(ctx context.Context, ref *provider.Reference, userID *user.UserId) error { + return errtypes.NotSupported("RemoveFavorite not implemented") +} + // ListStorageSpaces as defined in the storage.FS interface func (nc *StorageDriver) ListStorageSpaces(ctx context.Context, f []*provider.ListStorageSpacesRequest_Filter, unrestricted bool) ([]*provider.StorageSpace, error) { bodyStr, _ := json.Marshal(f) diff --git a/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/fs/owncloudsql/owncloudsql.go b/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/fs/owncloudsql/owncloudsql.go index 87356613e5..e0132328a4 100644 --- a/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/fs/owncloudsql/owncloudsql.go +++ b/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/fs/owncloudsql/owncloudsql.go @@ -1137,6 +1137,14 @@ func (fs *owncloudsqlfs) UnsetArbitraryMetadata(ctx context.Context, ref *provid } } +func (fs *owncloudsqlfs) AddFavorite(ctx context.Context, ref *provider.Reference, userID *userpb.UserId) error { + return errtypes.NotSupported("AddFavorite not implemented") +} + +func (fs *owncloudsqlfs) RemoveFavorite(ctx context.Context, ref *provider.Reference, userID *userpb.UserId) error { + return errtypes.NotSupported("RemoveFavorite not implemented") +} + // GetLock returns an existing lock on the given reference func (fs *owncloudsqlfs) GetLock(ctx context.Context, ref *provider.Reference) (*provider.Lock, error) { return nil, errtypes.NotSupported("unimplemented") diff --git a/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/fs/posix/tree/tree.go b/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/fs/posix/tree/tree.go index eb8dca8c30..7a36f95e65 100644 --- a/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/fs/posix/tree/tree.go +++ b/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/fs/posix/tree/tree.go @@ -38,6 +38,7 @@ import ( "go.opentelemetry.io/otel/trace" "golang.org/x/sync/errgroup" + user "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1" provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1" "github.com/opencloud-eu/reva/v2/pkg/appctx" @@ -806,3 +807,11 @@ func isLockFile(path string) bool { func isTrash(path string) bool { return strings.HasSuffix(path, ".trashinfo") || strings.HasSuffix(path, ".trashitem") || strings.Contains(path, ".Trash") } + +func (t *Tree) AddFavorite(ctx context.Context, ref *provider.Reference, userID *user.UserId) error { + return errtypes.NotSupported("AddFavorite not implemented") +} + +func (t *Tree) RemoveFavorite(ctx context.Context, ref *provider.Reference, userID *user.UserId) error { + return errtypes.NotSupported("RemoveFavorite not implemented") +} diff --git a/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/pkg/decomposedfs/decomposedfs.go b/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/pkg/decomposedfs/decomposedfs.go index 81532b35d4..a828d4524b 100644 --- a/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/pkg/decomposedfs/decomposedfs.go +++ b/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/pkg/decomposedfs/decomposedfs.go @@ -1035,6 +1035,52 @@ func (fs *Decomposedfs) ListFolder(ctx context.Context, ref *provider.Reference, return finfos, nil } +// AddFavorite adds a favorite +func (fs *Decomposedfs) AddFavorite(ctx context.Context, ref *provider.Reference, uid *user.UserId) error { + ctx, span := tracer.Start(ctx, "AddFavorite") + defer span.End() + n, err := fs.lu.NodeFromResource(ctx, ref) + if err != nil { + return err + } + if !n.Exists { + return errtypes.NotFound(filepath.Join(n.ParentID, n.Name)) + } + + rp, err := fs.p.AssemblePermissions(ctx, n) + if err != nil { + return err + } + if !rp.Stat { + return errtypes.PermissionDenied("stat") + } + + return n.SetFavorite(ctx, uid) +} + +// RemoveFavorite removes a favorite +func (fs *Decomposedfs) RemoveFavorite(ctx context.Context, ref *provider.Reference, uid *user.UserId) error { + ctx, span := tracer.Start(ctx, "RemoveFavorite") + defer span.End() + n, err := fs.lu.NodeFromResource(ctx, ref) + if err != nil { + return err + } + if !n.Exists { + return errtypes.NotFound(filepath.Join(n.ParentID, n.Name)) + } + + rp, err := fs.p.AssemblePermissions(ctx, n) + if err != nil { + return err + } + if !rp.Stat { + return errtypes.PermissionDenied("stat") + } + + return n.UnsetFavorite(ctx, uid) +} + // Delete deletes the specified resource func (fs *Decomposedfs) Delete(ctx context.Context, ref *provider.Reference) (err error) { ctx, span := tracer.Start(ctx, "Delete") diff --git a/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/pkg/decomposedfs/metadata.go b/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/pkg/decomposedfs/metadata.go index 1a18fcd011..52240acf7d 100644 --- a/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/pkg/decomposedfs/metadata.go +++ b/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/pkg/decomposedfs/metadata.go @@ -20,19 +20,14 @@ package decomposedfs import ( "context" - "fmt" "path/filepath" - userpb "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1" provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1" "github.com/opencloud-eu/reva/v2/pkg/appctx" - ctxpkg "github.com/opencloud-eu/reva/v2/pkg/ctx" "github.com/opencloud-eu/reva/v2/pkg/errtypes" "github.com/opencloud-eu/reva/v2/pkg/storage/pkg/decomposedfs/metadata" "github.com/opencloud-eu/reva/v2/pkg/storage/pkg/decomposedfs/metadata/prefixes" - "github.com/opencloud-eu/reva/v2/pkg/storage/pkg/decomposedfs/node" "github.com/opencloud-eu/reva/v2/pkg/storagespace" - "github.com/opencloud-eu/reva/v2/pkg/utils" "github.com/pkg/errors" ) @@ -44,8 +39,6 @@ func (fs *Decomposedfs) SetArbitraryMetadata(ctx context.Context, ref *provider. if err != nil { return errors.Wrap(err, "Decomposedfs: error resolving ref") } - sublog := appctx.GetLogger(ctx).With().Str("spaceid", n.SpaceID).Str("nodeid", n.ID).Logger() - if !n.Exists { err = errtypes.NotFound(filepath.Join(n.ParentID, n.Name)) return err @@ -91,25 +84,6 @@ func (fs *Decomposedfs) SetArbitraryMetadata(ctx context.Context, ref *provider. errs = append(errs, errors.Wrap(err, "could not set etag")) } } - if val, ok := md.Metadata[node.FavoriteKey]; ok { - delete(md.Metadata, node.FavoriteKey) - if u, ok := ctxpkg.ContextGetUser(ctx); ok { - if uid := u.GetId(); uid != nil { - if err := n.SetFavorite(ctx, uid, val); err != nil { - sublog.Error().Err(err). - Interface("user", u). - Msg("could not set favorite flag") - errs = append(errs, errors.Wrap(err, "could not set favorite flag")) - } - } else { - sublog.Error().Interface("user", u).Msg("user has no id") - errs = append(errs, errors.Wrap(errtypes.UserRequired("userrequired"), "user has no id")) - } - } else { - sublog.Error().Interface("user", u).Msg("error getting user from ctx") - errs = append(errs, errors.Wrap(errtypes.UserRequired("userrequired"), "error getting user from ctx")) - } - } } for k, v := range md.Metadata { attrName := prefixes.MetadataPrefix + k @@ -168,46 +142,14 @@ func (fs *Decomposedfs) UnsetArbitraryMetadata(ctx context.Context, ref *provide errs := []error{} for _, k := range keys { - switch k { - case node.FavoriteKey: - // the favorite flag is specific to the user, so we need to incorporate the userid - u, ok := ctxpkg.ContextGetUser(ctx) - if !ok { - sublog.Error(). - Interface("user", u). - Msg("error getting user from ctx") - errs = append(errs, errors.Wrap(errtypes.UserRequired("userrequired"), "error getting user from ctx")) - continue - } - var uid *userpb.UserId - if uid = u.GetId(); uid == nil || uid.OpaqueId == "" { - sublog.Error(). - Interface("user", u). - Msg("user has no id") - errs = append(errs, errors.Wrap(errtypes.UserRequired("userrequired"), "user has no id")) - continue - } - fa := fmt.Sprintf("%s:%s:%s@%s", prefixes.FavPrefix, utils.UserTypeToString(uid.GetType()), uid.GetOpaqueId(), uid.GetIdp()) - if err := n.RemoveXattr(ctx, fa, true); err != nil { - if metadata.IsAttrUnset(err) { - continue // already gone, ignore - } - sublog.Error().Err(err). - Interface("user", u). - Str("key", fa). - Msg("could not unset favorite flag") - errs = append(errs, errors.Wrap(err, "could not unset favorite flag")) - } - default: - if err = n.RemoveXattr(ctx, prefixes.MetadataPrefix+k, true); err != nil { - if metadata.IsAttrUnset(err) { - continue // already gone, ignore - } - sublog.Error().Err(err). - Str("key", k). - Msg("could not unset metadata") - errs = append(errs, errors.Wrap(err, "could not unset metadata")) + if err = n.RemoveXattr(ctx, prefixes.MetadataPrefix+k, true); err != nil { + if metadata.IsAttrUnset(err) { + continue // already gone, ignore } + sublog.Error().Err(err). + Str("key", k). + Msg("could not unset metadata") + errs = append(errs, errors.Wrap(err, "could not unset metadata")) } } switch len(errs) { diff --git a/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/pkg/decomposedfs/metadata/prefixes/prefixes.go b/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/pkg/decomposedfs/metadata/prefixes/prefixes.go index a830ba7d1c..843a02c789 100644 --- a/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/pkg/decomposedfs/metadata/prefixes/prefixes.go +++ b/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/pkg/decomposedfs/metadata/prefixes/prefixes.go @@ -18,6 +18,10 @@ package prefixes +import ( + userpb "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1" +) + // Declare a list of xattr keys // Currently,extended file attributes have four separated @@ -102,3 +106,8 @@ const ( UserAcePrefix string = "u:" GroupAcePrefix string = "g:" ) + +func FavoriteKey(uid *userpb.UserId) string { + // the favorite flag is specific to the user, so we need to incorporate the userid + return FavPrefix + uid.OpaqueId +} diff --git a/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/pkg/decomposedfs/node/node.go b/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/pkg/decomposedfs/node/node.go index 6572cddc3b..1b05a02058 100644 --- a/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/pkg/decomposedfs/node/node.go +++ b/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/pkg/decomposedfs/node/node.go @@ -723,26 +723,17 @@ func (n *Node) SetEtag(ctx context.Context, val string) (err error) { } // SetFavorite sets the favorite for the current user -// TODO we should not mess with the user here ... the favorites is now a user specific property for a file -// that cannot be mapped to extended attributes without leaking who has marked a file as a favorite -// it is a specific case of a tag, which is user individual as well -// TODO there are different types of tags -// 1. public that are managed by everyone -// 2. private tags that are only visible to the user -// 3. system tags that are only visible to the system -// 4. group tags that are only visible to a group ... -// urgh ... well this can be solved using different namespaces -// 1. public = p: -// 2. private = u:: for user specific -// 3. system = s: for system -// 4. group = g:: -// 5. app? = a:: for apps? -// obviously this only is secure when the u/s/g/a namespaces are not accessible by users in the filesystem -// public tags can be mapped to extended attributes -func (n *Node) SetFavorite(ctx context.Context, uid *userpb.UserId, val string) error { +func (n *Node) SetFavorite(ctx context.Context, uid *userpb.UserId) error { // the favorite flag is specific to the user, so we need to incorporate the userid - fa := fmt.Sprintf("%s:%s:%s@%s", prefixes.FavPrefix, utils.UserTypeToString(uid.GetType()), uid.GetOpaqueId(), uid.GetIdp()) - return n.SetXattrString(ctx, fa, val) + fa := prefixes.FavoriteKey(uid) + return n.SetXattrString(ctx, fa, "1") +} + +// UnsetFavorite unsets the favorite for the current user +func (n *Node) UnsetFavorite(ctx context.Context, uid *userpb.UserId) error { + // the favorite flag is specific to the user, so we need to incorporate the userid + fa := prefixes.FavoriteKey(uid) + return n.RemoveXattr(ctx, fa, true) } // IsDir returns true if the node is a directory @@ -853,16 +844,15 @@ func (n *Node) AsResourceInfo(ctx context.Context, rp *provider.ResourcePermissi // read favorite flag for the current user if _, ok := mdKeysMap[FavoriteKey]; returnAllMetadata || ok { - favorite := "" if u, ok := ctxpkg.ContextGetUser(ctx); ok { // the favorite flag is specific to the user, so we need to incorporate the userid if uid := u.GetId(); uid != nil { - fa := fmt.Sprintf("%s:%s:%s@%s", prefixes.FavPrefix, utils.UserTypeToString(uid.GetType()), uid.GetOpaqueId(), uid.GetIdp()) - if val, err := n.XattrString(ctx, fa); err == nil { + fa := prefixes.FavoriteKey(uid) + if val, err := n.XattrString(ctx, fa); err == nil && val == "1" { sublog.Debug(). Str("favorite", fa). Msg("found favorite flag") - favorite = val + metadata[FavoriteKey] = val } } else { sublog.Error().Err(errtypes.UserRequired("userrequired")).Msg("user has no id") @@ -870,15 +860,20 @@ func (n *Node) AsResourceInfo(ctx context.Context, rp *provider.ResourcePermissi } else { sublog.Error().Err(errtypes.UserRequired("userrequired")).Msg("error getting user from ctx") } - metadata[FavoriteKey] = favorite } + + // read favorites + if err = readFavoritesIntoOpaque(ctx, n, ri); err != nil { + sublog.Debug().Err(err).Msg("error reading favorites") + } + // read locks // FIXME move to fieldmask if _, ok := mdKeysMap[LockdiscoveryKey]; returnAllMetadata || ok { if n.hasLocks(ctx) { err = readLocksIntoOpaque(ctx, n, ri) if err != nil { - sublog.Debug().Err(errtypes.InternalError("lockfail")) + sublog.Debug().Err(errtypes.InternalError("lockfail")).Msg("error reading locks") } } } @@ -1493,3 +1488,32 @@ func ReadChildNodeFromLink(ctx context.Context, path string) (string, error) { nodeID = strings.ReplaceAll(nodeID, "/", "") return nodeID, nil } + +func readFavoritesIntoOpaque(ctx context.Context, n *Node, ri *provider.ResourceInfo) error { + attrs, err := n.Xattrs(ctx) + if err != nil { + return err + } + + favorites := []string{} + for key, value := range attrs { + if string(value) == "1" && strings.HasPrefix(key, prefixes.FavPrefix) { + favorites = append(favorites, key[len(prefixes.FavPrefix):]) + } + } + + var b []byte + if b, err = json.Marshal(favorites); err != nil { + appctx.GetLogger(ctx).Error().Err(err).Msg("Decomposedfs: could not marshal favorites") + } + if ri.Opaque == nil { + ri.Opaque = &types.Opaque{ + Map: map[string]*types.OpaqueEntry{}, + } + } + ri.Opaque.Map["favorites"] = &types.OpaqueEntry{ + Decoder: "json", + Value: b, + } + return nil +} diff --git a/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/storage.go b/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/storage.go index 4fbc399755..4a9cb0715f 100644 --- a/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/storage.go +++ b/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/storage.go @@ -23,6 +23,7 @@ import ( "io" "net/url" + user "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1" provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1" registry "github.com/cs3org/go-cs3apis/cs3/storage/registry/v1beta1" tusd "github.com/tus/tusd/v2/pkg/handler" @@ -116,6 +117,11 @@ type FS interface { // UnsetArbitraryMetadata removes arbitraty metadata from a resource UnsetArbitraryMetadata(ctx context.Context, ref *provider.Reference, keys []string) error + // AddFavorite adds a favorite to a resource + AddFavorite(ctx context.Context, ref *provider.Reference, userID *user.UserId) error + // RemoveFavorite removes a favorite from a resource + RemoveFavorite(ctx context.Context, ref *provider.Reference, userID *user.UserId) error + // Locks // GetLock returns an existing lock on the given reference diff --git a/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/utils/decomposedfs/decomposedfs.go b/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/utils/decomposedfs/decomposedfs.go index 12111c988c..34d1f8141a 100644 --- a/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/utils/decomposedfs/decomposedfs.go +++ b/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/utils/decomposedfs/decomposedfs.go @@ -1233,6 +1233,14 @@ func (fs *Decomposedfs) Unlock(ctx context.Context, ref *provider.Reference, loc return node.Unlock(ctx, lock) } +func (fs *Decomposedfs) AddFavorite(ctx context.Context, ref *provider.Reference, userID *user.UserId) error { + return errtypes.NotSupported("AddFavorite not implemented") +} + +func (fs *Decomposedfs) RemoveFavorite(ctx context.Context, ref *provider.Reference, userID *user.UserId) error { + return errtypes.NotSupported("RemoveFavorite not implemented") +} + func (fs *Decomposedfs) ListRecycle(ctx context.Context, ref *provider.Reference, key, relativePath string) ([]*provider.RecycleItem, error) { return fs.trashbin.ListRecycle(ctx, ref, key, relativePath) } diff --git a/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/utils/eosfs/eosfs.go b/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/utils/eosfs/eosfs.go index db528e058d..144ac48202 100644 --- a/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/utils/eosfs/eosfs.go +++ b/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/utils/eosfs/eosfs.go @@ -281,6 +281,14 @@ func (fs *eosfs) Shutdown(ctx context.Context) error { return nil } +func (fs *eosfs) AddFavorite(ctx context.Context, ref *provider.Reference, userID *userpb.UserId) error { + return errtypes.NotSupported("AddFavorite not implemented") +} + +func (fs *eosfs) RemoveFavorite(ctx context.Context, ref *provider.Reference, userID *userpb.UserId) error { + return errtypes.NotSupported("RemoveFavorite not implemented") +} + func getUser(ctx context.Context) (*userpb.User, error) { u, ok := ctxpkg.ContextGetUser(ctx) if !ok { diff --git a/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/utils/localfs/localfs.go b/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/utils/localfs/localfs.go index 30bd8d1bae..349ccfc851 100644 --- a/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/utils/localfs/localfs.go +++ b/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/utils/localfs/localfs.go @@ -722,6 +722,14 @@ func (fs *localfs) GetLock(ctx context.Context, ref *provider.Reference) (*provi return nil, errtypes.NotSupported("unimplemented") } +func (fs *localfs) AddFavorite(ctx context.Context, ref *provider.Reference, userID *userpb.UserId) error { + return errtypes.NotSupported("AddFavorite not implemented") +} + +func (fs *localfs) RemoveFavorite(ctx context.Context, ref *provider.Reference, userID *userpb.UserId) error { + return errtypes.NotSupported("RemoveFavorite not implemented") +} + // SetLock puts a lock on the given reference func (fs *localfs) SetLock(ctx context.Context, ref *provider.Reference, lock *provider.Lock) error { return errtypes.NotSupported("unimplemented") diff --git a/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/utils/middleware/middleware.go b/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/utils/middleware/middleware.go index 420dbba76e..a1b28b09ab 100644 --- a/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/utils/middleware/middleware.go +++ b/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/utils/middleware/middleware.go @@ -23,6 +23,7 @@ import ( "io" "net/url" + userpb "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1" provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1" tusd "github.com/tus/tusd/v2/pkg/handler" @@ -1088,3 +1089,57 @@ func (f *FS) DeleteStorageSpace(ctx context.Context, req *provider.DeleteStorage return res0 } + +func (f *FS) AddFavorite(ctx context.Context, ref *provider.Reference, userID *userpb.UserId) error { + var ( + err error + unhook UnHook + unhooks []UnHook + ) + for _, hook := range f.hooks { + ctx, unhook, err = hook("AddFavorite", ctx, ref.GetResourceId().GetSpaceId()) + if err != nil { + return err + } + if unhook != nil { + unhooks = append(unhooks, unhook) + } + } + + res0 := f.next.AddFavorite(ctx, ref, userID) + + for _, unhook := range unhooks { + if err := unhook(); err != nil { + return err + } + } + + return res0 +} + +func (f *FS) RemoveFavorite(ctx context.Context, ref *provider.Reference, userID *userpb.UserId) error { + var ( + err error + unhook UnHook + unhooks []UnHook + ) + for _, hook := range f.hooks { + ctx, unhook, err = hook("RemoveFavorite", ctx, ref.GetResourceId().GetSpaceId()) + if err != nil { + return err + } + if unhook != nil { + unhooks = append(unhooks, unhook) + } + } + + res0 := f.next.RemoveFavorite(ctx, ref, userID) + + for _, unhook := range unhooks { + if err := unhook(); err != nil { + return err + } + } + + return res0 +} diff --git a/vendor/github.com/opencloud-eu/reva/v2/tests/cs3mocks/mocks/GatewayAPIClient.go b/vendor/github.com/opencloud-eu/reva/v2/tests/cs3mocks/mocks/GatewayAPIClient.go index f8d9e4ebbf..ec595a5c89 100644 --- a/vendor/github.com/opencloud-eu/reva/v2/tests/cs3mocks/mocks/GatewayAPIClient.go +++ b/vendor/github.com/opencloud-eu/reva/v2/tests/cs3mocks/mocks/GatewayAPIClient.go @@ -222,6 +222,79 @@ func (_c *GatewayAPIClient_AddAppProvider_Call) RunAndReturn(run func(context.Co return _c } +// AddFavorite provides a mock function with given fields: ctx, in, opts +func (_m *GatewayAPIClient) AddFavorite(ctx context.Context, in *providerv1beta1.AddFavoriteRequest, opts ...grpc.CallOption) (*providerv1beta1.AddFavoriteResponse, error) { + var tmpRet mock.Arguments + if len(opts) > 0 { + tmpRet = _m.Called(ctx, in, opts) + } else { + tmpRet = _m.Called(ctx, in) + } + ret := tmpRet + + if len(ret) == 0 { + panic("no return value specified for AddFavorite") + } + + var r0 *providerv1beta1.AddFavoriteResponse + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, *providerv1beta1.AddFavoriteRequest, ...grpc.CallOption) (*providerv1beta1.AddFavoriteResponse, error)); ok { + return rf(ctx, in, opts...) + } + if rf, ok := ret.Get(0).(func(context.Context, *providerv1beta1.AddFavoriteRequest, ...grpc.CallOption) *providerv1beta1.AddFavoriteResponse); ok { + r0 = rf(ctx, in, opts...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*providerv1beta1.AddFavoriteResponse) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, *providerv1beta1.AddFavoriteRequest, ...grpc.CallOption) error); ok { + r1 = rf(ctx, in, opts...) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GatewayAPIClient_AddFavorite_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'AddFavorite' +type GatewayAPIClient_AddFavorite_Call struct { + *mock.Call +} + +// AddFavorite is a helper method to define mock.On call +// - ctx context.Context +// - in *providerv1beta1.AddFavoriteRequest +// - opts ...grpc.CallOption +func (_e *GatewayAPIClient_Expecter) AddFavorite(ctx interface{}, in interface{}, opts ...interface{}) *GatewayAPIClient_AddFavorite_Call { + return &GatewayAPIClient_AddFavorite_Call{Call: _e.mock.On("AddFavorite", + append([]interface{}{ctx, in}, opts...)...)} +} + +func (_c *GatewayAPIClient_AddFavorite_Call) Run(run func(ctx context.Context, in *providerv1beta1.AddFavoriteRequest, opts ...grpc.CallOption)) *GatewayAPIClient_AddFavorite_Call { + _c.Call.Run(func(args mock.Arguments) { + variadicArgs := make([]grpc.CallOption, len(args)-2) + for i, a := range args[2:] { + if a != nil { + variadicArgs[i] = a.(grpc.CallOption) + } + } + run(args[0].(context.Context), args[1].(*providerv1beta1.AddFavoriteRequest), variadicArgs...) + }) + return _c +} + +func (_c *GatewayAPIClient_AddFavorite_Call) Return(_a0 *providerv1beta1.AddFavoriteResponse, _a1 error) *GatewayAPIClient_AddFavorite_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *GatewayAPIClient_AddFavorite_Call) RunAndReturn(run func(context.Context, *providerv1beta1.AddFavoriteRequest, ...grpc.CallOption) (*providerv1beta1.AddFavoriteResponse, error)) *GatewayAPIClient_AddFavorite_Call { + _c.Call.Return(run) + return _c +} + // Authenticate provides a mock function with given fields: ctx, in, opts func (_m *GatewayAPIClient) Authenticate(ctx context.Context, in *gatewayv1beta1.AuthenticateRequest, opts ...grpc.CallOption) (*gatewayv1beta1.AuthenticateResponse, error) { var tmpRet mock.Arguments @@ -5989,6 +6062,79 @@ func (_c *GatewayAPIClient_RefreshLock_Call) RunAndReturn(run func(context.Conte return _c } +// RemoveFavorite provides a mock function with given fields: ctx, in, opts +func (_m *GatewayAPIClient) RemoveFavorite(ctx context.Context, in *providerv1beta1.RemoveFavoriteRequest, opts ...grpc.CallOption) (*providerv1beta1.RemoveFavoriteResponse, error) { + var tmpRet mock.Arguments + if len(opts) > 0 { + tmpRet = _m.Called(ctx, in, opts) + } else { + tmpRet = _m.Called(ctx, in) + } + ret := tmpRet + + if len(ret) == 0 { + panic("no return value specified for RemoveFavorite") + } + + var r0 *providerv1beta1.RemoveFavoriteResponse + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, *providerv1beta1.RemoveFavoriteRequest, ...grpc.CallOption) (*providerv1beta1.RemoveFavoriteResponse, error)); ok { + return rf(ctx, in, opts...) + } + if rf, ok := ret.Get(0).(func(context.Context, *providerv1beta1.RemoveFavoriteRequest, ...grpc.CallOption) *providerv1beta1.RemoveFavoriteResponse); ok { + r0 = rf(ctx, in, opts...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*providerv1beta1.RemoveFavoriteResponse) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, *providerv1beta1.RemoveFavoriteRequest, ...grpc.CallOption) error); ok { + r1 = rf(ctx, in, opts...) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GatewayAPIClient_RemoveFavorite_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'RemoveFavorite' +type GatewayAPIClient_RemoveFavorite_Call struct { + *mock.Call +} + +// RemoveFavorite is a helper method to define mock.On call +// - ctx context.Context +// - in *providerv1beta1.RemoveFavoriteRequest +// - opts ...grpc.CallOption +func (_e *GatewayAPIClient_Expecter) RemoveFavorite(ctx interface{}, in interface{}, opts ...interface{}) *GatewayAPIClient_RemoveFavorite_Call { + return &GatewayAPIClient_RemoveFavorite_Call{Call: _e.mock.On("RemoveFavorite", + append([]interface{}{ctx, in}, opts...)...)} +} + +func (_c *GatewayAPIClient_RemoveFavorite_Call) Run(run func(ctx context.Context, in *providerv1beta1.RemoveFavoriteRequest, opts ...grpc.CallOption)) *GatewayAPIClient_RemoveFavorite_Call { + _c.Call.Run(func(args mock.Arguments) { + variadicArgs := make([]grpc.CallOption, len(args)-2) + for i, a := range args[2:] { + if a != nil { + variadicArgs[i] = a.(grpc.CallOption) + } + } + run(args[0].(context.Context), args[1].(*providerv1beta1.RemoveFavoriteRequest), variadicArgs...) + }) + return _c +} + +func (_c *GatewayAPIClient_RemoveFavorite_Call) Return(_a0 *providerv1beta1.RemoveFavoriteResponse, _a1 error) *GatewayAPIClient_RemoveFavorite_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *GatewayAPIClient_RemoveFavorite_Call) RunAndReturn(run func(context.Context, *providerv1beta1.RemoveFavoriteRequest, ...grpc.CallOption) (*providerv1beta1.RemoveFavoriteResponse, error)) *GatewayAPIClient_RemoveFavorite_Call { + _c.Call.Return(run) + return _c +} + // RemoveOCMShare provides a mock function with given fields: ctx, in, opts func (_m *GatewayAPIClient) RemoveOCMShare(ctx context.Context, in *ocmv1beta1.RemoveOCMShareRequest, opts ...grpc.CallOption) (*ocmv1beta1.RemoveOCMShareResponse, error) { var tmpRet mock.Arguments diff --git a/vendor/modules.txt b/vendor/modules.txt index 7aff77ae47..d609183162 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -315,7 +315,7 @@ github.com/crewjam/saml github.com/crewjam/saml/logger github.com/crewjam/saml/samlsp github.com/crewjam/saml/xmlenc -# github.com/cs3org/go-cs3apis v0.0.0-20260130145416-2dc593dc27e7 +# github.com/cs3org/go-cs3apis v0.0.0-20260310080202-fb97596763d6 ## explicit; go 1.21 github.com/cs3org/go-cs3apis/cs3/app/provider/v1beta1 github.com/cs3org/go-cs3apis/cs3/app/registry/v1beta1 @@ -737,9 +737,6 @@ github.com/golang/protobuf/ptypes/empty # github.com/golang/snappy v0.0.4 ## explicit github.com/golang/snappy -# github.com/gomodule/redigo v1.9.3 -## explicit; go 1.17 -github.com/gomodule/redigo/redis # github.com/google/go-cmp v0.7.0 ## explicit; go 1.21 github.com/google/go-cmp/cmp @@ -762,8 +759,8 @@ github.com/google/go-tpm/tpmutil/tbs # github.com/google/pprof v0.0.0-20260115054156-294ebfa9ad83 ## explicit; go 1.24.0 github.com/google/pprof/profile -# github.com/google/renameio/v2 v2.0.1 -## explicit; go 1.13 +# github.com/google/renameio/v2 v2.0.2 +## explicit; go 1.25 github.com/google/renameio/v2 # github.com/google/uuid v1.6.0 ## explicit @@ -1084,8 +1081,8 @@ github.com/minio/highwayhash # github.com/minio/md5-simd v1.1.2 ## explicit; go 1.14 github.com/minio/md5-simd -# github.com/minio/minio-go/v7 v7.0.98 -## explicit; go 1.24.0 +# github.com/minio/minio-go/v7 v7.0.99 +## explicit; go 1.25 github.com/minio/minio-go/v7 github.com/minio/minio-go/v7/pkg/cors github.com/minio/minio-go/v7/pkg/credentials @@ -1370,11 +1367,11 @@ github.com/open-policy-agent/opa/v1/version # github.com/opencloud-eu/icap-client v0.0.0-20250930132611-28a2afe62d89 ## explicit; go 1.24.6 github.com/opencloud-eu/icap-client -# github.com/opencloud-eu/libre-graph-api-go v1.0.8-0.20260204102724-10bcda1b3068 +# github.com/opencloud-eu/libre-graph-api-go v1.0.8-0.20260310090739-853d972b282d ## explicit; go 1.18 github.com/opencloud-eu/libre-graph-api-go -# github.com/opencloud-eu/reva/v2 v2.42.5 -## explicit; go 1.24.1 +# github.com/opencloud-eu/reva/v2 v2.42.6-0.20260311175421-d77bc89ffe35 +## explicit; go 1.25.0 github.com/opencloud-eu/reva/v2/cmd/revad/internal/grace github.com/opencloud-eu/reva/v2/cmd/revad/runtime github.com/opencloud-eu/reva/v2/internal/grpc/interceptors/appctx @@ -1502,16 +1499,6 @@ github.com/opencloud-eu/reva/v2/pkg/auth/registry/registry github.com/opencloud-eu/reva/v2/pkg/auth/registry/static github.com/opencloud-eu/reva/v2/pkg/auth/scope github.com/opencloud-eu/reva/v2/pkg/bytesize -github.com/opencloud-eu/reva/v2/pkg/cbox/favorite/sql -github.com/opencloud-eu/reva/v2/pkg/cbox/group/rest -github.com/opencloud-eu/reva/v2/pkg/cbox/loader -github.com/opencloud-eu/reva/v2/pkg/cbox/preferences/sql -github.com/opencloud-eu/reva/v2/pkg/cbox/publicshare/sql -github.com/opencloud-eu/reva/v2/pkg/cbox/share/sql -github.com/opencloud-eu/reva/v2/pkg/cbox/storage/eoshomewrapper -github.com/opencloud-eu/reva/v2/pkg/cbox/storage/eoswrapper -github.com/opencloud-eu/reva/v2/pkg/cbox/user/rest -github.com/opencloud-eu/reva/v2/pkg/cbox/utils github.com/opencloud-eu/reva/v2/pkg/conversions github.com/opencloud-eu/reva/v2/pkg/ctx github.com/opencloud-eu/reva/v2/pkg/datatx @@ -1567,7 +1554,6 @@ github.com/opencloud-eu/reva/v2/pkg/ocm/invite/repository/json github.com/opencloud-eu/reva/v2/pkg/ocm/invite/repository/loader github.com/opencloud-eu/reva/v2/pkg/ocm/invite/repository/memory github.com/opencloud-eu/reva/v2/pkg/ocm/invite/repository/registry -github.com/opencloud-eu/reva/v2/pkg/ocm/invite/repository/sql github.com/opencloud-eu/reva/v2/pkg/ocm/provider github.com/opencloud-eu/reva/v2/pkg/ocm/provider/authorizer/json github.com/opencloud-eu/reva/v2/pkg/ocm/provider/authorizer/loader @@ -1600,7 +1586,6 @@ github.com/opencloud-eu/reva/v2/pkg/publicshare/manager/json/persistence/file github.com/opencloud-eu/reva/v2/pkg/publicshare/manager/json/persistence/memory github.com/opencloud-eu/reva/v2/pkg/publicshare/manager/loader github.com/opencloud-eu/reva/v2/pkg/publicshare/manager/memory -github.com/opencloud-eu/reva/v2/pkg/publicshare/manager/owncloudsql github.com/opencloud-eu/reva/v2/pkg/publicshare/manager/registry github.com/opencloud-eu/reva/v2/pkg/registry github.com/opencloud-eu/reva/v2/pkg/rgrpc @@ -1620,10 +1605,8 @@ github.com/opencloud-eu/reva/v2/pkg/rhttp/router github.com/opencloud-eu/reva/v2/pkg/sdk/common github.com/opencloud-eu/reva/v2/pkg/share github.com/opencloud-eu/reva/v2/pkg/share/cache -github.com/opencloud-eu/reva/v2/pkg/share/cache/warmup/cbox github.com/opencloud-eu/reva/v2/pkg/share/cache/warmup/loader github.com/opencloud-eu/reva/v2/pkg/share/cache/warmup/registry -github.com/opencloud-eu/reva/v2/pkg/share/manager/json github.com/opencloud-eu/reva/v2/pkg/share/manager/jsoncs3 github.com/opencloud-eu/reva/v2/pkg/share/manager/jsoncs3/providercache github.com/opencloud-eu/reva/v2/pkg/share/manager/jsoncs3/receivedsharecache @@ -1631,7 +1614,6 @@ github.com/opencloud-eu/reva/v2/pkg/share/manager/jsoncs3/sharecache github.com/opencloud-eu/reva/v2/pkg/share/manager/jsoncs3/shareid github.com/opencloud-eu/reva/v2/pkg/share/manager/loader github.com/opencloud-eu/reva/v2/pkg/share/manager/memory -github.com/opencloud-eu/reva/v2/pkg/share/manager/owncloudsql github.com/opencloud-eu/reva/v2/pkg/share/manager/registry github.com/opencloud-eu/reva/v2/pkg/sharedconf github.com/opencloud-eu/reva/v2/pkg/signedurl @@ -1657,10 +1639,6 @@ github.com/opencloud-eu/reva/v2/pkg/siteacc/manager/gocdb github.com/opencloud-eu/reva/v2/pkg/smtpclient github.com/opencloud-eu/reva/v2/pkg/storage github.com/opencloud-eu/reva/v2/pkg/storage/cache -github.com/opencloud-eu/reva/v2/pkg/storage/favorite -github.com/opencloud-eu/reva/v2/pkg/storage/favorite/loader -github.com/opencloud-eu/reva/v2/pkg/storage/favorite/memory -github.com/opencloud-eu/reva/v2/pkg/storage/favorite/registry github.com/opencloud-eu/reva/v2/pkg/storage/fs/cephfs github.com/opencloud-eu/reva/v2/pkg/storage/fs/decomposed github.com/opencloud-eu/reva/v2/pkg/storage/fs/decomposed/blobstore