diff --git a/changelog/unreleased/appreg-mimetypes.md b/changelog/unreleased/appreg-mimetypes.md new file mode 100644 index 0000000000..862f962145 --- /dev/null +++ b/changelog/unreleased/appreg-mimetypes.md @@ -0,0 +1,8 @@ +Enhancement: UI improvements for the AppProviders + +Mime types and their friendly names are now handled in +the /app/list HTTP endpoint, and an additional /app/new +endpoint is made available to create new files for apps. + +https://github.com/cs3org/cs3apis/pull/145 +https://github.com/cs3org/reva/pull/2067 diff --git a/docs/content/en/docs/config/http/services/owncloud/ocdav/_index.md b/docs/content/en/docs/config/http/services/owncloud/ocdav/_index.md index 8da469b329..3c90e8f5f7 100644 --- a/docs/content/en/docs/config/http/services/owncloud/ocdav/_index.md +++ b/docs/content/en/docs/config/http/services/owncloud/ocdav/_index.md @@ -6,15 +6,16 @@ description: > Configuration for the OCDav service --- -{{% pageinfo %}} -TODO -{{% /pageinfo %}} +# _struct: Config_ -{{% dir name="prefix" type="string" default=".well-known" %}} -Where the HTTP service is exposed. +{{% dir name="drivers" type="map[string]map[string]interface{}" default="localhome" %}} + [[Ref]](https://github.com/cs3org/reva/tree/master/internal/http/services/owncloud/ocdav/ocdav.go#L110) {{< highlight toml >}} -[http.services.wellknown] -prefix = "/" +[http.services.owncloud.ocdav.drivers.localhome] +root = "/var/tmp/reva/" +share_folder = "/MyShares" +user_layout = "{{.Username}}" + {{< /highlight >}} {{% /dir %}} diff --git a/docs/content/en/docs/config/packages/auth/manager/nextcloud/_index.md b/docs/content/en/docs/config/packages/auth/manager/nextcloud/_index.md index 0df7072ee6..757b08bc6c 100644 --- a/docs/content/en/docs/config/packages/auth/manager/nextcloud/_index.md +++ b/docs/content/en/docs/config/packages/auth/manager/nextcloud/_index.md @@ -6,10 +6,10 @@ description: > Configuration for the nextcloud service --- -# _struct: config_ +# _struct: AuthManagerConfig_ {{% dir name="endpoint" type="string" default="" %}} -The Nextcloud backend endpoint for user check [[Ref]](https://github.com/cs3org/reva/tree/master/pkg/auth/manager/nextcloud/nextcloud.go#L48) +The Nextcloud backend endpoint for user check [[Ref]](https://github.com/cs3org/reva/tree/master/pkg/auth/manager/nextcloud/nextcloud.go#L49) {{< highlight toml >}} [auth.manager.nextcloud] endpoint = "" diff --git a/docs/content/en/docs/config/packages/user/manager/nextcloud/_index.md b/docs/content/en/docs/config/packages/user/manager/nextcloud/_index.md new file mode 100644 index 0000000000..31e8958aa2 --- /dev/null +++ b/docs/content/en/docs/config/packages/user/manager/nextcloud/_index.md @@ -0,0 +1,18 @@ +--- +title: "nextcloud" +linkTitle: "nextcloud" +weight: 10 +description: > + Configuration for the nextcloud service +--- + +# _struct: UserManagerConfig_ + +{{% dir name="endpoint" type="string" default="" %}} +The Nextcloud backend endpoint for user management [[Ref]](https://github.com/cs3org/reva/tree/master/pkg/user/manager/nextcloud/nextcloud.go#L51) +{{< highlight toml >}} +[user.manager.nextcloud] +endpoint = "" +{{< /highlight >}} +{{% /dir %}} + diff --git a/go.mod b/go.mod index 78d6b87afa..9441dbb93a 100644 --- a/go.mod +++ b/go.mod @@ -9,14 +9,14 @@ require ( github.com/Masterminds/sprig v2.22.0+incompatible github.com/ReneKroon/ttlcache/v2 v2.8.1 github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d // indirect - github.com/aws/aws-sdk-go v1.40.43 + github.com/aws/aws-sdk-go v1.40.46 github.com/beevik/etree v1.1.0 github.com/bluele/gcache v0.0.2 github.com/c-bata/go-prompt v0.2.6 github.com/cheggaaa/pb v1.0.29 github.com/coreos/go-oidc v2.2.1+incompatible github.com/cs3org/cato v0.0.0-20200828125504-e418fc54dd5e - github.com/cs3org/go-cs3apis v0.0.0-20210916072651-dd30db9dbe58 + github.com/cs3org/go-cs3apis v0.0.0-20210922150613-cb9e3c99f8de github.com/cubewise-code/go-mime v0.0.0-20200519001935-8c5762b177d8 github.com/eventials/go-tus v0.0.0-20200718001131-45c7ec8f5d59 github.com/gdexlab/go-render v1.0.1 @@ -53,9 +53,9 @@ require ( github.com/rs/zerolog v1.25.0 github.com/sciencemesh/meshdirectory-web v1.0.4 github.com/sethvargo/go-password v0.2.0 - github.com/stretchr/objx v0.2.0 // indirect + github.com/stretchr/objx v0.3.0 // indirect github.com/stretchr/testify v1.7.0 - github.com/studio-b12/gowebdav v0.0.0-20210630100626-7ff61aa87be8 + github.com/studio-b12/gowebdav v0.0.0-20210917133250-a3a86976a1df github.com/thanhpk/randstr v1.0.4 github.com/tidwall/pretty v1.2.0 // indirect github.com/tus/tusd v1.6.0 @@ -66,10 +66,10 @@ require ( go.opentelemetry.io/otel/exporters/jaeger v1.0.0-RC3 go.opentelemetry.io/otel/sdk v1.0.0-RC3 go.opentelemetry.io/otel/trace v1.0.0-RC3 - golang.org/x/crypto v0.0.0-20210915214749-c084706c2272 + golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f - golang.org/x/sys v0.0.0-20210915083310-ed5796bab164 - golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b + golang.org/x/sys v0.0.0-20210921065528-437939a70204 + golang.org/x/term v0.0.0-20210916214954-140adaaadfaf google.golang.org/grpc v1.40.0 google.golang.org/protobuf v1.27.1 gopkg.in/square/go-jose.v2 v2.6.0 // indirect diff --git a/go.sum b/go.sum index ad7afe84ce..ac2c9244be 100644 --- a/go.sum +++ b/go.sum @@ -64,6 +64,8 @@ github.com/aws/aws-sdk-go v1.20.1/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN github.com/aws/aws-sdk-go v1.34.28/go.mod h1:H7NKnBqNVzoTJpGfLrQkkD+ytBA93eiDYi/+8rV9s48= github.com/aws/aws-sdk-go v1.40.43 h1:froMtO2//9kCu1sK+dOfAcwxUu91p5KgUP4AL7SDwUQ= github.com/aws/aws-sdk-go v1.40.43/go.mod h1:585smgzpB/KqRA+K3y/NL/oYRqQvpNJYvLm+LY1U59Q= +github.com/aws/aws-sdk-go v1.40.46 h1:2O4qZ1ROLry/cYkHo14G0p8cnLKB5feIFXY7xWgq1n8= +github.com/aws/aws-sdk-go v1.40.46/go.mod h1:585smgzpB/KqRA+K3y/NL/oYRqQvpNJYvLm+LY1U59Q= github.com/beevik/etree v1.1.0 h1:T0xke/WvNtMoCqgzPhkX2r4rjY3GDZFi+FjpRZY2Jbs= github.com/beevik/etree v1.1.0/go.mod h1:r8Aw8JqVegEf0w2fDnATrX9VpkMcyFeM0FhwO62wh+A= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= @@ -92,6 +94,8 @@ github.com/cs3org/cato v0.0.0-20200828125504-e418fc54dd5e h1:tqSPWQeueWTKnJVMJff github.com/cs3org/cato v0.0.0-20200828125504-e418fc54dd5e/go.mod h1:XJEZ3/EQuI3BXTp/6DUzFr850vlxq11I6satRtz0YQ4= github.com/cs3org/go-cs3apis v0.0.0-20210916072651-dd30db9dbe58 h1:BxySl8qrPon7Yd98Ly8y45esk1zKaddnatKSgeoblXY= github.com/cs3org/go-cs3apis v0.0.0-20210916072651-dd30db9dbe58/go.mod h1:UXha4TguuB52H14EMoSsCqDj7k8a/t7g4gVP+bgY5LY= +github.com/cs3org/go-cs3apis v0.0.0-20210922150613-cb9e3c99f8de h1:N+AI8wz7yhDDqHDuq9EGaqQoFhAOi9XW37xt0ormflw= +github.com/cs3org/go-cs3apis v0.0.0-20210922150613-cb9e3c99f8de/go.mod h1:UXha4TguuB52H14EMoSsCqDj7k8a/t7g4gVP+bgY5LY= github.com/cubewise-code/go-mime v0.0.0-20200519001935-8c5762b177d8 h1:Z9lwXumT5ACSmJ7WGnFl+OMLLjpz5uR2fyz7dC255FI= github.com/cubewise-code/go-mime v0.0.0-20200519001935-8c5762b177d8/go.mod h1:4abs/jPXcmJzYoYGF91JF9Uq9s/KL5n1jvFDix8KcqY= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -444,6 +448,8 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+ github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.2.0 h1:Hbg2NidpLE8veEBkEZTL3CvlkUIVzuU9jDplZO54c48= github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= +github.com/stretchr/objx v0.3.0 h1:NGXK3lHquSN08v5vWalVI/L8XU9hdzE/G6xsrze47As= +github.com/stretchr/objx v0.3.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= @@ -453,6 +459,8 @@ github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5Cc github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/studio-b12/gowebdav v0.0.0-20210630100626-7ff61aa87be8 h1:ipNUBPHSUmHhhcLhvqC2vGZsJPzVuJap8rJx3uGAEco= github.com/studio-b12/gowebdav v0.0.0-20210630100626-7ff61aa87be8/go.mod h1:gCcfDlA1Y7GqOaeEKw5l9dOGx1VLdc/HuQSlQAaZ30s= +github.com/studio-b12/gowebdav v0.0.0-20210917133250-a3a86976a1df h1:C+J/LwTqP8gRPt1MdSzBNZP0OYuDm5wsmDKgwpLjYzo= +github.com/studio-b12/gowebdav v0.0.0-20210917133250-a3a86976a1df/go.mod h1:gCcfDlA1Y7GqOaeEKw5l9dOGx1VLdc/HuQSlQAaZ30s= github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ= github.com/thanhpk/randstr v1.0.4 h1:IN78qu/bR+My+gHCvMEXhR/i5oriVHcTB/BJJIRTsNo= github.com/thanhpk/randstr v1.0.4/go.mod h1:M/H2P1eNLZzlDwAzpkkkUvoyNNMbzRGhESZuEQk3r0U= @@ -484,18 +492,38 @@ go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.23.0 h1:gqCw0LfLxScz8irSi8exQc7fyQ0fKQU/qnC/X8+V/1M= go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= +go.opentelemetry.io/contrib v0.22.0 h1:0F7gDEjgb1WGn4ODIjaCAg75hmqF+UN0LiVgwxsCodc= +go.opentelemetry.io/contrib v0.22.0/go.mod h1:EH4yDYeNoaTqn/8yCWQmfNB78VHfGX2Jt2bvnvzBlGM= go.opentelemetry.io/contrib v0.23.0 h1:MgRuo0JZZX8J9WLRjyd7OpTSbaLOdQXXJa6SnZvlWLM= go.opentelemetry.io/contrib v0.23.0/go.mod h1:EH4yDYeNoaTqn/8yCWQmfNB78VHfGX2Jt2bvnvzBlGM= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.22.0 h1:TjqELdtCtlOJQrTnXd2y+RP6wXKZUnnJer0HR0CSo18= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.22.0/go.mod h1:KjqwX4uJNaj479ZjFpADOMJKOM4rBXq4kN7nbeuGKrY= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.23.0 h1:mMzWiJCJv7iC8yOFI0azfmmTuMFaaWVEObHH8LQaw8o= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.23.0/go.mod h1:RlEDuaJ0wF4rNG/GOd8zknRW44rKISkcdsp46kt+FcA= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.24.0 h1:1hCzM7mwQbFQgk3Q4lAVEsGV6NB4Uj6Jt3EU+OiSBc8= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.24.0/go.mod h1:O0cG0vP6TP3c323kh70JmeG1jN69Sn9Z5HxgmeASFWY= +go.opentelemetry.io/otel v1.0.0-RC2/go.mod h1:w1thVQ7qbAy8MHb0IFj8a5Q2QU0l2ksf8u/CN8m3NOM= go.opentelemetry.io/otel v1.0.0-RC3 h1:kvwiyEkiUT/JaadXzVLI/R1wDO934A7r3Bs2wEe6wqA= go.opentelemetry.io/otel v1.0.0-RC3/go.mod h1:Ka5j3ua8tZs4Rkq4Ex3hwgBgOchyPVq5S6P2lz//nKQ= +go.opentelemetry.io/otel v1.0.0 h1:qTTn6x71GVBvoafHK/yaRUmFzI4LcONZD0/kXxl5PHI= +go.opentelemetry.io/otel v1.0.0/go.mod h1:AjRVh9A5/5DE7S+mZtTR6t8vpKKryam+0lREnfmS4cg= +go.opentelemetry.io/otel/exporters/jaeger v1.0.0-RC2 h1:RF0nWsIDpDBe+s06lkLxUw9CWQUAhO6hBSxxB7dz45s= +go.opentelemetry.io/otel/exporters/jaeger v1.0.0-RC2/go.mod h1:sZZqN3Vb0iT+NE6mZ1S7sNyH3t4PFk6ElK5TLGFBZ7E= go.opentelemetry.io/otel/exporters/jaeger v1.0.0-RC3 h1:pKXuRvOc+5NgM0vv05PVIUetreuM57mcC6QQAKkcqZA= go.opentelemetry.io/otel/exporters/jaeger v1.0.0-RC3/go.mod h1:UbP19Xlhk9tcRZ+A3PfvyN5ld4X4YrSnzXaYzx1yNLc= +go.opentelemetry.io/otel/exporters/jaeger v1.0.0 h1:cLhx8llHw02h5JTqGqaRbYn+QVKHmrzD9vEbKnSPk5U= +go.opentelemetry.io/otel/exporters/jaeger v1.0.0/go.mod h1:q10N1AolE1JjqKrFJK2tYw0iZpmX+HBaXBtuCzRnBGQ= +go.opentelemetry.io/otel/oteltest v1.0.0-RC2/go.mod h1:kiQ4tw5tAL4JLTbcOYwK1CWI1HkT5aiLzHovgOVnz/A= +go.opentelemetry.io/otel/sdk v1.0.0-RC2/go.mod h1:fgwHyiDn4e5k40TD9VX243rOxXR+jzsWBZYA2P5jpEw= go.opentelemetry.io/otel/sdk v1.0.0-RC3 h1:iRMkET+EmJUn5mW0hJzygBraXRmrUwzbOtNvTCh/oKs= go.opentelemetry.io/otel/sdk v1.0.0-RC3/go.mod h1:78H6hyg2fka0NYT9fqGuFLvly2yCxiBXDJAgLKo/2Us= +go.opentelemetry.io/otel/sdk v1.0.0 h1:BNPMYUONPNbLneMttKSjQhOTlFLOD9U22HNG1KrIN2Y= +go.opentelemetry.io/otel/sdk v1.0.0/go.mod h1:PCrDHlSy5x1kjezSdL37PhbFUMjrsLRshJ2zCzeXwbM= +go.opentelemetry.io/otel/trace v1.0.0-RC2/go.mod h1:JPQ+z6nNw9mqEGT8o3eoPTdnNI+Aj5JcxEsVGREIAy4= go.opentelemetry.io/otel/trace v1.0.0-RC3 h1:9F0ayEvlxv8BmNmPbU005WK7hC+7KbOazCPZjNa1yME= go.opentelemetry.io/otel/trace v1.0.0-RC3/go.mod h1:VUt2TUYd8S2/ZRX09ZDFZQwn2RqfMB5MzO17jBojGxo= +go.opentelemetry.io/otel/trace v1.0.0 h1:TSBr8GTEtKevYMG/2d21M989r5WJYVimhTHBKVEZuh4= +go.opentelemetry.io/otel/trace v1.0.0/go.mod h1:PXTWqayeFUlJV1YDNhsJYB184+IvAH814St6o6ajzIs= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/goleak v1.1.10 h1:z+mqJhf6ss6BSfSM671tgKyZBFPTTJM+HLxnhPC3wu0= go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= @@ -513,6 +541,8 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20201216223049-8b5274cf687f/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20210915214749-c084706c2272 h1:3erb+vDS8lU1sxfDHF4/hhWyaXnhIaO+7RgL4fDZORA= golang.org/x/crypto v0.0.0-20210915214749-c084706c2272/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 h1:7I4JAnoQBe7ZtJcBaYHi5UtiO8tQHbUSXxL+pnGRANg= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -662,10 +692,14 @@ golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210915083310-ed5796bab164 h1:7ZDGnxgHAMw7thfC5bEos0RDAccZKxioiWBhfIe+tvw= golang.org/x/sys v0.0.0-20210915083310-ed5796bab164/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210921065528-437939a70204 h1:JJhkWtBuTQKyz2bd5WG9H8iUsJRU3En/KRfN8B2RnDs= +golang.org/x/sys v0.0.0-20210921065528-437939a70204/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b h1:9zKuko04nR4gjZ4+DNjHqRlAJqbJETHwiNKDqTfOjfE= golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.0.0-20210916214954-140adaaadfaf h1:Ihq/mm/suC88gF8WFcVwk+OV6Tq+wyA1O0E5UEvDglI= +golang.org/x/term v0.0.0-20210916214954-140adaaadfaf/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= diff --git a/internal/http/services/appprovider/appprovider.go b/internal/http/services/appprovider/appprovider.go index 22c0a3e775..4063283a02 100644 --- a/internal/http/services/appprovider/appprovider.go +++ b/internal/http/services/appprovider/appprovider.go @@ -22,6 +22,7 @@ import ( "context" "encoding/base64" "encoding/json" + "fmt" "net/http" "strings" "unicode/utf8" @@ -30,9 +31,13 @@ import ( gateway "github.com/cs3org/go-cs3apis/cs3/gateway/v1beta1" rpc "github.com/cs3org/go-cs3apis/cs3/rpc/v1beta1" provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1" + typespb "github.com/cs3org/go-cs3apis/cs3/types/v1beta1" + "github.com/cs3org/reva/internal/http/services/datagateway" "github.com/cs3org/reva/internal/http/services/ocmd" + "github.com/cs3org/reva/pkg/errtypes" "github.com/cs3org/reva/pkg/rgrpc/status" "github.com/cs3org/reva/pkg/rgrpc/todo/pool" + "github.com/cs3org/reva/pkg/rhttp" "github.com/cs3org/reva/pkg/rhttp/global" "github.com/cs3org/reva/pkg/rhttp/router" "github.com/cs3org/reva/pkg/sharedconf" @@ -41,6 +46,7 @@ import ( "github.com/mitchellh/mapstructure" "github.com/pkg/errors" "github.com/rs/zerolog" + "github.com/rs/zerolog/log" ) func init() { @@ -97,43 +103,143 @@ func (s *svc) Handler() http.Handler { var head string head, r.URL.Path = router.ShiftPath(r.URL.Path) - switch head { - case "list": - s.handleList(w, r) - case "open": - s.handleOpen(w, r) + switch r.Method { + case "POST": + switch head { + case "new": + s.handleNew(w, r) + case "open": + s.handleOpen(w, r) + default: + ocmd.WriteError(w, r, ocmd.APIErrorServerError, "unsupported POST endpoint", nil) + } + case "GET": + switch head { + case "list": + s.handleList(w, r) + default: + ocmd.WriteError(w, r, ocmd.APIErrorServerError, "unsupported GET endpoint", nil) + } + default: + ocmd.WriteError(w, r, ocmd.APIErrorServerError, "unsupported method", nil) } }) } -func (s *svc) handleList(w http.ResponseWriter, r *http.Request) { +func (s *svc) handleNew(w http.ResponseWriter, r *http.Request) { ctx := r.Context() + client, err := pool.GetGatewayServiceClient(s.conf.GatewaySvc) if err != nil { ocmd.WriteError(w, r, ocmd.APIErrorServerError, "error getting grpc gateway client", err) return } - listRes, err := client.ListSupportedMimeTypes(ctx, &appregistry.ListSupportedMimeTypesRequest{}) + if r.URL.Query().Get("template") != "" { + // TODO in the future we want to create a file out of the given template + ocmd.WriteError(w, r, ocmd.APIErrorInvalidParameter, "Template not implemented", + errtypes.NotSupported("Templates are not yet supported")) + return + } + + target := r.URL.Query().Get("filename") + if target == "" { + ocmd.WriteError(w, r, ocmd.APIErrorInvalidParameter, "Missing filename", + errtypes.UserRequired("Missing filename")) + return + } + + // Create empty file via storageprovider + createReq := &provider.InitiateFileUploadRequest{ + Ref: &provider.Reference{Path: target}, + Opaque: &typespb.Opaque{ + Map: map[string]*typespb.OpaqueEntry{ + "Upload-Length": { + Decoder: "plain", + Value: []byte("0"), + }, + }, + }, + } + createRes, err := client.InitiateFileUpload(ctx, createReq) if err != nil { - ocmd.WriteError(w, r, ocmd.APIErrorServerError, "error listing supported mime types", err) + ocmd.WriteError(w, r, ocmd.APIErrorServerError, "error calling InitiateFileUpload", err) return } - if listRes.Status.Code != rpc.Code_CODE_OK { - ocmd.WriteError(w, r, ocmd.APIErrorServerError, "error listing supported mime types", status.NewErrorFromCode(listRes.Status.Code, "appprovider")) + if createRes.Status.Code != rpc.Code_CODE_OK { + ocmd.WriteError(w, r, ocmd.APIErrorServerError, "error creating resource", status.NewErrorFromCode(createRes.Status.Code, "appprovider")) return } - mimeTypes := listRes.MimeTypes - filterAppsByUserAgent(mimeTypes, r.UserAgent()) + // Do a HTTP PUT with an empty body + var ep, token string + for _, p := range createRes.Protocols { + if p.Protocol == "simple" { + ep, token = p.UploadEndpoint, p.Token + } + } + httpReq, err := rhttp.NewRequest(ctx, http.MethodPut, ep, nil) + if err != nil { + ocmd.WriteError(w, r, ocmd.APIErrorServerError, "error executing PUT", err) + return + } + + httpReq.Header.Set(datagateway.TokenTransportHeader, token) + httpRes, err := rhttp.GetHTTPClient().Do(httpReq) + if err != nil { + log.Error().Err(err).Msg("error doing PUT request to data service") + ocmd.WriteError(w, r, ocmd.APIErrorServerError, "error executing PUT", err) + return + } + defer httpRes.Body.Close() + if httpRes.StatusCode != http.StatusOK { + log.Error().Msg("PUT request to data server failed") + ocmd.WriteError(w, r, ocmd.APIErrorServerError, "error executing PUT", + errtypes.InternalError(fmt.Sprint(httpRes.StatusCode))) + return + } + + // Stat created file and return its file id + statRes, ocmderr, err := statRef(ctx, provider.Reference{Path: target}, client) + if err != nil { + log.Error().Err(err).Msg("error statting created file") + ocmd.WriteError(w, r, ocmderr, "Created file not found", errtypes.NotFound("Created file not found")) + return + } + js, err := json.Marshal(map[string]interface{}{"file_id": statRes.Id}) + if err != nil { + ocmd.WriteError(w, r, ocmd.APIErrorServerError, "error marshalling JSON response", err) + return + } + + w.Header().Set("Content-Type", "application/json") + if _, err = w.Write(js); err != nil { + ocmd.WriteError(w, r, ocmd.APIErrorServerError, "error writing JSON response", err) + return + } +} - filterMimeTypes(mimeTypes) +func (s *svc) handleList(w http.ResponseWriter, r *http.Request) { + ctx := r.Context() + client, err := pool.GetGatewayServiceClient(s.conf.GatewaySvc) + if err != nil { + ocmd.WriteError(w, r, ocmd.APIErrorServerError, "error getting grpc gateway client", err) + return + } - if mimeTypes == nil { - mimeTypes = make(map[string]*appregistry.AppProviderList) // ensure array empty object instead of null in json + listRes, err := client.ListSupportedMimeTypes(ctx, &appregistry.ListSupportedMimeTypesRequest{}) + if err != nil { + ocmd.WriteError(w, r, ocmd.APIErrorServerError, "error listing supported mime types", err) + return + } + if listRes.Status.Code != rpc.Code_CODE_OK { + ocmd.WriteError(w, r, ocmd.APIErrorServerError, "error listing supported mime types", + status.NewErrorFromCode(listRes.Status.Code, "appprovider")) + return } - js, err := json.Marshal(map[string]interface{}{"mime-types": mimeTypes}) + res := filterAppsByUserAgent(listRes.MimeTypes, r.UserAgent()) + js, err := json.Marshal(map[string]interface{}{"mime-types": res}) if err != nil { ocmd.WriteError(w, r, ocmd.APIErrorServerError, "error marshalling JSON response", err) return @@ -172,7 +278,8 @@ func (s *svc) handleOpen(w http.ResponseWriter, r *http.Request) { return } if openRes.Status.Code != rpc.Code_CODE_OK { - ocmd.WriteError(w, r, ocmd.APIErrorServerError, "error opening resource information", status.NewErrorFromCode(openRes.Status.Code, "appprovider")) + ocmd.WriteError(w, r, ocmd.APIErrorServerError, "error opening resource information", + status.NewErrorFromCode(openRes.Status.Code, "appprovider")) return } @@ -189,39 +296,25 @@ func (s *svc) handleOpen(w http.ResponseWriter, r *http.Request) { } } -func filterMimeTypes(mimeTypes map[string]*appregistry.AppProviderList) { - for m, providers := range mimeTypes { +func filterAppsByUserAgent(mimeTypes []*appregistry.MimeTypeInfo, userAgent string) []*appregistry.MimeTypeInfo { + ua := ua.Parse(userAgent) + res := []*appregistry.MimeTypeInfo{} + for _, m := range mimeTypes { apps := []*appregistry.ProviderInfo{} - for _, p := range providers.AppProviders { + for _, p := range m.AppProviders { p.Address = "" // address is internal only and not needed in the client - // apps are called by name, so if it has no name you cannot call it. Therefore we should not advertise it. - if p.Name != "" { + // apps are called by name, so if it has no name it cannot be called and should not be advertised + // also filter Desktop-only apps if ua is not Desktop + if p.Name != "" && (ua.Desktop || !p.DesktopOnly) { apps = append(apps, p) } } if len(apps) > 0 { - mimeTypes[m] = &appregistry.AppProviderList{AppProviders: apps} - } else { - delete(mimeTypes, m) + m.AppProviders = apps + res = append(res, m) } } -} - -func filterAppsByUserAgent(mimeTypes map[string]*appregistry.AppProviderList, userAgent string) { - ua := ua.Parse(userAgent) - if ua.Desktop { - return - } - - for m, providers := range mimeTypes { - apps := []*appregistry.ProviderInfo{} - for _, p := range providers.AppProviders { - if !p.DesktopOnly { - apps = append(apps, p) - } - } - mimeTypes[m] = &appregistry.AppProviderList{AppProviders: apps} - } + return res } func (s *svc) getStatInfo(ctx context.Context, fileID string, client gateway.GatewayAPIClient) (*provider.ResourceInfo, ocmd.APIErrorCode, error) { @@ -243,9 +336,11 @@ func (s *svc) getStatInfo(ctx context.Context, fileID string, client gateway.Gat OpaqueId: parts[1], } - statReq := provider.StatRequest{ - Ref: &provider.Reference{ResourceId: res}, - } + return statRef(ctx, provider.Reference{ResourceId: res}, client) +} + +func statRef(ctx context.Context, ref provider.Reference, client gateway.GatewayAPIClient) (*provider.ResourceInfo, ocmd.APIErrorCode, error) { + statReq := provider.StatRequest{Ref: &ref} statRes, err := client.Stat(ctx, &statReq) if err != nil { return nil, ocmd.APIErrorServerError, err @@ -256,7 +351,6 @@ func (s *svc) getStatInfo(ctx context.Context, fileID string, client gateway.Gat if statRes.Info.Type != provider.ResourceType_RESOURCE_TYPE_FILE { return nil, ocmd.APIErrorServerError, errors.New("unsupported resource type") } - return statRes.Info, ocmd.APIErrorCode(""), nil } diff --git a/pkg/app/app.go b/pkg/app/app.go index bb1319dc52..a6edad2a02 100644 --- a/pkg/app/app.go +++ b/pkg/app/app.go @@ -31,14 +31,14 @@ import ( type Registry interface { FindProviders(ctx context.Context, mimeType string) ([]*registry.ProviderInfo, error) ListProviders(ctx context.Context) ([]*registry.ProviderInfo, error) - ListSupportedMimeTypes(ctx context.Context) (map[string]*registry.AppProviderList, error) + ListSupportedMimeTypes(ctx context.Context) ([]*registry.MimeTypeInfo, error) AddProvider(ctx context.Context, p *registry.ProviderInfo) error GetDefaultProviderForMimeType(ctx context.Context, mimeType string) (*registry.ProviderInfo, error) SetDefaultProviderForMimeType(ctx context.Context, mimeType string, p *registry.ProviderInfo) error } // Provider is the interface that application providers implement -// for providing the URL of the app which will serve the requested resource. +// for interacting with external apps that serve the requested resource. type Provider interface { GetAppURL(ctx context.Context, resource *provider.ResourceInfo, viewMode appprovider.OpenInAppRequest_ViewMode, token string) (*appprovider.OpenInAppURL, error) GetAppProviderInfo(ctx context.Context) (*registry.ProviderInfo, error) diff --git a/pkg/app/provider/demo/demo.go b/pkg/app/provider/demo/demo.go index 254dd868ae..896893fa65 100644 --- a/pkg/app/provider/demo/demo.go +++ b/pkg/app/provider/demo/demo.go @@ -22,11 +22,10 @@ import ( "context" "fmt" - "github.com/cs3org/reva/pkg/app" - appprovider "github.com/cs3org/go-cs3apis/cs3/app/provider/v1beta1" appregistry "github.com/cs3org/go-cs3apis/cs3/app/registry/v1beta1" provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1" + "github.com/cs3org/reva/pkg/app" "github.com/cs3org/reva/pkg/app/provider/registry" "github.com/mitchellh/mapstructure" ) diff --git a/pkg/app/provider/wopi/wopi.go b/pkg/app/provider/wopi/wopi.go index 0cf3aa734e..b1277a9777 100644 --- a/pkg/app/provider/wopi/wopi.go +++ b/pkg/app/provider/wopi/wopi.go @@ -16,7 +16,7 @@ // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. -package demo +package wopi import ( "bytes" diff --git a/pkg/app/registry/static/static.go b/pkg/app/registry/static/static.go index 6ddb63864a..73275734af 100644 --- a/pkg/app/registry/static/static.go +++ b/pkg/app/registry/static/static.go @@ -148,23 +148,32 @@ func (b *reg) ListProviders(ctx context.Context) ([]*registrypb.ProviderInfo, er return providers, nil } -func (b *reg) ListSupportedMimeTypes(ctx context.Context) (map[string]*registrypb.AppProviderList, error) { +func (b *reg) ListSupportedMimeTypes(ctx context.Context) ([]*registrypb.MimeTypeInfo, error) { b.RLock() defer b.RUnlock() - mimeTypes := make(map[string]*registrypb.AppProviderList) + res := []*registrypb.MimeTypeInfo{} + mtmap := make(map[string]*registrypb.MimeTypeInfo) for _, p := range b.providers { t := *p t.MimeTypes = nil for _, m := range p.MimeTypes { - if _, ok := mimeTypes[m]; ok { - mimeTypes[m].AppProviders = append(mimeTypes[m].AppProviders, &t) + if _, ok := mtmap[m]; ok { + mtmap[m].AppProviders = append(mtmap[m].AppProviders, &t) } else { - mimeTypes[m] = ®istrypb.AppProviderList{AppProviders: []*registrypb.ProviderInfo{&t}} + mtmap[m] = ®istrypb.MimeTypeInfo{ + MimeType: m, + AppProviders: []*registrypb.ProviderInfo{&t}, + Ext: "", // TODO fetch from config + Name: "", + Description: "", + Icon: "", + } + res = append(res, mtmap[m]) } } } - return mimeTypes, nil + return res, nil } func (b *reg) SetDefaultProviderForMimeType(ctx context.Context, mimeType string, p *registrypb.ProviderInfo) error {