mirror of
https://github.com/opencloud-eu/opencloud.git
synced 2026-05-25 00:46:37 -04:00
Merge pull request #2471 from owncloud/spaces-crud
This commit is contained in:
10
changelog/unreleased/spaces-post.md
Normal file
10
changelog/unreleased/spaces-post.md
Normal file
@@ -0,0 +1,10 @@
|
||||
Enhancement: Create a Space using the Graph API
|
||||
|
||||
Spaces can now be created on `POST /drives/{drive-name}`. Only users with the `create-space` permissions can perform this operation.
|
||||
|
||||
Allowed body form values are:
|
||||
|
||||
- `quota` (bytes) maximum amount of bytes stored in the space.
|
||||
- `maxQuotaFiles` (integer) maximum amount of files supported by the space.
|
||||
|
||||
https://github.com/owncloud/ocis/pull/2471
|
||||
257
docs/extensions/graph/spaces.md
Normal file
257
docs/extensions/graph/spaces.md
Normal file
@@ -0,0 +1,257 @@
|
||||
---
|
||||
title: Spaces
|
||||
weight: 20
|
||||
geekdocRepo: https://github.com/owncloud/ocis
|
||||
geekdocEditPath: edit/master/docs/extensions/graph
|
||||
geekdocFilePath: spaces.md
|
||||
---
|
||||
|
||||
{{< toc >}}
|
||||
|
||||
## Graph Service
|
||||
|
||||
The Graph service is a reference implementation of the MS Graph API. There are no libraries doing any work only a set of routes and handlers.
|
||||
|
||||
## Spaces API
|
||||
|
||||
The Spaces API makes use of the [MS Graph API Drive resource](https://docs.microsoft.com/en-us/graph/api/resources/drive?view=graph-rest-1.0) to represent the concept of a Storage Space. Natively the MS Graph Specification [does not provide a way for creating Drives](https://docs.microsoft.com/en-us/graph/api/resources/drive?view=graph-rest-1.0#methods), as a Drive is a read only resource.
|
||||
|
||||
We circumvented this limitation by adding a `POST /drive/{drive-name}` to the Graph router. A major drawback of this solution is that this endpoint does not have support from the official MS Graph SDK, however it is reachable by any HTTP clients.
|
||||
|
||||
### Methods
|
||||
|
||||
```
|
||||
POST /drive/{drive-name}
|
||||
```
|
||||
|
||||
Calls to the following endpoint will create a Space with all the default parameters since we do not parse the request body just yet.
|
||||
|
||||
## Examples
|
||||
|
||||
We can now create a `Marketing` space and retrieve its WebDAV endpoint. Let's see how to do this.
|
||||
|
||||
### Starting conditions
|
||||
|
||||
This is the status of a DecomposedFS `users` tree. As we can see it is empty because we have not yet logged in with any users. It is a fresh new installation.
|
||||
|
||||
```
|
||||
❯ tree -a /var/tmp/ocis/storage/users
|
||||
/var/tmp/ocis/storage/users
|
||||
├── blobs
|
||||
├── nodes
|
||||
│ └── root
|
||||
├── spaces
|
||||
│ ├── personal
|
||||
│ └── share
|
||||
├── trash
|
||||
└── uploads
|
||||
```
|
||||
|
||||
Let's start with creating a space:
|
||||
|
||||
`curl -k -X POST 'https://localhost:9200/graph/v1.0/drives/marketing' -u einstein:relativity -v`
|
||||
|
||||
```
|
||||
❯ tree -a /var/tmp/ocis/storage/users
|
||||
/var/tmp/ocis/storage/users
|
||||
├── blobs
|
||||
├── nodes
|
||||
│ ├── 02dc1ec5-28b5-41c5-a48a-fabd4fa0562e
|
||||
│ │ └── .space -> ../e85d185f-cdaa-4618-a312-e33ea435acfe
|
||||
│ ├── 52efe3c2-c95a-47a1-8f3d-924aa473c711
|
||||
│ ├── e85d185f-cdaa-4618-a312-e33ea435acfe
|
||||
│ └── root
|
||||
│ ├── 4c510ada-c86b-4815-8820-42cdf82c3d51 -> ../52efe3c2-c95a-47a1-8f3d-924aa473c711
|
||||
│ └── c42debb8-926e-4a46-83b0-39dba56e59a4 -> ../02dc1ec5-28b5-41c5-a48a-fabd4fa0562e
|
||||
├── spaces
|
||||
│ ├── personal
|
||||
│ │ └── 52efe3c2-c95a-47a1-8f3d-924aa473c711 -> ../../nodes/52efe3c2-c95a-47a1-8f3d-924aa473c711
|
||||
│ ├── project
|
||||
│ │ └── 02dc1ec5-28b5-41c5-a48a-fabd4fa0562e -> ../../nodes/02dc1ec5-28b5-41c5-a48a-fabd4fa0562e
|
||||
│ └── share
|
||||
├── trash
|
||||
└── uploads
|
||||
```
|
||||
|
||||
we can see that the `project` folder was added to the spaces as well as the `.space` folder to the space node `02dc1ec5-28b5-41c5-a48a-fabd4fa0562e`. For demonstration purposes, let's list the extended attributes of the new node:
|
||||
|
||||
```
|
||||
xattr -l /var/tmp/ocis/storage/users/nodes/root/c42debb8-926e-4a46-83b0-39dba56e59a4
|
||||
user.ocis.blobid:
|
||||
user.ocis.blobsize: 0
|
||||
user.ocis.name: c42debb8-926e-4a46-83b0-39dba56e59a4
|
||||
user.ocis.owner.id: 4c510ada-c86b-4815-8820-42cdf82c3d51
|
||||
user.ocis.owner.idp: https://localhost:9200
|
||||
user.ocis.owner.type: primary
|
||||
user.ocis.parentid: root
|
||||
user.ocis.quota: 65536
|
||||
user.ocis.space.name: marketing
|
||||
```
|
||||
|
||||
As seen here it contains the metadata from the default list of requirements for this ticket.
|
||||
|
||||
Let's list the drive we just created using the graph API:
|
||||
|
||||
```
|
||||
curl -k 'https://localhost:9200/graph/v1.0/me/drives' -u einstein:relativity -v | jq .value
|
||||
|
||||
[
|
||||
{
|
||||
"driveType": "personal",
|
||||
"id": "1284d238-aa92-42ce-bdc4-0b0000009157!52efe3c2-c95a-47a1-8f3d-924aa473c711",
|
||||
"lastModifiedDateTime": "2021-09-07T14:42:39.025050471+02:00",
|
||||
"name": "root",
|
||||
"owner": {
|
||||
"user": {
|
||||
"id": "4c510ada-c86b-4815-8820-42cdf82c3d51"
|
||||
}
|
||||
},
|
||||
"root": {
|
||||
"id": "1284d238-aa92-42ce-bdc4-0b0000009157!52efe3c2-c95a-47a1-8f3d-924aa473c711",
|
||||
"webDavUrl": "https://localhost:9200/dav/spaces/1284d238-aa92-42ce-bdc4-0b0000009157!52efe3c2-c95a-47a1-8f3d-924aa473c711"
|
||||
}
|
||||
},
|
||||
{
|
||||
"driveType": "project",
|
||||
"id": "1284d238-aa92-42ce-bdc4-0b0000009157!02dc1ec5-28b5-41c5-a48a-fabd4fa0562e",
|
||||
"lastModifiedDateTime": "2021-09-07T14:42:39.030705579+02:00",
|
||||
"name": "root",
|
||||
"owner": {
|
||||
"user": {
|
||||
"id": "4c510ada-c86b-4815-8820-42cdf82c3d51"
|
||||
}
|
||||
},
|
||||
"quota": {
|
||||
"total": 65536
|
||||
},
|
||||
"root": {
|
||||
"id": "1284d238-aa92-42ce-bdc4-0b0000009157!02dc1ec5-28b5-41c5-a48a-fabd4fa0562e",
|
||||
"webDavUrl": "https://localhost:9200/dav/spaces/1284d238-aa92-42ce-bdc4-0b0000009157!02dc1ec5-28b5-41c5-a48a-fabd4fa0562e"
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
As we can see the response already contains a space-aware dav endpoint, which we can use to upload files to the space:
|
||||
|
||||
```
|
||||
curl -k https://localhost:9200/dav/spaces/1284d238-aa92-42ce-bdc4-0b0000009157\!02dc1ec5-28b5-41c5-a48a-fabd4fa0562e/test.txt -X PUT -d "beep-sboop" -v -u einstein:relativity
|
||||
* Trying ::1...
|
||||
* TCP_NODELAY set
|
||||
* Connected to localhost (::1) port 9200 (#0)
|
||||
* upload completely sent off: 10 out of 10 bytes
|
||||
< HTTP/1.1 201 Created
|
||||
< Access-Control-Allow-Origin: *
|
||||
< Content-Length: 0
|
||||
< Content-Security-Policy: default-src 'none';
|
||||
< Content-Type: text/plain
|
||||
< Date: Tue, 07 Sep 2021 12:45:54 GMT
|
||||
< Etag: "e2942565a4eb52e8754c2806f215fe93"
|
||||
< Last-Modified: Tue, 07 Sep 2021 12:45:54 +0000
|
||||
< Oc-Etag: "e2942565a4eb52e8754c2806f215fe93"
|
||||
< Oc-Fileid: MTI4NGQyMzgtYWE5Mi00MmNlLWJkYzQtMGIwMDAwMDA5MTU3OmU4ZDIwNDA5LTE1OWItNGI2Ny1iODZkLTlkM2U3ZjYyYmM0ZQ==
|
||||
< Vary: Origin
|
||||
< X-Content-Type-Options: nosniff
|
||||
< X-Download-Options: noopen
|
||||
< X-Frame-Options: SAMEORIGIN
|
||||
< X-Permitted-Cross-Domain-Policies: none
|
||||
< X-Robots-Tag: none
|
||||
< X-Xss-Protection: 1; mode=block
|
||||
<
|
||||
* Connection #0 to host localhost left intact
|
||||
* Closing connection 0
|
||||
```
|
||||
|
||||
This is the state after every transformation:
|
||||
|
||||
```
|
||||
tree -a /var/tmp/ocis/storage/users
|
||||
/var/tmp/ocis/storage/users
|
||||
├── blobs
|
||||
│ └── 83842d56-91de-41d5-8800-b2fb7b2d31cf
|
||||
├── nodes
|
||||
│ ├── 02dc1ec5-28b5-41c5-a48a-fabd4fa0562e
|
||||
│ │ ├── .space -> ../e85d185f-cdaa-4618-a312-e33ea435acfe
|
||||
│ │ └── test.txt -> ../e8d20409-159b-4b67-b86d-9d3e7f62bc4e
|
||||
│ ├── 52efe3c2-c95a-47a1-8f3d-924aa473c711
|
||||
│ ├── e85d185f-cdaa-4618-a312-e33ea435acfe
|
||||
│ ├── e8d20409-159b-4b67-b86d-9d3e7f62bc4e
|
||||
│ └── root
|
||||
│ ├── 4c510ada-c86b-4815-8820-42cdf82c3d51 -> ../52efe3c2-c95a-47a1-8f3d-924aa473c711
|
||||
│ └── c42debb8-926e-4a46-83b0-39dba56e59a4 -> ../02dc1ec5-28b5-41c5-a48a-fabd4fa0562e
|
||||
├── spaces
|
||||
│ ├── personal
|
||||
│ │ └── 52efe3c2-c95a-47a1-8f3d-924aa473c711 -> ../../nodes/52efe3c2-c95a-47a1-8f3d-924aa473c711
|
||||
│ ├── project
|
||||
│ │ └── 02dc1ec5-28b5-41c5-a48a-fabd4fa0562e -> ../../nodes/02dc1ec5-28b5-41c5-a48a-fabd4fa0562e
|
||||
│ └── share
|
||||
├── trash
|
||||
└── uploads
|
||||
```
|
||||
|
||||
Observe the `test.txt` in the `02dc1ec5-28b5-41c5-a48a-fabd4fa0562e` node.
|
||||
|
||||
To finalize, verify the new created file is webdav-listable:
|
||||
|
||||
```xml
|
||||
curl -k https://localhost:9200/dav/spaces/1284d238-aa92-42ce-bdc4-0b0000009157\!02dc1ec5-28b5-41c5-a48a-fabd4fa0562e -X PROPFIND -v -u einstein:relativity | xmllint --format -
|
||||
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<d:multistatus xmlns:d="DAV:" xmlns:s="http://sabredav.org/ns" xmlns:oc="http://owncloud.org/ns">
|
||||
<d:response>
|
||||
<d:href>/dav/spaces/1284d238-aa92-42ce-bdc4-0b0000009157!02dc1ec5-28b5-41c5-a48a-fabd4fa0562e/</d:href>
|
||||
<d:propstat>
|
||||
<d:prop>
|
||||
<oc:id>MTI4NGQyMzgtYWE5Mi00MmNlLWJkYzQtMGIwMDAwMDA5MTU3OjAyZGMxZWM1LTI4YjUtNDFjNS1hNDhhLWZhYmQ0ZmEwNTYyZQ==</oc:id>
|
||||
<oc:fileid>MTI4NGQyMzgtYWE5Mi00MmNlLWJkYzQtMGIwMDAwMDA5MTU3OjAyZGMxZWM1LTI4YjUtNDFjNS1hNDhhLWZhYmQ0ZmEwNTYyZQ==</oc:fileid>
|
||||
<d:getetag>"35a2ce5f56592d79d1b7233eff033347"</d:getetag>
|
||||
<oc:permissions>RDNVCK</oc:permissions>
|
||||
<d:resourcetype>
|
||||
<d:collection/>
|
||||
</d:resourcetype>
|
||||
<oc:size>0</oc:size>
|
||||
<d:getlastmodified>Tue, 07 Sep 2021 12:45:54 GMT</d:getlastmodified>
|
||||
<oc:favorite>0</oc:favorite>
|
||||
</d:prop>
|
||||
<d:status>HTTP/1.1 200 OK</d:status>
|
||||
</d:propstat>
|
||||
</d:response>
|
||||
<d:response>
|
||||
<d:href>/dav/spaces/1284d238-aa92-42ce-bdc4-0b0000009157!02dc1ec5-28b5-41c5-a48a-fabd4fa0562e/.space/</d:href>
|
||||
<d:propstat>
|
||||
<d:prop>
|
||||
<oc:id>MTI4NGQyMzgtYWE5Mi00MmNlLWJkYzQtMGIwMDAwMDA5MTU3OmU4NWQxODVmLWNkYWEtNDYxOC1hMzEyLWUzM2VhNDM1YWNmZQ==</oc:id>
|
||||
<oc:fileid>MTI4NGQyMzgtYWE5Mi00MmNlLWJkYzQtMGIwMDAwMDA5MTU3OmU4NWQxODVmLWNkYWEtNDYxOC1hMzEyLWUzM2VhNDM1YWNmZQ==</oc:fileid>
|
||||
<d:getetag>"2e9a84bffce8b648ba626185800ee8fa"</d:getetag>
|
||||
<oc:permissions>SRDNVCK</oc:permissions>
|
||||
<d:resourcetype>
|
||||
<d:collection/>
|
||||
</d:resourcetype>
|
||||
<oc:size>0</oc:size>
|
||||
<d:getlastmodified>Tue, 07 Sep 2021 12:42:39 GMT</d:getlastmodified>
|
||||
<oc:favorite>0</oc:favorite>
|
||||
</d:prop>
|
||||
<d:status>HTTP/1.1 200 OK</d:status>
|
||||
</d:propstat>
|
||||
</d:response>
|
||||
<d:response>
|
||||
<d:href>/dav/spaces/1284d238-aa92-42ce-bdc4-0b0000009157!02dc1ec5-28b5-41c5-a48a-fabd4fa0562e/test.txt</d:href>
|
||||
<d:propstat>
|
||||
<d:prop>
|
||||
<oc:id>MTI4NGQyMzgtYWE5Mi00MmNlLWJkYzQtMGIwMDAwMDA5MTU3OmU4ZDIwNDA5LTE1OWItNGI2Ny1iODZkLTlkM2U3ZjYyYmM0ZQ==</oc:id>
|
||||
<oc:fileid>MTI4NGQyMzgtYWE5Mi00MmNlLWJkYzQtMGIwMDAwMDA5MTU3OmU4ZDIwNDA5LTE1OWItNGI2Ny1iODZkLTlkM2U3ZjYyYmM0ZQ==</oc:fileid>
|
||||
<d:getetag>"e2942565a4eb52e8754c2806f215fe93"</d:getetag>
|
||||
<oc:permissions>RDNVW</oc:permissions>
|
||||
<d:resourcetype/>
|
||||
<d:getcontentlength>10</d:getcontentlength>
|
||||
<d:getcontenttype>text/plain</d:getcontenttype>
|
||||
<d:getlastmodified>Tue, 07 Sep 2021 12:45:54 GMT</d:getlastmodified>
|
||||
<oc:checksums>
|
||||
<oc:checksum>SHA1:8f4b4c83c565fc5ec54b78c30c94a6b65e411de5 MD5:6a3a4eca9a6726eef8f7be5b03ea9011 ADLER32:151303ed</oc:checksum>
|
||||
</oc:checksums>
|
||||
<oc:favorite>0</oc:favorite>
|
||||
</d:prop>
|
||||
<d:status>HTTP/1.1 200 OK</d:status>
|
||||
</d:propstat>
|
||||
</d:response>
|
||||
</d:multistatus>
|
||||
```
|
||||
12
go.mod
12
go.mod
@@ -20,11 +20,11 @@ require (
|
||||
github.com/asim/go-micro/v3 v3.6.0
|
||||
github.com/blevesearch/bleve/v2 v2.1.0
|
||||
github.com/coreos/go-oidc/v3 v3.0.0
|
||||
github.com/cs3org/go-cs3apis v0.0.0-20210812121411-f18cf19614e8
|
||||
github.com/cs3org/reva v1.12.1-0.20210903075054-73f10ed5ab21
|
||||
github.com/cs3org/go-cs3apis v0.0.0-20210906133842-03e4a408c1f3
|
||||
github.com/cs3org/reva v1.12.1-0.20210908153040-a1a5d61a9ac0
|
||||
github.com/disintegration/imaging v1.6.2
|
||||
github.com/glauth/glauth v1.1.3-0.20210729125545-b9aecdfcac31
|
||||
github.com/go-chi/chi/v5 v5.0.3
|
||||
github.com/go-chi/chi/v5 v5.0.4
|
||||
github.com/go-chi/render v1.0.1
|
||||
github.com/go-kit/kit v0.10.0 // indirect
|
||||
github.com/go-logr/logr v0.4.0
|
||||
@@ -61,11 +61,11 @@ require (
|
||||
github.com/yaegashi/msgraph.go v0.1.4
|
||||
go.opencensus.io v0.23.0
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.22.0
|
||||
go.opentelemetry.io/otel v1.0.0-RC2
|
||||
go.opentelemetry.io/otel v1.0.0-RC3
|
||||
go.opentelemetry.io/otel/exporters/jaeger v1.0.0-RC2
|
||||
go.opentelemetry.io/otel/metric v0.20.0 // indirect
|
||||
go.opentelemetry.io/otel/sdk v1.0.0-RC2
|
||||
go.opentelemetry.io/otel/trace v1.0.0-RC2
|
||||
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-20210711020723-a769d52b0f97
|
||||
golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8
|
||||
golang.org/x/net v0.0.0-20210614182718-04defd469f4e
|
||||
|
||||
16
go.sum
16
go.sum
@@ -178,6 +178,8 @@ github.com/aws/aws-sdk-go v1.34.28/go.mod h1:H7NKnBqNVzoTJpGfLrQkkD+ytBA93eiDYi/
|
||||
github.com/aws/aws-sdk-go v1.37.27/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro=
|
||||
github.com/aws/aws-sdk-go v1.40.17 h1:WcE72YOL7ChzAWlgpEv9YMOqAwJDM1yzkv4GxWyS5wk=
|
||||
github.com/aws/aws-sdk-go v1.40.17/go.mod h1:585smgzpB/KqRA+K3y/NL/oYRqQvpNJYvLm+LY1U59Q=
|
||||
github.com/aws/aws-sdk-go v1.40.37 h1:I+Q6cLctkFyMMrKukcDnj+i2kjrQ37LGiOM6xmsxC48=
|
||||
github.com/aws/aws-sdk-go v1.40.37/go.mod h1:585smgzpB/KqRA+K3y/NL/oYRqQvpNJYvLm+LY1U59Q=
|
||||
github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g=
|
||||
github.com/baiyubin/aliyun-sts-go-sdk v0.0.0-20180326062324-cfa1a18b161f/go.mod h1:AuiFmCCPBSrqvVMvuqFuk0qogytodnVFVSN5CeJB8Gc=
|
||||
github.com/beevik/etree v1.1.0 h1:T0xke/WvNtMoCqgzPhkX2r4rjY3GDZFi+FjpRZY2Jbs=
|
||||
@@ -313,10 +315,16 @@ github.com/cs3org/go-cs3apis v0.0.0-20210802070913-970eec344e59 h1:cj9HxIbmbGn+H
|
||||
github.com/cs3org/go-cs3apis v0.0.0-20210802070913-970eec344e59/go.mod h1:UXha4TguuB52H14EMoSsCqDj7k8a/t7g4gVP+bgY5LY=
|
||||
github.com/cs3org/go-cs3apis v0.0.0-20210812121411-f18cf19614e8 h1:bqUkE0l5wD62TKH6HkbSVYwyYzZ0PIeak/hnW7ggUdU=
|
||||
github.com/cs3org/go-cs3apis v0.0.0-20210812121411-f18cf19614e8/go.mod h1:UXha4TguuB52H14EMoSsCqDj7k8a/t7g4gVP+bgY5LY=
|
||||
github.com/cs3org/go-cs3apis v0.0.0-20210906133842-03e4a408c1f3 h1:NcLk09WK4wx/iIrEI+7ZFbr78APaRKJxF0+zl6kv4is=
|
||||
github.com/cs3org/go-cs3apis v0.0.0-20210906133842-03e4a408c1f3/go.mod h1:UXha4TguuB52H14EMoSsCqDj7k8a/t7g4gVP+bgY5LY=
|
||||
github.com/cs3org/reva v1.12.0 h1:31Z+9+rLXUHRP3K6U3LK2wWLJUuicFjeFc2iZGg7rWE=
|
||||
github.com/cs3org/reva v1.12.0/go.mod h1:Fx2PHTX2Y3s/aNG/APpCbmttg5STWnxjD4DpnqdwjQc=
|
||||
github.com/cs3org/reva v1.12.1-0.20210903075054-73f10ed5ab21 h1:noPCV/0p9EkjpNUQs1K+/U3f+twBefGJSRaPunhI2TA=
|
||||
github.com/cs3org/reva v1.12.1-0.20210903075054-73f10ed5ab21/go.mod h1:5dEcJZiu8FoxUYR+apy7lkBl5AGiXWwqBzmm/6zCRuE=
|
||||
github.com/cs3org/reva v1.12.1-0.20210908151045-bd4575a9a056 h1:yChJgTjMJCgpY4tpSjwTgoXMGDYIn6qkMWDXkOsw8zE=
|
||||
github.com/cs3org/reva v1.12.1-0.20210908151045-bd4575a9a056/go.mod h1:DfORq7oDhBndLw++i8FbHS06RUsFpPhfhJqX7YXpjyc=
|
||||
github.com/cs3org/reva v1.12.1-0.20210908153040-a1a5d61a9ac0 h1:ewOfYFUaG0gOWCOyD09m764wNZX7o+h5SOm9aH7DiWY=
|
||||
github.com/cs3org/reva v1.12.1-0.20210908153040-a1a5d61a9ac0/go.mod h1:DfORq7oDhBndLw++i8FbHS06RUsFpPhfhJqX7YXpjyc=
|
||||
github.com/cubewise-code/go-mime v0.0.0-20200519001935-8c5762b177d8 h1:Z9lwXumT5ACSmJ7WGnFl+OMLLjpz5uR2fyz7dC255FI=
|
||||
github.com/cubewise-code/go-mime v0.0.0-20200519001935-8c5762b177d8/go.mod h1:4abs/jPXcmJzYoYGF91JF9Uq9s/KL5n1jvFDix8KcqY=
|
||||
github.com/cyberdelia/templates v0.0.0-20141128023046-ca7fffd4298c/go.mod h1:GyV+0YP4qX0UQ7r2MoYZ+AvYDp12OF5yg4q8rGnyNh4=
|
||||
@@ -408,6 +416,8 @@ github.com/go-chi/chi v4.0.2+incompatible h1:maB6vn6FqCxrpz4FqWdh4+lwpyZIQS7YEAU
|
||||
github.com/go-chi/chi v4.0.2+incompatible/go.mod h1:eB3wogJHnLi3x/kFX2A+IbTBlXxmMeXJVKy9tTv1XzQ=
|
||||
github.com/go-chi/chi/v5 v5.0.3 h1:khYQBdPivkYG1s1TAzDQG1f6eX4kD2TItYVZexL5rS4=
|
||||
github.com/go-chi/chi/v5 v5.0.3/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8=
|
||||
github.com/go-chi/chi/v5 v5.0.4 h1:5e494iHzsYBiyXQAHHuI4tyJS9M3V84OuX3ufIIGHFo=
|
||||
github.com/go-chi/chi/v5 v5.0.4/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8=
|
||||
github.com/go-chi/render v1.0.1 h1:4/5tis2cKaNdnv9zFLfXzcquC9HbeZgCnxGnKrltBS8=
|
||||
github.com/go-chi/render v1.0.1/go.mod h1:pq4Rr7HbnsdaeHagklXub+p6Wd16Af5l9koip1OvJns=
|
||||
github.com/go-cmd/cmd v1.0.5/go.mod h1:y8q8qlK5wQibcw63djSl/ntiHUHXHGdCkPk0j4QeW4s=
|
||||
@@ -1249,6 +1259,8 @@ go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.2
|
||||
go.opentelemetry.io/otel v0.20.0/go.mod h1:Y3ugLH2oa81t5QO+Lty+zXf8zC9L26ax4Nzoxm/dooo=
|
||||
go.opentelemetry.io/otel v1.0.0-RC2 h1:SHhxSjB+omnGZPgGlKe+QMp3MyazcOHdQ8qwo89oKbg=
|
||||
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/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/metric v0.20.0/go.mod h1:598I5tYlH1vzBjn+BTuhzTCSb/9debfNp6R3s7Pr1eU=
|
||||
@@ -1257,9 +1269,13 @@ go.opentelemetry.io/otel/oteltest v1.0.0-RC2 h1:xNKqMhlZYkASSyvF4JwObZFMq0jhFN3c
|
||||
go.opentelemetry.io/otel/oteltest v1.0.0-RC2/go.mod h1:kiQ4tw5tAL4JLTbcOYwK1CWI1HkT5aiLzHovgOVnz/A=
|
||||
go.opentelemetry.io/otel/sdk v1.0.0-RC2 h1:ROuteeSCBaZNjiT9JcFzZepmInDvLktR28Y6qKo8bCs=
|
||||
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/trace v0.20.0/go.mod h1:6GjCW8zgDjwGHGa6GkyeB8+/5vjT16gUEi0Nf1iBdgw=
|
||||
go.opentelemetry.io/otel/trace v1.0.0-RC2 h1:dunAP0qDULMIT82atj34m5RgvsIK6LcsXf1c/MsYg1w=
|
||||
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/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI=
|
||||
go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||
|
||||
@@ -1,17 +1,26 @@
|
||||
package svc
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"path"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
cs3rpc "github.com/cs3org/go-cs3apis/cs3/rpc/v1beta1"
|
||||
v1beta11 "github.com/cs3org/go-cs3apis/cs3/rpc/v1beta1"
|
||||
provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1"
|
||||
storageprovider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1"
|
||||
types "github.com/cs3org/go-cs3apis/cs3/types/v1beta1"
|
||||
ctxpkg "github.com/cs3org/reva/pkg/ctx"
|
||||
"github.com/go-chi/chi/v5"
|
||||
"github.com/go-chi/render"
|
||||
"github.com/owncloud/ocis/graph/pkg/service/v0/errorcode"
|
||||
"github.com/owncloud/ocis/ocis-pkg/service/grpc"
|
||||
sproto "github.com/owncloud/ocis/settings/pkg/proto/v0"
|
||||
settingsSvc "github.com/owncloud/ocis/settings/pkg/service/v0"
|
||||
msgraph "github.com/owncloud/open-graph-api-go"
|
||||
)
|
||||
|
||||
@@ -128,6 +137,73 @@ func (g Graph) GetRootDriveChildren(w http.ResponseWriter, r *http.Request) {
|
||||
render.JSON(w, r, &listResponse{Value: files})
|
||||
}
|
||||
|
||||
// CreateDrive creates a storage drive (space).
|
||||
func (g Graph) CreateDrive(w http.ResponseWriter, r *http.Request) {
|
||||
us, ok := ctxpkg.ContextGetUser(r.Context())
|
||||
if !ok {
|
||||
errorcode.GeneralException.Render(w, r, http.StatusUnauthorized, "invalid user")
|
||||
return
|
||||
}
|
||||
|
||||
if err := r.ParseForm(); err != nil {
|
||||
errorcode.GeneralException.Render(w, r, http.StatusUnauthorized, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
s := sproto.NewPermissionService("com.owncloud.api.settings", grpc.DefaultClient)
|
||||
|
||||
_, err := s.GetPermissionByID(r.Context(), &sproto.GetPermissionByIDRequest{
|
||||
PermissionId: settingsSvc.CreateSpacePermissionID,
|
||||
})
|
||||
if err != nil {
|
||||
// if the permission is not existing for the user in context we can assume we don't have it. Return 401.
|
||||
errorcode.GeneralException.Render(w, r, http.StatusUnauthorized, "insufficient permissions to create a space.")
|
||||
return
|
||||
}
|
||||
|
||||
client, err := g.GetClient()
|
||||
if err != nil {
|
||||
errorcode.GeneralException.Render(w, r, http.StatusInternalServerError, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
spaceName := chi.URLParam(r, "drive-name")
|
||||
if spaceName == "" {
|
||||
errorcode.GeneralException.Render(w, r, http.StatusInternalServerError, fmt.Errorf("invalid name").Error())
|
||||
return
|
||||
}
|
||||
|
||||
quota, _ := strconv.ParseUint(r.Form.Get("quota"), 10, 64)
|
||||
if quota == 0 {
|
||||
quota = 65536 // set default quota if no form value was sent.
|
||||
}
|
||||
|
||||
quotaMaxFiles, _ := strconv.ParseUint(r.Form.Get("quotaMaxFiles"), 10, 64)
|
||||
if quotaMaxFiles == 0 {
|
||||
quotaMaxFiles = 20 // set default quotaMaxFiles if no form value was sent.
|
||||
}
|
||||
|
||||
csr := provider.CreateStorageSpaceRequest{
|
||||
Owner: us,
|
||||
Type: "share",
|
||||
Name: spaceName,
|
||||
Quota: &provider.Quota{
|
||||
QuotaMaxBytes: quota,
|
||||
QuotaMaxFiles: quotaMaxFiles,
|
||||
},
|
||||
}
|
||||
|
||||
resp, err := client.CreateStorageSpace(r.Context(), &csr)
|
||||
if err != nil {
|
||||
errorcode.GeneralException.Render(w, r, http.StatusInternalServerError, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
if resp.GetStatus().GetCode() != v1beta11.Code_CODE_OK {
|
||||
errorcode.GeneralException.Render(w, r, http.StatusInternalServerError, fmt.Errorf("").Error())
|
||||
}
|
||||
}
|
||||
|
||||
func cs3TimestampToTime(t *types.Timestamp) time.Time {
|
||||
return time.Unix(int64(t.Seconds), int64(t.Nanos))
|
||||
}
|
||||
|
||||
@@ -3,6 +3,9 @@ package svc
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/owncloud/ocis/ocis-pkg/account"
|
||||
opkgm "github.com/owncloud/ocis/ocis-pkg/middleware"
|
||||
|
||||
"github.com/go-chi/chi/v5"
|
||||
"github.com/go-chi/chi/v5/middleware"
|
||||
)
|
||||
@@ -50,6 +53,15 @@ func NewService(opts ...Option) Service {
|
||||
r.Get("/", svc.GetGroup)
|
||||
})
|
||||
})
|
||||
r.Route("/drives", func(r chi.Router) {
|
||||
r.Use(opkgm.ExtractAccountUUID(
|
||||
account.Logger(options.Logger),
|
||||
account.JWTSecret(options.Config.TokenManager.JWTSecret)),
|
||||
)
|
||||
// This route is non-compliant with MS Graph implementation; creating a drive is not supported. There
|
||||
// is no official MS SDK support for this method.
|
||||
r.Post("/{drive-name}", svc.CreateDrive)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
@@ -300,12 +300,6 @@ Synchronization features like etag propagation, setting mtime and locking files
|
||||
### Share
|
||||
File and sync features in a shared scenario
|
||||
|
||||
#### [etags don't change for a share receiver](https://github.com/owncloud/product/issues/243)
|
||||
- [apiWebdavEtagPropagation1/moveFileFolder.feature:244](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavEtagPropagation1/moveFileFolder.feature#L244)
|
||||
- [apiWebdavEtagPropagation1/moveFileFolder.feature:245](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavEtagPropagation1/moveFileFolder.feature#L245)
|
||||
- [apiWebdavEtagPropagation1/moveFileFolder.feature:314](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavEtagPropagation1/moveFileFolder.feature#L314)
|
||||
- [apiWebdavEtagPropagation1/moveFileFolder.feature:315](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavEtagPropagation1/moveFileFolder.feature#L315)
|
||||
|
||||
#### [Searching sharee with displayname](https://github.com/owncloud/ocis/issues/547)
|
||||
- [apiSharees/sharees.feature:32](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiSharees/sharees.feature#L32)
|
||||
- [apiSharees/sharees.feature:33](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiSharees/sharees.feature#L33)
|
||||
@@ -335,10 +329,8 @@ File and sync features in a shared scenario
|
||||
- [apiShareManagementToShares/acceptShares.feature:310](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareManagementToShares/acceptShares.feature#L310)
|
||||
|
||||
#### [cannot accept identical pending shares from different user serially](https://github.com/owncloud/ocis/issues/2131)
|
||||
- [apiShareManagementToShares/acceptShares.feature:82](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareManagementToShares/acceptShares.feature#L82)
|
||||
- [apiShareManagementToShares/acceptShares.feature:261](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareManagementToShares/acceptShares.feature#L261)
|
||||
- [apiShareCreateSpecialToShares1/createShareUniqueReceivedNames.feature:15](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareCreateSpecialToShares1/createShareUniqueReceivedNames.feature#L15)
|
||||
- [apiShareManagementToShares/acceptShares.feature:82](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareManagementToShares/acceptShares.feature#L82)
|
||||
- [apiShareManagementToShares/acceptShares.feature:504](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareManagementToShares/acceptShares.feature#L504)
|
||||
- [apiShareManagementToShares/acceptShares.feature:565](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareManagementToShares/acceptShares.feature#L565)
|
||||
- [apiShareCreateSpecialToShares1/createShareReceivedInMultipleWays.feature:153](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareCreateSpecialToShares1/createShareReceivedInMultipleWays.feature#L153)
|
||||
@@ -348,9 +340,6 @@ File and sync features in a shared scenario
|
||||
- [apiShareCreateSpecialToShares1/createShareReceivedInMultipleWays.feature:47](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareCreateSpecialToShares1/createShareReceivedInMultipleWays.feature#L47)
|
||||
- [apiShareCreateSpecialToShares1/createShareReceivedInMultipleWays.feature:48](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareCreateSpecialToShares1/createShareReceivedInMultipleWays.feature#L48)
|
||||
|
||||
#### [a declined share still exists in Shares directory](https://github.com/owncloud/ocis/issues/2128)
|
||||
- [apiShareManagementToShares/acceptShares.feature:207](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareManagementToShares/acceptShares.feature#L207)
|
||||
|
||||
#### [file_target of a auto-renamed file is not correct directly after sharing](https://github.com/owncloud/core/issues/32322)
|
||||
- [apiShareManagementBasicToShares/deleteShareFromShares.feature:46](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareManagementBasicToShares/deleteShareFromShares.feature#L46)
|
||||
- [apiShareManagementToShares/mergeShare.feature:89](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareManagementToShares/mergeShare.feature#L89)
|
||||
@@ -362,11 +351,6 @@ File and sync features in a shared scenario
|
||||
#### [Cannot move a file to a shared folder](https://github.com/owncloud/ocis/issues/2146)
|
||||
- [apiShareManagementBasicToShares/createShareToSharesFolder.feature:515](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareManagementBasicToShares/createShareToSharesFolder.feature#L515)
|
||||
|
||||
#### [deleting share response does not contain `data` field](https://github.com/owncloud/ocis/issues/721)
|
||||
|
||||
- [apiShareManagementBasicToShares/deleteShareFromShares.feature:43](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareManagementBasicToShares/deleteShareFromShares.feature#L43)
|
||||
- [apiShareManagementBasicToShares/deleteShareFromShares.feature:44](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareManagementBasicToShares/deleteShareFromShares.feature#L44)
|
||||
|
||||
#### [sharing via API and changing the cases in the username does not work correctly](https://github.com/owncloud/core/issues/35484)
|
||||
- [apiShareManagementBasicToShares/createShareToSharesFolder.feature:373](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareManagementBasicToShares/createShareToSharesFolder.feature#L373)
|
||||
|
||||
@@ -662,7 +646,6 @@ _getting and setting quota_
|
||||
#### [not possible to move file into a received folder](https://github.com/owncloud/ocis/issues/764)
|
||||
- [apiShareOperationsToShares1/changingFilesShare.feature:24](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareOperationsToShares1/changingFilesShare.feature#L24)
|
||||
- [apiShareOperationsToShares1/changingFilesShare.feature:25](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareOperationsToShares1/changingFilesShare.feature#L25)
|
||||
- [apiShareOperationsToShares1/changingFilesShare.feature:66](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareOperationsToShares1/changingFilesShare.feature#L66)
|
||||
- [apiShareOperationsToShares1/changingFilesShare.feature:82](https://github.com/owncloud/core/blob/master/test/acceptance/features/apiShareOperationsToShares1/changingFilesShare.feature#L82)
|
||||
- [apiShareOperationsToShares1/changingFilesShare.feature:98](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareOperationsToShares1/changingFilesShare.feature#L98)
|
||||
|
||||
@@ -1424,10 +1407,6 @@ Scenario Outline: Unauthenticated call
|
||||
- [apiShareOperationsToShares2/shareAccessByID.feature:155](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareOperationsToShares2/shareAccessByID.feature#L155)
|
||||
- [apiShareOperationsToShares2/shareAccessByID.feature:156](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareOperationsToShares2/shareAccessByID.feature#L156)
|
||||
|
||||
#### [File is still present in the file list after declining a share](https://github.com/owncloud/ocis/issues/2112)
|
||||
- [apiShareOperationsToShares2/shareAccessByID.feature:123](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareOperationsToShares2/shareAccessByID.feature#L123)
|
||||
- [apiShareOperationsToShares2/shareAccessByID.feature:124](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareOperationsToShares2/shareAccessByID.feature#L124)
|
||||
|
||||
#### [[OC-storage] share-types field empty for shared file folder in webdav response](https://github.com/owncloud/ocis/issues/2144)
|
||||
- [apiWebdavProperties2/getFileProperties.feature:156](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavProperties2/getFileProperties.feature#L156)
|
||||
- [apiWebdavProperties2/getFileProperties.feature:157](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavProperties2/getFileProperties.feature#L157)
|
||||
|
||||
@@ -137,9 +137,6 @@ Other free text and markdown formatting can be used elsewhere in the document if
|
||||
- [webUISharingPublicManagement/publicLinkIndicator.feature:81](https://github.com/owncloud/web/blob/master/tests/acceptance/features/webUISharingPublicManagement/publicLinkIndicator.feature#L81)
|
||||
- [webUISharingPublicManagement/publicLinkIndicator.feature:98](https://github.com/owncloud/web/blob/master/tests/acceptance/features/webUISharingPublicManagement/publicLinkIndicator.feature#L98)
|
||||
|
||||
### [different button to unshare self from a shared resource in ocis-web and web](https://github.com/owncloud/ocis/issues/2266)
|
||||
- [webUISharingInternalUsersShareWithPage/shareWithUsers.feature:91](https://github.com/owncloud/web/blob/master/tests/acceptance/features/webUISharingInternalUsersShareWithPage/shareWithUsers.feature#L91)
|
||||
|
||||
### [Copy private link option not available](https://github.com/owncloud/ocis/issues/1409)
|
||||
- [webUIFilesCopy/copyPrivateLinks.feature:20](https://github.com/owncloud/web/blob/master/tests/acceptance/features/webUIFilesCopy/copyPrivateLinks.feature#L20)
|
||||
- [webUIFilesCopy/copyPrivateLinks.feature:21](https://github.com/owncloud/web/blob/master/tests/acceptance/features/webUIFilesCopy/copyPrivateLinks.feature#L21)
|
||||
|
||||
Reference in New Issue
Block a user