mirror of
https://github.com/opencloud-eu/opencloud.git
synced 2026-04-04 23:54:03 -04:00
Merge branch 'master' into config-doc-descriptions
This commit is contained in:
0
docs/services/graph/.gitignore
vendored
Normal file
0
docs/services/graph/.gitignore
vendored
Normal file
17
docs/services/graph/_index.md
Normal file
17
docs/services/graph/_index.md
Normal file
@@ -0,0 +1,17 @@
|
||||
---
|
||||
title: "Graph"
|
||||
date: 2018-05-02T00:00:00+00:00
|
||||
weight: 20
|
||||
geekdocRepo: https://github.com/owncloud/ocis
|
||||
geekdocEditPath: edit/master/docs/services/graph
|
||||
geekdocFilePath: _index.md
|
||||
geekdocCollapseSection: true
|
||||
---
|
||||
|
||||
## Abstract
|
||||
|
||||
This service provides a simple graph world API which can be used by clients or other extensions.
|
||||
|
||||
## Table of Contents
|
||||
|
||||
{{< toc-tree >}}
|
||||
14
docs/services/graph/configuration.md
Normal file
14
docs/services/graph/configuration.md
Normal file
@@ -0,0 +1,14 @@
|
||||
---
|
||||
title: Service Configuration
|
||||
date: 2018-05-02T00:00:00+00:00
|
||||
weight: 20
|
||||
geekdocRepo: https://github.com/owncloud/ocis
|
||||
geekdocEditPath: edit/master/docs/services/graph
|
||||
geekdocFilePath: configuration.md
|
||||
geekdocCollapseSection: true
|
||||
---
|
||||
## Example YAML Config
|
||||
|
||||
{{< include file="services/_includes/graph-config-example.yaml" language="yaml" >}}
|
||||
|
||||
{{< include file="services/_includes/graph_configvars.md" >}}
|
||||
275
docs/services/graph/groups.md
Normal file
275
docs/services/graph/groups.md
Normal file
@@ -0,0 +1,275 @@
|
||||
---
|
||||
title: Groups
|
||||
weight: 40
|
||||
geekdocRepo: https://github.com/owncloud/ocis
|
||||
geekdocEditPath: edit/master/docs/services/graph
|
||||
geekdocFilePath: users.md
|
||||
---
|
||||
|
||||
{{< toc >}}
|
||||
|
||||
## Groups API
|
||||
|
||||
The Groups API is implementing a subset of the functionality of the
|
||||
[MS Graph Group resource](https://docs.microsoft.com/en-us/graph/api/resources/group?view=graph-rest-1.0)
|
||||
The JSON representation of a Group as handled by the Groups API looks like this:
|
||||
|
||||
```
|
||||
{
|
||||
"displayName": "group",
|
||||
"id": "f0d97060-da16-4b0d-9fa4-d1ec43afc5f1"
|
||||
}
|
||||
```
|
||||
|
||||
Our implementation currently supports two Attributes for a Group:
|
||||
|
||||
| Attribute | Description |
|
||||
|---------------|-----------------------------------------------------------------------------------------------------------------------------|
|
||||
| displayName | The groups name |
|
||||
| id | An unique, stable readonly identifier for the group that stays the same for the whole lifetime of the Group, usually a UUID |
|
||||
|
||||
|
||||
### Reading groups
|
||||
|
||||
#### `GET /groups`
|
||||
|
||||
Returns a list of all groups
|
||||
|
||||
Example:
|
||||
|
||||
```
|
||||
curl -k 'https://localhost:9200/graph/v1.0/groups' -u user:password
|
||||
|
||||
```
|
||||
|
||||
Response:
|
||||
|
||||
```
|
||||
{
|
||||
"value": [
|
||||
{
|
||||
"displayName": "group",
|
||||
"id": "38580a2e-7018-42ed-aff6-b2af0b4e9790"
|
||||
},
|
||||
{
|
||||
"displayName": "Example Users",
|
||||
"id": "7a20f238-8a22-4458-902d-47674c317e5f"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
#### `GET /groups?$expand=members`
|
||||
|
||||
Returns a list of all groups including its members
|
||||
|
||||
Example:
|
||||
|
||||
```
|
||||
curl -k 'https://localhost:9200/graph/v1.0/groups?$expand=members' -u user:password
|
||||
|
||||
```
|
||||
|
||||
Response:
|
||||
|
||||
```
|
||||
{
|
||||
"value": [
|
||||
{
|
||||
"displayName": "group",
|
||||
"id": "38580a2e-7018-42ed-aff6-b2af0b4e9790",
|
||||
"members": [
|
||||
{
|
||||
"displayName": "user1",
|
||||
"id": "2e7b7e23-6c42-4d34-81b0-2bed34e51983",
|
||||
"mail": "user1@example.org",
|
||||
"onPremisesSamAccountName": "user1"
|
||||
},
|
||||
{
|
||||
"displayName": "user2",
|
||||
"id": "b45c9e35-0d95-4165-96bc-68bff4a316ed",
|
||||
"mail": "user2@example.org",
|
||||
"onPremisesSamAccountName": "user2"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"displayName": "Example Users",
|
||||
"id": "7a20f238-8a22-4458-902d-47674c317e5f",
|
||||
"members": [
|
||||
{
|
||||
"displayName": "user3",
|
||||
"id": "026fbfef-79ef-4f5d-887b-9eaf42777239",
|
||||
"mail": "user3@example.org",
|
||||
"onPremisesSamAccountName": "user3"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
#### `GET /groups/{groupid}`
|
||||
|
||||
Example:
|
||||
|
||||
```
|
||||
curl -k 'https://localhost:9200/graph/v1.0/groups/7a20f238-8a22-4458-902d-47674c317e5f' -u user:password
|
||||
```
|
||||
|
||||
Response:
|
||||
|
||||
```
|
||||
{
|
||||
"displayName": "Example Users",
|
||||
"id": "7a20f238-8a22-4458-902d-47674c317e5f"
|
||||
}
|
||||
```
|
||||
|
||||
#### `GET /groups/{groupid}?$expand=members`
|
||||
|
||||
Example:
|
||||
|
||||
```
|
||||
curl -k 'https://localhost:9200/graph/v1.0/groups/7a20f238-8a22-4458-902d-47674c317e5f?$expand=members' -u user:password
|
||||
```
|
||||
|
||||
Response:
|
||||
|
||||
```
|
||||
{
|
||||
"displayName": "Example Users",
|
||||
"id": "7a20f238-8a22-4458-902d-47674c317e5f",
|
||||
"members": [
|
||||
{
|
||||
"displayName": "user3",
|
||||
"id": "026fbfef-79ef-4f5d-887b-9eaf42777239",
|
||||
"mail": "user3@example.org",
|
||||
"onPremisesSamAccountName": "user3"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
### Getting Group Members
|
||||
|
||||
#### `GET /groups/{groupid}/members`
|
||||
|
||||
Returns a list of User objects that are members of a group.
|
||||
|
||||
Example:
|
||||
|
||||
```
|
||||
curl -k 'https://localhost:9200/graph/v1.0/groups/7a20f238-8a22-4458-902d-47674c317e5f/members' -u user:password
|
||||
|
||||
```
|
||||
|
||||
Response:
|
||||
|
||||
```
|
||||
[
|
||||
{
|
||||
"displayName": "Test User",
|
||||
"id": "c54b0588-7157-4521-bb52-c1c8ca84ea71",
|
||||
"mail": "example@example.org",
|
||||
"onPremisesSamAccountName": "example"
|
||||
},
|
||||
{
|
||||
"displayName": "Albert Einstein",
|
||||
"id": "4c510ada-c86b-4815-8820-42cdf82c3d51",
|
||||
"mail": "einstein@example.org",
|
||||
"onPremisesSamAccountName": "einstein"
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
### Creating / Updating Groups
|
||||
|
||||
#### `POST /groups`
|
||||
|
||||
Use this to create a new group.
|
||||
h
|
||||
##### Request Body
|
||||
|
||||
Note the missing `"id"` Attribute. It will be generated by the server:
|
||||
|
||||
```
|
||||
{
|
||||
"displayName": "Example Users"
|
||||
}
|
||||
```
|
||||
|
||||
##### Response
|
||||
|
||||
When successful, the response will return the new group including the newly allocated `"id"`:
|
||||
|
||||
```
|
||||
{
|
||||
"displayName": "Example Users",
|
||||
"id": "7a20f238-8a22-4458-902d-47674c317e5f"
|
||||
}
|
||||
```
|
||||
|
||||
#### `DELETE /groups/{id}`
|
||||
|
||||
Example:
|
||||
|
||||
```
|
||||
curl -k --request DELETE 'https://localhost:9200/graph/v1.0/groups/7a20f238-8a22-4458-902d-47674c317e5f' -u user:password
|
||||
```
|
||||
|
||||
When successful the API returns no response body and the HTTP status code 204 (No Content)
|
||||
|
||||
#### `PATCH /groups/{id}`
|
||||
|
||||
Updating attributes of a single group is supposed to be done with a patch request. This is however currently not fully
|
||||
implemented for our write-enabled backends. The PATCH request can however be used to add multiple members to a group at once.
|
||||
See below.
|
||||
|
||||
### Adding a single member to a group
|
||||
|
||||
#### `POST /groups/{id}/members/$ref`
|
||||
|
||||
The request body contains a single attribute "`@odata.id`" referencing the new member of the group by URI. Example:
|
||||
|
||||
```
|
||||
curl -k --header "Content-Type: application/json" \
|
||||
--request POST --data \
|
||||
'{ "@odata.id": "https://localhost:9200/graph/v1.0/users/4c510ada-c86b-4815-8820-42cdf82c3d51" }' \
|
||||
'https://localhost:9200/graph/v1.0/groups/7a20f238-8a22-4458-902d-47674c317e5f/members/$ref' -u user:password
|
||||
|
||||
```
|
||||
|
||||
When successful the API returns no response body and the HTTP status code 204 (No Content)
|
||||
|
||||
### Adding multiple members in a single request
|
||||
|
||||
#### `PATCH /groups/{id}`
|
||||
|
||||
The request body contains the attribute `members@odata.bind` holding a list of URI references for the new members.
|
||||
Example:
|
||||
|
||||
```
|
||||
{
|
||||
"members@odata.bind": [
|
||||
"https://localhost:9200/graph/v1.0/users/4c510ada-c86b-4815-8820-42cdf82c3d51",
|
||||
"https://localhost:9200/graph/v1.0/users/c54b0588-7157-4521-bb52-c1c8ca84ea71"
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
When successful the API returns no response body and the HTTP status code 204 (No Content)
|
||||
|
||||
### Removing a member
|
||||
|
||||
#### `DELETE /groups/{groupid}/members/{id}/$ref`
|
||||
|
||||
Example
|
||||
|
||||
```
|
||||
curl -k --request DELETE \
|
||||
'https://localhost:9200/graph/v1.0/groups/7a20f238-8a22-4458-902d-47674c317e5f/members/4c510ada-c86b-4815-8820-42cdf82c3d51/$ref' \
|
||||
-u user:password
|
||||
```
|
||||
|
||||
When successful the API returns no response body and the HTTP status code 204 (No Content)
|
||||
258
docs/services/graph/spaces.md
Normal file
258
docs/services/graph/spaces.md
Normal file
@@ -0,0 +1,258 @@
|
||||
---
|
||||
title: Spaces
|
||||
weight: 20
|
||||
geekdocRepo: https://github.com/owncloud/ocis
|
||||
geekdocEditPath: edit/master/docs/services/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>
|
||||
```
|
||||
270
docs/services/graph/users.md
Normal file
270
docs/services/graph/users.md
Normal file
@@ -0,0 +1,270 @@
|
||||
---
|
||||
title: Users
|
||||
weight: 30
|
||||
geekdocRepo: https://github.com/owncloud/ocis
|
||||
geekdocEditPath: edit/master/docs/services/graph
|
||||
geekdocFilePath: users.md
|
||||
---
|
||||
|
||||
{{< toc >}}
|
||||
|
||||
## Users API
|
||||
|
||||
The Users API is implementing a subset of the functionality of the
|
||||
[MS Graph User resource](https://docs.microsoft.com/en-us/graph/api/resources/user?view=graph-rest-1.0)
|
||||
The JSON representation of a User handled by the Users API looks like this:
|
||||
|
||||
```
|
||||
{
|
||||
"displayName": "Albert Einstein",
|
||||
"id": "4c510ada-c86b-4815-8820-42cdf82c3d51",
|
||||
"mail": "einstein@example.org",
|
||||
"onPremisesSamAccountName": "einstein"
|
||||
}
|
||||
```
|
||||
|
||||
Our implementation currently supports only a limited set of Attributes of Users:
|
||||
|
||||
| Attribute | Description |
|
||||
|---------------|---------------------------------------------------------------------------------------------------------------------------|
|
||||
| displayName | The full name of the user, usually a combination of given name and last name |
|
||||
| mail | The user's email address |
|
||||
| onPremisesSamAccountName | The loginname/account name of the user |
|
||||
| id | An unique, stable readonly identifier for the user that stays the same for the whole lifetime of the User, usually a UUID |
|
||||
| passwordProfile | Contains the password of the users. This is only present when updating or creating users. It is never returned by the API |
|
||||
|
||||
|
||||
### Reading users
|
||||
|
||||
#### `GET /me`
|
||||
|
||||
Returns the user object of the currently signed-in user
|
||||
|
||||
Example:
|
||||
```
|
||||
curl -k 'https://localhost:9200/graph/v1.0/me' -u user:password
|
||||
```
|
||||
|
||||
Response:
|
||||
```
|
||||
{
|
||||
"displayName": "Albert Einstein",
|
||||
"id": "4c510ada-c86b-4815-8820-42cdf82c3d51",
|
||||
"mail": "einstein@example.org",
|
||||
"onPremisesSamAccountName": "einstein"
|
||||
}
|
||||
```
|
||||
|
||||
#### `GET /users`
|
||||
|
||||
Returns a list of all users
|
||||
|
||||
Example:
|
||||
|
||||
```
|
||||
curl -k 'https://localhost:9200/graph/v1.0/users' -u user:password
|
||||
|
||||
```
|
||||
|
||||
Response:
|
||||
|
||||
```
|
||||
{
|
||||
"value": [
|
||||
{
|
||||
"displayName": "Albert Einstein",
|
||||
"id": "4c510ada-c86b-4815-8820-42cdf82c3d51",
|
||||
"mail": "einstein@example.org",
|
||||
"onPremisesSamAccountName": "einstein"
|
||||
},
|
||||
{
|
||||
"displayName": "Maurice Moss",
|
||||
"id": "058bff95-6708-4fe5-91e4-9ea3d377588b",
|
||||
"mail": "moss@example.org",
|
||||
"onPremisesSamAccountName": "moss"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
#### `GET /users?$expand=memberOf`
|
||||
|
||||
Returns a list of all users
|
||||
|
||||
Example:
|
||||
|
||||
```
|
||||
curl -k 'https://localhost:9200/graph/v1.0/users?$expand=memberOf' -u user:password
|
||||
|
||||
```
|
||||
|
||||
Response:
|
||||
|
||||
```
|
||||
{
|
||||
"value": [
|
||||
{
|
||||
"displayName": "Albert Einstein",
|
||||
"id": "4c510ada-c86b-4815-8820-42cdf82c3d51",
|
||||
"mail": "einstein@example.org",
|
||||
"onPremisesSamAccountName": "einstein",
|
||||
"memberOf": [
|
||||
{
|
||||
"displayName": "users",
|
||||
"id": "509a9dcd-bb37-4f4f-a01a-19dca27d9cfa"
|
||||
},
|
||||
{
|
||||
"displayName": "sailing-lovers",
|
||||
"id": "6040aa17-9c64-4fef-9bd0-77234d71bad0"
|
||||
},
|
||||
{
|
||||
"displayName": "violin-haters",
|
||||
"id": "dd58e5ec-842e-498b-8800-61f2ec6f911f"
|
||||
},
|
||||
{
|
||||
"displayName": "physics-lovers",
|
||||
"id": "262982c1-2362-4afa-bfdf-8cbfef64a06e"
|
||||
}
|
||||
],
|
||||
},
|
||||
{
|
||||
"displayName": "Maurice Moss",
|
||||
"id": "058bff95-6708-4fe5-91e4-9ea3d377588b",
|
||||
"mail": "moss@example.org",
|
||||
"onPremisesSamAccountName": "moss",
|
||||
"memberOf": [
|
||||
{
|
||||
"displayName": "users",
|
||||
"id": "509a9dcd-bb37-4f4f-a01a-19dca27d9cfa"
|
||||
}
|
||||
],
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
#### `GET /users/{userid or accountname}`
|
||||
|
||||
Example:
|
||||
|
||||
```
|
||||
curl -k 'https://localhost:9200/graph/v1.0/users/058bff95-6708-4fe5-91e4-9ea3d377588b' -u user:password
|
||||
```
|
||||
|
||||
Response:
|
||||
|
||||
```
|
||||
{
|
||||
"displayName": "Maurice Moss",
|
||||
"id": "058bff95-6708-4fe5-91e4-9ea3d377588b",
|
||||
"mail": "moss@example.org",
|
||||
"onPremisesSamAccountName": "moss"
|
||||
}
|
||||
```
|
||||
|
||||
#### `GET /users/{userid or accountname}?$expand=memberOf`
|
||||
|
||||
Example:
|
||||
|
||||
```
|
||||
curl -k 'https://localhost:9200/graph/v1.0/users/058bff95-6708-4fe5-91e4-9ea3d377588b?$expand=memberOf' -u user:password
|
||||
```
|
||||
|
||||
Response:
|
||||
|
||||
```
|
||||
{
|
||||
"displayName": "Maurice Moss",
|
||||
"id": "058bff95-6708-4fe5-91e4-9ea3d377588b",
|
||||
"mail": "moss@example.org",
|
||||
"onPremisesSamAccountName": "moss",
|
||||
"memberOf": [
|
||||
{
|
||||
"displayName": "users",
|
||||
"id": "509a9dcd-bb37-4f4f-a01a-19dca27d9cfa"
|
||||
}
|
||||
],
|
||||
}
|
||||
```
|
||||
|
||||
### Creating / Updating Users
|
||||
|
||||
#### `POST /users`
|
||||
|
||||
Use this to create a new user.
|
||||
|
||||
##### Request Body
|
||||
|
||||
Note the missing `"id"` Attribute. It will be generated by the server:
|
||||
|
||||
```
|
||||
{
|
||||
"displayName": "Example User",
|
||||
"mail": "example@example.org",
|
||||
"onPremisesSamAccountName": "example",
|
||||
"passwordProfile": {
|
||||
"password": "ThePassword"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
##### Response
|
||||
|
||||
When successful, the response will return the new user, without the password, but including the newly allocated `"id"`:
|
||||
|
||||
```
|
||||
{
|
||||
"displayName":"Example User",
|
||||
"id":"c067b139-c91c-4e47-8be6-669156a0587b",
|
||||
"mail":"example@example.org",
|
||||
"onPremisesSamAccountName":"example"
|
||||
}
|
||||
```
|
||||
|
||||
#### `DELETE /users/{id}`
|
||||
|
||||
Example:
|
||||
|
||||
```
|
||||
curl -k --request DELETE 'https://localhost:9200/graph/v1.0/users/c067b139-c91c-4e47-8be6-669156a0587b' -u user:password
|
||||
```
|
||||
|
||||
When successful the API returns no response body and the HTTP status code 204 (No Content)
|
||||
|
||||
|
||||
#### `PATCH /users/{id}`
|
||||
|
||||
Updating attributes of a single user can be done with a patch request. The Request Body contains the new values of the attributes
|
||||
to be updated. E.g. to update the `displayName` Attribute:
|
||||
|
||||
```
|
||||
curl -k --header "Content-Type: application/json" \
|
||||
--request PATCH --data '{"displayName": "Test User" }' \
|
||||
'https://localhost:9200/graph/v1.0/users/c54b0588-7157-4521-bb52-c1c8ca84ea71' -u user:password
|
||||
```
|
||||
|
||||
Similar to creating a user via `POST`, the `PATCH` request will return the user object containing the new attribute values.
|
||||
|
||||
### Change password
|
||||
|
||||
#### `POST /me/changePassword`
|
||||
|
||||
Users can change their own password by sending a POST request to `/me/changePassword`
|
||||
|
||||
##### Request Body
|
||||
|
||||
```
|
||||
{
|
||||
"currentPassword": "current",
|
||||
"newPassword": "new"
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
When successful the API returns no response body and the HTTP status code 204 (No Content)
|
||||
|
||||
```
|
||||
curl -i -k --header "Content-Type: application/json" \
|
||||
--request POST --data '{"currentPassword": "current", "newPassword": "new" }' \
|
||||
'https://localhost:9200/graph/v1.0/me/changePassword' -u user:current
|
||||
```
|
||||
Reference in New Issue
Block a user