diff --git a/appinfo/routes.php b/appinfo/routes.php index 5899c005a..c91c41515 100644 --- a/appinfo/routes.php +++ b/appinfo/routes.php @@ -38,7 +38,7 @@ return [ ['name' => 'board#deleteUndo', 'url' => '/boards/{boardId}/deleteUndo', 'verb' => 'POST'], ['name' => 'board#getUserPermissions', 'url' => '/boards/{boardId}/permissions', 'verb' => 'GET'], ['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'], // stacks @@ -87,7 +87,11 @@ return [ ['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#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#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'], diff --git a/docs/API-Nextcloud.md b/docs/API-Nextcloud.md index 8c657d78a..a8a59d2af 100644 --- a/docs/API-Nextcloud.md +++ b/docs/API-Nextcloud.md @@ -1,5 +1,20 @@ # 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 are stored using the Nextcloud Comments API. You can use the WebDAV endpoint of Nextcloud to fetch, update and delete comments. diff --git a/docs/API.md b/docs/API.md index dc0a11759..d8aada7a3 100644 --- a/docs/API.md +++ b/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. +#### Request parameters + +| Parameter | Type | Description | +| --------- | ------- | ---------------------------- | +| options | Bool | **Optional** Enhance boards with details about labels, stacks and users | + #### Response ##### 200 Success @@ -288,6 +294,64 @@ Returns an array of board items ##### 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 ### GET /board/{boardId}/stacks - Get stacks diff --git a/lib/Controller/BoardApiController.php b/lib/Controller/BoardApiController.php index 68389b307..0fc00f322 100644 --- a/lib/Controller/BoardApiController.php +++ b/lib/Controller/BoardApiController.php @@ -40,7 +40,7 @@ use Sabre\HTTP\Util; */ class BoardApiController extends ApiController { - private $service; + private $boardService; /** * @param string $appName @@ -50,7 +50,7 @@ class BoardApiController extends ApiController { */ public function __construct($appName, IRequest $request, BoardService $service, $userId) { parent::__construct($appName, $request); - $this->service = $service; + $this->boardService = $service; $this->userId = $userId; } @@ -62,16 +62,16 @@ class BoardApiController extends ApiController { * Return all of the boards that the current user has access to. * @throws StatusException */ - public function index() { + public function index($details = null) { $modified = $this->request->getHeader('If-Modified-Since'); if ($modified === null || $modified === '') { - $boards = $this->service->findAll(); + $boards = $this->boardService->findAll(0, $details); } else { $date = Util::parseHTTPDate($modified); if (!$date) { 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); } @@ -85,7 +85,7 @@ class BoardApiController extends ApiController { * Return the board specified by $this->request->getParam('boardId'). */ 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); } @@ -100,7 +100,7 @@ class BoardApiController extends ApiController { * Create a board with the specified title and 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); } @@ -116,7 +116,7 @@ class BoardApiController extends ApiController { * Update a board with the specified boardId, title and color, and archived state. */ 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); } @@ -129,7 +129,7 @@ class BoardApiController extends ApiController { * Delete the board specified by $boardId. Return the board that was deleted. */ 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); } @@ -142,8 +142,38 @@ class BoardApiController extends ApiController { * Undo the deletion of the board specified by $boardId. */ 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); } + /** + * @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); + } + } diff --git a/lib/Service/BoardService.php b/lib/Service/BoardService.php index 992afcb46..1a47f59f3 100644 --- a/lib/Service/BoardService.php +++ b/lib/Service/BoardService.php @@ -94,7 +94,7 @@ class BoardService { /** * @return array */ - public function findAll($since = 0) { + public function findAll($since = 0, $details = null) { $userInfo = $this->getBoardPrerequisites(); $userBoards = $this->boardMapper->findAllByUser($userInfo['user'], 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->enrichWithStacks($item); + if ($details !== null) { + $this->enrichWithStacks($item); + $this->enrichWithLabels($item); + $this->enrichWithUsers($item); + } $permissions = $this->permissionService->matchPermissions($item); $item->setPermissions([ 'PERMISSION_READ' => $permissions[Acl::PERMISSION_READ], @@ -154,8 +158,7 @@ class BoardService { 'PERMISSION_MANAGE' => $permissions[Acl::PERMISSION_MANAGE], 'PERMISSION_SHARE' => $permissions[Acl::PERMISSION_SHARE] ]); - $boardUsers = $this->permissionService->findUsers($boardId); - $board->setUsers(array_values($boardUsers)); + $this->enrichWithUsers($board); return $board; } @@ -558,4 +561,22 @@ class BoardService { $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)); + } + }