Added application and project roles validation for API procedure calls
This commit is contained in:
parent
922e0fb6de
commit
4a230d331e
|
|
@ -1,6 +1,10 @@
|
|||
Version 1.0.31 (unreleased)
|
||||
--------------
|
||||
|
||||
New features:
|
||||
|
||||
* Added application and project roles validation for API procedure calls
|
||||
|
||||
Improvements:
|
||||
|
||||
* Rewrite integration tests to run with Docker containers
|
||||
|
|
|
|||
|
|
@ -0,0 +1,19 @@
|
|||
<?php
|
||||
|
||||
namespace Kanboard\Api\Authorization;
|
||||
|
||||
/**
|
||||
* Class ActionAuthorization
|
||||
*
|
||||
* @package Kanboard\Api\Authorization
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class ActionAuthorization extends ProjectAuthorization
|
||||
{
|
||||
public function check($class, $method, $action_id)
|
||||
{
|
||||
if ($this->userSession->isLogged()) {
|
||||
$this->checkProjectPermission($class, $method, $this->actionModel->getProjectId($action_id));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
<?php
|
||||
|
||||
namespace Kanboard\Api\Authorization;
|
||||
|
||||
/**
|
||||
* Class CategoryAuthorization
|
||||
*
|
||||
* @package Kanboard\Api\Authorization
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class CategoryAuthorization extends ProjectAuthorization
|
||||
{
|
||||
public function check($class, $method, $category_id)
|
||||
{
|
||||
if ($this->userSession->isLogged()) {
|
||||
$this->checkProjectPermission($class, $method, $this->categoryModel->getProjectId($category_id));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
<?php
|
||||
|
||||
namespace Kanboard\Api\Authorization;
|
||||
|
||||
/**
|
||||
* Class ColumnAuthorization
|
||||
*
|
||||
* @package Kanboard\Api\Authorization
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class ColumnAuthorization extends ProjectAuthorization
|
||||
{
|
||||
public function check($class, $method, $column_id)
|
||||
{
|
||||
if ($this->userSession->isLogged()) {
|
||||
$this->checkProjectPermission($class, $method, $this->columnModel->getProjectId($column_id));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
<?php
|
||||
|
||||
namespace Kanboard\Api\Authorization;
|
||||
|
||||
/**
|
||||
* Class CommentAuthorization
|
||||
*
|
||||
* @package Kanboard\Api\Authorization
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class CommentAuthorization extends ProjectAuthorization
|
||||
{
|
||||
public function check($class, $method, $comment_id)
|
||||
{
|
||||
if ($this->userSession->isLogged()) {
|
||||
$this->checkProjectPermission($class, $method, $this->commentModel->getProjectId($comment_id));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
<?php
|
||||
|
||||
namespace Kanboard\Api\Authorization;
|
||||
|
||||
use JsonRPC\Exception\AccessDeniedException;
|
||||
use Kanboard\Core\Base;
|
||||
|
||||
/**
|
||||
* Class ProcedureAuthorization
|
||||
*
|
||||
* @package Kanboard\Api\Authorization
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class ProcedureAuthorization extends Base
|
||||
{
|
||||
private $userSpecificProcedures = array(
|
||||
'getMe',
|
||||
'getMyDashboard',
|
||||
'getMyActivityStream',
|
||||
'createMyPrivateProject',
|
||||
'getMyProjectsList',
|
||||
'getMyProjects',
|
||||
'getMyOverdueTasks',
|
||||
);
|
||||
|
||||
public function check($procedure)
|
||||
{
|
||||
if (! $this->userSession->isLogged() && in_array($procedure, $this->userSpecificProcedures)) {
|
||||
throw new AccessDeniedException('This procedure is not available with the API credentials');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
<?php
|
||||
|
||||
namespace Kanboard\Api\Authorization;
|
||||
|
||||
use JsonRPC\Exception\AccessDeniedException;
|
||||
use Kanboard\Core\Base;
|
||||
|
||||
/**
|
||||
* Class ProjectAuthorization
|
||||
*
|
||||
* @package Kanboard\Api\Authorization
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class ProjectAuthorization extends Base
|
||||
{
|
||||
public function check($class, $method, $project_id)
|
||||
{
|
||||
if ($this->userSession->isLogged()) {
|
||||
$this->checkProjectPermission($class, $method, $project_id);
|
||||
}
|
||||
}
|
||||
|
||||
protected function checkProjectPermission($class, $method, $project_id)
|
||||
{
|
||||
if (empty($project_id)) {
|
||||
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');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
<?php
|
||||
|
||||
namespace Kanboard\Api\Authorization;
|
||||
|
||||
/**
|
||||
* Class SubtaskAuthorization
|
||||
*
|
||||
* @package Kanboard\Api\Authorization
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class SubtaskAuthorization extends ProjectAuthorization
|
||||
{
|
||||
public function check($class, $method, $subtask_id)
|
||||
{
|
||||
if ($this->userSession->isLogged()) {
|
||||
$this->checkProjectPermission($class, $method, $this->subtaskModel->getProjectId($subtask_id));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
<?php
|
||||
|
||||
namespace Kanboard\Api\Authorization;
|
||||
|
||||
/**
|
||||
* Class TaskAuthorization
|
||||
*
|
||||
* @package Kanboard\Api\Authorization
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class TaskAuthorization extends ProjectAuthorization
|
||||
{
|
||||
public function check($class, $method, $category_id)
|
||||
{
|
||||
if ($this->userSession->isLogged()) {
|
||||
$this->checkProjectPermission($class, $method, $this->taskFinderModel->getProjectId($category_id));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
<?php
|
||||
|
||||
namespace Kanboard\Api\Authorization;
|
||||
|
||||
/**
|
||||
* Class TaskFileAuthorization
|
||||
*
|
||||
* @package Kanboard\Api\Authorization
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class TaskFileAuthorization extends ProjectAuthorization
|
||||
{
|
||||
public function check($class, $method, $file_id)
|
||||
{
|
||||
if ($this->userSession->isLogged()) {
|
||||
$this->checkProjectPermission($class, $method, $this->taskFileModel->getProjectId($file_id));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
<?php
|
||||
|
||||
namespace Kanboard\Api\Authorization;
|
||||
|
||||
/**
|
||||
* Class TaskLinkAuthorization
|
||||
*
|
||||
* @package Kanboard\Api\Authorization
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class TaskLinkAuthorization extends ProjectAuthorization
|
||||
{
|
||||
public function check($class, $method, $task_link_id)
|
||||
{
|
||||
if ($this->userSession->isLogged()) {
|
||||
$this->checkProjectPermission($class, $method, $this->taskLinkModel->getProjectId($task_link_id));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
<?php
|
||||
|
||||
namespace Kanboard\Api\Authorization;
|
||||
|
||||
use JsonRPC\Exception\AccessDeniedException;
|
||||
use Kanboard\Core\Base;
|
||||
|
||||
/**
|
||||
* Class UserAuthorization
|
||||
*
|
||||
* @package Kanboard\Api\Authorization
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class UserAuthorization extends Base
|
||||
{
|
||||
public function check($class, $method)
|
||||
{
|
||||
if ($this->userSession->isLogged() && ! $this->apiAuthorization->isAllowed($class, $method, $this->userSession->getRole())) {
|
||||
throw new AccessDeniedException('You are not allowed to access to this resource');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -13,46 +13,8 @@ use Kanboard\Core\Base;
|
|||
* @package Kanboard\Api\Middleware
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class AuthenticationApiMiddleware extends Base implements MiddlewareInterface
|
||||
class AuthenticationMiddleware extends Base implements MiddlewareInterface
|
||||
{
|
||||
private $user_allowed_procedures = array(
|
||||
'getMe',
|
||||
'getMyDashboard',
|
||||
'getMyActivityStream',
|
||||
'createMyPrivateProject',
|
||||
'getMyProjectsList',
|
||||
'getMyProjects',
|
||||
'getMyOverdueTasks',
|
||||
);
|
||||
|
||||
private $both_allowed_procedures = array(
|
||||
'getTimezone',
|
||||
'getVersion',
|
||||
'getDefaultTaskColor',
|
||||
'getDefaultTaskColors',
|
||||
'getColorList',
|
||||
'getProjectById',
|
||||
'getSubTask',
|
||||
'getTask',
|
||||
'getTaskByReference',
|
||||
'getTimeSpent',
|
||||
'getAllTasks',
|
||||
'getAllSubTasks',
|
||||
'hasTimer',
|
||||
'logStartTime',
|
||||
'logEndTime',
|
||||
'openTask',
|
||||
'closeTask',
|
||||
'moveTaskPosition',
|
||||
'createTask',
|
||||
'createSubtask',
|
||||
'updateTask',
|
||||
'getBoard',
|
||||
'getProjectActivity',
|
||||
'getOverdueTasksByProject',
|
||||
'searchTasks',
|
||||
);
|
||||
|
||||
/**
|
||||
* Execute Middleware
|
||||
*
|
||||
|
|
@ -68,11 +30,8 @@ class AuthenticationApiMiddleware extends Base implements MiddlewareInterface
|
|||
$this->dispatcher->dispatch('app.bootstrap');
|
||||
|
||||
if ($this->isUserAuthenticated($username, $password)) {
|
||||
$this->checkProcedurePermission(true, $procedureName);
|
||||
$this->userSession->initialize($this->userModel->getByUsername($username));
|
||||
} elseif ($this->isAppAuthenticated($username, $password)) {
|
||||
$this->checkProcedurePermission(false, $procedureName);
|
||||
} else {
|
||||
} elseif (! $this->isAppAuthenticated($username, $password)) {
|
||||
$this->logger->error('API authentication failure for '.$username);
|
||||
throw new AuthenticationFailureException('Wrong credentials');
|
||||
}
|
||||
|
|
@ -120,18 +79,4 @@ class AuthenticationApiMiddleware extends Base implements MiddlewareInterface
|
|||
|
||||
return $this->configModel->get('api_token');
|
||||
}
|
||||
|
||||
public function checkProcedurePermission($is_user, $procedure)
|
||||
{
|
||||
$is_both_procedure = in_array($procedure, $this->both_allowed_procedures);
|
||||
$is_user_procedure = in_array($procedure, $this->user_allowed_procedures);
|
||||
|
||||
if ($is_user && ! $is_both_procedure && ! $is_user_procedure) {
|
||||
throw new AccessDeniedException('Permission denied');
|
||||
} elseif (! $is_user && ! $is_both_procedure && $is_user_procedure) {
|
||||
throw new AccessDeniedException('Permission denied');
|
||||
}
|
||||
|
||||
$this->logger->debug('API call: '.$procedure);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,16 +1,17 @@
|
|||
<?php
|
||||
|
||||
namespace Kanboard\Api;
|
||||
namespace Kanboard\Api\Procedure;
|
||||
|
||||
use Kanboard\Core\Base;
|
||||
use Kanboard\Api\Authorization\ActionAuthorization;
|
||||
use Kanboard\Api\Authorization\ProjectAuthorization;
|
||||
|
||||
/**
|
||||
* Action API controller
|
||||
*
|
||||
* @package Kanboard\Api
|
||||
* @package Kanboard\Api\Procedure
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class ActionApi extends Base
|
||||
class ActionProcedure extends BaseProcedure
|
||||
{
|
||||
public function getAvailableActions()
|
||||
{
|
||||
|
|
@ -29,16 +30,19 @@ class ActionApi extends Base
|
|||
|
||||
public function removeAction($action_id)
|
||||
{
|
||||
ActionAuthorization::getInstance($this->container)->check($this->getClassName(), 'removeAction', $action_id);
|
||||
return $this->actionModel->remove($action_id);
|
||||
}
|
||||
|
||||
public function getActions($project_id)
|
||||
{
|
||||
ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'getActions', $project_id);
|
||||
return $this->actionModel->getAllByProject($project_id);
|
||||
}
|
||||
|
||||
public function createAction($project_id, $event_name, $action_name, array $params)
|
||||
{
|
||||
ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'createAction', $project_id);
|
||||
$values = array(
|
||||
'project_id' => $project_id,
|
||||
'event_name' => $event_name,
|
||||
|
|
@ -1,16 +1,14 @@
|
|||
<?php
|
||||
|
||||
namespace Kanboard\Api;
|
||||
|
||||
use Kanboard\Core\Base;
|
||||
namespace Kanboard\Api\Procedure;
|
||||
|
||||
/**
|
||||
* App API controller
|
||||
*
|
||||
* @package Kanboard\Api
|
||||
* @package Kanboard\Api\Procedure
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class AppApi extends Base
|
||||
class AppProcedure extends BaseProcedure
|
||||
{
|
||||
public function getTimezone()
|
||||
{
|
||||
|
|
@ -1,30 +1,25 @@
|
|||
<?php
|
||||
|
||||
namespace Kanboard\Api;
|
||||
namespace Kanboard\Api\Procedure;
|
||||
|
||||
use JsonRPC\Exception\AccessDeniedException;
|
||||
use Kanboard\Api\Authorization\ProcedureAuthorization;
|
||||
use Kanboard\Api\Authorization\UserAuthorization;
|
||||
use Kanboard\Core\Base;
|
||||
use ReflectionClass;
|
||||
|
||||
/**
|
||||
* Base class
|
||||
*
|
||||
* @package Kanboard\Api
|
||||
* @package Kanboard\Api\Procedure
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
abstract class BaseApi extends Base
|
||||
abstract class BaseProcedure extends Base
|
||||
{
|
||||
public function checkProjectPermission($project_id)
|
||||
public function beforeProcedure($procedure)
|
||||
{
|
||||
if ($this->userSession->isLogged() && ! $this->projectPermissionModel->isUserAllowed($project_id, $this->userSession->getId())) {
|
||||
throw new AccessDeniedException('Permission denied');
|
||||
}
|
||||
}
|
||||
|
||||
public function checkTaskPermission($task_id)
|
||||
{
|
||||
if ($this->userSession->isLogged()) {
|
||||
$this->checkProjectPermission($this->taskFinderModel->getProjectId($task_id));
|
||||
}
|
||||
ProcedureAuthorization::getInstance($this->container)->check($procedure);
|
||||
UserAuthorization::getInstance($this->container)->check($this->getClassName(), $procedure);
|
||||
}
|
||||
|
||||
protected function formatTask($task)
|
||||
|
|
@ -82,4 +77,10 @@ abstract class BaseApi extends Base
|
|||
|
||||
return $values;
|
||||
}
|
||||
|
||||
protected function getClassName()
|
||||
{
|
||||
$reflection = new ReflectionClass(get_called_class());
|
||||
return $reflection->getShortName();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,21 +1,22 @@
|
|||
<?php
|
||||
|
||||
namespace Kanboard\Api;
|
||||
namespace Kanboard\Api\Procedure;
|
||||
|
||||
use Kanboard\Api\Authorization\ProjectAuthorization;
|
||||
use Kanboard\Formatter\BoardFormatter;
|
||||
|
||||
/**
|
||||
* Board API controller
|
||||
*
|
||||
* @package Kanboard\Api
|
||||
* @package Kanboard\Api\Procedure
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class BoardApi extends BaseApi
|
||||
class BoardProcedure extends BaseProcedure
|
||||
{
|
||||
public function getBoard($project_id)
|
||||
{
|
||||
$this->checkProjectPermission($project_id);
|
||||
|
||||
ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'getBoard', $project_id);
|
||||
|
||||
return BoardFormatter::getInstance($this->container)
|
||||
->withProjectId($project_id)
|
||||
->withQuery($this->taskFinderModel->getExtendedQuery())
|
||||
|
|
@ -1,34 +1,40 @@
|
|||
<?php
|
||||
|
||||
namespace Kanboard\Api;
|
||||
namespace Kanboard\Api\Procedure;
|
||||
|
||||
use Kanboard\Core\Base;
|
||||
use Kanboard\Api\Authorization\CategoryAuthorization;
|
||||
use Kanboard\Api\Authorization\ProjectAuthorization;
|
||||
|
||||
/**
|
||||
* Category API controller
|
||||
*
|
||||
* @package Kanboard\Api
|
||||
* @package Kanboard\Api\Procedure
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class CategoryApi extends Base
|
||||
class CategoryProcedure extends BaseProcedure
|
||||
{
|
||||
public function getCategory($category_id)
|
||||
{
|
||||
CategoryAuthorization::getInstance($this->container)->check($this->getClassName(), 'getCategory', $category_id);
|
||||
return $this->categoryModel->getById($category_id);
|
||||
}
|
||||
|
||||
public function getAllCategories($project_id)
|
||||
{
|
||||
ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'getAllCategories', $project_id);
|
||||
return $this->categoryModel->getAll($project_id);
|
||||
}
|
||||
|
||||
public function removeCategory($category_id)
|
||||
{
|
||||
CategoryAuthorization::getInstance($this->container)->check($this->getClassName(), 'removeCategory', $category_id);
|
||||
return $this->categoryModel->remove($category_id);
|
||||
}
|
||||
|
||||
public function createCategory($project_id, $name)
|
||||
{
|
||||
ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'createCategory', $project_id);
|
||||
|
||||
$values = array(
|
||||
'project_id' => $project_id,
|
||||
'name' => $name,
|
||||
|
|
@ -40,6 +46,8 @@ class CategoryApi extends Base
|
|||
|
||||
public function updateCategory($id, $name)
|
||||
{
|
||||
CategoryAuthorization::getInstance($this->container)->check($this->getClassName(), 'updateCategory', $id);
|
||||
|
||||
$values = array(
|
||||
'id' => $id,
|
||||
'name' => $name,
|
||||
|
|
@ -1,42 +1,51 @@
|
|||
<?php
|
||||
|
||||
namespace Kanboard\Api;
|
||||
namespace Kanboard\Api\Procedure;
|
||||
|
||||
use Kanboard\Api\Authorization\ColumnAuthorization;
|
||||
use Kanboard\Api\Authorization\ProjectAuthorization;
|
||||
|
||||
/**
|
||||
* Column API controller
|
||||
*
|
||||
* @package Kanboard\Api
|
||||
* @package Kanboard\Api\Procedure
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class ColumnApi extends BaseApi
|
||||
class ColumnProcedure extends BaseProcedure
|
||||
{
|
||||
public function getColumns($project_id)
|
||||
{
|
||||
ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'getColumns', $project_id);
|
||||
return $this->columnModel->getAll($project_id);
|
||||
}
|
||||
|
||||
public function getColumn($column_id)
|
||||
{
|
||||
ColumnAuthorization::getInstance($this->container)->check($this->getClassName(), 'getColumn', $column_id);
|
||||
return $this->columnModel->getById($column_id);
|
||||
}
|
||||
|
||||
public function updateColumn($column_id, $title, $task_limit = 0, $description = '')
|
||||
{
|
||||
ColumnAuthorization::getInstance($this->container)->check($this->getClassName(), 'updateColumn', $column_id);
|
||||
return $this->columnModel->update($column_id, $title, $task_limit, $description);
|
||||
}
|
||||
|
||||
public function addColumn($project_id, $title, $task_limit = 0, $description = '')
|
||||
{
|
||||
ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'addColumn', $project_id);
|
||||
return $this->columnModel->create($project_id, $title, $task_limit, $description);
|
||||
}
|
||||
|
||||
public function removeColumn($column_id)
|
||||
{
|
||||
ColumnAuthorization::getInstance($this->container)->check($this->getClassName(), 'removeColumn', $column_id);
|
||||
return $this->columnModel->remove($column_id);
|
||||
}
|
||||
|
||||
public function changeColumnPosition($project_id, $column_id, $position)
|
||||
{
|
||||
ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'changeColumnPosition', $project_id);
|
||||
return $this->columnModel->changePosition($project_id, $column_id, $position);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,34 +1,40 @@
|
|||
<?php
|
||||
|
||||
namespace Kanboard\Api;
|
||||
namespace Kanboard\Api\Procedure;
|
||||
|
||||
use Kanboard\Core\Base;
|
||||
use Kanboard\Api\Authorization\CommentAuthorization;
|
||||
use Kanboard\Api\Authorization\TaskAuthorization;
|
||||
|
||||
/**
|
||||
* Comment API controller
|
||||
*
|
||||
* @package Kanboard\Api
|
||||
* @package Kanboard\Api\Procedure
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class CommentApi extends Base
|
||||
class CommentProcedure extends BaseProcedure
|
||||
{
|
||||
public function getComment($comment_id)
|
||||
{
|
||||
CommentAuthorization::getInstance($this->container)->check($this->getClassName(), 'getComment', $comment_id);
|
||||
return $this->commentModel->getById($comment_id);
|
||||
}
|
||||
|
||||
public function getAllComments($task_id)
|
||||
{
|
||||
TaskAuthorization::getInstance($this->container)->check($this->getClassName(), 'getAllComments', $task_id);
|
||||
return $this->commentModel->getAll($task_id);
|
||||
}
|
||||
|
||||
public function removeComment($comment_id)
|
||||
{
|
||||
CommentAuthorization::getInstance($this->container)->check($this->getClassName(), 'removeComment', $comment_id);
|
||||
return $this->commentModel->remove($comment_id);
|
||||
}
|
||||
|
||||
public function createComment($task_id, $user_id, $content, $reference = '')
|
||||
{
|
||||
TaskAuthorization::getInstance($this->container)->check($this->getClassName(), 'createComment', $task_id);
|
||||
|
||||
$values = array(
|
||||
'task_id' => $task_id,
|
||||
'user_id' => $user_id,
|
||||
|
|
@ -43,6 +49,8 @@ class CommentApi extends Base
|
|||
|
||||
public function updateComment($id, $content)
|
||||
{
|
||||
CommentAuthorization::getInstance($this->container)->check($this->getClassName(), 'updateComment', $id);
|
||||
|
||||
$values = array(
|
||||
'id' => $id,
|
||||
'comment' => $content,
|
||||
|
|
@ -1,16 +1,14 @@
|
|||
<?php
|
||||
|
||||
namespace Kanboard\Api;
|
||||
|
||||
use Kanboard\Core\Base;
|
||||
namespace Kanboard\Api\Procedure;
|
||||
|
||||
/**
|
||||
* Group Member API controller
|
||||
*
|
||||
* @package Kanboard\Api
|
||||
* @package Kanboard\Api\Procedure
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class GroupMemberApi extends Base
|
||||
class GroupMemberProcedure extends BaseProcedure
|
||||
{
|
||||
public function getMemberGroups($user_id)
|
||||
{
|
||||
|
|
@ -1,16 +1,14 @@
|
|||
<?php
|
||||
|
||||
namespace Kanboard\Api;
|
||||
|
||||
use Kanboard\Core\Base;
|
||||
namespace Kanboard\Api\Procedure;
|
||||
|
||||
/**
|
||||
* Group API controller
|
||||
*
|
||||
* @package Kanboard\Api
|
||||
* @package Kanboard\Api\Procedure
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class GroupApi extends Base
|
||||
class GroupProcedure extends BaseProcedure
|
||||
{
|
||||
public function createGroup($name, $external_id = '')
|
||||
{
|
||||
|
|
@ -1,16 +1,14 @@
|
|||
<?php
|
||||
|
||||
namespace Kanboard\Api;
|
||||
|
||||
use Kanboard\Core\Base;
|
||||
namespace Kanboard\Api\Procedure;
|
||||
|
||||
/**
|
||||
* Link API controller
|
||||
*
|
||||
* @package Kanboard\Api
|
||||
* @package Kanboard\Api\Procedure
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class LinkApi extends Base
|
||||
class LinkProcedure extends BaseProcedure
|
||||
{
|
||||
/**
|
||||
* Get a link by id
|
||||
|
|
@ -1,16 +1,16 @@
|
|||
<?php
|
||||
|
||||
namespace Kanboard\Api;
|
||||
namespace Kanboard\Api\Procedure;
|
||||
|
||||
use Kanboard\Model\SubtaskModel;
|
||||
|
||||
/**
|
||||
* Me API controller
|
||||
*
|
||||
* @package Kanboard\Api
|
||||
* @package Kanboard\Api\Procedure
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class MeApi extends BaseApi
|
||||
class MeProcedure extends BaseProcedure
|
||||
{
|
||||
public function getMe()
|
||||
{
|
||||
|
|
@ -1,55 +1,69 @@
|
|||
<?php
|
||||
|
||||
namespace Kanboard\Api;
|
||||
namespace Kanboard\Api\Procedure;
|
||||
|
||||
use Kanboard\Core\Base;
|
||||
use Kanboard\Api\Authorization\ProjectAuthorization;
|
||||
use Kanboard\Core\Security\Role;
|
||||
|
||||
/**
|
||||
* Project Permission API controller
|
||||
*
|
||||
* @package Kanboard\Api
|
||||
* @package Kanboard\Api\Procedure
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class ProjectPermissionApi extends Base
|
||||
class ProjectPermissionProcedure extends BaseProcedure
|
||||
{
|
||||
public function getProjectUsers($project_id)
|
||||
{
|
||||
ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'getProjectUsers', $project_id);
|
||||
return $this->projectUserRoleModel->getAllUsers($project_id);
|
||||
}
|
||||
|
||||
public function getAssignableUsers($project_id, $prepend_unassigned = false)
|
||||
{
|
||||
ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'getAssignableUsers', $project_id);
|
||||
return $this->projectUserRoleModel->getAssignableUsersList($project_id, $prepend_unassigned);
|
||||
}
|
||||
|
||||
public function addProjectUser($project_id, $user_id, $role = Role::PROJECT_MEMBER)
|
||||
{
|
||||
ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'addProjectUser', $project_id);
|
||||
return $this->projectUserRoleModel->addUser($project_id, $user_id, $role);
|
||||
}
|
||||
|
||||
public function addProjectGroup($project_id, $group_id, $role = Role::PROJECT_MEMBER)
|
||||
{
|
||||
ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'addProjectGroup', $project_id);
|
||||
return $this->projectGroupRoleModel->addGroup($project_id, $group_id, $role);
|
||||
}
|
||||
|
||||
public function removeProjectUser($project_id, $user_id)
|
||||
{
|
||||
ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'removeProjectUser', $project_id);
|
||||
return $this->projectUserRoleModel->removeUser($project_id, $user_id);
|
||||
}
|
||||
|
||||
public function removeProjectGroup($project_id, $group_id)
|
||||
{
|
||||
ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'removeProjectGroup', $project_id);
|
||||
return $this->projectGroupRoleModel->removeGroup($project_id, $group_id);
|
||||
}
|
||||
|
||||
public function changeProjectUserRole($project_id, $user_id, $role)
|
||||
{
|
||||
ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'changeProjectUserRole', $project_id);
|
||||
return $this->projectUserRoleModel->changeUserRole($project_id, $user_id, $role);
|
||||
}
|
||||
|
||||
public function changeProjectGroupRole($project_id, $group_id, $role)
|
||||
{
|
||||
ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'changeProjectGroupRole', $project_id);
|
||||
return $this->projectGroupRoleModel->changeGroupRole($project_id, $group_id, $role);
|
||||
}
|
||||
|
||||
public function getProjectUserRole($project_id, $user_id)
|
||||
{
|
||||
ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'getProjectUserRole', $project_id);
|
||||
return $this->projectUserRoleModel->getUserRole($project_id, $user_id);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,106 @@
|
|||
<?php
|
||||
|
||||
namespace Kanboard\Api\Procedure;
|
||||
|
||||
use Kanboard\Api\Authorization\ProjectAuthorization;
|
||||
|
||||
/**
|
||||
* Project API controller
|
||||
*
|
||||
* @package Kanboard\Api\Procedure
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class ProjectProcedure extends BaseProcedure
|
||||
{
|
||||
public function getProjectById($project_id)
|
||||
{
|
||||
ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'getProjectById', $project_id);
|
||||
return $this->formatProject($this->projectModel->getById($project_id));
|
||||
}
|
||||
|
||||
public function getProjectByName($name)
|
||||
{
|
||||
$project = $this->projectModel->getByName($name);
|
||||
ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'getProjectByName', $project['id']);
|
||||
return $this->formatProject($project);
|
||||
}
|
||||
|
||||
public function getAllProjects()
|
||||
{
|
||||
return $this->formatProjects($this->projectModel->getAll());
|
||||
}
|
||||
|
||||
public function removeProject($project_id)
|
||||
{
|
||||
ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'removeProject', $project_id);
|
||||
return $this->projectModel->remove($project_id);
|
||||
}
|
||||
|
||||
public function enableProject($project_id)
|
||||
{
|
||||
ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'enableProject', $project_id);
|
||||
return $this->projectModel->enable($project_id);
|
||||
}
|
||||
|
||||
public function disableProject($project_id)
|
||||
{
|
||||
ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'disableProject', $project_id);
|
||||
return $this->projectModel->disable($project_id);
|
||||
}
|
||||
|
||||
public function enableProjectPublicAccess($project_id)
|
||||
{
|
||||
ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'enableProjectPublicAccess', $project_id);
|
||||
return $this->projectModel->enablePublicAccess($project_id);
|
||||
}
|
||||
|
||||
public function disableProjectPublicAccess($project_id)
|
||||
{
|
||||
ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'disableProjectPublicAccess', $project_id);
|
||||
return $this->projectModel->disablePublicAccess($project_id);
|
||||
}
|
||||
|
||||
public function getProjectActivities(array $project_ids)
|
||||
{
|
||||
foreach ($project_ids as $project_id) {
|
||||
ProjectAuthorization::getInstance($this->container)
|
||||
->check($this->getClassName(), 'getProjectActivities', $project_id);
|
||||
}
|
||||
|
||||
return $this->helper->projectActivity->getProjectsEvents($project_ids);
|
||||
}
|
||||
|
||||
public function getProjectActivity($project_id)
|
||||
{
|
||||
ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'getProjectActivity', $project_id);
|
||||
return $this->helper->projectActivity->getProjectEvents($project_id);
|
||||
}
|
||||
|
||||
public function createProject($name, $description = null, $owner_id = 0, $identifier = null)
|
||||
{
|
||||
$values = array(
|
||||
'name' => $name,
|
||||
'description' => $description,
|
||||
'identifier' => $identifier,
|
||||
);
|
||||
|
||||
list($valid, ) = $this->projectValidator->validateCreation($values);
|
||||
return $valid ? $this->projectModel->create($values, $owner_id, $this->userSession->isLogged()) : false;
|
||||
}
|
||||
|
||||
public function updateProject($project_id, $name, $description = null, $owner_id = null, $identifier = null)
|
||||
{
|
||||
ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'updateProject', $project_id);
|
||||
|
||||
$values = $this->filterValues(array(
|
||||
'id' => $project_id,
|
||||
'name' => $name,
|
||||
'description' => $description,
|
||||
'owner_id' => $owner_id,
|
||||
'identifier' => $identifier,
|
||||
));
|
||||
|
||||
list($valid, ) = $this->projectValidator->validateModification($values);
|
||||
return $valid && $this->projectModel->update($values);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,34 +1,40 @@
|
|||
<?php
|
||||
|
||||
namespace Kanboard\Api;
|
||||
namespace Kanboard\Api\Procedure;
|
||||
|
||||
use Kanboard\Core\Base;
|
||||
use Kanboard\Api\Authorization\SubtaskAuthorization;
|
||||
use Kanboard\Api\Authorization\TaskAuthorization;
|
||||
|
||||
/**
|
||||
* Subtask API controller
|
||||
*
|
||||
* @package Kanboard\Api
|
||||
* @package Kanboard\Api\Procedure
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class SubtaskApi extends Base
|
||||
class SubtaskProcedure extends BaseProcedure
|
||||
{
|
||||
public function getSubtask($subtask_id)
|
||||
{
|
||||
SubtaskAuthorization::getInstance($this->container)->check($this->getClassName(), 'getSubtask', $subtask_id);
|
||||
return $this->subtaskModel->getById($subtask_id);
|
||||
}
|
||||
|
||||
public function getAllSubtasks($task_id)
|
||||
{
|
||||
TaskAuthorization::getInstance($this->container)->check($this->getClassName(), 'getAllSubtasks', $task_id);
|
||||
return $this->subtaskModel->getAll($task_id);
|
||||
}
|
||||
|
||||
public function removeSubtask($subtask_id)
|
||||
{
|
||||
SubtaskAuthorization::getInstance($this->container)->check($this->getClassName(), 'removeSubtask', $subtask_id);
|
||||
return $this->subtaskModel->remove($subtask_id);
|
||||
}
|
||||
|
||||
public function createSubtask($task_id, $title, $user_id = 0, $time_estimated = 0, $time_spent = 0, $status = 0)
|
||||
{
|
||||
TaskAuthorization::getInstance($this->container)->check($this->getClassName(), 'createSubtask', $task_id);
|
||||
|
||||
$values = array(
|
||||
'title' => $title,
|
||||
'task_id' => $task_id,
|
||||
|
|
@ -44,6 +50,8 @@ class SubtaskApi extends Base
|
|||
|
||||
public function updateSubtask($id, $task_id, $title = null, $user_id = null, $time_estimated = null, $time_spent = null, $status = null)
|
||||
{
|
||||
TaskAuthorization::getInstance($this->container)->check($this->getClassName(), 'updateSubtask', $task_id);
|
||||
|
||||
$values = array(
|
||||
'id' => $id,
|
||||
'task_id' => $task_id,
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
<?php
|
||||
|
||||
namespace Kanboard\Api\Procedure;
|
||||
|
||||
use Kanboard\Api\Authorization\SubtaskAuthorization;
|
||||
|
||||
/**
|
||||
* Subtask Time Tracking API controller
|
||||
*
|
||||
* @package Kanboard\Api\Procedure
|
||||
* @author Frederic Guillot
|
||||
* @author Nikolaos Georgakis
|
||||
*/
|
||||
class SubtaskTimeTrackingProcedure extends BaseProcedure
|
||||
{
|
||||
public function hasSubtaskTimer($subtask_id, $user_id)
|
||||
{
|
||||
SubtaskAuthorization::getInstance($this->container)->check($this->getClassName(), 'hasSubtaskTimer', $subtask_id);
|
||||
return $this->subtaskTimeTrackingModel->hasTimer($subtask_id, $user_id);
|
||||
}
|
||||
|
||||
public function logSubtaskStartTime($subtask_id, $user_id)
|
||||
{
|
||||
SubtaskAuthorization::getInstance($this->container)->check($this->getClassName(), 'logSubtaskStartTime', $subtask_id);
|
||||
return $this->subtaskTimeTrackingModel->logStartTime($subtask_id, $user_id);
|
||||
}
|
||||
|
||||
public function logSubtaskEndTime($subtask_id,$user_id)
|
||||
{
|
||||
SubtaskAuthorization::getInstance($this->container)->check($this->getClassName(), 'logSubtaskEndTime', $subtask_id);
|
||||
return $this->subtaskTimeTrackingModel->logEndTime($subtask_id, $user_id);
|
||||
}
|
||||
|
||||
public function getSubtaskTimeSpent($subtask_id,$user_id)
|
||||
{
|
||||
SubtaskAuthorization::getInstance($this->container)->check($this->getClassName(), 'getSubtaskTimeSpent', $subtask_id);
|
||||
return $this->subtaskTimeTrackingModel->getTimeSpent($subtask_id, $user_id);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,34 +1,39 @@
|
|||
<?php
|
||||
|
||||
namespace Kanboard\Api;
|
||||
namespace Kanboard\Api\Procedure;
|
||||
|
||||
use Kanboard\Core\Base;
|
||||
use Kanboard\Api\Authorization\ProjectAuthorization;
|
||||
|
||||
/**
|
||||
* Swimlane API controller
|
||||
*
|
||||
* @package Kanboard\Api
|
||||
* @package Kanboard\Api\Procedure
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class SwimlaneApi extends Base
|
||||
class SwimlaneProcedure extends BaseProcedure
|
||||
{
|
||||
public function getActiveSwimlanes($project_id)
|
||||
{
|
||||
ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'getActiveSwimlanes', $project_id);
|
||||
return $this->swimlaneModel->getSwimlanes($project_id);
|
||||
}
|
||||
|
||||
public function getAllSwimlanes($project_id)
|
||||
{
|
||||
ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'getAllSwimlanes', $project_id);
|
||||
return $this->swimlaneModel->getAll($project_id);
|
||||
}
|
||||
|
||||
public function getSwimlaneById($swimlane_id)
|
||||
{
|
||||
return $this->swimlaneModel->getById($swimlane_id);
|
||||
$swimlane = $this->swimlaneModel->getById($swimlane_id);
|
||||
ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'getSwimlaneById', $swimlane['project_id']);
|
||||
return $swimlane;
|
||||
}
|
||||
|
||||
public function getSwimlaneByName($project_id, $name)
|
||||
{
|
||||
ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'getSwimlaneByName', $project_id);
|
||||
return $this->swimlaneModel->getByName($project_id, $name);
|
||||
}
|
||||
|
||||
|
|
@ -39,11 +44,13 @@ class SwimlaneApi extends Base
|
|||
|
||||
public function getDefaultSwimlane($project_id)
|
||||
{
|
||||
ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'getDefaultSwimlane', $project_id);
|
||||
return $this->swimlaneModel->getDefault($project_id);
|
||||
}
|
||||
|
||||
public function addSwimlane($project_id, $name, $description = '')
|
||||
{
|
||||
ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'addSwimlane', $project_id);
|
||||
return $this->swimlaneModel->create(array('project_id' => $project_id, 'name' => $name, 'description' => $description));
|
||||
}
|
||||
|
||||
|
|
@ -60,21 +67,25 @@ class SwimlaneApi extends Base
|
|||
|
||||
public function removeSwimlane($project_id, $swimlane_id)
|
||||
{
|
||||
ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'removeSwimlane', $project_id);
|
||||
return $this->swimlaneModel->remove($project_id, $swimlane_id);
|
||||
}
|
||||
|
||||
public function disableSwimlane($project_id, $swimlane_id)
|
||||
{
|
||||
ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'disableSwimlane', $project_id);
|
||||
return $this->swimlaneModel->disable($project_id, $swimlane_id);
|
||||
}
|
||||
|
||||
public function enableSwimlane($project_id, $swimlane_id)
|
||||
{
|
||||
ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'enableSwimlane', $project_id);
|
||||
return $this->swimlaneModel->enable($project_id, $swimlane_id);
|
||||
}
|
||||
|
||||
public function changeSwimlanePosition($project_id, $swimlane_id, $position)
|
||||
{
|
||||
ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'changeSwimlanePosition', $project_id);
|
||||
return $this->swimlaneModel->changePosition($project_id, $swimlane_id, $position);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,29 +1,36 @@
|
|||
<?php
|
||||
|
||||
namespace Kanboard\Api;
|
||||
namespace Kanboard\Api\Procedure;
|
||||
|
||||
use Kanboard\Api\Authorization\ProjectAuthorization;
|
||||
use Kanboard\Api\Authorization\TaskAuthorization;
|
||||
use Kanboard\Api\Authorization\TaskFileAuthorization;
|
||||
use Kanboard\Core\ObjectStorage\ObjectStorageException;
|
||||
|
||||
/**
|
||||
* Task File API controller
|
||||
*
|
||||
* @package Kanboard\Api
|
||||
* @package Kanboard\Api\Procedure
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class TaskFileApi extends BaseApi
|
||||
class TaskFileProcedure extends BaseProcedure
|
||||
{
|
||||
public function getTaskFile($file_id)
|
||||
{
|
||||
TaskFileAuthorization::getInstance($this->container)->check($this->getClassName(), 'getTaskFile', $file_id);
|
||||
return $this->taskFileModel->getById($file_id);
|
||||
}
|
||||
|
||||
public function getAllTaskFiles($task_id)
|
||||
{
|
||||
TaskAuthorization::getInstance($this->container)->check($this->getClassName(), 'getAllTaskFiles', $task_id);
|
||||
return $this->taskFileModel->getAll($task_id);
|
||||
}
|
||||
|
||||
public function downloadTaskFile($file_id)
|
||||
{
|
||||
TaskFileAuthorization::getInstance($this->container)->check($this->getClassName(), 'downloadTaskFile', $file_id);
|
||||
|
||||
try {
|
||||
$file = $this->taskFileModel->getById($file_id);
|
||||
|
||||
|
|
@ -39,6 +46,8 @@ class TaskFileApi extends BaseApi
|
|||
|
||||
public function createTaskFile($project_id, $task_id, $filename, $blob)
|
||||
{
|
||||
ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'createTaskFile', $project_id);
|
||||
|
||||
try {
|
||||
return $this->taskFileModel->uploadContent($task_id, $filename, $blob);
|
||||
} catch (ObjectStorageException $e) {
|
||||
|
|
@ -49,11 +58,13 @@ class TaskFileApi extends BaseApi
|
|||
|
||||
public function removeTaskFile($file_id)
|
||||
{
|
||||
TaskFileAuthorization::getInstance($this->container)->check($this->getClassName(), 'removeTaskFile', $file_id);
|
||||
return $this->taskFileModel->remove($file_id);
|
||||
}
|
||||
|
||||
public function removeAllTaskFiles($task_id)
|
||||
{
|
||||
TaskAuthorization::getInstance($this->container)->check($this->getClassName(), 'removeAllTaskFiles', $task_id);
|
||||
return $this->taskFileModel->removeAll($task_id);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,16 +1,17 @@
|
|||
<?php
|
||||
|
||||
namespace Kanboard\Api;
|
||||
namespace Kanboard\Api\Procedure;
|
||||
|
||||
use Kanboard\Core\Base;
|
||||
use Kanboard\Api\Authorization\TaskAuthorization;
|
||||
use Kanboard\Api\Authorization\TaskLinkAuthorization;
|
||||
|
||||
/**
|
||||
* TaskLink API controller
|
||||
*
|
||||
* @package Kanboard\Api
|
||||
* @package Kanboard\Api\Procedure
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class TaskLinkApi extends Base
|
||||
class TaskLinkProcedure extends BaseProcedure
|
||||
{
|
||||
/**
|
||||
* Get a task link
|
||||
|
|
@ -21,6 +22,7 @@ class TaskLinkApi extends Base
|
|||
*/
|
||||
public function getTaskLinkById($task_link_id)
|
||||
{
|
||||
TaskLinkAuthorization::getInstance($this->container)->check($this->getClassName(), 'getTaskLinkById', $task_link_id);
|
||||
return $this->taskLinkModel->getById($task_link_id);
|
||||
}
|
||||
|
||||
|
|
@ -33,6 +35,7 @@ class TaskLinkApi extends Base
|
|||
*/
|
||||
public function getAllTaskLinks($task_id)
|
||||
{
|
||||
TaskAuthorization::getInstance($this->container)->check($this->getClassName(), 'getAllTaskLinks', $task_id);
|
||||
return $this->taskLinkModel->getAll($task_id);
|
||||
}
|
||||
|
||||
|
|
@ -47,6 +50,7 @@ class TaskLinkApi extends Base
|
|||
*/
|
||||
public function createTaskLink($task_id, $opposite_task_id, $link_id)
|
||||
{
|
||||
TaskAuthorization::getInstance($this->container)->check($this->getClassName(), 'createTaskLink', $task_id);
|
||||
return $this->taskLinkModel->create($task_id, $opposite_task_id, $link_id);
|
||||
}
|
||||
|
||||
|
|
@ -62,6 +66,7 @@ class TaskLinkApi extends Base
|
|||
*/
|
||||
public function updateTaskLink($task_link_id, $task_id, $opposite_task_id, $link_id)
|
||||
{
|
||||
TaskAuthorization::getInstance($this->container)->check($this->getClassName(), 'updateTaskLink', $task_id);
|
||||
return $this->taskLinkModel->update($task_link_id, $task_id, $opposite_task_id, $link_id);
|
||||
}
|
||||
|
||||
|
|
@ -74,6 +79,7 @@ class TaskLinkApi extends Base
|
|||
*/
|
||||
public function removeTaskLink($task_link_id)
|
||||
{
|
||||
TaskLinkAuthorization::getInstance($this->container)->check($this->getClassName(), 'removeTaskLink', $task_link_id);
|
||||
return $this->taskLinkModel->remove($task_link_id);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,39 +1,41 @@
|
|||
<?php
|
||||
|
||||
namespace Kanboard\Api;
|
||||
namespace Kanboard\Api\Procedure;
|
||||
|
||||
use Kanboard\Api\Authorization\ProjectAuthorization;
|
||||
use Kanboard\Api\Authorization\TaskAuthorization;
|
||||
use Kanboard\Filter\TaskProjectFilter;
|
||||
use Kanboard\Model\TaskModel;
|
||||
|
||||
/**
|
||||
* Task API controller
|
||||
*
|
||||
* @package Kanboard\Api
|
||||
* @package Kanboard\Api\Procedure
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class TaskApi extends BaseApi
|
||||
class TaskProcedure extends BaseProcedure
|
||||
{
|
||||
public function searchTasks($project_id, $query)
|
||||
{
|
||||
$this->checkProjectPermission($project_id);
|
||||
ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'searchTasks', $project_id);
|
||||
return $this->taskLexer->build($query)->withFilter(new TaskProjectFilter($project_id))->toArray();
|
||||
}
|
||||
|
||||
public function getTask($task_id)
|
||||
{
|
||||
$this->checkTaskPermission($task_id);
|
||||
TaskAuthorization::getInstance($this->container)->check($this->getClassName(), 'getTask', $task_id);
|
||||
return $this->formatTask($this->taskFinderModel->getById($task_id));
|
||||
}
|
||||
|
||||
public function getTaskByReference($project_id, $reference)
|
||||
{
|
||||
$this->checkProjectPermission($project_id);
|
||||
ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'getTaskByReference', $project_id);
|
||||
return $this->formatTask($this->taskFinderModel->getByReference($project_id, $reference));
|
||||
}
|
||||
|
||||
public function getAllTasks($project_id, $status_id = TaskModel::STATUS_OPEN)
|
||||
{
|
||||
$this->checkProjectPermission($project_id);
|
||||
ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'getAllTasks', $project_id);
|
||||
return $this->formatTasks($this->taskFinderModel->getAll($project_id, $status_id));
|
||||
}
|
||||
|
||||
|
|
@ -44,40 +46,43 @@ class TaskApi extends BaseApi
|
|||
|
||||
public function getOverdueTasksByProject($project_id)
|
||||
{
|
||||
$this->checkProjectPermission($project_id);
|
||||
ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'getOverdueTasksByProject', $project_id);
|
||||
return $this->taskFinderModel->getOverdueTasksByProject($project_id);
|
||||
}
|
||||
|
||||
public function openTask($task_id)
|
||||
{
|
||||
$this->checkTaskPermission($task_id);
|
||||
TaskAuthorization::getInstance($this->container)->check($this->getClassName(), 'openTask', $task_id);
|
||||
return $this->taskStatusModel->open($task_id);
|
||||
}
|
||||
|
||||
public function closeTask($task_id)
|
||||
{
|
||||
$this->checkTaskPermission($task_id);
|
||||
TaskAuthorization::getInstance($this->container)->check($this->getClassName(), 'closeTask', $task_id);
|
||||
return $this->taskStatusModel->close($task_id);
|
||||
}
|
||||
|
||||
public function removeTask($task_id)
|
||||
{
|
||||
TaskAuthorization::getInstance($this->container)->check($this->getClassName(), 'removeTask', $task_id);
|
||||
return $this->taskModel->remove($task_id);
|
||||
}
|
||||
|
||||
public function moveTaskPosition($project_id, $task_id, $column_id, $position, $swimlane_id = 0)
|
||||
{
|
||||
$this->checkProjectPermission($project_id);
|
||||
ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'moveTaskPosition', $project_id);
|
||||
return $this->taskPositionModel->movePosition($project_id, $task_id, $column_id, $position, $swimlane_id);
|
||||
}
|
||||
|
||||
public function moveTaskToProject($task_id, $project_id, $swimlane_id = null, $column_id = null, $category_id = null, $owner_id = null)
|
||||
{
|
||||
ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'moveTaskToProject', $project_id);
|
||||
return $this->taskDuplicationModel->moveToProject($task_id, $project_id, $swimlane_id, $column_id, $category_id, $owner_id);
|
||||
}
|
||||
|
||||
public function duplicateTaskToProject($task_id, $project_id, $swimlane_id = null, $column_id = null, $category_id = null, $owner_id = null)
|
||||
{
|
||||
ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'duplicateTaskToProject', $project_id);
|
||||
return $this->taskDuplicationModel->duplicateToProject($task_id, $project_id, $swimlane_id, $column_id, $category_id, $owner_id);
|
||||
}
|
||||
|
||||
|
|
@ -86,8 +91,8 @@ class TaskApi extends BaseApi
|
|||
$recurrence_status = 0, $recurrence_trigger = 0, $recurrence_factor = 0, $recurrence_timeframe = 0,
|
||||
$recurrence_basedate = 0, $reference = '')
|
||||
{
|
||||
$this->checkProjectPermission($project_id);
|
||||
|
||||
ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'createTask', $project_id);
|
||||
|
||||
if ($owner_id !== 0 && ! $this->projectPermissionModel->isAssignable($project_id, $owner_id)) {
|
||||
return false;
|
||||
}
|
||||
|
|
@ -127,8 +132,7 @@ class TaskApi extends BaseApi
|
|||
$recurrence_status = null, $recurrence_trigger = null, $recurrence_factor = null,
|
||||
$recurrence_timeframe = null, $recurrence_basedate = null, $reference = null)
|
||||
{
|
||||
$this->checkTaskPermission($id);
|
||||
|
||||
TaskAuthorization::getInstance($this->container)->check($this->getClassName(), 'updateTask', $id);
|
||||
$project_id = $this->taskFinderModel->getProjectId($id);
|
||||
|
||||
if ($project_id === 0) {
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
<?php
|
||||
|
||||
namespace Kanboard\Api;
|
||||
namespace Kanboard\Api\Procedure;
|
||||
|
||||
use LogicException;
|
||||
use Kanboard\Core\Security\Role;
|
||||
|
|
@ -11,10 +11,10 @@ use Kanboard\Core\Ldap\User as LdapUser;
|
|||
/**
|
||||
* User API controller
|
||||
*
|
||||
* @package Kanboard\Api
|
||||
* @package Kanboard\Api\Procedure
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class UserApi extends BaseApi
|
||||
class UserProcedure extends BaseProcedure
|
||||
{
|
||||
public function getUser($user_id)
|
||||
{
|
||||
|
|
@ -1,87 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Kanboard\Api;
|
||||
|
||||
/**
|
||||
* Project API controller
|
||||
*
|
||||
* @package Kanboard\Api
|
||||
* @author Frederic Guillot
|
||||
*/
|
||||
class ProjectApi extends BaseApi
|
||||
{
|
||||
public function getProjectById($project_id)
|
||||
{
|
||||
$this->checkProjectPermission($project_id);
|
||||
return $this->formatProject($this->projectModel->getById($project_id));
|
||||
}
|
||||
|
||||
public function getProjectByName($name)
|
||||
{
|
||||
return $this->formatProject($this->projectModel->getByName($name));
|
||||
}
|
||||
|
||||
public function getAllProjects()
|
||||
{
|
||||
return $this->formatProjects($this->projectModel->getAll());
|
||||
}
|
||||
|
||||
public function removeProject($project_id)
|
||||
{
|
||||
return $this->projectModel->remove($project_id);
|
||||
}
|
||||
|
||||
public function enableProject($project_id)
|
||||
{
|
||||
return $this->projectModel->enable($project_id);
|
||||
}
|
||||
|
||||
public function disableProject($project_id)
|
||||
{
|
||||
return $this->projectModel->disable($project_id);
|
||||
}
|
||||
|
||||
public function enableProjectPublicAccess($project_id)
|
||||
{
|
||||
return $this->projectModel->enablePublicAccess($project_id);
|
||||
}
|
||||
|
||||
public function disableProjectPublicAccess($project_id)
|
||||
{
|
||||
return $this->projectModel->disablePublicAccess($project_id);
|
||||
}
|
||||
|
||||
public function getProjectActivities(array $project_ids)
|
||||
{
|
||||
return $this->helper->projectActivity->getProjectsEvents($project_ids);
|
||||
}
|
||||
|
||||
public function getProjectActivity($project_id)
|
||||
{
|
||||
$this->checkProjectPermission($project_id);
|
||||
return $this->helper->projectActivity->getProjectEvents($project_id);
|
||||
}
|
||||
|
||||
public function createProject($name, $description = null)
|
||||
{
|
||||
$values = array(
|
||||
'name' => $name,
|
||||
'description' => $description
|
||||
);
|
||||
|
||||
list($valid, ) = $this->projectValidator->validateCreation($values);
|
||||
return $valid ? $this->projectModel->create($values) : false;
|
||||
}
|
||||
|
||||
public function updateProject($project_id, $name, $description = null)
|
||||
{
|
||||
$values = $this->filterValues(array(
|
||||
'id' => $project_id,
|
||||
'name' => $name,
|
||||
'description' => $description
|
||||
));
|
||||
|
||||
list($valid, ) = $this->projectValidator->validateModification($values);
|
||||
return $valid && $this->projectModel->update($values);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,34 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Kanboard\Api;
|
||||
|
||||
use Kanboard\Core\Base;
|
||||
|
||||
/**
|
||||
* Subtask Time Tracking API controller
|
||||
*
|
||||
* @package api
|
||||
* @author Nikolaos Georgakis
|
||||
*/
|
||||
class SubtaskTimeTrackingApi extends Base
|
||||
{
|
||||
public function hasTimer($subtask_id,$user_id)
|
||||
{
|
||||
return $this->subtaskTimeTrackingModel->hasTimer($subtask_id,$user_id);
|
||||
}
|
||||
|
||||
public function logStartTime($subtask_id,$user_id)
|
||||
{
|
||||
return $this->subtaskTimeTrackingModel->logStartTime($subtask_id,$user_id);
|
||||
}
|
||||
|
||||
public function logEndTime($subtask_id,$user_id)
|
||||
{
|
||||
return $this->subtaskTimeTrackingModel->logEndTime($subtask_id,$user_id);
|
||||
}
|
||||
|
||||
public function getTimeSpent($subtask_id,$user_id)
|
||||
{
|
||||
return $this->subtaskTimeTrackingModel->getTimeSpent($subtask_id,$user_id);
|
||||
}
|
||||
}
|
||||
|
|
@ -35,8 +35,12 @@ use Pimple\Container;
|
|||
* @property \Kanboard\Core\Security\AuthenticationManager $authenticationManager
|
||||
* @property \Kanboard\Core\Security\AccessMap $applicationAccessMap
|
||||
* @property \Kanboard\Core\Security\AccessMap $projectAccessMap
|
||||
* @property \Kanboard\Core\Security\AccessMap $apiAccessMap
|
||||
* @property \Kanboard\Core\Security\AccessMap $apiProjectAccessMap
|
||||
* @property \Kanboard\Core\Security\Authorization $applicationAuthorization
|
||||
* @property \Kanboard\Core\Security\Authorization $projectAuthorization
|
||||
* @property \Kanboard\Core\Security\Authorization $apiAuthorization
|
||||
* @property \Kanboard\Core\Security\Authorization $apiProjectAuthorization
|
||||
* @property \Kanboard\Core\Security\Role $role
|
||||
* @property \Kanboard\Core\Security\Token $token
|
||||
* @property \Kanboard\Core\Session\FlashMessage $flash
|
||||
|
|
|
|||
|
|
@ -85,6 +85,18 @@ class ActionModel extends Base
|
|||
return $action;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the projectId by the actionId
|
||||
*
|
||||
* @access public
|
||||
* @param integer $action_id
|
||||
* @return integer
|
||||
*/
|
||||
public function getProjectId($action_id)
|
||||
{
|
||||
return $this->db->table(self::TABLE)->eq('id', $action_id)->findOneColumn('project_id') ?: 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Attach parameters to actions
|
||||
*
|
||||
|
|
|
|||
|
|
@ -55,6 +55,18 @@ class CategoryModel extends Base
|
|||
return $this->db->table(self::TABLE)->eq('id', $category_id)->findOneColumn('name') ?: '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the projectId by the category id
|
||||
*
|
||||
* @access public
|
||||
* @param integer $category_id Category id
|
||||
* @return integer
|
||||
*/
|
||||
public function getProjectId($category_id)
|
||||
{
|
||||
return $this->db->table(self::TABLE)->eq('id', $category_id)->findOneColumn('project_id') ?: 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a category id by the category name and project id
|
||||
*
|
||||
|
|
|
|||
|
|
@ -31,6 +31,18 @@ class ColumnModel extends Base
|
|||
return $this->db->table(self::TABLE)->eq('id', $column_id)->findOne();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get projectId by the columnId
|
||||
*
|
||||
* @access public
|
||||
* @param integer $column_id Column id
|
||||
* @return integer
|
||||
*/
|
||||
public function getProjectId($column_id)
|
||||
{
|
||||
return $this->db->table(self::TABLE)->eq('id', $column_id)->findOneColumn('project_id');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the first column id for a given project
|
||||
*
|
||||
|
|
|
|||
|
|
@ -29,6 +29,22 @@ class CommentModel extends Base
|
|||
const EVENT_CREATE = 'comment.create';
|
||||
const EVENT_USER_MENTION = 'comment.user.mention';
|
||||
|
||||
/**
|
||||
* Get projectId from commentId
|
||||
*
|
||||
* @access public
|
||||
* @param integer $comment_id
|
||||
* @return integer
|
||||
*/
|
||||
public function getProjectId($comment_id)
|
||||
{
|
||||
return $this->db
|
||||
->table(self::TABLE)
|
||||
->eq(self::TABLE.'.id', $comment_id)
|
||||
->join(TaskModel::TABLE, 'id', 'task_id')
|
||||
->findOneColumn(TaskModel::TABLE . '.project_id') ?: 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all comments for a given task
|
||||
*
|
||||
|
|
|
|||
|
|
@ -51,6 +51,22 @@ class SubtaskModel extends Base
|
|||
const EVENT_CREATE = 'subtask.create';
|
||||
const EVENT_DELETE = 'subtask.delete';
|
||||
|
||||
/**
|
||||
* Get projectId from subtaskId
|
||||
*
|
||||
* @access public
|
||||
* @param integer $subtask_id
|
||||
* @return integer
|
||||
*/
|
||||
public function getProjectId($subtask_id)
|
||||
{
|
||||
return $this->db
|
||||
->table(self::TABLE)
|
||||
->eq(self::TABLE.'.id', $subtask_id)
|
||||
->join(TaskModel::TABLE, 'id', 'task_id')
|
||||
->findOneColumn(TaskModel::TABLE . '.project_id') ?: 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get available status
|
||||
*
|
||||
|
|
|
|||
|
|
@ -72,6 +72,22 @@ class TaskFileModel extends FileModel
|
|||
return self::EVENT_CREATE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get projectId from fileId
|
||||
*
|
||||
* @access public
|
||||
* @param integer $file_id
|
||||
* @return integer
|
||||
*/
|
||||
public function getProjectId($file_id)
|
||||
{
|
||||
return $this->db
|
||||
->table(self::TABLE)
|
||||
->eq(self::TABLE.'.id', $file_id)
|
||||
->join(TaskModel::TABLE, 'id', 'task_id')
|
||||
->findOneColumn(TaskModel::TABLE . '.project_id') ?: 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle screenshot upload
|
||||
*
|
||||
|
|
|
|||
|
|
@ -28,6 +28,22 @@ class TaskLinkModel extends Base
|
|||
*/
|
||||
const EVENT_CREATE_UPDATE = 'tasklink.create_update';
|
||||
|
||||
/**
|
||||
* Get projectId from $task_link_id
|
||||
*
|
||||
* @access public
|
||||
* @param integer $task_link_id
|
||||
* @return integer
|
||||
*/
|
||||
public function getProjectId($task_link_id)
|
||||
{
|
||||
return $this->db
|
||||
->table(self::TABLE)
|
||||
->eq(self::TABLE.'.id', $task_link_id)
|
||||
->join(TaskModel::TABLE, 'id', 'task_id')
|
||||
->findOneColumn(TaskModel::TABLE . '.project_id') ?: 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a task link
|
||||
*
|
||||
|
|
|
|||
|
|
@ -3,26 +3,26 @@
|
|||
namespace Kanboard\ServiceProvider;
|
||||
|
||||
use JsonRPC\Server;
|
||||
use Kanboard\Api\ActionApi;
|
||||
use Kanboard\Api\AppApi;
|
||||
use Kanboard\Api\BoardApi;
|
||||
use Kanboard\Api\CategoryApi;
|
||||
use Kanboard\Api\ColumnApi;
|
||||
use Kanboard\Api\CommentApi;
|
||||
use Kanboard\Api\TaskFileApi;
|
||||
use Kanboard\Api\GroupApi;
|
||||
use Kanboard\Api\GroupMemberApi;
|
||||
use Kanboard\Api\LinkApi;
|
||||
use Kanboard\Api\MeApi;
|
||||
use Kanboard\Api\Middleware\AuthenticationApiMiddleware;
|
||||
use Kanboard\Api\ProjectApi;
|
||||
use Kanboard\Api\ProjectPermissionApi;
|
||||
use Kanboard\Api\SubtaskApi;
|
||||
use Kanboard\Api\SubtaskTimeTrackingApi;
|
||||
use Kanboard\Api\SwimlaneApi;
|
||||
use Kanboard\Api\TaskApi;
|
||||
use Kanboard\Api\TaskLinkApi;
|
||||
use Kanboard\Api\UserApi;
|
||||
use Kanboard\Api\Procedure\ActionProcedure;
|
||||
use Kanboard\Api\Procedure\AppProcedure;
|
||||
use Kanboard\Api\Procedure\BoardProcedure;
|
||||
use Kanboard\Api\Procedure\CategoryProcedure;
|
||||
use Kanboard\Api\Procedure\ColumnProcedure;
|
||||
use Kanboard\Api\Procedure\CommentProcedure;
|
||||
use Kanboard\Api\Procedure\TaskFileProcedure;
|
||||
use Kanboard\Api\Procedure\GroupProcedure;
|
||||
use Kanboard\Api\Procedure\GroupMemberProcedure;
|
||||
use Kanboard\Api\Procedure\LinkProcedure;
|
||||
use Kanboard\Api\Procedure\MeProcedure;
|
||||
use Kanboard\Api\Middleware\AuthenticationMiddleware;
|
||||
use Kanboard\Api\Procedure\ProjectProcedure;
|
||||
use Kanboard\Api\Procedure\ProjectPermissionProcedure;
|
||||
use Kanboard\Api\Procedure\SubtaskProcedure;
|
||||
use Kanboard\Api\Procedure\SubtaskTimeTrackingProcedure;
|
||||
use Kanboard\Api\Procedure\SwimlaneProcedure;
|
||||
use Kanboard\Api\Procedure\TaskProcedure;
|
||||
use Kanboard\Api\Procedure\TaskLinkProcedure;
|
||||
use Kanboard\Api\Procedure\UserProcedure;
|
||||
use Pimple\Container;
|
||||
use Pimple\ServiceProviderInterface;
|
||||
|
||||
|
|
@ -45,31 +45,32 @@ class ApiProvider implements ServiceProviderInterface
|
|||
$server = new Server();
|
||||
$server->setAuthenticationHeader(API_AUTHENTICATION_HEADER);
|
||||
$server->getMiddlewareHandler()
|
||||
->withMiddleware(new AuthenticationApiMiddleware($container))
|
||||
->withMiddleware(new AuthenticationMiddleware($container))
|
||||
;
|
||||
|
||||
$server->getProcedureHandler()
|
||||
->withObject(new MeApi($container))
|
||||
->withObject(new ActionApi($container))
|
||||
->withObject(new AppApi($container))
|
||||
->withObject(new BoardApi($container))
|
||||
->withObject(new ColumnApi($container))
|
||||
->withObject(new CategoryApi($container))
|
||||
->withObject(new CommentApi($container))
|
||||
->withObject(new TaskFileApi($container))
|
||||
->withObject(new LinkApi($container))
|
||||
->withObject(new ProjectApi($container))
|
||||
->withObject(new ProjectPermissionApi($container))
|
||||
->withObject(new SubtaskApi($container))
|
||||
->withObject(new SubtaskTimeTrackingApi($container))
|
||||
->withObject(new SwimlaneApi($container))
|
||||
->withObject(new TaskApi($container))
|
||||
->withObject(new TaskLinkApi($container))
|
||||
->withObject(new UserApi($container))
|
||||
->withObject(new GroupApi($container))
|
||||
->withObject(new GroupMemberApi($container))
|
||||
->withObject(new MeProcedure($container))
|
||||
->withObject(new ActionProcedure($container))
|
||||
->withObject(new AppProcedure($container))
|
||||
->withObject(new BoardProcedure($container))
|
||||
->withObject(new ColumnProcedure($container))
|
||||
->withObject(new CategoryProcedure($container))
|
||||
->withObject(new CommentProcedure($container))
|
||||
->withObject(new TaskFileProcedure($container))
|
||||
->withObject(new LinkProcedure($container))
|
||||
->withObject(new ProjectProcedure($container))
|
||||
->withObject(new ProjectPermissionProcedure($container))
|
||||
->withObject(new SubtaskProcedure($container))
|
||||
->withObject(new SubtaskTimeTrackingProcedure($container))
|
||||
->withObject(new SwimlaneProcedure($container))
|
||||
->withObject(new TaskProcedure($container))
|
||||
->withObject(new TaskLinkProcedure($container))
|
||||
->withObject(new UserProcedure($container))
|
||||
->withObject(new GroupProcedure($container))
|
||||
->withObject(new GroupMemberProcedure($container))
|
||||
->withBeforeMethod('beforeProcedure')
|
||||
;
|
||||
|
||||
|
||||
$container['api'] = $server;
|
||||
return $container;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -46,9 +46,13 @@ class AuthenticationProvider implements ServiceProviderInterface
|
|||
|
||||
$container['projectAccessMap'] = $this->getProjectAccessMap();
|
||||
$container['applicationAccessMap'] = $this->getApplicationAccessMap();
|
||||
$container['apiAccessMap'] = $this->getApiAccessMap();
|
||||
$container['apiProjectAccessMap'] = $this->getApiProjectAccessMap();
|
||||
|
||||
$container['projectAuthorization'] = new Authorization($container['projectAccessMap']);
|
||||
$container['applicationAuthorization'] = new Authorization($container['applicationAccessMap']);
|
||||
$container['apiAuthorization'] = new Authorization($container['apiAccessMap']);
|
||||
$container['apiProjectAuthorization'] = new Authorization($container['apiProjectAccessMap']);
|
||||
|
||||
return $container;
|
||||
}
|
||||
|
|
@ -151,4 +155,57 @@ class AuthenticationProvider implements ServiceProviderInterface
|
|||
|
||||
return $acl;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get ACL for the API
|
||||
*
|
||||
* @access public
|
||||
* @return AccessMap
|
||||
*/
|
||||
public function getApiAccessMap()
|
||||
{
|
||||
$acl = new AccessMap;
|
||||
$acl->setDefaultRole(Role::APP_USER);
|
||||
$acl->setRoleHierarchy(Role::APP_ADMIN, array(Role::APP_MANAGER, Role::APP_USER, Role::APP_PUBLIC));
|
||||
$acl->setRoleHierarchy(Role::APP_MANAGER, array(Role::APP_USER, Role::APP_PUBLIC));
|
||||
|
||||
$acl->add('UserProcedure', '*', Role::APP_ADMIN);
|
||||
$acl->add('GroupMemberProcedure', '*', Role::APP_ADMIN);
|
||||
$acl->add('GroupProcedure', '*', Role::APP_ADMIN);
|
||||
$acl->add('LinkProcedure', '*', Role::APP_ADMIN);
|
||||
$acl->add('TaskProcedure', array('getOverdueTasks'), Role::APP_ADMIN);
|
||||
$acl->add('ProjectProcedure', array('getAllProjects'), Role::APP_ADMIN);
|
||||
$acl->add('ProjectProcedure', array('createProject'), Role::APP_MANAGER);
|
||||
|
||||
return $acl;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get ACL for the API
|
||||
*
|
||||
* @access public
|
||||
* @return AccessMap
|
||||
*/
|
||||
public function getApiProjectAccessMap()
|
||||
{
|
||||
$acl = new AccessMap;
|
||||
$acl->setDefaultRole(Role::PROJECT_VIEWER);
|
||||
$acl->setRoleHierarchy(Role::PROJECT_MANAGER, array(Role::PROJECT_MEMBER, Role::PROJECT_VIEWER));
|
||||
$acl->setRoleHierarchy(Role::PROJECT_MEMBER, array(Role::PROJECT_VIEWER));
|
||||
|
||||
$acl->add('ActionProcedure', array('removeAction', 'getActions', 'createAction'), Role::PROJECT_MANAGER);
|
||||
$acl->add('CategoryProcedure', '*', Role::PROJECT_MANAGER);
|
||||
$acl->add('ColumnProcedure', '*', Role::PROJECT_MANAGER);
|
||||
$acl->add('CommentProcedure', array('removeComment', 'createComment', 'updateComment'), Role::PROJECT_MEMBER);
|
||||
$acl->add('ProjectPermissionProcedure', '*', Role::PROJECT_MANAGER);
|
||||
$acl->add('ProjectProcedure', array('updateProject', 'removeProject', 'enableProject', 'disableProject', 'enableProjectPublicAccess', 'disableProjectPublicAccess'), Role::PROJECT_MANAGER);
|
||||
$acl->add('SubtaskProcedure', '*', Role::PROJECT_MEMBER);
|
||||
$acl->add('SubtaskTimeTrackingProcedure', '*', Role::PROJECT_MEMBER);
|
||||
$acl->add('SwimlaneProcedure', '*', Role::PROJECT_MANAGER);
|
||||
$acl->add('TaskFileProcedure', '*', Role::PROJECT_MEMBER);
|
||||
$acl->add('TaskLinkProcedure', '*', Role::PROJECT_MEMBER);
|
||||
$acl->add('TaskProcedure', '*', Role::PROJECT_MEMBER);
|
||||
|
||||
return $acl;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@
|
|||
"christian-riesen/otp" : "1.4",
|
||||
"eluceo/ical": "0.8.0",
|
||||
"erusev/parsedown" : "1.6.0",
|
||||
"fguillot/json-rpc" : "1.2.0",
|
||||
"fguillot/json-rpc" : "1.2.1",
|
||||
"fguillot/picodb" : "1.0.12",
|
||||
"fguillot/simpleLogger" : "1.0.1",
|
||||
"fguillot/simple-validator" : "1.0.0",
|
||||
|
|
|
|||
|
|
@ -4,8 +4,8 @@
|
|||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"hash": "2de2026649db7bc41653bef80f974c6a",
|
||||
"content-hash": "ea8ef74f1f1cf53b9f96b7609d756873",
|
||||
"hash": "283af0b856598f5bc3d8ee0b226959e5",
|
||||
"content-hash": "18c0bbff5406ceb8b567d9655de26746",
|
||||
"packages": [
|
||||
{
|
||||
"name": "christian-riesen/base32",
|
||||
|
|
@ -203,16 +203,16 @@
|
|||
},
|
||||
{
|
||||
"name": "fguillot/json-rpc",
|
||||
"version": "v1.2.0",
|
||||
"version": "v1.2.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/fguillot/JsonRPC.git",
|
||||
"reference": "b002320b10aa1eeb7aee83f7b703cd6a6e99ff78"
|
||||
"reference": "d491bb549bfa11aff4c37abcea2ffb28c9523f69"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/fguillot/JsonRPC/zipball/b002320b10aa1eeb7aee83f7b703cd6a6e99ff78",
|
||||
"reference": "b002320b10aa1eeb7aee83f7b703cd6a6e99ff78",
|
||||
"url": "https://api.github.com/repos/fguillot/JsonRPC/zipball/d491bb549bfa11aff4c37abcea2ffb28c9523f69",
|
||||
"reference": "d491bb549bfa11aff4c37abcea2ffb28c9523f69",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
|
@ -238,7 +238,7 @@
|
|||
],
|
||||
"description": "Simple Json-RPC client/server library that just works",
|
||||
"homepage": "https://github.com/fguillot/JsonRPC",
|
||||
"time": "2016-05-29 13:06:36"
|
||||
"time": "2016-06-25 23:11:10"
|
||||
},
|
||||
{
|
||||
"name": "fguillot/picodb",
|
||||
|
|
@ -682,16 +682,16 @@
|
|||
},
|
||||
{
|
||||
"name": "symfony/console",
|
||||
"version": "v2.8.6",
|
||||
"version": "v2.8.7",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/console.git",
|
||||
"reference": "48221d3de4dc22d2cd57c97e8b9361821da86609"
|
||||
"reference": "5ac8bc9aa77bb2edf06af3a1bb6bc1020d23acd3"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/console/zipball/48221d3de4dc22d2cd57c97e8b9361821da86609",
|
||||
"reference": "48221d3de4dc22d2cd57c97e8b9361821da86609",
|
||||
"url": "https://api.github.com/repos/symfony/console/zipball/5ac8bc9aa77bb2edf06af3a1bb6bc1020d23acd3",
|
||||
"reference": "5ac8bc9aa77bb2edf06af3a1bb6bc1020d23acd3",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
|
@ -738,20 +738,20 @@
|
|||
],
|
||||
"description": "Symfony Console Component",
|
||||
"homepage": "https://symfony.com",
|
||||
"time": "2016-04-26 12:00:47"
|
||||
"time": "2016-06-06 15:06:25"
|
||||
},
|
||||
{
|
||||
"name": "symfony/event-dispatcher",
|
||||
"version": "v2.8.6",
|
||||
"version": "v2.8.7",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/event-dispatcher.git",
|
||||
"reference": "a158f13992a3147d466af7a23b564ac719a4ddd8"
|
||||
"reference": "2a6b8713f8bdb582058cfda463527f195b066110"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/a158f13992a3147d466af7a23b564ac719a4ddd8",
|
||||
"reference": "a158f13992a3147d466af7a23b564ac719a4ddd8",
|
||||
"url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/2a6b8713f8bdb582058cfda463527f195b066110",
|
||||
"reference": "2a6b8713f8bdb582058cfda463527f195b066110",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
|
@ -798,7 +798,7 @@
|
|||
],
|
||||
"description": "Symfony EventDispatcher Component",
|
||||
"homepage": "https://symfony.com",
|
||||
"time": "2016-05-03 18:59:18"
|
||||
"time": "2016-06-06 11:11:27"
|
||||
},
|
||||
{
|
||||
"name": "symfony/polyfill-mbstring",
|
||||
|
|
@ -916,38 +916,87 @@
|
|||
"time": "2015-06-14 21:17:01"
|
||||
},
|
||||
{
|
||||
"name": "phpdocumentor/reflection-docblock",
|
||||
"version": "2.0.4",
|
||||
"name": "phpdocumentor/reflection-common",
|
||||
"version": "1.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/phpDocumentor/ReflectionDocBlock.git",
|
||||
"reference": "d68dbdc53dc358a816f00b300704702b2eaff7b8"
|
||||
"url": "https://github.com/phpDocumentor/ReflectionCommon.git",
|
||||
"reference": "144c307535e82c8fdcaacbcfc1d6d8eeb896687c"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/d68dbdc53dc358a816f00b300704702b2eaff7b8",
|
||||
"reference": "d68dbdc53dc358a816f00b300704702b2eaff7b8",
|
||||
"url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/144c307535e82c8fdcaacbcfc1d6d8eeb896687c",
|
||||
"reference": "144c307535e82c8fdcaacbcfc1d6d8eeb896687c",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.3"
|
||||
"php": ">=5.5"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "~4.0"
|
||||
},
|
||||
"suggest": {
|
||||
"dflydev/markdown": "~1.0",
|
||||
"erusev/parsedown": "~1.0"
|
||||
"phpunit/phpunit": "^4.6"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.0.x-dev"
|
||||
"dev-master": "1.0.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-0": {
|
||||
"phpDocumentor": [
|
||||
"psr-4": {
|
||||
"phpDocumentor\\Reflection\\": [
|
||||
"src"
|
||||
]
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Jaap van Otterdijk",
|
||||
"email": "opensource@ijaap.nl"
|
||||
}
|
||||
],
|
||||
"description": "Common reflection classes used by phpdocumentor to reflect the code structure",
|
||||
"homepage": "http://www.phpdoc.org",
|
||||
"keywords": [
|
||||
"FQSEN",
|
||||
"phpDocumentor",
|
||||
"phpdoc",
|
||||
"reflection",
|
||||
"static analysis"
|
||||
],
|
||||
"time": "2015-12-27 11:43:31"
|
||||
},
|
||||
{
|
||||
"name": "phpdocumentor/reflection-docblock",
|
||||
"version": "3.1.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/phpDocumentor/ReflectionDocBlock.git",
|
||||
"reference": "9270140b940ff02e58ec577c237274e92cd40cdd"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/9270140b940ff02e58ec577c237274e92cd40cdd",
|
||||
"reference": "9270140b940ff02e58ec577c237274e92cd40cdd",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.5",
|
||||
"phpdocumentor/reflection-common": "^1.0@dev",
|
||||
"phpdocumentor/type-resolver": "^0.2.0",
|
||||
"webmozart/assert": "^1.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"mockery/mockery": "^0.9.4",
|
||||
"phpunit/phpunit": "^4.4"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"phpDocumentor\\Reflection\\": [
|
||||
"src/"
|
||||
]
|
||||
}
|
||||
|
|
@ -959,39 +1008,87 @@
|
|||
"authors": [
|
||||
{
|
||||
"name": "Mike van Riel",
|
||||
"email": "mike.vanriel@naenius.com"
|
||||
"email": "me@mikevanriel.com"
|
||||
}
|
||||
],
|
||||
"time": "2015-02-03 12:10:50"
|
||||
"description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.",
|
||||
"time": "2016-06-10 09:48:41"
|
||||
},
|
||||
{
|
||||
"name": "phpspec/prophecy",
|
||||
"version": "v1.6.0",
|
||||
"name": "phpdocumentor/type-resolver",
|
||||
"version": "0.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/phpspec/prophecy.git",
|
||||
"reference": "3c91bdf81797d725b14cb62906f9a4ce44235972"
|
||||
"url": "https://github.com/phpDocumentor/TypeResolver.git",
|
||||
"reference": "b39c7a5b194f9ed7bd0dd345c751007a41862443"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/phpspec/prophecy/zipball/3c91bdf81797d725b14cb62906f9a4ce44235972",
|
||||
"reference": "3c91bdf81797d725b14cb62906f9a4ce44235972",
|
||||
"url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/b39c7a5b194f9ed7bd0dd345c751007a41862443",
|
||||
"reference": "b39c7a5b194f9ed7bd0dd345c751007a41862443",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.5",
|
||||
"phpdocumentor/reflection-common": "^1.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"mockery/mockery": "^0.9.4",
|
||||
"phpunit/phpunit": "^5.2||^4.8.24"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.0.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"phpDocumentor\\Reflection\\": [
|
||||
"src/"
|
||||
]
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Mike van Riel",
|
||||
"email": "me@mikevanriel.com"
|
||||
}
|
||||
],
|
||||
"time": "2016-06-10 07:14:17"
|
||||
},
|
||||
{
|
||||
"name": "phpspec/prophecy",
|
||||
"version": "v1.6.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/phpspec/prophecy.git",
|
||||
"reference": "58a8137754bc24b25740d4281399a4a3596058e0"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/phpspec/prophecy/zipball/58a8137754bc24b25740d4281399a4a3596058e0",
|
||||
"reference": "58a8137754bc24b25740d4281399a4a3596058e0",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"doctrine/instantiator": "^1.0.2",
|
||||
"php": "^5.3|^7.0",
|
||||
"phpdocumentor/reflection-docblock": "~2.0",
|
||||
"sebastian/comparator": "~1.1",
|
||||
"sebastian/recursion-context": "~1.0"
|
||||
"phpdocumentor/reflection-docblock": "^2.0|^3.0.2",
|
||||
"sebastian/comparator": "^1.1",
|
||||
"sebastian/recursion-context": "^1.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpspec/phpspec": "~2.0"
|
||||
"phpspec/phpspec": "^2.0"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.5.x-dev"
|
||||
"dev-master": "1.6.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
|
|
@ -1024,7 +1121,7 @@
|
|||
"spy",
|
||||
"stub"
|
||||
],
|
||||
"time": "2016-02-15 07:46:21"
|
||||
"time": "2016-06-07 08:13:47"
|
||||
},
|
||||
{
|
||||
"name": "phpunit/php-code-coverage",
|
||||
|
|
@ -1629,16 +1726,16 @@
|
|||
},
|
||||
{
|
||||
"name": "sebastian/exporter",
|
||||
"version": "1.2.1",
|
||||
"version": "1.2.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sebastianbergmann/exporter.git",
|
||||
"reference": "7ae5513327cb536431847bcc0c10edba2701064e"
|
||||
"reference": "42c4c2eec485ee3e159ec9884f95b431287edde4"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/7ae5513327cb536431847bcc0c10edba2701064e",
|
||||
"reference": "7ae5513327cb536431847bcc0c10edba2701064e",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/42c4c2eec485ee3e159ec9884f95b431287edde4",
|
||||
"reference": "42c4c2eec485ee3e159ec9884f95b431287edde4",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
|
@ -1646,12 +1743,13 @@
|
|||
"sebastian/recursion-context": "~1.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"ext-mbstring": "*",
|
||||
"phpunit/phpunit": "~4.4"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.2.x-dev"
|
||||
"dev-master": "1.3.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
|
|
@ -1691,7 +1789,7 @@
|
|||
"export",
|
||||
"exporter"
|
||||
],
|
||||
"time": "2015-06-21 07:55:53"
|
||||
"time": "2016-06-17 09:04:28"
|
||||
},
|
||||
{
|
||||
"name": "sebastian/global-state",
|
||||
|
|
@ -1834,16 +1932,16 @@
|
|||
},
|
||||
{
|
||||
"name": "symfony/stopwatch",
|
||||
"version": "v2.8.6",
|
||||
"version": "v2.8.7",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/stopwatch.git",
|
||||
"reference": "9e24824b2a9a16e17ab997f61d70bc03948e434e"
|
||||
"reference": "5e628055488bcc42dbace3af65be435d094e37e4"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/stopwatch/zipball/9e24824b2a9a16e17ab997f61d70bc03948e434e",
|
||||
"reference": "9e24824b2a9a16e17ab997f61d70bc03948e434e",
|
||||
"url": "https://api.github.com/repos/symfony/stopwatch/zipball/5e628055488bcc42dbace3af65be435d094e37e4",
|
||||
"reference": "5e628055488bcc42dbace3af65be435d094e37e4",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
|
@ -1879,7 +1977,7 @@
|
|||
],
|
||||
"description": "Symfony Stopwatch Component",
|
||||
"homepage": "https://symfony.com",
|
||||
"time": "2016-03-04 07:54:35"
|
||||
"time": "2016-06-06 11:11:27"
|
||||
},
|
||||
{
|
||||
"name": "symfony/yaml",
|
||||
|
|
@ -1927,6 +2025,55 @@
|
|||
"description": "Symfony Yaml Component",
|
||||
"homepage": "http://symfony.com",
|
||||
"time": "2012-08-22 13:48:41"
|
||||
},
|
||||
{
|
||||
"name": "webmozart/assert",
|
||||
"version": "1.0.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/webmozart/assert.git",
|
||||
"reference": "30eed06dd6bc88410a4ff7f77b6d22f3ce13dbde"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/webmozart/assert/zipball/30eed06dd6bc88410a4ff7f77b6d22f3ce13dbde",
|
||||
"reference": "30eed06dd6bc88410a4ff7f77b6d22f3ce13dbde",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.3"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^4.6"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.0-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Webmozart\\Assert\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Bernhard Schussek",
|
||||
"email": "bschussek@gmail.com"
|
||||
}
|
||||
],
|
||||
"description": "Assertions to validate method input/output with nice error messages.",
|
||||
"keywords": [
|
||||
"assert",
|
||||
"check",
|
||||
"validate"
|
||||
],
|
||||
"time": "2015-08-24 13:29:44"
|
||||
}
|
||||
],
|
||||
"aliases": [],
|
||||
|
|
|
|||
|
|
@ -1,48 +1,26 @@
|
|||
API Authentication
|
||||
==================
|
||||
|
||||
API endpoint
|
||||
------------
|
||||
|
||||
URL: `https://YOUR_SERVER/jsonrpc.php`
|
||||
|
||||
|
||||
Default method (HTTP Basic)
|
||||
---------------------------
|
||||
|
||||
The API credentials are available on the settings page.
|
||||
|
||||
- API end-point: `https://YOUR_SERVER/jsonrpc.php`
|
||||
|
||||
If you want to use the "application api":
|
||||
### Application credentials
|
||||
|
||||
- Username: `jsonrpc`
|
||||
- Password: API token on the settings page
|
||||
|
||||
Otherwise for the "user api", just use the real username/passsword.
|
||||
### User credentials
|
||||
|
||||
- Use the real username and password
|
||||
|
||||
The API use the [HTTP Basic Authentication Scheme described in the RFC2617](http://www.ietf.org/rfc/rfc2617.txt).
|
||||
If there is an authentication error, you will receive the HTTP status code `401 Not Authorized`.
|
||||
|
||||
### Authorized User API procedures
|
||||
|
||||
- getMe
|
||||
- getMyDashboard
|
||||
- getMyActivityStream
|
||||
- createMyPrivateProject
|
||||
- getMyProjectsList
|
||||
- getMyProjects
|
||||
- getTimezone
|
||||
- getVersion
|
||||
- getDefaultTaskColor
|
||||
- getDefaultTaskColors
|
||||
- getColorList
|
||||
- getProjectById
|
||||
- getTask
|
||||
- getTaskByReference
|
||||
- getAllTasks
|
||||
- openTask
|
||||
- closeTask
|
||||
- moveTaskPosition
|
||||
- createTask
|
||||
- updateTask
|
||||
- getBoard
|
||||
- getProjectActivity
|
||||
- getMyOverdueTasks
|
||||
|
||||
Custom HTTP header
|
||||
------------------
|
||||
|
|
@ -64,3 +42,14 @@ curl \
|
|||
-d '{"jsonrpc": "2.0", "method": "getAllProjects", "id": 1}' \
|
||||
http://localhost/kanboard/jsonrpc.php
|
||||
```
|
||||
|
||||
Authentication error
|
||||
--------------------
|
||||
|
||||
If the credentials are wrong, you will receive a `401 Not Authorized` and the corresponding JSON response.
|
||||
|
||||
|
||||
Authorization error
|
||||
-------------------
|
||||
|
||||
If the connected user is not allowed to access to the resource, you will receive a `403 Forbidden`.
|
||||
|
|
|
|||
|
|
@ -8,25 +8,25 @@ There are two types of API access:
|
|||
|
||||
### Application API
|
||||
|
||||
- Access to the API with the user "jsonrpc" and the token available in settings
|
||||
- Access to the API with the user "jsonrpc" and the token available on the settings page
|
||||
- Access to all procedures
|
||||
- No permission checked
|
||||
- There is no user session on the server
|
||||
- No access to procedures that starts with "My..." (example: "getMe" or "getMyProjects")
|
||||
- Example of possible clients: tools to migrate/import data, create tasks from another system, etc...
|
||||
|
||||
### User API
|
||||
|
||||
- Access to the API with the user credentials (username and password)
|
||||
- Access to a restricted set of procedures
|
||||
- The project permissions are checked
|
||||
- Application role and project permissions are checked for each procedure
|
||||
- A user session is created on the server
|
||||
- Example of possible clients: mobile/desktop application, command line utility, etc...
|
||||
- Example of possible clients: native mobile/desktop application, command line utility, etc...
|
||||
|
||||
Security
|
||||
--------
|
||||
|
||||
- Always use HTTPS with a valid certificate
|
||||
- If you make a mobile application, it's your job to store securely the user credentials on the device
|
||||
- Always use HTTPS with a valid certificate (avoid clear text communication)
|
||||
- If you make a mobile application, it's your responsability to store securely the user credentials on the device
|
||||
- After 3 authentication failure on the user api, the end-user have to unlock his account by using the login form
|
||||
- Two factor authentication is not yet available through the API
|
||||
|
||||
|
|
|
|||
|
|
@ -272,3 +272,36 @@ Response example:
|
|||
"result": true
|
||||
}
|
||||
```
|
||||
|
||||
## getProjectUserRole
|
||||
|
||||
- Purpose: **Get the role of a user for a given project**
|
||||
- Parameters:
|
||||
- **project_id** (integer, required)
|
||||
- **user_id** (integer, required)
|
||||
- Result on success: **role name**
|
||||
- Result on failure: **false**
|
||||
|
||||
Request example:
|
||||
|
||||
```json
|
||||
{
|
||||
"jsonrpc": "2.0",
|
||||
"method": "getProjectUserRole",
|
||||
"id": 2114673298,
|
||||
"params": [
|
||||
"2",
|
||||
"3"
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
Response example:
|
||||
|
||||
```json
|
||||
{
|
||||
"jsonrpc": "2.0",
|
||||
"id": 2114673298,
|
||||
"result": "project-viewer"
|
||||
}
|
||||
```
|
||||
|
|
|
|||
|
|
@ -7,6 +7,8 @@ API Project Procedures
|
|||
- Parameters:
|
||||
- **name** (string, required)
|
||||
- **description** (string, optional)
|
||||
- **owner_id** (integer, optional)
|
||||
- **identifier** (string, optional)
|
||||
- Result on success: **project_id**
|
||||
- Result on failure: **false**
|
||||
|
||||
|
|
@ -186,6 +188,8 @@ Response example:
|
|||
- **project_id** (integer, required)
|
||||
- **name** (string, required)
|
||||
- **description** (string, optional)
|
||||
- **owner_id** (integer, optional)
|
||||
- **identifier** (string, optional)
|
||||
- Result on success: **true**
|
||||
- Result on failure: **false**
|
||||
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
<?php
|
||||
|
||||
require_once __DIR__.'/BaseIntegrationTest.php';
|
||||
require_once __DIR__.'/BaseProcedureTest.php';
|
||||
|
||||
class ActionTest extends BaseIntegrationTest
|
||||
class ActionProcedureTest extends BaseProcedureTest
|
||||
{
|
||||
protected $projectName = 'My project to test actions';
|
||||
|
||||
|
|
@ -1,8 +1,8 @@
|
|||
<?php
|
||||
|
||||
require_once __DIR__.'/BaseIntegrationTest.php';
|
||||
require_once __DIR__.'/BaseProcedureTest.php';
|
||||
|
||||
class AppTest extends BaseIntegrationTest
|
||||
class AppProcedureTest extends BaseProcedureTest
|
||||
{
|
||||
public function testGetTimezone()
|
||||
{
|
||||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
require_once __DIR__.'/../../vendor/autoload.php';
|
||||
|
||||
abstract class BaseIntegrationTest extends PHPUnit_Framework_TestCase
|
||||
abstract class BaseProcedureTest extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
protected $app = null;
|
||||
protected $admin = null;
|
||||
|
|
@ -1,8 +1,8 @@
|
|||
<?php
|
||||
|
||||
require_once __DIR__.'/BaseIntegrationTest.php';
|
||||
require_once __DIR__.'/BaseProcedureTest.php';
|
||||
|
||||
class BoardTest extends BaseIntegrationTest
|
||||
class BoardProcedureTest extends BaseProcedureTest
|
||||
{
|
||||
protected $projectName = 'My project to test board';
|
||||
|
||||
|
|
@ -1,8 +1,8 @@
|
|||
<?php
|
||||
|
||||
require_once __DIR__.'/BaseIntegrationTest.php';
|
||||
require_once __DIR__.'/BaseProcedureTest.php';
|
||||
|
||||
class CategoryTest extends BaseIntegrationTest
|
||||
class CategoryProcedureTest extends BaseProcedureTest
|
||||
{
|
||||
protected $projectName = 'My project to test categories';
|
||||
private $categoryId = 0;
|
||||
|
|
@ -1,8 +1,8 @@
|
|||
<?php
|
||||
|
||||
require_once __DIR__.'/BaseIntegrationTest.php';
|
||||
require_once __DIR__.'/BaseProcedureTest.php';
|
||||
|
||||
class ColumnTest extends BaseIntegrationTest
|
||||
class ColumnProcedureTest extends BaseProcedureTest
|
||||
{
|
||||
protected $projectName = 'My project to test columns';
|
||||
private $columns = array();
|
||||
|
|
@ -1,8 +1,8 @@
|
|||
<?php
|
||||
|
||||
require_once __DIR__.'/BaseIntegrationTest.php';
|
||||
require_once __DIR__.'/BaseProcedureTest.php';
|
||||
|
||||
class CommentTest extends BaseIntegrationTest
|
||||
class CommentProcedureTest extends BaseProcedureTest
|
||||
{
|
||||
protected $projectName = 'My project to test comments';
|
||||
private $commentId = 0;
|
||||
|
|
@ -1,8 +1,8 @@
|
|||
<?php
|
||||
|
||||
require_once __DIR__.'/BaseIntegrationTest.php';
|
||||
require_once __DIR__.'/BaseProcedureTest.php';
|
||||
|
||||
class GroupMemberTest extends BaseIntegrationTest
|
||||
class GroupMemberProcedureTest extends BaseProcedureTest
|
||||
{
|
||||
protected $username = 'user-group-member';
|
||||
protected $groupName1 = 'My group member A';
|
||||
|
|
@ -1,8 +1,8 @@
|
|||
<?php
|
||||
|
||||
require_once __DIR__.'/BaseIntegrationTest.php';
|
||||
require_once __DIR__.'/BaseProcedureTest.php';
|
||||
|
||||
class GroupTest extends BaseIntegrationTest
|
||||
class GroupProcedureTest extends BaseProcedureTest
|
||||
{
|
||||
public function testAll()
|
||||
{
|
||||
|
|
@ -1,8 +1,8 @@
|
|||
<?php
|
||||
|
||||
require_once __DIR__.'/BaseIntegrationTest.php';
|
||||
require_once __DIR__.'/BaseProcedureTest.php';
|
||||
|
||||
class LinkTest extends BaseIntegrationTest
|
||||
class LinkProcedureTest extends BaseProcedureTest
|
||||
{
|
||||
public function testGetAllLinks()
|
||||
{
|
||||
|
|
@ -1,8 +1,8 @@
|
|||
<?php
|
||||
|
||||
require_once __DIR__.'/BaseIntegrationTest.php';
|
||||
require_once __DIR__.'/BaseProcedureTest.php';
|
||||
|
||||
class MeTest extends BaseIntegrationTest
|
||||
class MeProcedureTest extends BaseProcedureTest
|
||||
{
|
||||
protected $projectName = 'My private project';
|
||||
|
||||
|
|
@ -41,11 +41,6 @@ class MeTest extends BaseIntegrationTest
|
|||
{
|
||||
$projects = $this->user->getMyProjects();
|
||||
$this->assertNotEmpty($projects);
|
||||
$this->assertCount(1, $projects);
|
||||
$this->assertEquals($this->projectName, $projects[0]['name']);
|
||||
$this->assertNotEmpty($projects[0]['url']['calendar']);
|
||||
$this->assertNotEmpty($projects[0]['url']['board']);
|
||||
$this->assertNotEmpty($projects[0]['url']['list']);
|
||||
}
|
||||
|
||||
public function assertCreateTask()
|
||||
|
|
@ -1,8 +1,8 @@
|
|||
<?php
|
||||
|
||||
require_once __DIR__.'/BaseIntegrationTest.php';
|
||||
require_once __DIR__.'/BaseProcedureTest.php';
|
||||
|
||||
class OverdueTaskTest extends BaseIntegrationTest
|
||||
class OverdueTaskProcedureTest extends BaseProcedureTest
|
||||
{
|
||||
protected $projectName = 'My project to test overdue tasks';
|
||||
|
||||
|
|
@ -0,0 +1,306 @@
|
|||
<?php
|
||||
|
||||
require_once __DIR__.'/BaseProcedureTest.php';
|
||||
|
||||
class ProcedureAuthorizationTest extends BaseProcedureTest
|
||||
{
|
||||
public function testApiCredentialDoNotHaveAccessToUserCredentialProcedure()
|
||||
{
|
||||
$this->setExpectedException('JsonRPC\Exception\AccessDeniedException');
|
||||
$this->app->getMe();
|
||||
}
|
||||
|
||||
public function testUserCredentialDoNotHaveAccessToAdminProcedures()
|
||||
{
|
||||
$this->setExpectedException('JsonRPC\Exception\AccessDeniedException');
|
||||
$this->user->getUser(1);
|
||||
}
|
||||
|
||||
public function testManagerCredentialDoNotHaveAccessToAdminProcedures()
|
||||
{
|
||||
$this->setExpectedException('JsonRPC\Exception\AccessDeniedException');
|
||||
$this->user->getAllProjects();
|
||||
}
|
||||
|
||||
public function testUserCredentialDoNotHaveAccessToManagerProcedures()
|
||||
{
|
||||
$this->setExpectedException('JsonRPC\Exception\AccessDeniedException');
|
||||
$this->user->createProject('Team project creation are only for app managers');
|
||||
}
|
||||
|
||||
public function testAppManagerCanCreateTeamProject()
|
||||
{
|
||||
$this->assertNotFalse($this->manager->createProject('Team project created by app manager'));
|
||||
}
|
||||
|
||||
public function testAdminManagerCanCreateTeamProject()
|
||||
{
|
||||
$projectId = $this->admin->createProject('Team project created by admin');
|
||||
$this->assertNotFalse($projectId);
|
||||
|
||||
$this->setExpectedException('JsonRPC\Exception\AccessDeniedException');
|
||||
$this->assertNotNull($this->manager->getProjectById($projectId));
|
||||
}
|
||||
|
||||
public function testProjectManagerCanUpdateHisProject()
|
||||
{
|
||||
$projectId = $this->manager->createProject(array(
|
||||
'name' => 'Team project can be updated',
|
||||
'owner_id' => $this->managerUserId,
|
||||
));
|
||||
|
||||
$this->assertNotFalse($projectId);
|
||||
$this->assertEquals('project-manager', $this->app->getProjectUserRole($projectId, $this->managerUserId));
|
||||
$this->assertNotNull($this->manager->getProjectById($projectId));
|
||||
|
||||
$this->assertTrue($this->manager->updateProject($projectId, 'My team project have been updated'));
|
||||
}
|
||||
|
||||
public function testProjectAuthorizationForbidden()
|
||||
{
|
||||
$projectId = $this->manager->createProject('A team project without members');
|
||||
$this->assertNotFalse($projectId);
|
||||
|
||||
$this->setExpectedException('JsonRPC\Exception\AccessDeniedException');
|
||||
$this->user->getProjectById($projectId);
|
||||
}
|
||||
|
||||
public function testProjectAuthorizationGranted()
|
||||
{
|
||||
$projectId = $this->manager->createProject(array(
|
||||
'name' => 'A team project with members',
|
||||
'owner_id' => $this->managerUserId,
|
||||
));
|
||||
|
||||
$this->assertNotFalse($projectId);
|
||||
|
||||
$this->assertTrue($this->manager->addProjectUser($projectId, $this->userUserId));
|
||||
$this->assertNotNull($this->user->getProjectById($projectId));
|
||||
}
|
||||
|
||||
public function testActionAuthorizationForbidden()
|
||||
{
|
||||
$projectId = $this->manager->createProject(array(
|
||||
'name' => 'Test Project',
|
||||
'owner_id' => $this->managerUserId,
|
||||
));
|
||||
|
||||
$this->assertNotFalse($projectId);
|
||||
|
||||
$actionId = $this->manager->createAction($projectId, 'task.move.column', '\Kanboard\Action\TaskCloseColumn', array('column_id' => 1));
|
||||
$this->assertNotFalse($actionId);
|
||||
|
||||
$this->setExpectedException('JsonRPC\Exception\AccessDeniedException');
|
||||
$this->user->removeAction($projectId);
|
||||
}
|
||||
|
||||
public function testActionAuthorizationForbiddenBecauseNotProjectManager()
|
||||
{
|
||||
$projectId = $this->manager->createProject(array(
|
||||
'name' => 'Test Project',
|
||||
'owner_id' => $this->managerUserId,
|
||||
));
|
||||
|
||||
$this->assertNotFalse($projectId);
|
||||
|
||||
$actionId = $this->manager->createAction($projectId, 'task.move.column', '\Kanboard\Action\TaskCloseColumn', array('column_id' => 1));
|
||||
$this->assertNotFalse($actionId);
|
||||
|
||||
$this->assertTrue($this->manager->addProjectUser($projectId, $this->userUserId, 'project-member'));
|
||||
|
||||
$this->setExpectedException('JsonRPC\Exception\AccessDeniedException');
|
||||
$this->user->removeAction($actionId);
|
||||
}
|
||||
|
||||
public function testActionAuthorizationGranted()
|
||||
{
|
||||
$projectId = $this->manager->createProject(array(
|
||||
'name' => 'Test Project',
|
||||
'owner_id' => $this->managerUserId,
|
||||
));
|
||||
|
||||
$this->assertNotFalse($projectId);
|
||||
|
||||
$actionId = $this->manager->createAction($projectId, 'task.move.column', '\Kanboard\Action\TaskCloseColumn', array('column_id' => 1));
|
||||
$this->assertNotFalse($actionId);
|
||||
|
||||
$this->assertTrue($this->manager->addProjectUser($projectId, $this->userUserId, 'project-manager'));
|
||||
$this->assertTrue($this->user->removeAction($actionId));
|
||||
}
|
||||
|
||||
public function testCategoryAuthorizationForbidden()
|
||||
{
|
||||
$projectId = $this->manager->createProject(array(
|
||||
'name' => 'Test Project',
|
||||
'owner_id' => $this->managerUserId,
|
||||
));
|
||||
|
||||
$this->assertNotFalse($projectId);
|
||||
|
||||
$categoryId = $this->manager->createCategory($projectId, 'Test');
|
||||
$this->assertNotFalse($categoryId);
|
||||
|
||||
$this->setExpectedException('JsonRPC\Exception\AccessDeniedException');
|
||||
$this->user->removeCategory($categoryId);
|
||||
}
|
||||
|
||||
public function testCategoryAuthorizationForbiddenBecauseNotProjectManager()
|
||||
{
|
||||
$projectId = $this->manager->createProject(array(
|
||||
'name' => 'Test Project',
|
||||
'owner_id' => $this->managerUserId,
|
||||
));
|
||||
|
||||
$this->assertNotFalse($projectId);
|
||||
|
||||
$categoryId = $this->manager->createCategory($projectId, 'Test');
|
||||
$this->assertNotFalse($categoryId);
|
||||
|
||||
$this->assertTrue($this->manager->addProjectUser($projectId, $this->userUserId, 'project-member'));
|
||||
$this->setExpectedException('JsonRPC\Exception\AccessDeniedException');
|
||||
$this->user->removeCategory($categoryId);
|
||||
}
|
||||
|
||||
public function testCategoryAuthorizationGranted()
|
||||
{
|
||||
$projectId = $this->manager->createProject(array(
|
||||
'name' => 'Test Project',
|
||||
'owner_id' => $this->managerUserId,
|
||||
));
|
||||
|
||||
$this->assertNotFalse($projectId);
|
||||
|
||||
$categoryId = $this->manager->createCategory($projectId, 'Test');
|
||||
$this->assertNotFalse($categoryId);
|
||||
|
||||
$this->assertTrue($this->manager->addProjectUser($projectId, $this->userUserId, 'project-manager'));
|
||||
$this->assertTrue($this->user->removeCategory($categoryId));
|
||||
}
|
||||
|
||||
public function testColumnAuthorizationForbidden()
|
||||
{
|
||||
$projectId = $this->manager->createProject(array(
|
||||
'name' => 'Test Project',
|
||||
'owner_id' => $this->managerUserId,
|
||||
));
|
||||
|
||||
$this->assertNotFalse($projectId);
|
||||
|
||||
$columnId = $this->manager->addColumn($projectId, 'Test');
|
||||
$this->assertNotFalse($columnId);
|
||||
|
||||
$this->setExpectedException('JsonRPC\Exception\AccessDeniedException');
|
||||
$this->user->removeColumn($columnId);
|
||||
}
|
||||
|
||||
public function testColumnAuthorizationForbiddenBecauseNotProjectManager()
|
||||
{
|
||||
$projectId = $this->manager->createProject(array(
|
||||
'name' => 'Test Project',
|
||||
'owner_id' => $this->managerUserId,
|
||||
));
|
||||
|
||||
$this->assertNotFalse($projectId);
|
||||
|
||||
$columnId = $this->manager->addColumn($projectId, 'Test');
|
||||
$this->assertNotFalse($columnId);
|
||||
|
||||
$this->assertTrue($this->manager->addProjectUser($projectId, $this->userUserId, 'project-member'));
|
||||
$this->setExpectedException('JsonRPC\Exception\AccessDeniedException');
|
||||
$this->user->removeColumn($columnId);
|
||||
}
|
||||
|
||||
public function testColumnAuthorizationGranted()
|
||||
{
|
||||
$projectId = $this->manager->createProject(array(
|
||||
'name' => 'Test Project',
|
||||
'owner_id' => $this->managerUserId,
|
||||
));
|
||||
|
||||
$this->assertNotFalse($projectId);
|
||||
|
||||
$columnId = $this->manager->addColumn($projectId, 'Test');
|
||||
$this->assertNotFalse($columnId);
|
||||
|
||||
$this->assertTrue($this->manager->addProjectUser($projectId, $this->userUserId, 'project-manager'));
|
||||
$this->assertTrue($this->user->removeColumn($columnId));
|
||||
}
|
||||
|
||||
public function testCommentAuthorizationForbidden()
|
||||
{
|
||||
$projectId = $this->manager->createProject(array(
|
||||
'name' => 'Test Project',
|
||||
'owner_id' => $this->managerUserId,
|
||||
));
|
||||
|
||||
$this->assertNotFalse($projectId);
|
||||
$this->assertTrue($this->manager->addProjectUser($projectId, $this->userUserId, 'project-viewer'));
|
||||
|
||||
$taskId = $this->manager->createTask('My Task', $projectId);
|
||||
$this->assertNotFalse($taskId);
|
||||
|
||||
$commentId = $this->manager->createComment($taskId, $this->userUserId, 'My comment');
|
||||
$this->assertNotFalse($commentId);
|
||||
|
||||
$this->setExpectedException('JsonRPC\Exception\AccessDeniedException');
|
||||
$this->user->updateComment($commentId, 'something else');
|
||||
}
|
||||
|
||||
public function testCommentAuthorizationGranted()
|
||||
{
|
||||
$projectId = $this->manager->createProject(array(
|
||||
'name' => 'Test Project',
|
||||
'owner_id' => $this->managerUserId,
|
||||
));
|
||||
|
||||
$this->assertNotFalse($projectId);
|
||||
$this->assertTrue($this->manager->addProjectUser($projectId, $this->userUserId, 'project-member'));
|
||||
|
||||
$taskId = $this->user->createTask('My Task', $projectId);
|
||||
$this->assertNotFalse($taskId);
|
||||
|
||||
$commentId = $this->user->createComment($taskId, $this->userUserId, 'My comment');
|
||||
$this->assertNotFalse($commentId);
|
||||
|
||||
$this->assertTrue($this->user->updateComment($commentId, 'something else'));
|
||||
}
|
||||
|
||||
public function testSubtaskAuthorizationForbidden()
|
||||
{
|
||||
$projectId = $this->manager->createProject(array(
|
||||
'name' => 'Test Project',
|
||||
'owner_id' => $this->managerUserId,
|
||||
));
|
||||
|
||||
$this->assertNotFalse($projectId);
|
||||
$this->assertTrue($this->manager->addProjectUser($projectId, $this->userUserId, 'project-viewer'));
|
||||
|
||||
$taskId = $this->manager->createTask('My Task', $projectId);
|
||||
$this->assertNotFalse($taskId);
|
||||
|
||||
$subtaskId = $this->manager->createSubtask($taskId, 'My subtask');
|
||||
$this->assertNotFalse($subtaskId);
|
||||
|
||||
$this->setExpectedException('JsonRPC\Exception\AccessDeniedException');
|
||||
$this->user->removeSubtask($subtaskId);
|
||||
}
|
||||
|
||||
public function testSubtaskAuthorizationGranted()
|
||||
{
|
||||
$projectId = $this->manager->createProject(array(
|
||||
'name' => 'Test Project',
|
||||
'owner_id' => $this->managerUserId,
|
||||
));
|
||||
|
||||
$this->assertNotFalse($projectId);
|
||||
$this->assertTrue($this->manager->addProjectUser($projectId, $this->userUserId, 'project-member'));
|
||||
|
||||
$taskId = $this->user->createTask('My Task', $projectId);
|
||||
$this->assertNotFalse($taskId);
|
||||
|
||||
$subtaskId = $this->manager->createSubtask($taskId, 'My subtask');
|
||||
$this->assertNotFalse($subtaskId);
|
||||
|
||||
$this->assertTrue($this->user->removeSubtask($subtaskId));
|
||||
}
|
||||
}
|
||||
|
|
@ -1,8 +1,8 @@
|
|||
<?php
|
||||
|
||||
require_once __DIR__.'/BaseIntegrationTest.php';
|
||||
require_once __DIR__.'/BaseProcedureTest.php';
|
||||
|
||||
class ProjectPermissionTest extends BaseIntegrationTest
|
||||
class ProjectPermissionProcedureTest extends BaseProcedureTest
|
||||
{
|
||||
protected $projectName = 'Project with permission';
|
||||
protected $username = 'user-project-permission';
|
||||
|
|
@ -1,8 +1,8 @@
|
|||
<?php
|
||||
|
||||
require_once __DIR__.'/BaseIntegrationTest.php';
|
||||
require_once __DIR__.'/BaseProcedureTest.php';
|
||||
|
||||
class ProjectTest extends BaseIntegrationTest
|
||||
class ProjectProcedureTest extends BaseProcedureTest
|
||||
{
|
||||
protected $projectName = 'My team project';
|
||||
|
||||
|
|
@ -1,8 +1,8 @@
|
|||
<?php
|
||||
|
||||
require_once __DIR__.'/BaseIntegrationTest.php';
|
||||
require_once __DIR__.'/BaseProcedureTest.php';
|
||||
|
||||
class SubtaskTest extends BaseIntegrationTest
|
||||
class SubtaskProcedureTest extends BaseProcedureTest
|
||||
{
|
||||
protected $projectName = 'My project to test subtasks';
|
||||
private $subtaskId = 0;
|
||||
|
|
@ -1,8 +1,8 @@
|
|||
<?php
|
||||
|
||||
require_once __DIR__.'/BaseIntegrationTest.php';
|
||||
require_once __DIR__.'/BaseProcedureTest.php';
|
||||
|
||||
class SwimlaneTest extends BaseIntegrationTest
|
||||
class SwimlaneProcedureTest extends BaseProcedureTest
|
||||
{
|
||||
protected $projectName = 'My project to test swimlanes';
|
||||
private $swimlaneId = 0;
|
||||
|
|
@ -1,8 +1,8 @@
|
|||
<?php
|
||||
|
||||
require_once __DIR__.'/BaseIntegrationTest.php';
|
||||
require_once __DIR__.'/BaseProcedureTest.php';
|
||||
|
||||
class TaskFileTest extends BaseIntegrationTest
|
||||
class TaskFileProcedureTest extends BaseProcedureTest
|
||||
{
|
||||
protected $projectName = 'My project to test task files';
|
||||
protected $fileId;
|
||||
|
|
@ -1,8 +1,8 @@
|
|||
<?php
|
||||
|
||||
require_once __DIR__.'/BaseIntegrationTest.php';
|
||||
require_once __DIR__.'/BaseProcedureTest.php';
|
||||
|
||||
class TaskLinkTest extends BaseIntegrationTest
|
||||
class TaskLinkProcedureTest extends BaseProcedureTest
|
||||
{
|
||||
protected $projectName = 'My project to test task links';
|
||||
protected $taskLinkId;
|
||||
|
|
@ -1,8 +1,8 @@
|
|||
<?php
|
||||
|
||||
require_once __DIR__.'/BaseIntegrationTest.php';
|
||||
require_once __DIR__.'/BaseProcedureTest.php';
|
||||
|
||||
class TaskTest extends BaseIntegrationTest
|
||||
class TaskProcedureTest extends BaseProcedureTest
|
||||
{
|
||||
protected $projectName = 'My project to test tasks';
|
||||
|
||||
|
|
@ -1,8 +1,8 @@
|
|||
<?php
|
||||
|
||||
require_once __DIR__.'/BaseIntegrationTest.php';
|
||||
require_once __DIR__.'/BaseProcedureTest.php';
|
||||
|
||||
class UserTest extends BaseIntegrationTest
|
||||
class UserProcedureTest extends BaseProcedureTest
|
||||
{
|
||||
public function testAll()
|
||||
{
|
||||
|
|
@ -11,7 +11,7 @@ use Kanboard\Model\CategoryModel;
|
|||
use Kanboard\Model\ProjectUserRoleModel;
|
||||
use Kanboard\Core\Security\Role;
|
||||
|
||||
class ActionTest extends Base
|
||||
class ActionModelTest extends Base
|
||||
{
|
||||
public function testCreate()
|
||||
{
|
||||
|
|
@ -69,6 +69,24 @@ class ActionTest extends Base
|
|||
$this->assertEquals(array('column_id' => 1, 'color_id' => 'red'), $action['params']);
|
||||
}
|
||||
|
||||
public function testGetProjectId()
|
||||
{
|
||||
$projectModel = new ProjectModel($this->container);
|
||||
$actionModel = new ActionModel($this->container);
|
||||
|
||||
$this->assertEquals(1, $projectModel->create(array('name' => 'test')));
|
||||
|
||||
$this->assertEquals(1, $actionModel->create(array(
|
||||
'project_id' => 1,
|
||||
'event_name' => TaskModel::EVENT_CREATE,
|
||||
'action_name' => '\Kanboard\Action\TaskAssignColorColumn',
|
||||
'params' => array('column_id' => 1, 'color_id' => 'red'),
|
||||
)));
|
||||
|
||||
$this->assertEquals(1, $actionModel->getProjectId(1));
|
||||
$this->assertSame(0, $actionModel->getProjectId(42));
|
||||
}
|
||||
|
||||
public function testGetAll()
|
||||
{
|
||||
$projectModel = new ProjectModel($this->container);
|
||||
|
|
@ -8,7 +8,7 @@ use Kanboard\Model\TaskFinderModel;
|
|||
use Kanboard\Model\ProjectModel;
|
||||
use Kanboard\Model\CategoryModel;
|
||||
|
||||
class CategoryTest extends Base
|
||||
class CategoryModelTest extends Base
|
||||
{
|
||||
public function testCreation()
|
||||
{
|
||||
|
|
@ -81,6 +81,18 @@ class CategoryTest extends Base
|
|||
$this->assertSame(0, $categoryModel->getIdByName(1, 'Category #2'));
|
||||
}
|
||||
|
||||
public function testGetProjectId()
|
||||
{
|
||||
$projectModel = new ProjectModel($this->container);
|
||||
$categoryModel = new CategoryModel($this->container);
|
||||
|
||||
$this->assertEquals(1, $projectModel->create(array('name' => 'Project #1')));
|
||||
$this->assertEquals(1, $categoryModel->create(array('name' => 'Category #1', 'project_id' => 1, 'description' => 'test')));
|
||||
|
||||
$this->assertEquals(1, $categoryModel->getProjectId(1));
|
||||
$this->assertSame(0, $categoryModel->getProjectId(2));
|
||||
}
|
||||
|
||||
public function testGetList()
|
||||
{
|
||||
$projectModel = new ProjectModel($this->container);
|
||||
|
|
@ -10,16 +10,16 @@ class CommentTest extends Base
|
|||
{
|
||||
public function testCreate()
|
||||
{
|
||||
$c = new CommentModel($this->container);
|
||||
$tc = new TaskCreationModel($this->container);
|
||||
$p = new ProjectModel($this->container);
|
||||
$commentModel = new CommentModel($this->container);
|
||||
$taskCreationModel = new TaskCreationModel($this->container);
|
||||
$projectModel = new ProjectModel($this->container);
|
||||
|
||||
$this->assertEquals(1, $p->create(array('name' => 'test1')));
|
||||
$this->assertEquals(1, $tc->create(array('title' => 'test', 'project_id' => 1, 'column_id' => 3, 'owner_id' => 1)));
|
||||
$this->assertEquals(1, $c->create(array('task_id' => 1, 'comment' => 'bla bla', 'user_id' => 1)));
|
||||
$this->assertEquals(2, $c->create(array('task_id' => 1, 'comment' => 'bla bla')));
|
||||
$this->assertEquals(1, $projectModel->create(array('name' => 'test1')));
|
||||
$this->assertEquals(1, $taskCreationModel->create(array('title' => 'test', 'project_id' => 1, 'column_id' => 3, 'owner_id' => 1)));
|
||||
$this->assertEquals(1, $commentModel->create(array('task_id' => 1, 'comment' => 'bla bla', 'user_id' => 1)));
|
||||
$this->assertEquals(2, $commentModel->create(array('task_id' => 1, 'comment' => 'bla bla')));
|
||||
|
||||
$comment = $c->getById(1);
|
||||
$comment = $commentModel->getById(1);
|
||||
$this->assertNotEmpty($comment);
|
||||
$this->assertEquals('bla bla', $comment['comment']);
|
||||
$this->assertEquals(1, $comment['task_id']);
|
||||
|
|
@ -27,7 +27,7 @@ class CommentTest extends Base
|
|||
$this->assertEquals('admin', $comment['username']);
|
||||
$this->assertEquals(time(), $comment['date_creation'], '', 3);
|
||||
|
||||
$comment = $c->getById(2);
|
||||
$comment = $commentModel->getById(2);
|
||||
$this->assertNotEmpty($comment);
|
||||
$this->assertEquals('bla bla', $comment['comment']);
|
||||
$this->assertEquals(1, $comment['task_id']);
|
||||
|
|
@ -38,17 +38,17 @@ class CommentTest extends Base
|
|||
|
||||
public function testGetAll()
|
||||
{
|
||||
$c = new CommentModel($this->container);
|
||||
$tc = new TaskCreationModel($this->container);
|
||||
$p = new ProjectModel($this->container);
|
||||
$commentModel = new CommentModel($this->container);
|
||||
$taskCreationModel = new TaskCreationModel($this->container);
|
||||
$projectModel = new ProjectModel($this->container);
|
||||
|
||||
$this->assertEquals(1, $p->create(array('name' => 'test1')));
|
||||
$this->assertEquals(1, $tc->create(array('title' => 'test', 'project_id' => 1, 'column_id' => 3, 'owner_id' => 1)));
|
||||
$this->assertNotFalse($c->create(array('task_id' => 1, 'comment' => 'c1', 'user_id' => 1)));
|
||||
$this->assertNotFalse($c->create(array('task_id' => 1, 'comment' => 'c2', 'user_id' => 1)));
|
||||
$this->assertNotFalse($c->create(array('task_id' => 1, 'comment' => 'c3', 'user_id' => 1)));
|
||||
$this->assertEquals(1, $projectModel->create(array('name' => 'test1')));
|
||||
$this->assertEquals(1, $taskCreationModel->create(array('title' => 'test', 'project_id' => 1, 'column_id' => 3, 'owner_id' => 1)));
|
||||
$this->assertEquals(1, $commentModel->create(array('task_id' => 1, 'comment' => 'c1', 'user_id' => 1)));
|
||||
$this->assertEquals(2, $commentModel->create(array('task_id' => 1, 'comment' => 'c2', 'user_id' => 1)));
|
||||
$this->assertEquals(3, $commentModel->create(array('task_id' => 1, 'comment' => 'c3', 'user_id' => 1)));
|
||||
|
||||
$comments = $c->getAll(1);
|
||||
$comments = $commentModel->getAll(1);
|
||||
|
||||
$this->assertNotEmpty($comments);
|
||||
$this->assertEquals(3, count($comments));
|
||||
|
|
@ -56,37 +56,51 @@ class CommentTest extends Base
|
|||
$this->assertEquals(2, $comments[1]['id']);
|
||||
$this->assertEquals(3, $comments[2]['id']);
|
||||
|
||||
$this->assertEquals(3, $c->count(1));
|
||||
$this->assertEquals(3, $commentModel->count(1));
|
||||
}
|
||||
|
||||
public function testUpdate()
|
||||
{
|
||||
$c = new CommentModel($this->container);
|
||||
$tc = new TaskCreationModel($this->container);
|
||||
$p = new ProjectModel($this->container);
|
||||
$commentModel = new CommentModel($this->container);
|
||||
$taskCreationModel = new TaskCreationModel($this->container);
|
||||
$projectModel = new ProjectModel($this->container);
|
||||
|
||||
$this->assertEquals(1, $p->create(array('name' => 'test1')));
|
||||
$this->assertEquals(1, $tc->create(array('title' => 'test', 'project_id' => 1, 'column_id' => 3, 'owner_id' => 1)));
|
||||
$this->assertNotFalse($c->create(array('task_id' => 1, 'comment' => 'c1', 'user_id' => 1)));
|
||||
$this->assertTrue($c->update(array('id' => 1, 'comment' => 'bla')));
|
||||
$this->assertEquals(1, $projectModel->create(array('name' => 'test1')));
|
||||
$this->assertEquals(1, $taskCreationModel->create(array('title' => 'test', 'project_id' => 1, 'column_id' => 3, 'owner_id' => 1)));
|
||||
$this->assertEquals(1, $commentModel->create(array('task_id' => 1, 'comment' => 'c1', 'user_id' => 1)));
|
||||
$this->assertTrue($commentModel->update(array('id' => 1, 'comment' => 'bla')));
|
||||
|
||||
$comment = $c->getById(1);
|
||||
$comment = $commentModel->getById(1);
|
||||
$this->assertNotEmpty($comment);
|
||||
$this->assertEquals('bla', $comment['comment']);
|
||||
}
|
||||
|
||||
public function validateRemove()
|
||||
{
|
||||
$c = new CommentModel($this->container);
|
||||
$tc = new TaskCreationModel($this->container);
|
||||
$p = new ProjectModel($this->container);
|
||||
$commentModel = new CommentModel($this->container);
|
||||
$taskCreationModel = new TaskCreationModel($this->container);
|
||||
$projectModel = new ProjectModel($this->container);
|
||||
|
||||
$this->assertEquals(1, $p->create(array('name' => 'test1')));
|
||||
$this->assertEquals(1, $tc->create(array('title' => 'test', 'project_id' => 1, 'column_id' => 3, 'owner_id' => 1)));
|
||||
$this->assertTrue($c->create(array('task_id' => 1, 'comment' => 'c1', 'user_id' => 1)));
|
||||
$this->assertEquals(1, $projectModel->create(array('name' => 'test1')));
|
||||
$this->assertEquals(1, $taskCreationModel->create(array('title' => 'test', 'project_id' => 1, 'column_id' => 3, 'owner_id' => 1)));
|
||||
$this->assertEquals(1, $commentModel->create(array('task_id' => 1, 'comment' => 'c1', 'user_id' => 1)));
|
||||
|
||||
$this->assertTrue($c->remove(1));
|
||||
$this->assertFalse($c->remove(1));
|
||||
$this->assertFalse($c->remove(1111));
|
||||
$this->assertTrue($commentModel->remove(1));
|
||||
$this->assertFalse($commentModel->remove(1));
|
||||
$this->assertFalse($commentModel->remove(1111));
|
||||
}
|
||||
|
||||
public function testGetProjectId()
|
||||
{
|
||||
$commentModel = new CommentModel($this->container);
|
||||
$taskCreationModel = new TaskCreationModel($this->container);
|
||||
$projectModel = new ProjectModel($this->container);
|
||||
|
||||
$this->assertEquals(1, $projectModel->create(array('name' => 'test1')));
|
||||
$this->assertEquals(1, $taskCreationModel->create(array('title' => 'test', 'project_id' => 1, 'column_id' => 3, 'owner_id' => 1)));
|
||||
$this->assertEquals(1, $commentModel->create(array('task_id' => 1, 'comment' => 'c1', 'user_id' => 1)));
|
||||
|
||||
$this->assertEquals(1, $commentModel->getProjectId(1));
|
||||
$this->assertSame(0, $commentModel->getProjectId(2));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,10 +5,9 @@ require_once __DIR__.'/../Base.php';
|
|||
use Kanboard\Model\TaskCreationModel;
|
||||
use Kanboard\Model\SubtaskModel;
|
||||
use Kanboard\Model\ProjectModel;
|
||||
use Kanboard\Core\User\UserSession;
|
||||
use Kanboard\Model\TaskFinderModel;
|
||||
|
||||
class SubtaskTest extends Base
|
||||
class SubtaskModelTest extends Base
|
||||
{
|
||||
public function onSubtaskCreated($event)
|
||||
{
|
||||
|
|
@ -70,18 +69,18 @@ class SubtaskTest extends Base
|
|||
|
||||
public function testCreation()
|
||||
{
|
||||
$tc = new TaskCreationModel($this->container);
|
||||
$s = new SubtaskModel($this->container);
|
||||
$p = new ProjectModel($this->container);
|
||||
$taskCreationModel = new TaskCreationModel($this->container);
|
||||
$subtaskModel = new SubtaskModel($this->container);
|
||||
$projectModel = new ProjectModel($this->container);
|
||||
|
||||
$this->assertEquals(1, $p->create(array('name' => 'test')));
|
||||
$this->assertEquals(1, $tc->create(array('title' => 'test 1', 'project_id' => 1)));
|
||||
$this->assertEquals(1, $projectModel->create(array('name' => 'test')));
|
||||
$this->assertEquals(1, $taskCreationModel->create(array('title' => 'test 1', 'project_id' => 1)));
|
||||
|
||||
$this->container['dispatcher']->addListener(SubtaskModel::EVENT_CREATE, array($this, 'onSubtaskCreated'));
|
||||
|
||||
$this->assertEquals(1, $s->create(array('title' => 'subtask #1', 'task_id' => 1)));
|
||||
$this->assertEquals(1, $subtaskModel->create(array('title' => 'subtask #1', 'task_id' => 1)));
|
||||
|
||||
$subtask = $s->getById(1);
|
||||
$subtask = $subtaskModel->getById(1);
|
||||
$this->assertNotEmpty($subtask);
|
||||
$this->assertEquals(1, $subtask['id']);
|
||||
$this->assertEquals(1, $subtask['task_id']);
|
||||
|
|
@ -95,19 +94,19 @@ class SubtaskTest extends Base
|
|||
|
||||
public function testModification()
|
||||
{
|
||||
$tc = new TaskCreationModel($this->container);
|
||||
$s = new SubtaskModel($this->container);
|
||||
$p = new ProjectModel($this->container);
|
||||
$taskCreationModel = new TaskCreationModel($this->container);
|
||||
$subtaskModel = new SubtaskModel($this->container);
|
||||
$projectModel = new ProjectModel($this->container);
|
||||
|
||||
$this->assertEquals(1, $p->create(array('name' => 'test')));
|
||||
$this->assertEquals(1, $tc->create(array('title' => 'test 1', 'project_id' => 1)));
|
||||
$this->assertEquals(1, $projectModel->create(array('name' => 'test')));
|
||||
$this->assertEquals(1, $taskCreationModel->create(array('title' => 'test 1', 'project_id' => 1)));
|
||||
|
||||
$this->container['dispatcher']->addListener(SubtaskModel::EVENT_UPDATE, array($this, 'onSubtaskUpdated'));
|
||||
|
||||
$this->assertEquals(1, $s->create(array('title' => 'subtask #1', 'task_id' => 1)));
|
||||
$this->assertTrue($s->update(array('id' => 1, 'user_id' => 1, 'status' => SubtaskModel::STATUS_INPROGRESS)));
|
||||
$this->assertEquals(1, $subtaskModel->create(array('title' => 'subtask #1', 'task_id' => 1)));
|
||||
$this->assertTrue($subtaskModel->update(array('id' => 1, 'user_id' => 1, 'status' => SubtaskModel::STATUS_INPROGRESS)));
|
||||
|
||||
$subtask = $s->getById(1);
|
||||
$subtask = $subtaskModel->getById(1);
|
||||
$this->assertNotEmpty($subtask);
|
||||
$this->assertEquals(1, $subtask['id']);
|
||||
$this->assertEquals(1, $subtask['task_id']);
|
||||
|
|
@ -121,61 +120,61 @@ class SubtaskTest extends Base
|
|||
|
||||
public function testRemove()
|
||||
{
|
||||
$tc = new TaskCreationModel($this->container);
|
||||
$s = new SubtaskModel($this->container);
|
||||
$p = new ProjectModel($this->container);
|
||||
$taskCreationModel = new TaskCreationModel($this->container);
|
||||
$subtaskModel = new SubtaskModel($this->container);
|
||||
$projectModel = new ProjectModel($this->container);
|
||||
|
||||
$this->assertEquals(1, $p->create(array('name' => 'test')));
|
||||
$this->assertEquals(1, $tc->create(array('title' => 'test 1', 'project_id' => 1)));
|
||||
$this->assertEquals(1, $s->create(array('title' => 'subtask #1', 'task_id' => 1)));
|
||||
$this->assertEquals(1, $projectModel->create(array('name' => 'test')));
|
||||
$this->assertEquals(1, $taskCreationModel->create(array('title' => 'test 1', 'project_id' => 1)));
|
||||
$this->assertEquals(1, $subtaskModel->create(array('title' => 'subtask #1', 'task_id' => 1)));
|
||||
|
||||
$this->container['dispatcher']->addListener(SubtaskModel::EVENT_DELETE, array($this, 'onSubtaskDeleted'));
|
||||
|
||||
$subtask = $s->getById(1);
|
||||
$subtask = $subtaskModel->getById(1);
|
||||
$this->assertNotEmpty($subtask);
|
||||
|
||||
$this->assertTrue($s->remove(1));
|
||||
$this->assertTrue($subtaskModel->remove(1));
|
||||
|
||||
$subtask = $s->getById(1);
|
||||
$subtask = $subtaskModel->getById(1);
|
||||
$this->assertEmpty($subtask);
|
||||
}
|
||||
|
||||
public function testToggleStatusWithoutSession()
|
||||
{
|
||||
$tc = new TaskCreationModel($this->container);
|
||||
$s = new SubtaskModel($this->container);
|
||||
$p = new ProjectModel($this->container);
|
||||
$taskCreationModel = new TaskCreationModel($this->container);
|
||||
$subtaskModel = new SubtaskModel($this->container);
|
||||
$projectModel = new ProjectModel($this->container);
|
||||
|
||||
$this->assertEquals(1, $p->create(array('name' => 'test1')));
|
||||
$this->assertEquals(1, $tc->create(array('title' => 'test 1', 'project_id' => 1)));
|
||||
$this->assertEquals(1, $projectModel->create(array('name' => 'test1')));
|
||||
$this->assertEquals(1, $taskCreationModel->create(array('title' => 'test 1', 'project_id' => 1)));
|
||||
|
||||
$this->assertEquals(1, $s->create(array('title' => 'subtask #1', 'task_id' => 1)));
|
||||
$this->assertEquals(1, $subtaskModel->create(array('title' => 'subtask #1', 'task_id' => 1)));
|
||||
|
||||
$subtask = $s->getById(1);
|
||||
$subtask = $subtaskModel->getById(1);
|
||||
$this->assertNotEmpty($subtask);
|
||||
$this->assertEquals(SubtaskModel::STATUS_TODO, $subtask['status']);
|
||||
$this->assertEquals(0, $subtask['user_id']);
|
||||
$this->assertEquals(1, $subtask['task_id']);
|
||||
|
||||
$this->assertEquals(SubtaskModel::STATUS_INPROGRESS, $s->toggleStatus(1));
|
||||
$this->assertEquals(SubtaskModel::STATUS_INPROGRESS, $subtaskModel->toggleStatus(1));
|
||||
|
||||
$subtask = $s->getById(1);
|
||||
$subtask = $subtaskModel->getById(1);
|
||||
$this->assertNotEmpty($subtask);
|
||||
$this->assertEquals(SubtaskModel::STATUS_INPROGRESS, $subtask['status']);
|
||||
$this->assertEquals(0, $subtask['user_id']);
|
||||
$this->assertEquals(1, $subtask['task_id']);
|
||||
|
||||
$this->assertEquals(SubtaskModel::STATUS_DONE, $s->toggleStatus(1));
|
||||
$this->assertEquals(SubtaskModel::STATUS_DONE, $subtaskModel->toggleStatus(1));
|
||||
|
||||
$subtask = $s->getById(1);
|
||||
$subtask = $subtaskModel->getById(1);
|
||||
$this->assertNotEmpty($subtask);
|
||||
$this->assertEquals(SubtaskModel::STATUS_DONE, $subtask['status']);
|
||||
$this->assertEquals(0, $subtask['user_id']);
|
||||
$this->assertEquals(1, $subtask['task_id']);
|
||||
|
||||
$this->assertEquals(SubtaskModel::STATUS_TODO, $s->toggleStatus(1));
|
||||
$this->assertEquals(SubtaskModel::STATUS_TODO, $subtaskModel->toggleStatus(1));
|
||||
|
||||
$subtask = $s->getById(1);
|
||||
$subtask = $subtaskModel->getById(1);
|
||||
$this->assertNotEmpty($subtask);
|
||||
$this->assertEquals(SubtaskModel::STATUS_TODO, $subtask['status']);
|
||||
$this->assertEquals(0, $subtask['user_id']);
|
||||
|
|
@ -184,17 +183,16 @@ class SubtaskTest extends Base
|
|||
|
||||
public function testToggleStatusWithSession()
|
||||
{
|
||||
$tc = new TaskCreationModel($this->container);
|
||||
$s = new SubtaskModel($this->container);
|
||||
$p = new ProjectModel($this->container);
|
||||
$us = new UserSession($this->container);
|
||||
$taskCreationModel = new TaskCreationModel($this->container);
|
||||
$subtaskModel = new SubtaskModel($this->container);
|
||||
$projectModel = new ProjectModel($this->container);
|
||||
|
||||
$this->assertEquals(1, $p->create(array('name' => 'test1')));
|
||||
$this->assertEquals(1, $tc->create(array('title' => 'test 1', 'project_id' => 1)));
|
||||
$this->assertEquals(1, $projectModel->create(array('name' => 'test1')));
|
||||
$this->assertEquals(1, $taskCreationModel->create(array('title' => 'test 1', 'project_id' => 1)));
|
||||
|
||||
$this->assertEquals(1, $s->create(array('title' => 'subtask #1', 'task_id' => 1)));
|
||||
$this->assertEquals(1, $subtaskModel->create(array('title' => 'subtask #1', 'task_id' => 1)));
|
||||
|
||||
$subtask = $s->getById(1);
|
||||
$subtask = $subtaskModel->getById(1);
|
||||
$this->assertNotEmpty($subtask);
|
||||
$this->assertEquals(SubtaskModel::STATUS_TODO, $subtask['status']);
|
||||
$this->assertEquals(0, $subtask['user_id']);
|
||||
|
|
@ -203,25 +201,25 @@ class SubtaskTest extends Base
|
|||
// Set the current logged user
|
||||
$this->container['sessionStorage']->user = array('id' => 1);
|
||||
|
||||
$this->assertEquals(SubtaskModel::STATUS_INPROGRESS, $s->toggleStatus(1));
|
||||
$this->assertEquals(SubtaskModel::STATUS_INPROGRESS, $subtaskModel->toggleStatus(1));
|
||||
|
||||
$subtask = $s->getById(1);
|
||||
$subtask = $subtaskModel->getById(1);
|
||||
$this->assertNotEmpty($subtask);
|
||||
$this->assertEquals(SubtaskModel::STATUS_INPROGRESS, $subtask['status']);
|
||||
$this->assertEquals(1, $subtask['user_id']);
|
||||
$this->assertEquals(1, $subtask['task_id']);
|
||||
|
||||
$this->assertEquals(SubtaskModel::STATUS_DONE, $s->toggleStatus(1));
|
||||
$this->assertEquals(SubtaskModel::STATUS_DONE, $subtaskModel->toggleStatus(1));
|
||||
|
||||
$subtask = $s->getById(1);
|
||||
$subtask = $subtaskModel->getById(1);
|
||||
$this->assertNotEmpty($subtask);
|
||||
$this->assertEquals(SubtaskModel::STATUS_DONE, $subtask['status']);
|
||||
$this->assertEquals(1, $subtask['user_id']);
|
||||
$this->assertEquals(1, $subtask['task_id']);
|
||||
|
||||
$this->assertEquals(SubtaskModel::STATUS_TODO, $s->toggleStatus(1));
|
||||
$this->assertEquals(SubtaskModel::STATUS_TODO, $subtaskModel->toggleStatus(1));
|
||||
|
||||
$subtask = $s->getById(1);
|
||||
$subtask = $subtaskModel->getById(1);
|
||||
$this->assertNotEmpty($subtask);
|
||||
$this->assertEquals(SubtaskModel::STATUS_TODO, $subtask['status']);
|
||||
$this->assertEquals(1, $subtask['user_id']);
|
||||
|
|
@ -230,19 +228,19 @@ class SubtaskTest extends Base
|
|||
|
||||
public function testCloseAll()
|
||||
{
|
||||
$tc = new TaskCreationModel($this->container);
|
||||
$s = new SubtaskModel($this->container);
|
||||
$p = new ProjectModel($this->container);
|
||||
$taskCreationModel = new TaskCreationModel($this->container);
|
||||
$subtaskModel = new SubtaskModel($this->container);
|
||||
$projectModel = new ProjectModel($this->container);
|
||||
|
||||
$this->assertEquals(1, $p->create(array('name' => 'test1')));
|
||||
$this->assertEquals(1, $tc->create(array('title' => 'test 1', 'project_id' => 1)));
|
||||
$this->assertEquals(1, $projectModel->create(array('name' => 'test1')));
|
||||
$this->assertEquals(1, $taskCreationModel->create(array('title' => 'test 1', 'project_id' => 1)));
|
||||
|
||||
$this->assertEquals(1, $s->create(array('title' => 'subtask #1', 'task_id' => 1)));
|
||||
$this->assertEquals(2, $s->create(array('title' => 'subtask #2', 'task_id' => 1)));
|
||||
$this->assertEquals(1, $subtaskModel->create(array('title' => 'subtask #1', 'task_id' => 1)));
|
||||
$this->assertEquals(2, $subtaskModel->create(array('title' => 'subtask #2', 'task_id' => 1)));
|
||||
|
||||
$this->assertTrue($s->closeAll(1));
|
||||
$this->assertTrue($subtaskModel->closeAll(1));
|
||||
|
||||
$subtasks = $s->getAll(1);
|
||||
$subtasks = $subtaskModel->getAll(1);
|
||||
$this->assertNotEmpty($subtasks);
|
||||
|
||||
foreach ($subtasks as $subtask) {
|
||||
|
|
@ -252,24 +250,24 @@ class SubtaskTest extends Base
|
|||
|
||||
public function testDuplicate()
|
||||
{
|
||||
$tc = new TaskCreationModel($this->container);
|
||||
$s = new SubtaskModel($this->container);
|
||||
$p = new ProjectModel($this->container);
|
||||
$taskCreationModel = new TaskCreationModel($this->container);
|
||||
$subtaskModel = new SubtaskModel($this->container);
|
||||
$projectModel = new ProjectModel($this->container);
|
||||
|
||||
// We create a project
|
||||
$this->assertEquals(1, $p->create(array('name' => 'test1')));
|
||||
$this->assertEquals(1, $projectModel->create(array('name' => 'test1')));
|
||||
|
||||
// We create 2 tasks
|
||||
$this->assertEquals(1, $tc->create(array('title' => 'test 1', 'project_id' => 1, 'column_id' => 1, 'owner_id' => 1)));
|
||||
$this->assertEquals(2, $tc->create(array('title' => 'test 2', 'project_id' => 1, 'column_id' => 1, 'owner_id' => 0)));
|
||||
$this->assertEquals(1, $taskCreationModel->create(array('title' => 'test 1', 'project_id' => 1, 'column_id' => 1, 'owner_id' => 1)));
|
||||
$this->assertEquals(2, $taskCreationModel->create(array('title' => 'test 2', 'project_id' => 1, 'column_id' => 1, 'owner_id' => 0)));
|
||||
|
||||
// We create many subtasks for the first task
|
||||
$this->assertEquals(1, $s->create(array('title' => 'subtask #1', 'task_id' => 1, 'time_estimated' => 5, 'time_spent' => 3, 'status' => 1, 'another_subtask' => 'on')));
|
||||
$this->assertEquals(2, $s->create(array('title' => 'subtask #2', 'task_id' => 1, 'time_estimated' => '', 'time_spent' => '', 'status' => 2, 'user_id' => 1)));
|
||||
$this->assertEquals(1, $subtaskModel->create(array('title' => 'subtask #1', 'task_id' => 1, 'time_estimated' => 5, 'time_spent' => 3, 'status' => 1, 'another_subtask' => 'on')));
|
||||
$this->assertEquals(2, $subtaskModel->create(array('title' => 'subtask #2', 'task_id' => 1, 'time_estimated' => '', 'time_spent' => '', 'status' => 2, 'user_id' => 1)));
|
||||
|
||||
// We duplicate our subtasks
|
||||
$this->assertTrue($s->duplicate(1, 2));
|
||||
$subtasks = $s->getAll(2);
|
||||
$this->assertTrue($subtaskModel->duplicate(1, 2));
|
||||
$subtasks = $subtaskModel->getAll(2);
|
||||
|
||||
$this->assertNotFalse($subtasks);
|
||||
$this->assertNotEmpty($subtasks);
|
||||
|
|
@ -385,4 +383,18 @@ class SubtaskTest extends Base
|
|||
$this->assertEquals(2, $task['time_spent']);
|
||||
$this->assertEquals(3, $task['time_estimated']);
|
||||
}
|
||||
|
||||
public function testGetProjectId()
|
||||
{
|
||||
$taskCreationModel = new TaskCreationModel($this->container);
|
||||
$subtaskModel = new SubtaskModel($this->container);
|
||||
$projectModel = new ProjectModel($this->container);
|
||||
|
||||
$this->assertEquals(1, $projectModel->create(array('name' => 'test1')));
|
||||
$this->assertEquals(1, $taskCreationModel->create(array('title' => 'test 1', 'project_id' => 1)));
|
||||
$this->assertEquals(1, $subtaskModel->create(array('title' => 'subtask #1', 'task_id' => 1)));
|
||||
|
||||
$this->assertEquals(1, $subtaskModel->getProjectId(1));
|
||||
$this->assertEquals(0, $subtaskModel->getProjectId(2));
|
||||
}
|
||||
}
|
||||
|
|
@ -6,7 +6,7 @@ use Kanboard\Model\TaskFileModel;
|
|||
use Kanboard\Model\TaskCreationModel;
|
||||
use Kanboard\Model\ProjectModel;
|
||||
|
||||
class TaskFileTest extends Base
|
||||
class TaskFileModelTest extends Base
|
||||
{
|
||||
public function testCreation()
|
||||
{
|
||||
|
|
@ -442,4 +442,17 @@ class TaskFileTest extends Base
|
|||
|
||||
$this->assertTrue($fileModel->removeAll(1));
|
||||
}
|
||||
|
||||
public function testGetProjectId()
|
||||
{
|
||||
$projectModel = new ProjectModel($this->container);
|
||||
$fileModel = new TaskFileModel($this->container);
|
||||
$taskCreationModel = new TaskCreationModel($this->container);
|
||||
|
||||
$this->assertEquals(1, $projectModel->create(array('name' => 'test')));
|
||||
$this->assertEquals(1, $taskCreationModel->create(array('project_id' => 1, 'title' => 'test')));
|
||||
$this->assertEquals(1, $fileModel->create(1, 'test', '/tmp/foobar', 10));
|
||||
$this->assertEquals(1, $fileModel->getProjectId(1));
|
||||
$this->assertEquals(0, $fileModel->getProjectId(2));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,211 @@
|
|||
<?php
|
||||
|
||||
require_once __DIR__.'/../Base.php';
|
||||
|
||||
use Kanboard\Model\TaskFinderModel;
|
||||
use Kanboard\Model\TaskLinkModel;
|
||||
use Kanboard\Model\TaskCreationModel;
|
||||
use Kanboard\Model\ProjectModel;
|
||||
|
||||
class TaskLinkModelTest extends Base
|
||||
{
|
||||
// Check postgres issue: "Cardinality violation: 7 ERROR: more than one row returned by a subquery used as an expression"
|
||||
public function testGetTaskWithMultipleMilestoneLink()
|
||||
{
|
||||
$taskFinderModel = new TaskFinderModel($this->container);
|
||||
$taskLinkModel = new TaskLinkModel($this->container);
|
||||
$projectModel = new ProjectModel($this->container);
|
||||
$taskCreationModel = new TaskCreationModel($this->container);
|
||||
|
||||
$this->assertEquals(1, $projectModel->create(array('name' => 'test')));
|
||||
$this->assertEquals(1, $taskCreationModel->create(array('project_id' => 1, 'title' => 'A')));
|
||||
$this->assertEquals(2, $taskCreationModel->create(array('project_id' => 1, 'title' => 'B')));
|
||||
$this->assertEquals(3, $taskCreationModel->create(array('project_id' => 1, 'title' => 'C')));
|
||||
|
||||
$this->assertNotFalse($taskLinkModel->create(1, 2, 9));
|
||||
$this->assertNotFalse($taskLinkModel->create(1, 3, 9));
|
||||
|
||||
$task = $taskFinderModel->getExtendedQuery()->findOne();
|
||||
$this->assertNotEmpty($task);
|
||||
}
|
||||
|
||||
public function testCreateTaskLinkWithNoOpposite()
|
||||
{
|
||||
$taskLinkModel = new TaskLinkModel($this->container);
|
||||
$projectModel = new ProjectModel($this->container);
|
||||
$taskCreationModel = new TaskCreationModel($this->container);
|
||||
|
||||
$this->assertEquals(1, $projectModel->create(array('name' => 'test')));
|
||||
$this->assertEquals(1, $taskCreationModel->create(array('project_id' => 1, 'title' => 'A')));
|
||||
$this->assertEquals(2, $taskCreationModel->create(array('project_id' => 1, 'title' => 'B')));
|
||||
$this->assertEquals(1, $taskLinkModel->create(1, 2, 1));
|
||||
|
||||
$links = $taskLinkModel->getAll(1);
|
||||
$this->assertNotEmpty($links);
|
||||
$this->assertCount(1, $links);
|
||||
$this->assertEquals('relates to', $links[0]['label']);
|
||||
$this->assertEquals('B', $links[0]['title']);
|
||||
$this->assertEquals(2, $links[0]['task_id']);
|
||||
$this->assertEquals(1, $links[0]['is_active']);
|
||||
|
||||
$links = $taskLinkModel->getAll(2);
|
||||
$this->assertNotEmpty($links);
|
||||
$this->assertCount(1, $links);
|
||||
$this->assertEquals('relates to', $links[0]['label']);
|
||||
$this->assertEquals('A', $links[0]['title']);
|
||||
$this->assertEquals(1, $links[0]['task_id']);
|
||||
$this->assertEquals(1, $links[0]['is_active']);
|
||||
|
||||
$task_link = $taskLinkModel->getById(1);
|
||||
$this->assertNotEmpty($task_link);
|
||||
$this->assertEquals(1, $task_link['id']);
|
||||
$this->assertEquals(1, $task_link['task_id']);
|
||||
$this->assertEquals(2, $task_link['opposite_task_id']);
|
||||
$this->assertEquals(1, $task_link['link_id']);
|
||||
|
||||
$opposite_task_link = $taskLinkModel->getOppositeTaskLink($task_link);
|
||||
$this->assertNotEmpty($opposite_task_link);
|
||||
$this->assertEquals(2, $opposite_task_link['id']);
|
||||
$this->assertEquals(2, $opposite_task_link['task_id']);
|
||||
$this->assertEquals(1, $opposite_task_link['opposite_task_id']);
|
||||
$this->assertEquals(1, $opposite_task_link['link_id']);
|
||||
}
|
||||
|
||||
public function testCreateTaskLinkWithOpposite()
|
||||
{
|
||||
$taskLinkModel = new TaskLinkModel($this->container);
|
||||
$projectModel = new ProjectModel($this->container);
|
||||
$taskCreationModel = new TaskCreationModel($this->container);
|
||||
|
||||
$this->assertEquals(1, $projectModel->create(array('name' => 'test')));
|
||||
$this->assertEquals(1, $taskCreationModel->create(array('project_id' => 1, 'title' => 'A')));
|
||||
$this->assertEquals(2, $taskCreationModel->create(array('project_id' => 1, 'title' => 'B')));
|
||||
$this->assertEquals(1, $taskLinkModel->create(1, 2, 2));
|
||||
|
||||
$links = $taskLinkModel->getAll(1);
|
||||
$this->assertNotEmpty($links);
|
||||
$this->assertCount(1, $links);
|
||||
$this->assertEquals('blocks', $links[0]['label']);
|
||||
$this->assertEquals('B', $links[0]['title']);
|
||||
$this->assertEquals(2, $links[0]['task_id']);
|
||||
$this->assertEquals(1, $links[0]['is_active']);
|
||||
|
||||
$links = $taskLinkModel->getAll(2);
|
||||
$this->assertNotEmpty($links);
|
||||
$this->assertCount(1, $links);
|
||||
$this->assertEquals('is blocked by', $links[0]['label']);
|
||||
$this->assertEquals('A', $links[0]['title']);
|
||||
$this->assertEquals(1, $links[0]['task_id']);
|
||||
$this->assertEquals(1, $links[0]['is_active']);
|
||||
|
||||
$task_link = $taskLinkModel->getById(1);
|
||||
$this->assertNotEmpty($task_link);
|
||||
$this->assertEquals(1, $task_link['id']);
|
||||
$this->assertEquals(1, $task_link['task_id']);
|
||||
$this->assertEquals(2, $task_link['opposite_task_id']);
|
||||
$this->assertEquals(2, $task_link['link_id']);
|
||||
|
||||
$opposite_task_link = $taskLinkModel->getOppositeTaskLink($task_link);
|
||||
$this->assertNotEmpty($opposite_task_link);
|
||||
$this->assertEquals(2, $opposite_task_link['id']);
|
||||
$this->assertEquals(2, $opposite_task_link['task_id']);
|
||||
$this->assertEquals(1, $opposite_task_link['opposite_task_id']);
|
||||
$this->assertEquals(3, $opposite_task_link['link_id']);
|
||||
}
|
||||
|
||||
public function testGroupByLabel()
|
||||
{
|
||||
$taskLinkModel = new TaskLinkModel($this->container);
|
||||
$projectModel = new ProjectModel($this->container);
|
||||
$taskCreationModel = new TaskCreationModel($this->container);
|
||||
|
||||
$this->assertEquals(1, $projectModel->create(array('name' => 'test')));
|
||||
|
||||
$this->assertEquals(1, $taskCreationModel->create(array('project_id' => 1, 'title' => 'A')));
|
||||
$this->assertEquals(2, $taskCreationModel->create(array('project_id' => 1, 'title' => 'B')));
|
||||
$this->assertEquals(3, $taskCreationModel->create(array('project_id' => 1, 'title' => 'C')));
|
||||
|
||||
$this->assertNotFalse($taskLinkModel->create(1, 2, 2));
|
||||
$this->assertNotFalse($taskLinkModel->create(1, 3, 2));
|
||||
|
||||
$links = $taskLinkModel->getAllGroupedByLabel(1);
|
||||
$this->assertCount(1, $links);
|
||||
$this->assertArrayHasKey('blocks', $links);
|
||||
$this->assertCount(2, $links['blocks']);
|
||||
$this->assertEquals('test', $links['blocks'][0]['project_name']);
|
||||
$this->assertEquals('Backlog', $links['blocks'][0]['column_title']);
|
||||
$this->assertEquals('blocks', $links['blocks'][0]['label']);
|
||||
}
|
||||
|
||||
public function testUpdate()
|
||||
{
|
||||
$taskLinkModel = new TaskLinkModel($this->container);
|
||||
$projectModel = new ProjectModel($this->container);
|
||||
$taskCreationModel = new TaskCreationModel($this->container);
|
||||
|
||||
$this->assertEquals(1, $projectModel->create(array('name' => 'test1')));
|
||||
$this->assertEquals(2, $projectModel->create(array('name' => 'test2')));
|
||||
$this->assertEquals(1, $taskCreationModel->create(array('project_id' => 1, 'title' => 'A')));
|
||||
$this->assertEquals(2, $taskCreationModel->create(array('project_id' => 2, 'title' => 'B')));
|
||||
$this->assertEquals(3, $taskCreationModel->create(array('project_id' => 1, 'title' => 'C')));
|
||||
|
||||
$this->assertEquals(1, $taskLinkModel->create(1, 2, 5));
|
||||
$this->assertTrue($taskLinkModel->update(1, 1, 3, 11));
|
||||
|
||||
$links = $taskLinkModel->getAll(1);
|
||||
$this->assertNotEmpty($links);
|
||||
$this->assertCount(1, $links);
|
||||
$this->assertEquals('is fixed by', $links[0]['label']);
|
||||
$this->assertEquals('C', $links[0]['title']);
|
||||
$this->assertEquals(3, $links[0]['task_id']);
|
||||
|
||||
$links = $taskLinkModel->getAll(2);
|
||||
$this->assertEmpty($links);
|
||||
|
||||
$links = $taskLinkModel->getAll(3);
|
||||
$this->assertNotEmpty($links);
|
||||
$this->assertCount(1, $links);
|
||||
$this->assertEquals('fixes', $links[0]['label']);
|
||||
$this->assertEquals('A', $links[0]['title']);
|
||||
$this->assertEquals(1, $links[0]['task_id']);
|
||||
}
|
||||
|
||||
public function testRemove()
|
||||
{
|
||||
$taskLinkModel = new TaskLinkModel($this->container);
|
||||
$projectModel = new ProjectModel($this->container);
|
||||
$taskCreationModel = new TaskCreationModel($this->container);
|
||||
|
||||
$this->assertEquals(1, $projectModel->create(array('name' => 'test')));
|
||||
$this->assertEquals(1, $taskCreationModel->create(array('project_id' => 1, 'title' => 'A')));
|
||||
$this->assertEquals(2, $taskCreationModel->create(array('project_id' => 1, 'title' => 'B')));
|
||||
$this->assertEquals(1, $taskLinkModel->create(1, 2, 2));
|
||||
|
||||
$links = $taskLinkModel->getAll(1);
|
||||
$this->assertNotEmpty($links);
|
||||
$links = $taskLinkModel->getAll(2);
|
||||
$this->assertNotEmpty($links);
|
||||
|
||||
$this->assertTrue($taskLinkModel->remove($links[0]['id']));
|
||||
|
||||
$links = $taskLinkModel->getAll(1);
|
||||
$this->assertEmpty($links);
|
||||
$links = $taskLinkModel->getAll(2);
|
||||
$this->assertEmpty($links);
|
||||
}
|
||||
|
||||
public function testGetProjectId()
|
||||
{
|
||||
$taskLinkModel = new TaskLinkModel($this->container);
|
||||
$projectModel = new ProjectModel($this->container);
|
||||
$taskCreationModel = new TaskCreationModel($this->container);
|
||||
|
||||
$this->assertEquals(1, $projectModel->create(array('name' => 'test')));
|
||||
$this->assertEquals(1, $taskCreationModel->create(array('project_id' => 1, 'title' => 'A')));
|
||||
$this->assertEquals(2, $taskCreationModel->create(array('project_id' => 1, 'title' => 'B')));
|
||||
$this->assertEquals(1, $taskLinkModel->create(1, 2, 2));
|
||||
|
||||
$this->assertEquals(1, $taskLinkModel->getProjectId(1));
|
||||
$this->assertEquals(0, $taskLinkModel->getProjectId(42));
|
||||
}
|
||||
}
|
||||
|
|
@ -1,196 +0,0 @@
|
|||
<?php
|
||||
|
||||
require_once __DIR__.'/../Base.php';
|
||||
|
||||
use Kanboard\Model\TaskFinderModel;
|
||||
use Kanboard\Model\TaskLinkModel;
|
||||
use Kanboard\Model\TaskCreationModel;
|
||||
use Kanboard\Model\ProjectModel;
|
||||
|
||||
class TaskLinkTest extends Base
|
||||
{
|
||||
// Check postgres issue: "Cardinality violation: 7 ERROR: more than one row returned by a subquery used as an expression"
|
||||
public function testGetTaskWithMultipleMilestoneLink()
|
||||
{
|
||||
$tf = new TaskFinderModel($this->container);
|
||||
$tl = new TaskLinkModel($this->container);
|
||||
$p = new ProjectModel($this->container);
|
||||
$tc = new TaskCreationModel($this->container);
|
||||
|
||||
$this->assertEquals(1, $p->create(array('name' => 'test')));
|
||||
$this->assertEquals(1, $tc->create(array('project_id' => 1, 'title' => 'A')));
|
||||
$this->assertEquals(2, $tc->create(array('project_id' => 1, 'title' => 'B')));
|
||||
$this->assertEquals(3, $tc->create(array('project_id' => 1, 'title' => 'C')));
|
||||
|
||||
$this->assertNotFalse($tl->create(1, 2, 9));
|
||||
$this->assertNotFalse($tl->create(1, 3, 9));
|
||||
|
||||
$task = $tf->getExtendedQuery()->findOne();
|
||||
$this->assertNotEmpty($task);
|
||||
}
|
||||
|
||||
public function testCreateTaskLinkWithNoOpposite()
|
||||
{
|
||||
$tl = new TaskLinkModel($this->container);
|
||||
$p = new ProjectModel($this->container);
|
||||
$tc = new TaskCreationModel($this->container);
|
||||
|
||||
$this->assertEquals(1, $p->create(array('name' => 'test')));
|
||||
$this->assertEquals(1, $tc->create(array('project_id' => 1, 'title' => 'A')));
|
||||
$this->assertEquals(2, $tc->create(array('project_id' => 1, 'title' => 'B')));
|
||||
$this->assertEquals(1, $tl->create(1, 2, 1));
|
||||
|
||||
$links = $tl->getAll(1);
|
||||
$this->assertNotEmpty($links);
|
||||
$this->assertCount(1, $links);
|
||||
$this->assertEquals('relates to', $links[0]['label']);
|
||||
$this->assertEquals('B', $links[0]['title']);
|
||||
$this->assertEquals(2, $links[0]['task_id']);
|
||||
$this->assertEquals(1, $links[0]['is_active']);
|
||||
|
||||
$links = $tl->getAll(2);
|
||||
$this->assertNotEmpty($links);
|
||||
$this->assertCount(1, $links);
|
||||
$this->assertEquals('relates to', $links[0]['label']);
|
||||
$this->assertEquals('A', $links[0]['title']);
|
||||
$this->assertEquals(1, $links[0]['task_id']);
|
||||
$this->assertEquals(1, $links[0]['is_active']);
|
||||
|
||||
$task_link = $tl->getById(1);
|
||||
$this->assertNotEmpty($task_link);
|
||||
$this->assertEquals(1, $task_link['id']);
|
||||
$this->assertEquals(1, $task_link['task_id']);
|
||||
$this->assertEquals(2, $task_link['opposite_task_id']);
|
||||
$this->assertEquals(1, $task_link['link_id']);
|
||||
|
||||
$opposite_task_link = $tl->getOppositeTaskLink($task_link);
|
||||
$this->assertNotEmpty($opposite_task_link);
|
||||
$this->assertEquals(2, $opposite_task_link['id']);
|
||||
$this->assertEquals(2, $opposite_task_link['task_id']);
|
||||
$this->assertEquals(1, $opposite_task_link['opposite_task_id']);
|
||||
$this->assertEquals(1, $opposite_task_link['link_id']);
|
||||
}
|
||||
|
||||
public function testCreateTaskLinkWithOpposite()
|
||||
{
|
||||
$tl = new TaskLinkModel($this->container);
|
||||
$p = new ProjectModel($this->container);
|
||||
$tc = new TaskCreationModel($this->container);
|
||||
|
||||
$this->assertEquals(1, $p->create(array('name' => 'test')));
|
||||
$this->assertEquals(1, $tc->create(array('project_id' => 1, 'title' => 'A')));
|
||||
$this->assertEquals(2, $tc->create(array('project_id' => 1, 'title' => 'B')));
|
||||
$this->assertEquals(1, $tl->create(1, 2, 2));
|
||||
|
||||
$links = $tl->getAll(1);
|
||||
$this->assertNotEmpty($links);
|
||||
$this->assertCount(1, $links);
|
||||
$this->assertEquals('blocks', $links[0]['label']);
|
||||
$this->assertEquals('B', $links[0]['title']);
|
||||
$this->assertEquals(2, $links[0]['task_id']);
|
||||
$this->assertEquals(1, $links[0]['is_active']);
|
||||
|
||||
$links = $tl->getAll(2);
|
||||
$this->assertNotEmpty($links);
|
||||
$this->assertCount(1, $links);
|
||||
$this->assertEquals('is blocked by', $links[0]['label']);
|
||||
$this->assertEquals('A', $links[0]['title']);
|
||||
$this->assertEquals(1, $links[0]['task_id']);
|
||||
$this->assertEquals(1, $links[0]['is_active']);
|
||||
|
||||
$task_link = $tl->getById(1);
|
||||
$this->assertNotEmpty($task_link);
|
||||
$this->assertEquals(1, $task_link['id']);
|
||||
$this->assertEquals(1, $task_link['task_id']);
|
||||
$this->assertEquals(2, $task_link['opposite_task_id']);
|
||||
$this->assertEquals(2, $task_link['link_id']);
|
||||
|
||||
$opposite_task_link = $tl->getOppositeTaskLink($task_link);
|
||||
$this->assertNotEmpty($opposite_task_link);
|
||||
$this->assertEquals(2, $opposite_task_link['id']);
|
||||
$this->assertEquals(2, $opposite_task_link['task_id']);
|
||||
$this->assertEquals(1, $opposite_task_link['opposite_task_id']);
|
||||
$this->assertEquals(3, $opposite_task_link['link_id']);
|
||||
}
|
||||
|
||||
public function testGroupByLabel()
|
||||
{
|
||||
$tl = new TaskLinkModel($this->container);
|
||||
$p = new ProjectModel($this->container);
|
||||
$tc = new TaskCreationModel($this->container);
|
||||
|
||||
$this->assertEquals(1, $p->create(array('name' => 'test')));
|
||||
|
||||
$this->assertEquals(1, $tc->create(array('project_id' => 1, 'title' => 'A')));
|
||||
$this->assertEquals(2, $tc->create(array('project_id' => 1, 'title' => 'B')));
|
||||
$this->assertEquals(3, $tc->create(array('project_id' => 1, 'title' => 'C')));
|
||||
|
||||
$this->assertNotFalse($tl->create(1, 2, 2));
|
||||
$this->assertNotFalse($tl->create(1, 3, 2));
|
||||
|
||||
$links = $tl->getAllGroupedByLabel(1);
|
||||
$this->assertCount(1, $links);
|
||||
$this->assertArrayHasKey('blocks', $links);
|
||||
$this->assertCount(2, $links['blocks']);
|
||||
$this->assertEquals('test', $links['blocks'][0]['project_name']);
|
||||
$this->assertEquals('Backlog', $links['blocks'][0]['column_title']);
|
||||
$this->assertEquals('blocks', $links['blocks'][0]['label']);
|
||||
}
|
||||
|
||||
public function testUpdate()
|
||||
{
|
||||
$tl = new TaskLinkModel($this->container);
|
||||
$p = new ProjectModel($this->container);
|
||||
$tc = new TaskCreationModel($this->container);
|
||||
|
||||
$this->assertEquals(1, $p->create(array('name' => 'test1')));
|
||||
$this->assertEquals(2, $p->create(array('name' => 'test2')));
|
||||
$this->assertEquals(1, $tc->create(array('project_id' => 1, 'title' => 'A')));
|
||||
$this->assertEquals(2, $tc->create(array('project_id' => 2, 'title' => 'B')));
|
||||
$this->assertEquals(3, $tc->create(array('project_id' => 1, 'title' => 'C')));
|
||||
|
||||
$this->assertEquals(1, $tl->create(1, 2, 5));
|
||||
$this->assertTrue($tl->update(1, 1, 3, 11));
|
||||
|
||||
$links = $tl->getAll(1);
|
||||
$this->assertNotEmpty($links);
|
||||
$this->assertCount(1, $links);
|
||||
$this->assertEquals('is fixed by', $links[0]['label']);
|
||||
$this->assertEquals('C', $links[0]['title']);
|
||||
$this->assertEquals(3, $links[0]['task_id']);
|
||||
|
||||
$links = $tl->getAll(2);
|
||||
$this->assertEmpty($links);
|
||||
|
||||
$links = $tl->getAll(3);
|
||||
$this->assertNotEmpty($links);
|
||||
$this->assertCount(1, $links);
|
||||
$this->assertEquals('fixes', $links[0]['label']);
|
||||
$this->assertEquals('A', $links[0]['title']);
|
||||
$this->assertEquals(1, $links[0]['task_id']);
|
||||
}
|
||||
|
||||
public function testRemove()
|
||||
{
|
||||
$tl = new TaskLinkModel($this->container);
|
||||
$p = new ProjectModel($this->container);
|
||||
$tc = new TaskCreationModel($this->container);
|
||||
|
||||
$this->assertEquals(1, $p->create(array('name' => 'test')));
|
||||
$this->assertEquals(1, $tc->create(array('project_id' => 1, 'title' => 'A')));
|
||||
$this->assertEquals(2, $tc->create(array('project_id' => 1, 'title' => 'B')));
|
||||
$this->assertEquals(1, $tl->create(1, 2, 2));
|
||||
|
||||
$links = $tl->getAll(1);
|
||||
$this->assertNotEmpty($links);
|
||||
$links = $tl->getAll(2);
|
||||
$this->assertNotEmpty($links);
|
||||
|
||||
$this->assertTrue($tl->remove($links[0]['id']));
|
||||
|
||||
$links = $tl->getAll(1);
|
||||
$this->assertEmpty($links);
|
||||
$links = $tl->getAll(2);
|
||||
$this->assertEmpty($links);
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue