diff options
-rw-r--r-- | ChangeLog | 1 | ||||
-rw-r--r-- | app/Api/Authorization/ProjectAuthorization.php | 4 | ||||
-rw-r--r-- | app/Api/Authorization/TagAuthorization.php | 23 | ||||
-rw-r--r-- | app/Api/Authorization/TaskAuthorization.php | 4 | ||||
-rw-r--r-- | app/Api/Procedure/TagProcedure.php | 44 | ||||
-rw-r--r-- | app/Api/Procedure/TaskTagProcedure.php | 26 | ||||
-rw-r--r-- | app/ServiceProvider/ApiProvider.php | 4 | ||||
-rw-r--r-- | app/ServiceProvider/AuthenticationProvider.php | 2 | ||||
-rw-r--r-- | tests/integration/TagProcedureTest.php | 58 | ||||
-rw-r--r-- | tests/integration/TaskTagProcedureTest.php | 27 |
10 files changed, 189 insertions, 4 deletions
@@ -4,6 +4,7 @@ Version 1.0.36 (unreleased) New features: * Add slideshow for images +* Add API calls to manage tags Improvements: diff --git a/app/Api/Authorization/ProjectAuthorization.php b/app/Api/Authorization/ProjectAuthorization.php index 21ecf311..7dcdc445 100644 --- a/app/Api/Authorization/ProjectAuthorization.php +++ b/app/Api/Authorization/ProjectAuthorization.php @@ -23,13 +23,13 @@ class ProjectAuthorization extends Base protected function checkProjectPermission($class, $method, $project_id) { if (empty($project_id)) { - throw new AccessDeniedException('Project not found'); + throw new AccessDeniedException('Project Not Found'); } $role = $this->projectUserRoleModel->getUserRole($project_id, $this->userSession->getId()); if (! $this->apiProjectAuthorization->isAllowed($class, $method, $role)) { - throw new AccessDeniedException('Project access denied'); + throw new AccessDeniedException('Project Access Denied'); } } } diff --git a/app/Api/Authorization/TagAuthorization.php b/app/Api/Authorization/TagAuthorization.php new file mode 100644 index 00000000..247f57db --- /dev/null +++ b/app/Api/Authorization/TagAuthorization.php @@ -0,0 +1,23 @@ +<?php + +namespace Kanboard\Api\Authorization; + +/** + * Class TagAuthorization + * + * @package Kanboard\Api\Authorization + * @author Frederic Guillot + */ +class TagAuthorization extends ProjectAuthorization +{ + public function check($class, $method, $tag_id) + { + if ($this->userSession->isLogged()) { + $tag = $this->tagModel->getById($tag_id); + + if (! empty($tag)) { + $this->checkProjectPermission($class, $method, $tag['project_id']); + } + } + } +} diff --git a/app/Api/Authorization/TaskAuthorization.php b/app/Api/Authorization/TaskAuthorization.php index db93b76b..6e044211 100644 --- a/app/Api/Authorization/TaskAuthorization.php +++ b/app/Api/Authorization/TaskAuthorization.php @@ -10,10 +10,10 @@ namespace Kanboard\Api\Authorization; */ class TaskAuthorization extends ProjectAuthorization { - public function check($class, $method, $category_id) + public function check($class, $method, $task_id) { if ($this->userSession->isLogged()) { - $this->checkProjectPermission($class, $method, $this->taskFinderModel->getProjectId($category_id)); + $this->checkProjectPermission($class, $method, $this->taskFinderModel->getProjectId($task_id)); } } } diff --git a/app/Api/Procedure/TagProcedure.php b/app/Api/Procedure/TagProcedure.php new file mode 100644 index 00000000..f1c06d01 --- /dev/null +++ b/app/Api/Procedure/TagProcedure.php @@ -0,0 +1,44 @@ +<?php + +namespace Kanboard\Api\Procedure; + +use Kanboard\Api\Authorization\ProjectAuthorization; +use Kanboard\Api\Authorization\TagAuthorization; + +/** + * Class TagProcedure + * + * @package Kanboard\Api\Procedure + * @author Frederic Guillot + */ +class TagProcedure extends BaseProcedure +{ + public function getAllTags() + { + return $this->tagModel->getAll(); + } + + public function getTagsByProject($project_id) + { + ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'getTagsByProject', $project_id); + return $this->tagModel->getAllByProject($project_id); + } + + public function createTag($project_id, $tag) + { + ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'createTag', $project_id); + return $this->tagModel->findOrCreateTag($project_id, $tag); + } + + public function updateTag($tag_id, $tag) + { + TagAuthorization::getInstance($this->container)->check($this->getClassName(), 'updateTag', $tag_id); + return $this->tagModel->update($tag_id, $tag); + } + + public function removeTag($tag_id) + { + TagAuthorization::getInstance($this->container)->check($this->getClassName(), 'removeTag', $tag_id); + return $this->tagModel->remove($tag_id); + } +} diff --git a/app/Api/Procedure/TaskTagProcedure.php b/app/Api/Procedure/TaskTagProcedure.php new file mode 100644 index 00000000..8596f507 --- /dev/null +++ b/app/Api/Procedure/TaskTagProcedure.php @@ -0,0 +1,26 @@ +<?php + +namespace Kanboard\Api\Procedure; + +use Kanboard\Api\Authorization\TaskAuthorization; + +/** + * Class TaskTagProcedure + * + * @package Kanboard\Api\Procedure + * @author Frederic Guillot + */ +class TaskTagProcedure extends BaseProcedure +{ + public function setTaskTags($project_id, $task_id, array $tags) + { + TaskAuthorization::getInstance($this->container)->check($this->getClassName(), 'setTaskTags', $task_id); + return $this->taskTagModel->save($project_id, $task_id, $tags); + } + + public function getTaskTags($task_id) + { + TaskAuthorization::getInstance($this->container)->check($this->getClassName(), 'getTaskTags', $task_id); + return $this->taskTagModel->getList($task_id); + } +} diff --git a/app/ServiceProvider/ApiProvider.php b/app/ServiceProvider/ApiProvider.php index d5d1f260..2c9abec7 100644 --- a/app/ServiceProvider/ApiProvider.php +++ b/app/ServiceProvider/ApiProvider.php @@ -10,6 +10,7 @@ use Kanboard\Api\Procedure\CategoryProcedure; use Kanboard\Api\Procedure\ColumnProcedure; use Kanboard\Api\Procedure\CommentProcedure; use Kanboard\Api\Procedure\ProjectFileProcedure; +use Kanboard\Api\Procedure\TagProcedure; use Kanboard\Api\Procedure\TaskExternalLinkProcedure; use Kanboard\Api\Procedure\TaskFileProcedure; use Kanboard\Api\Procedure\GroupProcedure; @@ -25,6 +26,7 @@ use Kanboard\Api\Procedure\SwimlaneProcedure; use Kanboard\Api\Procedure\TaskMetadataProcedure; use Kanboard\Api\Procedure\TaskProcedure; use Kanboard\Api\Procedure\TaskLinkProcedure; +use Kanboard\Api\Procedure\TaskTagProcedure; use Kanboard\Api\Procedure\UserProcedure; use Pimple\Container; use Pimple\ServiceProviderInterface; @@ -71,9 +73,11 @@ class ApiProvider implements ServiceProviderInterface ->withObject(new TaskLinkProcedure($container)) ->withObject(new TaskExternalLinkProcedure($container)) ->withObject(new TaskMetadataProcedure($container)) + ->withObject(new TaskTagProcedure($container)) ->withObject(new UserProcedure($container)) ->withObject(new GroupProcedure($container)) ->withObject(new GroupMemberProcedure($container)) + ->withObject(new TagProcedure($container)) ->withBeforeMethod('beforeProcedure') ; diff --git a/app/ServiceProvider/AuthenticationProvider.php b/app/ServiceProvider/AuthenticationProvider.php index a3dc7e1a..80882456 100644 --- a/app/ServiceProvider/AuthenticationProvider.php +++ b/app/ServiceProvider/AuthenticationProvider.php @@ -210,6 +210,8 @@ class AuthenticationProvider implements ServiceProviderInterface $acl->add('TaskLinkProcedure', '*', Role::PROJECT_MEMBER); $acl->add('TaskExternalLinkProcedure', array('createExternalTaskLink', 'updateExternalTaskLink', 'removeExternalTaskLink'), Role::PROJECT_MEMBER); $acl->add('TaskProcedure', '*', Role::PROJECT_MEMBER); + $acl->add('TaskTagProcedure', array('setTaskTags'), Role::PROJECT_MEMBER); + $acl->add('TagProcedure', array('createTag', 'updateTag', 'removeTag'), Role::PROJECT_MEMBER); return $acl; } diff --git a/tests/integration/TagProcedureTest.php b/tests/integration/TagProcedureTest.php new file mode 100644 index 00000000..f15efa3c --- /dev/null +++ b/tests/integration/TagProcedureTest.php @@ -0,0 +1,58 @@ +<?php + +require_once __DIR__.'/BaseProcedureTest.php'; + +class TagProcedureTest extends BaseProcedureTest +{ + protected $projectName = 'My project with tags'; + + public function testAll() + { + $this->assertCreateTeamProject(); + $this->assertCreateTag(); + $this->assertGetProjectTags(); + $this->assertGetAllTags(); + $this->assertUpdateTag(); + $this->assertRemoveTag(); + } + + public function assertCreateTag() + { + $this->assertNotFalse($this->app->createTag($this->projectId, 'some tag')); + } + + public function assertGetProjectTags() + { + $tags = $this->app->getTagsByProject($this->projectId); + $this->assertCount(1, $tags); + $this->assertEquals('some tag', $tags[0]['name']); + } + + public function assertGetAllTags() + { + $tags = $this->app->getAllTags(); + $this->assertCount(1, $tags); + $this->assertEquals('some tag', $tags[0]['name']); + } + + public function assertUpdateTag() + { + $tags = $this->app->getAllTags(); + $this->assertCount(1, $tags); + $this->assertTrue($this->app->updateTag($tags[0]['id'], 'another tag')); + + $tags = $this->app->getAllTags(); + $this->assertCount(1, $tags); + $this->assertEquals('another tag', $tags[0]['name']); + } + + public function assertRemoveTag() + { + $tags = $this->app->getAllTags(); + $this->assertCount(1, $tags); + $this->assertTrue($this->app->removeTag($tags[0]['id'])); + + $tags = $this->app->getAllTags(); + $this->assertCount(0, $tags); + } +} diff --git a/tests/integration/TaskTagProcedureTest.php b/tests/integration/TaskTagProcedureTest.php new file mode 100644 index 00000000..ae6139d3 --- /dev/null +++ b/tests/integration/TaskTagProcedureTest.php @@ -0,0 +1,27 @@ +<?php + +require_once __DIR__.'/BaseProcedureTest.php'; + +class TaskTagProcedureTest extends BaseProcedureTest +{ + protected $projectName = 'My project with tasks and tags'; + + public function testAll() + { + $this->assertCreateTeamProject(); + $this->assertCreateTask(); + $this->assertSetTaskTags(); + $this->assertGetTaskTags(); + } + + public function assertSetTaskTags() + { + $this->assertTrue($this->app->setTaskTags($this->projectId, $this->taskId, array('tag1', 'tag2'))); + } + + public function assertGetTaskTags() + { + $tags = $this->app->getTaskTags($this->taskId); + $this->assertEquals(array('tag1', 'tag2'), array_values($tags)); + } +} |