From 75c5690280a40e2a69d7964cf247afd54d0d0572 Mon Sep 17 00:00:00 2001 From: Matthew Ross Date: Sat, 18 Jun 2016 13:52:27 -0700 Subject: [PATCH] Response filtering for task endpoints --- src/api/controllers/Tasks.php | 42 ++++++++++-- test/api/controllers/CommentsTest.php | 3 - test/api/controllers/TasksTest.php | 94 +++++++++++++++++++++++++-- 3 files changed, 125 insertions(+), 14 deletions(-) diff --git a/src/api/controllers/Tasks.php b/src/api/controllers/Tasks.php index 8eaffbb..271d194 100644 --- a/src/api/controllers/Tasks.php +++ b/src/api/controllers/Tasks.php @@ -21,6 +21,10 @@ class Tasks extends BaseController { return $this->jsonResponse($response); } + if (!$this->checkBoardAccess($this->getBoardId($task->id), $request)) { + return $this->jsonResponse($response, 403); + } + $this->apiJson->setSuccess(); $this->apiJson->addData($task); @@ -37,7 +41,9 @@ class Tasks extends BaseController { $task = new Task($this->container); $task->loadFromJson($request->getBody()); - if (!$task->save()) { + $column = new Column($this->container, $task->column_id); + + if ($column->id === 0) { $this->logger->addError('Add Task: ', [$task]); $this->apiJson->addAlert('error', 'Error adding task. ' . 'Please check your entries and try again.'); @@ -45,7 +51,14 @@ class Tasks extends BaseController { return $this->jsonResponse($response); } + if (!$this->checkBoardAccess($column->board_id, $request)) { + return $this->jsonResponse($response, 403); + } + + $task->save(); + $actor = new User($this->container, Auth::GetUserId($request)); + $this->dbLogger->logChange($this->container, $actor->id, $actor->username . ' added task ' . $task->title . '.', '', json_encode($task), 'task', $task->id); @@ -64,7 +77,11 @@ class Tasks extends BaseController { return $this->jsonResponse($response, $status); } - $task = new Task($this->container, (int)$args['id']); + $actor = new User($this->container, Auth::GetUserId($request)); + + $id = (int)$args['id']; + $task = new Task($this->container, $id); + $update = new Task($this->container); $update->loadFromJson($request->getBody()); @@ -76,9 +93,13 @@ class Tasks extends BaseController { return $this->jsonResponse($response); } + if (!$this->checkBoardAccess($this->getBoardId($task->column_id), + $request)) { + return $this->jsonResponse($response, 403); + } + $update->save(); - $actor = new User($this->container, Auth::GetUserId($request)); $this->dbLogger->logChange($this->container, $actor->id, $actor->username . ' updated task ' . $task->title, json_encode($task), json_encode($update), @@ -98,6 +119,8 @@ class Tasks extends BaseController { return $this->jsonResponse($response, $status); } + $actor = new User($this->container, Auth::GetUserId($request)); + $id = (int)$args['id']; $task = new Task($this->container, $id); @@ -109,10 +132,13 @@ class Tasks extends BaseController { return $this->jsonResponse($response); } + if (!$this->checkBoardAccess($this->getBoardId($task->id), $request)) { + return $this->jsonResponse($response, 403); + } + $before = $task; $task->delete(); - $actor = new User($this->container, Auth::GetUserId($request)); $this->dbLogger->logChange($this->container, $actor->id, $actor->username . ' removed task ' . $before->title, json_encode($before), '', 'task', $id); @@ -123,5 +149,13 @@ class Tasks extends BaseController { return $this->jsonResponse($response); } + + private function getBoardId($taskId) { + $task = new Task($this->container, $taskId); + + $column = new Column($this->container, $task->column_id); + + return $column->board_id; + } } diff --git a/test/api/controllers/CommentsTest.php b/test/api/controllers/CommentsTest.php index 1095954..f323355 100644 --- a/test/api/controllers/CommentsTest.php +++ b/test/api/controllers/CommentsTest.php @@ -1,9 +1,6 @@ assertEquals(2, count($actual->data)); } + public function testGetTaskForbidden() { + $this->createTask(); + + DataMock::createBoardAdminUser(); + + $args = []; + $args['id'] = 1; + + $request = new RequestMock(); + $request->header = [DataMock::getJwt(2)]; + + $actual = $this->tasks->getTask($request, new ResponseMock(), $args); + $this->assertEquals('Access restricted.', + $actual->alerts[0]['text']); + } + public function testGetTaskUnprivileged() { $args = []; $args['id'] = 1; @@ -128,6 +144,39 @@ class TasksTest extends PHPUnit_Framework_TestCase { $this->assertEquals('failure', $response->status); } + public function testAddTaskForbidden() { + $this->createBoard(); + DataMock::createBoardAdminUser(); + + $request = new RequestMock(); + $request->header = [DataMock::getJwt(2)]; + + $task = DataMock::getTask(); + $task->id = 0; + + $request->payload = $task; + + $actual = $this->tasks->addTask($request, new ResponseMock(), null); + $this->assertEquals('Access restricted.', + $actual->alerts[0]['text']); + } + + public function testRemoveTaskForbidden() { + $this->createTask(); + DataMock::createBoardAdminUser(); + + $request = new RequestMock(); + $request->header = [DataMock::getJwt(2)]; + + $args = []; + $args['id'] = 1; + + $actual = $this->tasks->removeTask($request, + new ResponseMock(), $args); + $this->assertEquals('Access restricted.', + $actual->alerts[0]['text']); + } + public function testUpdateTask() { $this->createTask(); @@ -166,20 +215,51 @@ class TasksTest extends PHPUnit_Framework_TestCase { $actual->alerts[0]['text']); } + public function testUpdateTaskForbidden() { + $this->createTask(); + DataMock::createBoardAdminUser(); + + $task = DataMock::getTask(); + $task->text = 'updated'; + + $args = []; + $args['id'] = 1; + + $request = new RequestMock(); + $request->header = [DataMock::getJwt(2)]; + $request->payload = $task; + + $actual = $this->tasks->updateTask($request, + new ResponseMock(), $args); + $this->assertEquals('Access restricted.', + $actual->alerts[0]['text']); + } + + private function createBoard() { + $board = DataMock::getBoard(); + $board->users = []; + $board->users[] = new User(new ContainerMock(), 1); + $board->auto_actions = []; + + $request = new RequestMock(); + $request->payload = $board; + $request->header = [DataMock::getJwt()]; + + $boards = new Boards(new ContainerMock()); + $boards->addBoard($request, new ResponseMock(), null); + } + private function createTask() { - $request= new RequestMock(); + $this->createBoard(); + $task = DataMock::getTask(); $task->id = 0; - $task->column_id = 0; - $task->category_id = 0; - $task->attachments = []; - $task->comments = []; + $request= new RequestMock(); $request->payload = $task; $request->header = [DataMock::getJwt()]; - $response = $this->tasks->addTask($request, - new ResponseMock(), null); + $response = $this->tasks->addTask($request, new ResponseMock(), null); $this->assertEquals('success', $response->status); $this->tasks = new Tasks(new ContainerMock);