Merge pull request #960 from nextcloud/enhancement/954/rest
REST API enhancements
This commit is contained in:
@@ -38,7 +38,7 @@ return [
|
|||||||
['name' => 'board#deleteUndo', 'url' => '/boards/{boardId}/deleteUndo', 'verb' => 'POST'],
|
['name' => 'board#deleteUndo', 'url' => '/boards/{boardId}/deleteUndo', 'verb' => 'POST'],
|
||||||
['name' => 'board#getUserPermissions', 'url' => '/boards/{boardId}/permissions', 'verb' => 'GET'],
|
['name' => 'board#getUserPermissions', 'url' => '/boards/{boardId}/permissions', 'verb' => 'GET'],
|
||||||
['name' => 'board#addAcl', 'url' => '/boards/{boardId}/acl', 'verb' => 'POST'],
|
['name' => 'board#addAcl', 'url' => '/boards/{boardId}/acl', 'verb' => 'POST'],
|
||||||
['name' => 'board#updateAcl', 'url' => '/boards/{boardId}/acl', 'verb' => 'PUT'],
|
['name' => 'board#updateAcl', 'url' => '/boards/{boardId}/acl/{aclId}', 'verb' => 'PUT'],
|
||||||
['name' => 'board#deleteAcl', 'url' => '/boards/{boardId}/acl/{aclId}', 'verb' => 'DELETE'],
|
['name' => 'board#deleteAcl', 'url' => '/boards/{boardId}/acl/{aclId}', 'verb' => 'DELETE'],
|
||||||
|
|
||||||
// stacks
|
// stacks
|
||||||
@@ -87,7 +87,11 @@ return [
|
|||||||
['name' => 'board_api#delete', 'url' => '/api/v1.0/boards/{boardId}', 'verb' => 'DELETE'],
|
['name' => 'board_api#delete', 'url' => '/api/v1.0/boards/{boardId}', 'verb' => 'DELETE'],
|
||||||
['name' => 'board_api#update', 'url' => '/api/v1.0/boards/{boardId}', 'verb' => 'PUT'],
|
['name' => 'board_api#update', 'url' => '/api/v1.0/boards/{boardId}', 'verb' => 'PUT'],
|
||||||
['name' => 'board_api#undo_delete', 'url' => '/api/v1.0/boards/{boardId}/undo_delete', 'verb' => 'POST'],
|
['name' => 'board_api#undo_delete', 'url' => '/api/v1.0/boards/{boardId}/undo_delete', 'verb' => 'POST'],
|
||||||
|
['name' => 'board_api#addAcl', 'url' => '/api/v1.0/boards/{boardId}/acl', 'verb' => 'POST'],
|
||||||
|
['name' => 'board_api#deleteAcl', 'url' => '/api/v1.0/boards/{boardId}/acl', 'verb' => 'DELETE'],
|
||||||
|
['name' => 'board_api#updateAcl', 'url' => '/api/v1.0/boards/{boardId}/acl', 'verb' => 'PUT'],
|
||||||
|
|
||||||
|
|
||||||
['name' => 'stack_api#index', 'url' => '/api/v1.0/boards/{boardId}/stacks', 'verb' => 'GET'],
|
['name' => 'stack_api#index', 'url' => '/api/v1.0/boards/{boardId}/stacks', 'verb' => 'GET'],
|
||||||
['name' => 'stack_api#getArchived', 'url' => '/api/v1.0/boards/{boardId}/stacks/archived', 'verb' => 'GET'],
|
['name' => 'stack_api#getArchived', 'url' => '/api/v1.0/boards/{boardId}/stacks/archived', 'verb' => 'GET'],
|
||||||
['name' => 'stack_api#get', 'url' => '/api/v1.0/boards/{boardId}/stacks/{stackId}', 'verb' => 'GET'],
|
['name' => 'stack_api#get', 'url' => '/api/v1.0/boards/{boardId}/stacks/{stackId}', 'verb' => 'GET'],
|
||||||
|
|||||||
@@ -1,5 +1,20 @@
|
|||||||
# Nextcloud APIs
|
# Nextcloud APIs
|
||||||
|
|
||||||
|
## Available sharees
|
||||||
|
|
||||||
|
When sharing a board to a user, group or circle, the possible sharees can be obtained though the files_sharing API.
|
||||||
|
|
||||||
|
API endpoint: https://nextcloud.local/index.php/apps/files_sharing/api/v1/sharees
|
||||||
|
|
||||||
|
### Parameters
|
||||||
|
- format: **The response format**
|
||||||
|
- perPage: **Limit response number**
|
||||||
|
- itemType: **List of types. Currently supported are**
|
||||||
|
- 0 user
|
||||||
|
- 1 group
|
||||||
|
- 7 circle
|
||||||
|
|
||||||
|
|
||||||
## Comments
|
## Comments
|
||||||
|
|
||||||
Comments are stored using the Nextcloud Comments API. You can use the WebDAV endpoint of Nextcloud to fetch, update and delete comments.
|
Comments are stored using the Nextcloud Comments API. You can use the WebDAV endpoint of Nextcloud to fetch, update and delete comments.
|
||||||
|
|||||||
64
docs/API.md
64
docs/API.md
@@ -65,6 +65,12 @@ curl -u admin:admin -X GET \
|
|||||||
|
|
||||||
The board list endpoint supports setting an `If-Modified-Since` header to limit the results to entities that are changed after the provided time.
|
The board list endpoint supports setting an `If-Modified-Since` header to limit the results to entities that are changed after the provided time.
|
||||||
|
|
||||||
|
#### Request parameters
|
||||||
|
|
||||||
|
| Parameter | Type | Description |
|
||||||
|
| --------- | ------- | ---------------------------- |
|
||||||
|
| options | Bool | **Optional** Enhance boards with details about labels, stacks and users |
|
||||||
|
|
||||||
#### Response
|
#### Response
|
||||||
|
|
||||||
##### 200 Success
|
##### 200 Success
|
||||||
@@ -288,6 +294,64 @@ Returns an array of board items
|
|||||||
|
|
||||||
##### 200 Success
|
##### 200 Success
|
||||||
|
|
||||||
|
### POST /boards/{boardId}/acl - Add new acl rule
|
||||||
|
|
||||||
|
#### Request body
|
||||||
|
|
||||||
|
| Parameter | Type | Description |
|
||||||
|
| --------- | ------ | ---------------------------------------------------- |
|
||||||
|
| type | Integer | Type of the participant |
|
||||||
|
| participant | String | The uid of the participant |
|
||||||
|
| permissionEdit | Bool | Setting if the participant has edit permissions |
|
||||||
|
| permissionShare | Bool | Setting if the participant has sharing permissions |
|
||||||
|
| permissionManage | Bool | Setting if the participant has management permissions |
|
||||||
|
|
||||||
|
##### Supported participant types:
|
||||||
|
- 0 User
|
||||||
|
- 1 Group
|
||||||
|
- 7 Circle
|
||||||
|
|
||||||
|
#### Response
|
||||||
|
|
||||||
|
##### 200 Success
|
||||||
|
|
||||||
|
```json
|
||||||
|
[{
|
||||||
|
"participant": {
|
||||||
|
"primaryKey": "userid",
|
||||||
|
"uid": "userid",
|
||||||
|
"displayname": "User Name"
|
||||||
|
},
|
||||||
|
"type": 0,
|
||||||
|
"boardId": 1,
|
||||||
|
"permissionEdit": true,
|
||||||
|
"permissionShare": false,
|
||||||
|
"permissionManage": true,
|
||||||
|
"owner": false,
|
||||||
|
"id": 1
|
||||||
|
}]
|
||||||
|
```
|
||||||
|
|
||||||
|
### PUT /boards/{boardId}/acl/{aclId} - Update an acl rule
|
||||||
|
|
||||||
|
#### Request parameters
|
||||||
|
|
||||||
|
| Parameter | Type | Description |
|
||||||
|
| --------- | ------ | ---------------------------------------------------- |
|
||||||
|
| permissionEdit | Bool | Setting if the participant has edit permissions |
|
||||||
|
| permissionShare | Bool | Setting if the participant has sharing permissions |
|
||||||
|
| permissionManage | Bool | Setting if the participant has management permissions |
|
||||||
|
|
||||||
|
#### Response
|
||||||
|
|
||||||
|
##### 200 Success
|
||||||
|
|
||||||
|
### DELETE /boards/{boardId}/acl/{aclId} - Delete an acl rule
|
||||||
|
|
||||||
|
#### Response
|
||||||
|
|
||||||
|
##### 200 Success
|
||||||
|
|
||||||
## Stacks
|
## Stacks
|
||||||
|
|
||||||
### GET /board/{boardId}/stacks - Get stacks
|
### GET /board/{boardId}/stacks - Get stacks
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ use Sabre\HTTP\Util;
|
|||||||
*/
|
*/
|
||||||
class BoardApiController extends ApiController {
|
class BoardApiController extends ApiController {
|
||||||
|
|
||||||
private $service;
|
private $boardService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $appName
|
* @param string $appName
|
||||||
@@ -50,7 +50,7 @@ class BoardApiController extends ApiController {
|
|||||||
*/
|
*/
|
||||||
public function __construct($appName, IRequest $request, BoardService $service, $userId) {
|
public function __construct($appName, IRequest $request, BoardService $service, $userId) {
|
||||||
parent::__construct($appName, $request);
|
parent::__construct($appName, $request);
|
||||||
$this->service = $service;
|
$this->boardService = $service;
|
||||||
$this->userId = $userId;
|
$this->userId = $userId;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -62,16 +62,16 @@ class BoardApiController extends ApiController {
|
|||||||
* Return all of the boards that the current user has access to.
|
* Return all of the boards that the current user has access to.
|
||||||
* @throws StatusException
|
* @throws StatusException
|
||||||
*/
|
*/
|
||||||
public function index() {
|
public function index($details = null) {
|
||||||
$modified = $this->request->getHeader('If-Modified-Since');
|
$modified = $this->request->getHeader('If-Modified-Since');
|
||||||
if ($modified === null || $modified === '') {
|
if ($modified === null || $modified === '') {
|
||||||
$boards = $this->service->findAll();
|
$boards = $this->boardService->findAll(0, $details);
|
||||||
} else {
|
} else {
|
||||||
$date = Util::parseHTTPDate($modified);
|
$date = Util::parseHTTPDate($modified);
|
||||||
if (!$date) {
|
if (!$date) {
|
||||||
throw new StatusException('Invalid If-Modified-Since header provided.');
|
throw new StatusException('Invalid If-Modified-Since header provided.');
|
||||||
}
|
}
|
||||||
$boards = $this->service->findAll($date->getTimestamp());
|
$boards = $this->boardService->findAll($date->getTimestamp(), $details);
|
||||||
}
|
}
|
||||||
return new DataResponse($boards, HTTP::STATUS_OK);
|
return new DataResponse($boards, HTTP::STATUS_OK);
|
||||||
}
|
}
|
||||||
@@ -85,7 +85,7 @@ class BoardApiController extends ApiController {
|
|||||||
* Return the board specified by $this->request->getParam('boardId').
|
* Return the board specified by $this->request->getParam('boardId').
|
||||||
*/
|
*/
|
||||||
public function get() {
|
public function get() {
|
||||||
$board = $this->service->find($this->request->getParam('boardId'));
|
$board = $this->boardService->find($this->request->getParam('boardId'));
|
||||||
return new DataResponse($board, HTTP::STATUS_OK);
|
return new DataResponse($board, HTTP::STATUS_OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -100,7 +100,7 @@ class BoardApiController extends ApiController {
|
|||||||
* Create a board with the specified title and color.
|
* Create a board with the specified title and color.
|
||||||
*/
|
*/
|
||||||
public function create($title, $color) {
|
public function create($title, $color) {
|
||||||
$board = $this->service->create($title, $this->userId, $color);
|
$board = $this->boardService->create($title, $this->userId, $color);
|
||||||
return new DataResponse($board, HTTP::STATUS_OK);
|
return new DataResponse($board, HTTP::STATUS_OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -116,7 +116,7 @@ class BoardApiController extends ApiController {
|
|||||||
* Update a board with the specified boardId, title and color, and archived state.
|
* Update a board with the specified boardId, title and color, and archived state.
|
||||||
*/
|
*/
|
||||||
public function update($title, $color, $archived = false) {
|
public function update($title, $color, $archived = false) {
|
||||||
$board = $this->service->update($this->request->getParam('boardId'), $title, $color, $archived);
|
$board = $this->boardService->update($this->request->getParam('boardId'), $title, $color, $archived);
|
||||||
return new DataResponse($board, HTTP::STATUS_OK);
|
return new DataResponse($board, HTTP::STATUS_OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -129,7 +129,7 @@ class BoardApiController extends ApiController {
|
|||||||
* Delete the board specified by $boardId. Return the board that was deleted.
|
* Delete the board specified by $boardId. Return the board that was deleted.
|
||||||
*/
|
*/
|
||||||
public function delete() {
|
public function delete() {
|
||||||
$board = $this->service->delete($this->request->getParam('boardId'));
|
$board = $this->boardService->delete($this->request->getParam('boardId'));
|
||||||
return new DataResponse($board, HTTP::STATUS_OK);
|
return new DataResponse($board, HTTP::STATUS_OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -142,8 +142,38 @@ class BoardApiController extends ApiController {
|
|||||||
* Undo the deletion of the board specified by $boardId.
|
* Undo the deletion of the board specified by $boardId.
|
||||||
*/
|
*/
|
||||||
public function undoDelete() {
|
public function undoDelete() {
|
||||||
$board = $this->service->deleteUndo($this->request->getParam('boardId'));
|
$board = $this->boardService->deleteUndo($this->request->getParam('boardId'));
|
||||||
return new DataResponse($board, HTTP::STATUS_OK);
|
return new DataResponse($board, HTTP::STATUS_OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @NoAdminRequired
|
||||||
|
* @CORS
|
||||||
|
* @NoCSRFRequired
|
||||||
|
*/
|
||||||
|
public function addAcl($boardId, $type, $participant, $permissionEdit, $permissionShare, $permissionManage) {
|
||||||
|
$acl = $this->boardService->addAcl($boardId, $type, $participant, $permissionEdit, $permissionShare, $permissionManage);
|
||||||
|
return new DataResponse($acl, HTTP::STATUS_OK);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @NoAdminRequired
|
||||||
|
* @CORS
|
||||||
|
* @NoCSRFRequired
|
||||||
|
*/
|
||||||
|
public function updateAcl($aclId, $permissionEdit, $permissionShare, $permissionManage) {
|
||||||
|
$acl = $this->boardService->updateAcl($aclId, $permissionEdit, $permissionShare, $permissionManage);
|
||||||
|
return new DataResponse($acl, HTTP::STATUS_OK);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @NoAdminRequired
|
||||||
|
* @CORS
|
||||||
|
* @NoCSRFRequired
|
||||||
|
*/
|
||||||
|
public function deleteAcl($aclId) {
|
||||||
|
$acl = $this->boardService->deleteAcl($aclId);
|
||||||
|
return new DataResponse($acl, HTTP::STATUS_OK);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -94,7 +94,7 @@ class BoardService {
|
|||||||
/**
|
/**
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
public function findAll($since = 0) {
|
public function findAll($since = 0, $details = null) {
|
||||||
$userInfo = $this->getBoardPrerequisites();
|
$userInfo = $this->getBoardPrerequisites();
|
||||||
$userBoards = $this->boardMapper->findAllByUser($userInfo['user'], null, null, $since);
|
$userBoards = $this->boardMapper->findAllByUser($userInfo['user'], null, null, $since);
|
||||||
$groupBoards = $this->boardMapper->findAllByGroups($userInfo['user'], $userInfo['groups'],null, null, $since);
|
$groupBoards = $this->boardMapper->findAllByGroups($userInfo['user'], $userInfo['groups'],null, null, $since);
|
||||||
@@ -110,7 +110,11 @@ class BoardService {
|
|||||||
$this->boardMapper->mapAcl($acl);
|
$this->boardMapper->mapAcl($acl);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$this->enrichWithStacks($item);
|
if ($details !== null) {
|
||||||
|
$this->enrichWithStacks($item);
|
||||||
|
$this->enrichWithLabels($item);
|
||||||
|
$this->enrichWithUsers($item);
|
||||||
|
}
|
||||||
$permissions = $this->permissionService->matchPermissions($item);
|
$permissions = $this->permissionService->matchPermissions($item);
|
||||||
$item->setPermissions([
|
$item->setPermissions([
|
||||||
'PERMISSION_READ' => $permissions[Acl::PERMISSION_READ],
|
'PERMISSION_READ' => $permissions[Acl::PERMISSION_READ],
|
||||||
@@ -154,8 +158,7 @@ class BoardService {
|
|||||||
'PERMISSION_MANAGE' => $permissions[Acl::PERMISSION_MANAGE],
|
'PERMISSION_MANAGE' => $permissions[Acl::PERMISSION_MANAGE],
|
||||||
'PERMISSION_SHARE' => $permissions[Acl::PERMISSION_SHARE]
|
'PERMISSION_SHARE' => $permissions[Acl::PERMISSION_SHARE]
|
||||||
]);
|
]);
|
||||||
$boardUsers = $this->permissionService->findUsers($boardId);
|
$this->enrichWithUsers($board);
|
||||||
$board->setUsers(array_values($boardUsers));
|
|
||||||
return $board;
|
return $board;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -558,4 +561,22 @@ class BoardService {
|
|||||||
$board->setStacks($stacks);
|
$board->setStacks($stacks);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function enrichWithLabels($board, $since = -1) {
|
||||||
|
$labels = $this->labelMapper->findAll($board->getId(), null, null, $since);
|
||||||
|
|
||||||
|
if(\count($labels) === 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$board->setLabels($labels);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function enrichWithUsers($board, $since = -1) {
|
||||||
|
$boardUsers = $this->permissionService->findUsers($board->getId());
|
||||||
|
if(\count($boardUsers) === 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
$board->setUsers(array_values($boardUsers));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user