Route security and tests complete

This commit is contained in:
kiswa 2016-05-31 21:46:26 +00:00
parent 4da377f426
commit 6a4156291b
11 changed files with 297 additions and 85 deletions

View File

@ -4,12 +4,18 @@ use RedBeanPHP\R;
class Comments extends BaseController {
public function getComment($request, $response, $args) {
$status = $this->secureRoute($request, $response,
SecurityLevel::User);
if ($status !== 200) {
return $this->jsonResponse($response, $status);
}
$comment = new Comment($this->container, (int)$args['id']);
if ($comment->id === 0) {
$this->logger->addError('Attempt to load comment ' .
$args['id'] . ' failed.');
$this->apiJson->addAlert('error', 'No column found for ID ' .
$this->apiJson->addAlert('error', 'No comment found for ID ' .
$args['id'] . '.');
return $this->jsonResponse($response);
@ -22,6 +28,12 @@ class Comments extends BaseController {
}
public function addComment($request, $response, $args) {
$status = $this->secureRoute($request, $response,
SecurityLevel::User);
if ($status !== 200) {
return $this->jsonResponse($response, $status);
}
$comment = new Comment($this->container);
$comment->loadFromJson($request->getBody());
@ -33,9 +45,9 @@ class Comments extends BaseController {
return $this->jsonResponse($response);
}
// TODO: Get existing user to log user_id and name
$this->dbLogger->logChange($this->container, 0,
'$user->name added comment ' . $comment->id . '.',
$actor = new User($this->container, Auth::GetUserId($request));
$this->dbLogger->logChange($this->container, $actor->id,
$actor->username . ' added comment ' . $comment->id . '.',
'', json_encode($comment), 'comment', $comment->id);
$this->apiJson->setSuccess();
@ -45,6 +57,15 @@ class Comments extends BaseController {
}
public function updateComment($request, $response, $args) {
$status = $this->secureRoute($request, $response,
SecurityLevel::User);
if ($status !== 200) {
return $this->jsonResponse($response, $status);
}
// TODO: If user, verify submitting user
$actor = new User($this->container, Auth::GetUserId($request));
$comment = new Comment($this->container, (int)$args['id']);
$update = new Comment($this->container);
$update->loadFromJson($request->getBody());
@ -59,9 +80,8 @@ class Comments extends BaseController {
$update->save();
// TODO: Get existing user to log user_id and name
$this->dbLogger->logChange($this->container, 0,
'$user->name updated comment ' . $update->id,
$this->dbLogger->logChange($this->container, $actor->id,
$actor->username . ' updated comment ' . $update->id,
json_encode($comment), json_encode($update),
'comment', $update->id);
@ -72,6 +92,15 @@ class Comments extends BaseController {
}
public function removeComment($request, $response, $args) {
$status = $this->secureRoute($request, $response,
SecurityLevel::User);
if ($status !== 200) {
return $this->jsonResponse($response, $status);
}
// TODO: If user, verify submitting user
$actor = new User($this->container, Auth::GetUserId($request));
$id = (int)$args['id'];
$comment = new Comment($this->container, $id);
@ -86,9 +115,8 @@ class Comments extends BaseController {
$before = $comment;
$comment->delete();
// TODO: Get existing user to log user_id and name
$this->dbLogger->logChange($this->container, 0,
'$user->name removed comment ' . $before->id,
$this->dbLogger->logChange($this->container, $actor->id,
$actor->username . ' removed comment ' . $before->id,
json_encode($before), '', 'comment', $id);
$this->apiJson->setSuccess();

View File

@ -4,6 +4,12 @@ use RedBeanPHP\R;
class Tasks extends BaseController {
public function getTask($request, $response, $args) {
$status = $this->secureRoute($request, $response,
SecurityLevel::User);
if ($status !== 200) {
return $this->jsonResponse($response, $status);
}
$task = new Task($this->container, (int)$args['id']);
if ($task->id === 0) {
@ -22,6 +28,12 @@ class Tasks extends BaseController {
}
public function addTask($request, $response, $args) {
$status = $this->secureRoute($request, $response,
SecurityLevel::User);
if ($status !== 200) {
return $this->jsonResponse($response, $status);
}
$task = new Task($this->container);
$task->loadFromJson($request->getBody());
@ -33,9 +45,9 @@ class Tasks extends BaseController {
return $this->jsonResponse($response);
}
// TODO: Get existing user to log user_id and name
$this->dbLogger->logChange($this->container, 0,
'$user->name added task ' . $task->title . '.',
$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);
$this->apiJson->setSuccess();
@ -46,6 +58,12 @@ class Tasks extends BaseController {
}
public function updateTask($request, $response, $args) {
$status = $this->secureRoute($request, $response,
SecurityLevel::User);
if ($status !== 200) {
return $this->jsonResponse($response, $status);
}
$task = new Task($this->container, (int)$args['id']);
$update = new Task($this->container);
$update->loadFromJson($request->getBody());
@ -74,6 +92,12 @@ class Tasks extends BaseController {
}
public function removeTask($request, $response, $args) {
$status = $this->secureRoute($request, $response,
SecurityLevel::User);
if ($status !== 200) {
return $this->jsonResponse($response, $status);
}
$id = (int)$args['id'];
$task = new Task($this->container, $id);
@ -88,9 +112,9 @@ class Tasks extends BaseController {
$before = $task;
$task->delete();
// TODO: Get existing user to log user_id and name
$this->dbLogger->logChange($this->container, 0,
'$user->name removed task ' . $before->title,
$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);
$this->apiJson->setSuccess();

View File

@ -5,7 +5,7 @@ class Category extends BaseModel {
public $board_id = 0;
public function __construct($container, $id = 0) {
parent::__construct('column', $id, $container);
parent::__construct('category', $id, $container);
$this->loadFromBean($this->bean);
}

View File

@ -3,7 +3,7 @@ class Task extends BaseModel {
public $id = 0;
public $title = '';
public $description = '';
public $assignee_id = 0;
public $assignee = 0;
public $category_id = 0;
public $column_id = 0;
public $color = '';
@ -25,7 +25,7 @@ class Task extends BaseModel {
$bean->id = $this->id;
$bean->title = $this->title;
$bean->description = $this->description;
$bean->assignee_id = $this->assignee_id;
$bean->assignee = $this->assignee;
$bean->category_id = $this->category_id;
$bean->column_id = $this->column_id;
$bean->color = $this->color;
@ -111,7 +111,7 @@ class Task extends BaseModel {
$this->id = (int)$obj->id;
$this->title = $obj->title;
$this->description = $obj->description;
$this->assignee_id = (int)$obj->assignee_id;
$this->assignee = (int)$obj->assignee;
$this->category_id = (int)$obj->category_id;
$this->column_id = (int)$obj->column_id;
$this->color = $obj->color;

View File

@ -91,8 +91,8 @@ class DataMock {
public static function getCategory() {
$category = new stdClass();
$category->id = 1;
$category->board_id = 1;
$category->name = 'cat1';
$category->board_id = 1;
return $category;
}
@ -166,13 +166,13 @@ class DataMock {
$task->id = 1;
$task->title = 'test';
$task->description = 'description';
$task->assignee_id = 1;
$task->assignee = 1;
$task->category_id = 1;
$task->column_id = 1;
$task->color = '#ffffff';
$task->due_date = 1234567890;
$task->points = 3;
$task->position = 1;
$task->column_id = 1;
$task->attachments[] = DataMock::getAttachment();
$task->comments[] = DataMock::getComment();

View File

@ -190,6 +190,11 @@ class BoardsTest extends PHPUnit_Framework_TestCase {
$request = new RequestMock();
$request->header = [DataMock::getJwt()];
$board = DataMock::getBoard();
$board->id = 0;
$request->payload = $board;
$response = $this->boards->addBoard($request,
new ResponseMock(), null);
$this->assertTrue($response->status === 'success');

View File

@ -147,9 +147,6 @@ class ColumnsTest extends PHPUnit_Framework_TestCase {
$this->assertEquals('error', $response->alerts[2]['type']);
}
/**
* @group single
*/
public function testUpdateColumnUnprivileged() {
$res = DataMock::createUnpriviligedUser();
$this->assertEquals('success', $res->status);

View File

@ -14,70 +14,119 @@ class CommentsTest extends PHPUnit_Framework_TestCase {
public function setUp() {
RedBeanPHP\R::nuke();
Auth::CreateInitialAdmin(new ContainerMock());
$this->comments = new Comments(new ContainerMock());
}
public function testGetComment() {
$expected = new ApiJson();
$expected->addAlert('error', 'No column found for ID 1.');
$request = new RequestMock();
$request->header = [DataMock::getJwt()];
$args = [];
$args['id'] = 1;
$actual = $this->comments->getComment(null,
$actual = $this->comments->getComment($request,
new ResponseMock(), $args);
$this->assertEquals($expected, $actual);
$this->assertEquals('No comment found for ID 1.',
$actual->alerts[0]['text']);
$this->createComment();
$actual = $this->comments->getComment(null,
$this->comments = new Comments(new ContainerMock());
$request->header = [DataMock::getJwt()];
$actual = $this->comments->getComment($request,
new ResponseMock(), $args);
$this->assertTrue($actual->status === 'success');
$this->assertTrue(count($actual->data) === 1);
$this->assertEquals('success', $actual->status);
$this->assertEquals(2, count($actual->data));
}
public function testGetCommentUnprivileged() {
$res = DataMock::createUnpriviligedUser();
$this->assertEquals('success', $res->status);
$request = new RequestMock();
$request->header = [DataMock::getJwt(2)];
$actual = $this->comments->getComment($request,
new ResponseMock(), null);
$this->assertEquals('Insufficient privileges.',
$actual->alerts[0]['text']);
}
public function testAddRemoveComment() {
$expected = new ApiJson();
$actual = $this->createComment();
$this->comments = new Comments(new ContainerMock());
$expected->setSuccess();
$expected->addAlert('success', 'Comment added.');
$this->assertEquals($expected, $actual);
$expected->addAlert('success', 'Comment removed.');
$request = new RequestMock();
$request->header = [DataMock::getJwt()];
$args = [];
$args['id'] = 1;
$actual = $this->comments->removeComment(null,
$actual = $this->comments->removeComment($request,
new ResponseMock(), $args);
$this->assertEquals($expected, $actual);
$this->assertEquals('Comment removed.', $actual->alerts[0]['text']);
}
public function testAddBadComment() {
public function testAddRemoveCommentUnprivileged() {
$res = DataMock::createUnpriviligedUser();
$this->assertEquals('success', $res->status);
$request = new RequestMock();
$request->header = [DataMock::getJwt(2)];
$comment = DataMock::getComment();
$comment->id = 0;
$request->payload = $comment;
$actual = $this->comments->addComment($request,
new ResponseMock(), null);
$this->assertEquals('Insufficient privileges.',
$actual->alerts[0]['text']);
$args = [];
$args['id'] = 1;
$request->header = [DataMock::getJwt(2)];
$actual = $this->comments->removeComment($request,
new ResponseMock(), $args);
$this->assertEquals('Insufficient privileges.',
$actual->alerts[0]['text']);
}
public function testAddRemoveBadComment() {
$request = new RequestMock();
$request->invalidPayload = true;
$request->header = [DataMock::getJwt()];
$response = $this->comments->addComment($request,
new ResponseMock(), null);
$this->assertTrue($response->status === 'failure');
$this->assertTrue($response->alerts[0]['type'] === 'error');
}
$this->assertEquals('failure', $response->status);
$this->assertEquals('error', $response->alerts[0]['type']);
$this->comments = new Comments(new ContainerMock());
$request->header = [DataMock::getJwt()];
public function testRemoveBadComment() {
$args = [];
$args['id'] = 5; // No such comment
$response = $this->comments->removeComment(null,
$response = $this->comments->removeComment($request,
new ResponseMock(), $args);
$this->assertTrue($response->status === 'failure');
$this->assertEquals('failure', $response->status);
}
public function testUpdateComment() {
$this->createComment();
$this->comments = new Comments(new ContainerMock());
$comment = DataMock::getComment();
$comment->text = 'updated';
@ -87,15 +136,42 @@ class CommentsTest extends PHPUnit_Framework_TestCase {
$request = new RequestMock();
$request->payload = $comment;
$request->header = [DataMock::getJwt()];
$response = $this->comments->updateComment($request,
new ResponseMock(), $args);
$this->assertTrue($response->status === 'success');
$this->assertEquals('success', $response->status);
$this->comments = new Comments(new ContainerMock());
$request->payload = new stdClass();
$request->header = [DataMock::getJwt()];
$response = $this->comments->updateComment($request,
new ResponseMock(), $args);
$this->assertTrue($response->alerts[2]['type'] === 'error');
$this->assertEquals('error', $response->alerts[0]['type']);
}
public function testUpdateCommentUnprivileged() {
$res = DataMock::createUnpriviligedUser();
$this->assertEquals('success', $res->status);
$this->createComment();
$this->comments = new Comments(new ContainerMock());
$comment = DataMock::getComment();
$comment->text = 'updated';
$args = [];
$args['id'] = $comment->id;
$request = new RequestMock();
$request->payload = $comment;
$request->header = [DataMock::getJwt(2)];
$actual = $this->comments->updateComment($request,
new ResponseMock(), $args);
$this->assertEquals('Insufficient privileges.',
$actual->alerts[0]['text']);
}
private function createComment() {
@ -104,10 +180,11 @@ class CommentsTest extends PHPUnit_Framework_TestCase {
$comment->id = 0;
$request->payload = $comment;
$request->header = [DataMock::getJwt()];
$response = $this->comments->addComment($request,
new ResponseMock(), null);
$this->assertTrue($response->status === 'success');
$this->assertEquals('success', $response->status);
return $response;
}

View File

@ -7,73 +7,125 @@ class TasksTest extends PHPUnit_Framework_TestCase {
public static function setupBeforeClass() {
try {
RedBeanPHP\R::setup('sqlite:tests.db');
// RedBeanPHP\R::fancyDebug(true);
} catch (Exception $ex) { }
}
public function setUp() {
RedBeanPHP\R::nuke();
Auth::CreateInitialAdmin(new ContainerMock());
$this->tasks = new Tasks(new ContainerMock());
}
public function testGetTask() {
$expected = new ApiJson();
$expected->addAlert('error', 'No task found for ID 1.');
$args = [];
$args['id'] = 1;
$actual = $this->tasks->getTask(null,
$request = new RequestMock();
$request->header = [DataMock::getJwt()];
$actual = $this->tasks->getTask($request,
new ResponseMock(), $args);
$this->assertEquals($expected, $actual);
$this->assertEquals('No task found for ID 1.',
$actual->alerts[0]['text']);
$this->createTask();
$actual = $this->tasks->getTask(null,
new ResponseMock(), $args);
$this->assertTrue($actual->status === 'success');
$this->assertTrue(count($actual->data) === 1);
$request->header = [DataMock::getJwt()];
$actual = $this->tasks->getTask($request, new ResponseMock(), $args);
$this->assertEquals('success', $actual->status);
$this->assertEquals(2, count($actual->data));
}
public function testGetTaskUnprivileged() {
$args = [];
$args['id'] = 1;
$this->createTask();
DataMock::createUnpriviligedUser();
$request = new RequestMock();
$request->header = [DataMock::getJwt(2)];
$actual = $this->tasks->getTask($request, new ResponseMock(), $args);
$this->assertEquals('Insufficient privileges.',
$actual->alerts[0]['text']);
}
public function testAddRemoveTask() {
$expected = new ApiJson();
$actual = $this->createTask();
$expected->setSuccess();
$expected->addAlert('success', 'Task test added.');
$this->assertEquals($expected, $actual);
$expected->addAlert('success', 'Task test removed.');
$this->assertEquals('success', $actual->status);
$args = [];
$args['id'] = 1;
$actual = $this->tasks->removeTask(null,
$request = new RequestMock();
$request->header = [DataMock::getJwt()];
$actual = $this->tasks->removeTask($request,
new ResponseMock(), $args);
$this->assertEquals($expected, $actual);
$this->assertEquals('Task test removed.', $actual->alerts[0]['text']);
}
public function testAddRemoveTaskUnprivileged() {
DataMock::createUnpriviligedUser();
$request= new RequestMock();
$task = DataMock::getTask();
$task->id = 0;
$task->column_id = 0;
$task->category_id = 0;
$task->attachments = [];
$task->comments = [];
$request->payload = $task;
$request->header = [DataMock::getJwt(2)];
$actual = $this->tasks->addTask($request,
new ResponseMock(), null);
$this->assertEquals('Insufficient privileges.',
$actual->alerts[0]['text']);
$this->tasks = new Tasks(new ContainerMock);
$args = [];
$args['id'] = 1;
$request = new RequestMock();
$request->header = [DataMock::getJwt(2)];
$actual = $this->tasks->removeTask($request,
new ResponseMock(), $args);
$this->assertEquals('Insufficient privileges.',
$actual->alerts[0]['text']);
}
public function testAddBadTask() {
$request = new RequestMock();
$request->invalidPayload = true;
$request->header = [DataMock::getJwt()];
$response = $this->tasks->addTask($request,
new ResponseMock(), null);
$this->assertTrue($response->status === 'failure');
$this->assertTrue($response->alerts[0]['type'] === 'error');
$this->assertEquals('failure', $response->status);
$this->assertEquals('error', $response->alerts[0]['type']);
}
public function testRemoveBadTask() {
$request = new RequestMock();
$request->header = [DataMock::getJwt()];
$args = [];
$args['id'] = 5; // No such task
$response = $this->tasks->removeTask(null,
$response = $this->tasks->removeTask($request,
new ResponseMock(), $args);
$this->assertTrue($response->status === 'failure');
$this->assertEquals('failure', $response->status);
}
public function testUpdateTask() {
@ -87,29 +139,53 @@ class TasksTest extends PHPUnit_Framework_TestCase {
$request = new RequestMock();
$request->payload = $task;
$request->header = [DataMock::getJwt()];
$response = $this->tasks->updateTask($request,
new ResponseMock(), $args);
$this->assertTrue($response->status === 'success');
$this->assertEquals('success', $response->status);
$this->tasks = new Tasks(new ContainerMock());
$request->payload = new stdClass();
$request->header = [DataMock::getJwt()];
$response = $this->tasks->updateTask($request,
new ResponseMock(), $args);
$this->assertTrue($response->alerts[2]['type'] === 'error');
$this->assertEquals('error', $response->alerts[0]['type']);
}
public function testUpdateTaskUnprivileged() {
DataMock::createUnpriviligedUser();
$request = new RequestMock();
$request->header = [DataMock::getJwt(2)];
$actual = $this->tasks->updateTask($request,
new ResponseMock(), null);
$this->assertEquals('Insufficient privileges.',
$actual->alerts[0]['text']);
}
private function createTask() {
$request= new RequestMock();
$task = DataMock::getTask();
$task->id = 0;
$task->column_id = 0;
$task->category_id = 0;
$task->attachments = [];
$task->comments = [];
$request->payload = $task;
$request->header = [DataMock::getJwt()];
$response = $this->tasks->addTask($request,
new ResponseMock(), null);
$this->assertTrue($response->status === 'success');
$this->assertEquals('success', $response->status);
$this->tasks = new Tasks(new ContainerMock);
return $response;
}
}

View File

@ -18,9 +18,9 @@ class CategoryTest extends PHPUnit_Framework_TestCase {
return;
}
$task = DataMock::getCategory();
$this->json = json_encode($task);
$this->bean = $task;
$category = DataMock::getCategory();
$this->json = json_encode($category);
$this->bean = $category;
}
public function testCreateCategory() {
@ -28,6 +28,11 @@ class CategoryTest extends PHPUnit_Framework_TestCase {
$this->assertDefaultProperties($category);
}
public function testSaveCategory() {
$category = new Category(new ContainerMock());
$this->assertTrue($category->save());
}
public function testLoadFromBean() {
$category = new Category(new ContainerMock());

View File

@ -70,7 +70,7 @@ class TaskTest extends PHPUnit_Framework_TestCase {
$this->assertTrue($task->id === 0);
$this->assertTrue($task->title === '');
$this->assertTrue($task->description === '');
$this->assertTrue($task->assignee_id === 0);
$this->assertTrue($task->assignee === 0);
$this->assertTrue($task->category_id === 0);
$this->assertTrue($task->column_id === 0);
$this->assertTrue($task->color === '');
@ -83,7 +83,7 @@ class TaskTest extends PHPUnit_Framework_TestCase {
$this->assertTrue($task->id === 1);
$this->assertTrue($task->title === 'test');
$this->assertTrue($task->description === 'description');
$this->assertTrue($task->assignee_id === 1);
$this->assertTrue($task->assignee === 1);
$this->assertTrue($task->category_id === 1);
$this->assertTrue($task->column_id === 1);
$this->assertTrue($task->color === '#ffffff');