# Task OP-11979 - Investigate Nextcloud API

Project: OpenProject
Status: closed
URL: https://community.openproject.org/work_packages/OP-11979

## Details

| Attribute | Value |
| --- | --- |
| Assignee |  |
| Date | 2022-06-10 –  |
| Priority | Medium |
| Target versions | 13.0.0 |
| Category |  |
| Labels |  |

## Description

Check what permission can be set and changed through the API

  - Check if the API is usable as we intend

API parts to check:

- [x] Access control on group folders
- [x] Membership management of a specific group
- [x] Get ID of group by name *OpenProject*
- [x] Complexity of certain requests (e.g. delete all permissions, readd all permissions)
- [x] Check file(s) info endpoint for getting path of folder ID
- [x] Check if group admin can add users to their group

Acceptance Criteria:

- [x] list of curl commands

# Findings

## User/Group Provisioning

<https://docs.nextcloud.com/server/latest/admin_manual/configuration_user/user_provisioning_api.html>

### Get groups:

Request:

``` curl
curl --request GET \
  --url 'https://nextcloud.local/ocs/v1.php/cloud/groups?search=OpenProject' \
  --header 'Authorization: Basic YWRtaW46amR6ZUwtM1Q0TVMta1BYcHQtcDg5WUItWFRKMmY=' \
  --header 'OCS-APIRequest: true'
```

Response:

``` xml
<?xml version="1.0"?>
<ocs>
  <meta>
    <status>ok</status>
    <statuscode>100</statuscode>
    <message>OK</message>
    <totalitems></totalitems>
    <itemsperpage></itemsperpage>
  </meta>
  <data>
    <groups>
      <element>OpenProject</element>
    </groups>
  </data>
</ocs>
```

### Add user to a group:

Request:

``` curl
curl -u 'OpenProject:wKWyg-ZbypL-xx6co-WtA4X-bLyJS' \
     --request POST \
     --url https://nextcloud.local/ocs/v1.php/cloud/users/TestUser/groups \
     -d groupid="OpenProject" \
     --header 'OCS-APIRequest: true'
```

Response:

``` xml
<?xml version="1.0"?>
<ocs>
 <meta>
  <status>ok</status>
  <statuscode>100</statuscode>
  <message>OK</message>
  <totalitems></totalitems>
  <itemsperpage></itemsperpage>
 </meta>
 <data/>
</ocs>
```

### Remove user from a group:

Request:

``` curl
curl -u 'OpenProject:wKWyg-ZbypL-xx6co-WtA4X-bLyJS' \
     --request DELETE \
     --url https://nextcloud.local/ocs/v1.php/cloud/users/TestUser/groups \
     -d groupid="OpenProject" \
     --header 'OCS-APIRequest: true'
```

Response:

``` xml
<?xml version="1.0"?>
<ocs>
 <meta>
  <status>ok</status>
  <statuscode>100</statuscode>
  <message>OK</message>
  <totalitems></totalitems>
  <itemsperpage></itemsperpage>
 </meta>
 <data/>
</ocs>
```

## **Group Folder Permissions**

### Get group folders:

Request:

``` curl
curl --request GET \
  --url https://nextcloud.local/index.php/apps/groupfolders/folders \
  --header 'Accept: application/json' \
  --header 'Authorization: Basic YWRtaW46amR6ZUwtM1Q0TVMta1BYcHQtcDg5WUItWFRKMmY=' \
  --header 'OCS-APIRequest: true'
```

Response:

``` json
{
  "ocs": {
    "meta": {
      "status": "ok",
      "statuscode": 100,
      "message": "OK",
      "totalitems": "",
      "itemsperpage": ""
    },
    "data": {
      "2": {
        "id": 2,
        "mount_point": "OpenProject",
        "groups": {
          "OpenProject": 31
        },
        "quota": -3,
        "size": 1109861,
        "acl": true,
        "manage": [
          {
            "type": "user",
            "id": "OpenProject",
            "displayname": "OpenProject"
          }
        ]
      }
    }
  }
}
```

### Get specific group folder:

Request:

``` curl
curl --request GET \
  --url https://nextcloud.local/index.php/apps/groupfolders/folders/2 \
  --header 'Accept: application/json' \
  --header 'Authorization: Basic YWRtaW46amR6ZUwtM1Q0TVMta1BYcHQtcDg5WUItWFRKMmY=' \
  --header 'OCS-APIRequest: true'
```

Response:

``` json
{
  "ocs": {
    "meta": {
      "status": "ok",
      "statuscode": 100,
      "message": "OK",
      "totalitems": "",
      "itemsperpage": ""
    },
    "data": {
      "id": 2,
      "mount_point": "OpenProject",
      "groups": {
        "OpenProject": 31
      },
      "quota": -3,
      "size": 989753,
      "acl": true,
      "manage": [
        {
          "type": "user",
          "id": "OpenProject",
          "displayname": "OpenProject"
        }
      ]
    }
  }
}
```

### Fetching ACLs for a folder:

Request:

``` curl
curl --request PROPFIND \
  --url https://nextcloud.local/remote.php/dav/files/OpenProject/OpenProject \
  --header 'Authorization: Basic T3BlblByb2plY3Q6Q240WDUtZGdzWkYtdGpHd0otMm9TbmUtVHBFQXM=' \
  --data '<?xml version="1.0"?>
<d:propfind xmlns:d="DAV:"
  xmlns:oc="http://owncloud.org/ns"
  xmlns:nc="http://nextcloud.org/ns">
  <d:prop>
    <nc:acl-list />
  </d:prop>
</d:propfind>'
```

Response:

``` xml
<?xml version="1.0"?>
<d:multistatus
  xmlns:d="DAV:"
  xmlns:s="http://sabredav.org/ns"
  xmlns:oc="http://owncloud.org/ns"
  xmlns:nc="http://nextcloud.org/ns">
  <d:response>
    <d:href>/remote.php/dav/files/OpenProject/OpenProject/</d:href>
    <d:propstat>
      <d:prop>
        <nc:acl-list>
          <nc:acl>
            <nc:acl-mapping-type>user</nc:acl-mapping-type>
            <nc:acl-mapping-id>OpenProject</nc:acl-mapping-id>
            <nc:acl-mapping-display-name>OpenProject</nc:acl-mapping-display-name>
            <nc:acl-mask>0</nc:acl-mask>
            <nc:acl-permissions>31</nc:acl-permissions>
          </nc:acl>
          <nc:acl>
            <nc:acl-mapping-type>group</nc:acl-mapping-type>
            <nc:acl-mapping-id>OpenProject</nc:acl-mapping-id>
            <nc:acl-mapping-display-name>OpenProject</nc:acl-mapping-display-name>
            <nc:acl-mask>31</nc:acl-mask>
            <nc:acl-permissions>1</nc:acl-permissions>
          </nc:acl>
        </nc:acl-list>
      </d:prop>
      <d:status>HTTP/1.1 200 OK</d:status>
    </d:propstat>
  </d:response>
  <d:response>
    <d:href>/remote.php/dav/files/OpenProject/OpenProject/Project%20A/</d:href>
    <d:propstat>
      <d:prop>
        <nc:acl-list>
          <nc:acl>
            <nc:acl-mapping-type>user</nc:acl-mapping-type>
            <nc:acl-mapping-id>OpenProject</nc:acl-mapping-id>
            <nc:acl-mapping-display-name>OpenProject</nc:acl-mapping-display-name>
            <nc:acl-mask>31</nc:acl-mask>
            <nc:acl-permissions>31</nc:acl-permissions>
          </nc:acl>
          <nc:acl>
            <nc:acl-mapping-type>group</nc:acl-mapping-type>
            <nc:acl-mapping-id>OpenProject</nc:acl-mapping-id>
            <nc:acl-mapping-display-name>OpenProject</nc:acl-mapping-display-name>
            <nc:acl-mask>31</nc:acl-mask>
            <nc:acl-permissions>0</nc:acl-permissions>
          </nc:acl>
          <nc:acl>
            <nc:acl-mapping-type>user</nc:acl-mapping-type>
            <nc:acl-mapping-id>andreas</nc:acl-mapping-id>
            <nc:acl-mapping-display-name>Andreas</nc:acl-mapping-display-name>
            <nc:acl-mask>0</nc:acl-mask>
            <nc:acl-permissions>31</nc:acl-permissions>
          </nc:acl>
          <nc:acl>
            <nc:acl-mapping-type>user</nc:acl-mapping-type>
            <nc:acl-mapping-id>member</nc:acl-mapping-id>
            <nc:acl-mapping-display-name>Member</nc:acl-mapping-display-name>
            <nc:acl-mask>0</nc:acl-mask>
            <nc:acl-permissions>31</nc:acl-permissions>
          </nc:acl>
        </nc:acl-list>
      </d:prop>
      <d:status>HTTP/1.1 200 OK</d:status>
    </d:propstat>
  </d:response>
  <d:response>
    <d:href>/remote.php/dav/files/OpenProject/OpenProject/Project%20B/</d:href>
    <d:propstat>
      <d:prop>
        <nc:acl-list>
          <nc:acl>
            <nc:acl-mapping-type>user</nc:acl-mapping-type>
            <nc:acl-mapping-id>OpenProject</nc:acl-mapping-id>
            <nc:acl-mapping-display-name>OpenProject</nc:acl-mapping-display-name>
            <nc:acl-mask>31</nc:acl-mask>
            <nc:acl-permissions>31</nc:acl-permissions>
          </nc:acl>
          <nc:acl>
            <nc:acl-mapping-type>group</nc:acl-mapping-type>
            <nc:acl-mapping-id>OpenProject</nc:acl-mapping-id>
            <nc:acl-mapping-display-name>OpenProject</nc:acl-mapping-display-name>
            <nc:acl-mask>31</nc:acl-mask>
            <nc:acl-permissions>0</nc:acl-permissions>
          </nc:acl>
          <nc:acl>
            <nc:acl-mapping-type>user</nc:acl-mapping-type>
            <nc:acl-mapping-id>andreas</nc:acl-mapping-id>
            <nc:acl-mapping-display-name>Andreas</nc:acl-mapping-display-name>
            <nc:acl-mask>0</nc:acl-mask>
            <nc:acl-permissions>31</nc:acl-permissions>
          </nc:acl>
        </nc:acl-list>
      </d:prop>
      <d:status>HTTP/1.1 200 OK</d:status>
    </d:propstat>
  </d:response>
</d:multistatus>
```

### Change ACLs for group folder

ACLs: <https://github.com/nextcloud/server/blob/b4f36d44c43aac0efdc6c70ff8e46473341a9bfe/lib/public/Constants.php#L65>

Request:

``` curl
curl --request PROPPATCH \
  --url https://nextcloud.local/remote.php/dav/files/admin/OpenProject/Project%20A/minecraft.jpg \
  --header 'Authorization: Basic YWRtaW46amR6ZUwtM1Q0TVMta1BYcHQtcDg5WUItWFRKMmY=' \
  --cookie 'ocg9pf67mryk=0077397d951ff6f1bba3372173b62abf; oc_sessionPassphrase=aYYxLxv1kAmhMLqw0vy1nqPw1Byf0%252Bf9UYHIYOScr8oTaff9NU2Vt7a6A0cv6ArG0CsJM4oJEOhn6KdFKYx8k3PJtfDGbkDj1tMcAwWopgZHx1Zp5tpG02%252Br5auo0rR1; __Host-nc_sameSiteCookielax=true; __Host-nc_sameSiteCookiestrict=true' \
  --data '<?xml version="1.0"?>
<d:propertyupdate xmlns:d="DAV:"
  xmlns:oc="http://owncloud.org/ns"
  xmlns:nc="http://nextcloud.org/ns"
  xmlns:ocs="http://open-collaboration-services.org/ns">
  <d:set>
    <d:prop>
      <nc:acl-list>
        <nc:acl>
          <nc:acl-mapping-type>user</nc:acl-mapping-type>
          <nc:acl-mapping-id>OpenProject</nc:acl-mapping-id>
          <nc:acl-mask>31</nc:acl-mask>
          <nc:acl-permissions>31</nc:acl-permissions>
        </nc:acl>
        <nc:acl>
          <nc:acl-mapping-type>group</nc:acl-mapping-type>
          <nc:acl-mapping-id>OpenProject</nc:acl-mapping-id>
          <nc:acl-mask>31</nc:acl-mask>
          <nc:acl-permissions>0</nc:acl-permissions>
        </nc:acl>
        <nc:acl>
          <nc:acl-mapping-type>user</nc:acl-mapping-type>
          <nc:acl-mapping-id>andreas</nc:acl-mapping-id>
          <nc:acl-mask>31</nc:acl-mask>
          <nc:acl-permissions>31</nc:acl-permissions>
        </nc:acl>
      </nc:acl-list>
    </d:prop>
  </d:set>
</d:propertyupdate>'
```

Response:

``` xml
<?xml version="1.0"?>
<d:multistatus
  xmlns:d="DAV:"
  xmlns:s="http://sabredav.org/ns"
  xmlns:oc="http://owncloud.org/ns"
  xmlns:nc="http://nextcloud.org/ns">
  <d:response>
    <d:href>/remote.php/dav/files/OpenProject/OpenProject/Project%20A/minecraft.jpg</d:href>
    <d:propstat>
      <d:prop>
        <nc:acl-list/>
      </d:prop>
      <d:status>HTTP/1.1 200 OK</d:status>
    </d:propstat>
  </d:response>
</d:multistatus>
```
