Add project restrictions for custom roles
This commit is contained in:
parent
a0227cad69
commit
d8f6d85683
|
|
@ -28,14 +28,8 @@ class BoardAjaxController extends BaseController
|
||||||
}
|
}
|
||||||
|
|
||||||
$values = $this->request->getJson();
|
$values = $this->request->getJson();
|
||||||
$canMoveTask = $this->columnMoveRestrictionModel->isAllowed(
|
|
||||||
$project_id,
|
|
||||||
$this->helper->user->getProjectUserRole($project_id),
|
|
||||||
$values['src_column_id'],
|
|
||||||
$values['dst_column_id']
|
|
||||||
);
|
|
||||||
|
|
||||||
if (! $canMoveTask) {
|
if (! $this->helper->projectRole->canMoveTask($project_id, $values['src_column_id'], $values['dst_column_id'])) {
|
||||||
throw new AccessForbiddenException(e("You don't have the permission to move this task"));
|
throw new AccessForbiddenException(e("You don't have the permission to move this task"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -45,14 +45,14 @@ class ColumnMoveRestrictionController extends BaseController
|
||||||
list($valid, $errors) = $this->columnMoveRestrictionValidator->validateCreation($values);
|
list($valid, $errors) = $this->columnMoveRestrictionValidator->validateCreation($values);
|
||||||
|
|
||||||
if ($valid) {
|
if ($valid) {
|
||||||
$role_id = $this->columnMoveRestrictionModel->create(
|
$restriction_id = $this->columnMoveRestrictionModel->create(
|
||||||
$project['id'],
|
$project['id'],
|
||||||
$values['role_id'],
|
$values['role_id'],
|
||||||
$values['src_column_id'],
|
$values['src_column_id'],
|
||||||
$values['dst_column_id']
|
$values['dst_column_id']
|
||||||
);
|
);
|
||||||
|
|
||||||
if ($role_id !== false) {
|
if ($restriction_id !== false) {
|
||||||
$this->flash->success(t('The column restriction has been created successfully.'));
|
$this->flash->success(t('The column restriction has been created successfully.'));
|
||||||
} else {
|
} else {
|
||||||
$this->flash->failure(t('Unable to create this column restriction.'));
|
$this->flash->failure(t('Unable to create this column restriction.'));
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,96 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Kanboard\Controller;
|
||||||
|
|
||||||
|
use Kanboard\Core\Controller\AccessForbiddenException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class ProjectRoleRestrictionController
|
||||||
|
*
|
||||||
|
* @package Kanboard\Controller
|
||||||
|
* @author Frederic Guillot
|
||||||
|
*/
|
||||||
|
class ProjectRoleRestrictionController extends BaseController
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Show form to create a new project restriction
|
||||||
|
*
|
||||||
|
* @param array $values
|
||||||
|
* @param array $errors
|
||||||
|
* @throws AccessForbiddenException
|
||||||
|
*/
|
||||||
|
public function create(array $values = array(), array $errors = array())
|
||||||
|
{
|
||||||
|
$project = $this->getProject();
|
||||||
|
$role_id = $this->request->getIntegerParam('role_id');
|
||||||
|
$role = $this->projectRoleModel->getById($project['id'], $role_id);
|
||||||
|
|
||||||
|
$this->response->html($this->template->render('project_role_restriction/create', array(
|
||||||
|
'project' => $project,
|
||||||
|
'role' => $role,
|
||||||
|
'values' => $values + array('project_id' => $project['id'], 'role_id' => $role['role_id']),
|
||||||
|
'errors' => $errors,
|
||||||
|
'restrictions' => $this->projectRoleRestrictionModel->getRules(),
|
||||||
|
)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Save new restriction
|
||||||
|
*/
|
||||||
|
public function save()
|
||||||
|
{
|
||||||
|
$project = $this->getProject();
|
||||||
|
$values = $this->request->getValues();
|
||||||
|
|
||||||
|
$restriction_id = $this->projectRoleRestrictionModel->create(
|
||||||
|
$project['id'],
|
||||||
|
$values['role_id'],
|
||||||
|
$values['rule']
|
||||||
|
);
|
||||||
|
|
||||||
|
if ($restriction_id !== false) {
|
||||||
|
$this->flash->success(t('The project restriction has been created successfully.'));
|
||||||
|
} else {
|
||||||
|
$this->flash->failure(t('Unable to create this project restriction.'));
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->response->redirect($this->helper->url->to('ProjectRoleController', 'show', array('project_id' => $project['id'])));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Confirm suppression
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
public function confirm()
|
||||||
|
{
|
||||||
|
$project = $this->getProject();
|
||||||
|
$restriction_id = $this->request->getIntegerParam('restriction_id');
|
||||||
|
|
||||||
|
$this->response->html($this->helper->layout->project('project_role_restriction/remove', array(
|
||||||
|
'project' => $project,
|
||||||
|
'restriction' => $this->projectRoleRestrictionModel->getById($project['id'], $restriction_id),
|
||||||
|
'restrictions' => $this->projectRoleRestrictionModel->getRules(),
|
||||||
|
)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove a restriction
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
public function remove()
|
||||||
|
{
|
||||||
|
$project = $this->getProject();
|
||||||
|
$this->checkCSRFParam();
|
||||||
|
$restriction_id = $this->request->getIntegerParam('restriction_id');
|
||||||
|
|
||||||
|
if ($this->projectRoleRestrictionModel->remove($restriction_id)) {
|
||||||
|
$this->flash->success(t('Project restriction removed successfully.'));
|
||||||
|
} else {
|
||||||
|
$this->flash->failure(t('Unable to remove this restriction.'));
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->response->redirect($this->helper->url->to('ProjectRoleController', 'show', array('project_id' => $project['id'])));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -19,7 +19,7 @@ class TaskSuppressionController extends BaseController
|
||||||
{
|
{
|
||||||
$task = $this->getTask();
|
$task = $this->getTask();
|
||||||
|
|
||||||
if (! $this->helper->user->canRemoveTask($task)) {
|
if (! $this->helper->projectRole->canRemoveTask($task)) {
|
||||||
throw new AccessForbiddenException();
|
throw new AccessForbiddenException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -37,7 +37,7 @@ class TaskSuppressionController extends BaseController
|
||||||
$task = $this->getTask();
|
$task = $this->getTask();
|
||||||
$this->checkCSRFParam();
|
$this->checkCSRFParam();
|
||||||
|
|
||||||
if (! $this->helper->user->canRemoveTask($task)) {
|
if (! $this->helper->projectRole->canRemoveTask($task)) {
|
||||||
throw new AccessForbiddenException();
|
throw new AccessForbiddenException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -91,6 +91,7 @@ use Pimple\Container;
|
||||||
* @property \Kanboard\Model\ProjectNotificationModel $projectNotificationModel
|
* @property \Kanboard\Model\ProjectNotificationModel $projectNotificationModel
|
||||||
* @property \Kanboard\Model\ProjectNotificationTypeModel $projectNotificationTypeModel
|
* @property \Kanboard\Model\ProjectNotificationTypeModel $projectNotificationTypeModel
|
||||||
* @property \Kanboard\Model\ProjectRoleModel $projectRoleModel
|
* @property \Kanboard\Model\ProjectRoleModel $projectRoleModel
|
||||||
|
* @property \Kanboard\Model\ProjectRoleRestrictionModel $projectRoleRestrictionModel
|
||||||
* @property \Kanboard\Model\ProjectTaskDuplicationModel $projectTaskDuplicationModel
|
* @property \Kanboard\Model\ProjectTaskDuplicationModel $projectTaskDuplicationModel
|
||||||
* @property \Kanboard\Model\ProjectTaskPriorityModel $projectTaskPriorityModel
|
* @property \Kanboard\Model\ProjectTaskPriorityModel $projectTaskPriorityModel
|
||||||
* @property \Kanboard\Model\RememberMeSessionModel $rememberMeSessionModel
|
* @property \Kanboard\Model\RememberMeSessionModel $rememberMeSessionModel
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,7 @@ use Pimple\Container;
|
||||||
* @property \Kanboard\Helper\UrlHelper $url
|
* @property \Kanboard\Helper\UrlHelper $url
|
||||||
* @property \Kanboard\Helper\UserHelper $user
|
* @property \Kanboard\Helper\UserHelper $user
|
||||||
* @property \Kanboard\Helper\LayoutHelper $layout
|
* @property \Kanboard\Helper\LayoutHelper $layout
|
||||||
|
* @property \Kanboard\Helper\ProjectRoleHelper $projectRole
|
||||||
* @property \Kanboard\Helper\ProjectHeaderHelper $projectHeader
|
* @property \Kanboard\Helper\ProjectHeaderHelper $projectHeader
|
||||||
* @property \Kanboard\Helper\ProjectActivityHelper $projectActivity
|
* @property \Kanboard\Helper\ProjectActivityHelper $projectActivity
|
||||||
* @property \Kanboard\Helper\MailHelper $mail
|
* @property \Kanboard\Helper\MailHelper $mail
|
||||||
|
|
|
||||||
|
|
@ -81,7 +81,7 @@ class BoardTaskFormatter extends BaseFormatter implements FormatterInterface
|
||||||
array_merge_relation($tasks, $this->tags, 'tags', 'id');
|
array_merge_relation($tasks, $this->tags, 'tags', 'id');
|
||||||
|
|
||||||
foreach ($tasks as &$task) {
|
foreach ($tasks as &$task) {
|
||||||
$task['is_draggable'] = $this->helper->board->isDraggable($task);
|
$task['is_draggable'] = $this->helper->projectRole->isDraggable($task);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $tasks;
|
return $tasks;
|
||||||
|
|
|
||||||
|
|
@ -24,26 +24,4 @@ class BoardHelper extends Base
|
||||||
{
|
{
|
||||||
return $this->userMetadataCacheDecorator->get(UserMetadataModel::KEY_BOARD_COLLAPSED.$project_id, 0) == 1;
|
return $this->userMetadataCacheDecorator->get(UserMetadataModel::KEY_BOARD_COLLAPSED.$project_id, 0) == 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Return true if the task can be moved by the connected user
|
|
||||||
*
|
|
||||||
* @param array $task
|
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
public function isDraggable(array $task)
|
|
||||||
{
|
|
||||||
if ($task['is_active'] == 1 && $this->helper->user->hasProjectAccess('BoardViewController', 'save', $task['project_id'])) {
|
|
||||||
$role = $this->helper->user->getProjectUserRole($task['project_id']);
|
|
||||||
|
|
||||||
if ($this->role->isCustomProjectRole($role)) {
|
|
||||||
$srcColumnIds = $this->columnMoveRestrictionCacheDecorator->getAllSrcColumns($task['project_id'], $role);
|
|
||||||
return isset($srcColumnIds[$task['column_id']]);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,130 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Kanboard\Helper;
|
||||||
|
|
||||||
|
use Kanboard\Core\Base;
|
||||||
|
use Kanboard\Core\Security\Role;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class ProjectRoleHelper
|
||||||
|
*
|
||||||
|
* @package Kanboard\Helper
|
||||||
|
* @author Frederic Guillot
|
||||||
|
*/
|
||||||
|
class ProjectRoleHelper extends Base
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Get project role for the current user
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @param integer $project_id
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getProjectUserRole($project_id)
|
||||||
|
{
|
||||||
|
return $this->memoryCache->proxy($this->projectUserRoleModel, 'getUserRole', $project_id, $this->userSession->getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return true if the task can be moved by the connected user
|
||||||
|
*
|
||||||
|
* @param array $task
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function isDraggable(array $task)
|
||||||
|
{
|
||||||
|
if ($task['is_active'] == 1 && $this->helper->user->hasProjectAccess('BoardViewController', 'save', $task['project_id'])) {
|
||||||
|
$role = $this->getProjectUserRole($task['project_id']);
|
||||||
|
|
||||||
|
if ($this->role->isCustomProjectRole($role)) {
|
||||||
|
$srcColumnIds = $this->columnMoveRestrictionCacheDecorator->getAllSrcColumns($task['project_id'], $role);
|
||||||
|
return isset($srcColumnIds[$task['column_id']]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if the user can move a task
|
||||||
|
*
|
||||||
|
* @param int $project_id
|
||||||
|
* @param int $src_column_id
|
||||||
|
* @param int $dst_column_id
|
||||||
|
* @return bool|int
|
||||||
|
*/
|
||||||
|
public function canMoveTask($project_id, $src_column_id, $dst_column_id)
|
||||||
|
{
|
||||||
|
$role = $this->getProjectUserRole($project_id);
|
||||||
|
|
||||||
|
if ($this->role->isCustomProjectRole($role)) {
|
||||||
|
return $this->columnMoveRestrictionModel->isAllowed(
|
||||||
|
$project_id,
|
||||||
|
$role,
|
||||||
|
$src_column_id,
|
||||||
|
$dst_column_id
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return true if the user can remove a task
|
||||||
|
*
|
||||||
|
* Regular users can't remove tasks from other people
|
||||||
|
*
|
||||||
|
* @public
|
||||||
|
* @param array $task
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function canRemoveTask(array $task)
|
||||||
|
{
|
||||||
|
if (isset($task['creator_id']) && $task['creator_id'] == $this->userSession->getId()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->userSession->isAdmin() || $this->getProjectUserRole($task['project_id']) === Role::PROJECT_MANAGER) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check project access
|
||||||
|
*
|
||||||
|
* @param string $controller
|
||||||
|
* @param string $action
|
||||||
|
* @param integer $project_id
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function checkProjectAccess($controller, $action, $project_id)
|
||||||
|
{
|
||||||
|
if (! $this->userSession->isLogged()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->userSession->isAdmin()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (! $this->helper->user->hasAccess($controller, $action)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$role = $this->getProjectUserRole($project_id);
|
||||||
|
|
||||||
|
if ($this->role->isCustomProjectRole($role)) {
|
||||||
|
$restrictions = $this->projectRoleRestrictionModel->getAllByRole($project_id, $role);
|
||||||
|
$result = $this->projectRoleRestrictionModel->isAllowed($restrictions, $controller, $action);
|
||||||
|
$result = $result && $this->projectAuthorization->isAllowed($controller, $action, Role::PROJECT_MEMBER);
|
||||||
|
} else {
|
||||||
|
$result = $this->projectAuthorization->isAllowed($controller, $action, $role);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -3,7 +3,6 @@
|
||||||
namespace Kanboard\Helper;
|
namespace Kanboard\Helper;
|
||||||
|
|
||||||
use Kanboard\Core\Base;
|
use Kanboard\Core\Base;
|
||||||
use Kanboard\Core\Security\Role;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* User helpers
|
* User helpers
|
||||||
|
|
@ -133,66 +132,14 @@ class UserHelper extends Base
|
||||||
*/
|
*/
|
||||||
public function hasProjectAccess($controller, $action, $project_id)
|
public function hasProjectAccess($controller, $action, $project_id)
|
||||||
{
|
{
|
||||||
if (! $this->userSession->isLogged()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($this->userSession->isAdmin()) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (! $this->hasAccess($controller, $action)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
$key = 'project_access:'.$controller.$action.$project_id;
|
$key = 'project_access:'.$controller.$action.$project_id;
|
||||||
$result = $this->memoryCache->get($key);
|
$result = $this->memoryCache->get($key);
|
||||||
|
|
||||||
if ($result === null) {
|
if ($result === null) {
|
||||||
$role = $this->getProjectUserRole($project_id);
|
$result = $this->helper->projectRole->checkProjectAccess($controller, $action, $project_id);
|
||||||
|
|
||||||
if ($this->role->isCustomProjectRole($role)) {
|
|
||||||
$role = Role::PROJECT_MEMBER;
|
|
||||||
}
|
|
||||||
|
|
||||||
$result = $this->projectAuthorization->isAllowed($controller, $action, $role);
|
|
||||||
$this->memoryCache->set($key, $result);
|
$this->memoryCache->set($key, $result);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Get project role for the current user
|
|
||||||
*
|
|
||||||
* @access public
|
|
||||||
* @param integer $project_id
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function getProjectUserRole($project_id)
|
|
||||||
{
|
|
||||||
return $this->memoryCache->proxy($this->projectUserRoleModel, 'getUserRole', $project_id, $this->userSession->getId());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return true if the user can remove a task
|
|
||||||
*
|
|
||||||
* Regular users can't remove tasks from other people
|
|
||||||
*
|
|
||||||
* @public
|
|
||||||
* @param array $task
|
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
public function canRemoveTask(array $task)
|
|
||||||
{
|
|
||||||
if (isset($task['creator_id']) && $task['creator_id'] == $this->userSession->getId()) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($this->userSession->isAdmin() || $this->getProjectUserRole($task['project_id']) === Role::PROJECT_MANAGER) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ class ProjectRoleModel extends Base
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get list of project roles
|
* Get list of project roles
|
||||||
*
|
*
|
||||||
* @param int $project_id
|
* @param int $project_id
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
|
|
@ -70,9 +70,14 @@ class ProjectRoleModel extends Base
|
||||||
public function getAllWithRestrictions($project_id)
|
public function getAllWithRestrictions($project_id)
|
||||||
{
|
{
|
||||||
$roles = $this->getAll($project_id);
|
$roles = $this->getAll($project_id);
|
||||||
$restrictions = $this->columnMoveRestrictionModel->getAll($project_id);
|
|
||||||
$restrictions = array_column_index($restrictions, 'role_id');
|
$column_restrictions = $this->columnMoveRestrictionModel->getAll($project_id);
|
||||||
array_merge_relation($roles, $restrictions, 'restrictions', 'role_id');
|
$column_restrictions = array_column_index($column_restrictions, 'role_id');
|
||||||
|
array_merge_relation($roles, $column_restrictions, 'column_restrictions', 'role_id');
|
||||||
|
|
||||||
|
$project_restrictions = $this->projectRoleRestrictionModel->getAll($project_id);
|
||||||
|
$project_restrictions = array_column_index($project_restrictions, 'role_id');
|
||||||
|
array_merge_relation($roles, $project_restrictions, 'project_restrictions', 'role_id');
|
||||||
|
|
||||||
return $roles;
|
return $roles;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,164 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Kanboard\Model;
|
||||||
|
|
||||||
|
use Kanboard\Core\Base;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class ProjectRoleRestrictionModel
|
||||||
|
*
|
||||||
|
* @package Kanboard\Model
|
||||||
|
* @author Frederic Guillot
|
||||||
|
*/
|
||||||
|
class ProjectRoleRestrictionModel extends Base
|
||||||
|
{
|
||||||
|
const TABLE = 'project_role_has_restrictions';
|
||||||
|
const RULE_TASK_CREATION = 'task_creation';
|
||||||
|
|
||||||
|
protected $ruleMapping = array(
|
||||||
|
self::RULE_TASK_CREATION => array(
|
||||||
|
array('controller' => 'TaskCreationController', 'method' => '*'),
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get rules
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function getRules()
|
||||||
|
{
|
||||||
|
return array(
|
||||||
|
self::RULE_TASK_CREATION => t('Task creation is not permitted'),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a single restriction
|
||||||
|
*
|
||||||
|
* @param integer $project_id
|
||||||
|
* @param integer $restriction_id
|
||||||
|
* @return array|null
|
||||||
|
*/
|
||||||
|
public function getById($project_id, $restriction_id)
|
||||||
|
{
|
||||||
|
return $this->db
|
||||||
|
->table(self::TABLE)
|
||||||
|
->eq('project_id', $project_id)
|
||||||
|
->eq('restriction_id', $restriction_id)
|
||||||
|
->findOne();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get restrictions
|
||||||
|
*
|
||||||
|
* @param int $project_id
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function getAll($project_id)
|
||||||
|
{
|
||||||
|
$rules = $this->getRules();
|
||||||
|
$restrictions = $this->db
|
||||||
|
->table(self::TABLE)
|
||||||
|
->columns(
|
||||||
|
self::TABLE.'.restriction_id',
|
||||||
|
self::TABLE.'.project_id',
|
||||||
|
self::TABLE.'.role_id',
|
||||||
|
self::TABLE.'.rule'
|
||||||
|
)
|
||||||
|
->eq(self::TABLE.'.project_id', $project_id)
|
||||||
|
->findAll();
|
||||||
|
|
||||||
|
foreach ($restrictions as &$restriction) {
|
||||||
|
$restriction['title'] = $rules[$restriction['rule']];
|
||||||
|
}
|
||||||
|
|
||||||
|
return $restrictions;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get restrictions
|
||||||
|
*
|
||||||
|
* @param int $project_id
|
||||||
|
* @param string $role
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function getAllByRole($project_id, $role)
|
||||||
|
{
|
||||||
|
$rules = $this->db
|
||||||
|
->table(self::TABLE)
|
||||||
|
->columns(
|
||||||
|
self::TABLE.'.restriction_id',
|
||||||
|
self::TABLE.'.project_id',
|
||||||
|
self::TABLE.'.role_id',
|
||||||
|
self::TABLE.'.rule',
|
||||||
|
'pr.role'
|
||||||
|
)
|
||||||
|
->eq(self::TABLE.'.project_id', $project_id)
|
||||||
|
->eq('role', $role)
|
||||||
|
->left(ProjectRoleModel::TABLE, 'pr', 'role_id', self::TABLE, 'role_id')
|
||||||
|
->findAll();
|
||||||
|
|
||||||
|
foreach ($rules as &$rule) {
|
||||||
|
$rule['acl'] = $this->ruleMapping[$rule['rule']];
|
||||||
|
}
|
||||||
|
|
||||||
|
return $rules;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new restriction
|
||||||
|
*
|
||||||
|
* @param int $project_id
|
||||||
|
* @param int $role_id
|
||||||
|
* @param string $rule
|
||||||
|
* @return bool|int
|
||||||
|
*/
|
||||||
|
public function create($project_id, $role_id, $rule)
|
||||||
|
{
|
||||||
|
return $this->db->table(self::TABLE)
|
||||||
|
->persist(array(
|
||||||
|
'project_id' => $project_id,
|
||||||
|
'role_id' => $role_id,
|
||||||
|
'rule' => $rule,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove a restriction
|
||||||
|
*
|
||||||
|
* @param integer $restriction_id
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function remove($restriction_id)
|
||||||
|
{
|
||||||
|
return $this->db->table(self::TABLE)->eq('restriction_id', $restriction_id)->remove();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if the controller/method is allowed
|
||||||
|
*
|
||||||
|
* @param array $restrictions
|
||||||
|
* @param string $controller
|
||||||
|
* @param string $method
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function isAllowed(array $restrictions, $controller, $method)
|
||||||
|
{
|
||||||
|
$controller = strtolower($controller);
|
||||||
|
$method = strtolower($method);
|
||||||
|
|
||||||
|
foreach ($restrictions as $restriction) {
|
||||||
|
foreach ($restriction['acl'] as $acl) {
|
||||||
|
$acl['controller'] = strtolower($acl['controller']);
|
||||||
|
$acl['method'] = strtolower($acl['method']);
|
||||||
|
|
||||||
|
if ($acl['controller'] === $controller && ($acl['method'] === '*' || $acl['method'] === $method)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -6,7 +6,22 @@ use PDO;
|
||||||
use Kanboard\Core\Security\Token;
|
use Kanboard\Core\Security\Token;
|
||||||
use Kanboard\Core\Security\Role;
|
use Kanboard\Core\Security\Role;
|
||||||
|
|
||||||
const VERSION = 113;
|
const VERSION = 114;
|
||||||
|
|
||||||
|
function version_114(PDO $pdo)
|
||||||
|
{
|
||||||
|
$pdo->exec("
|
||||||
|
CREATE TABLE project_role_has_restrictions (
|
||||||
|
restriction_id INT NOT NULL AUTO_INCREMENT,
|
||||||
|
project_id INT NOT NULL,
|
||||||
|
role_id INT NOT NULL,
|
||||||
|
rule VARCHAR(255) NOT NULL,
|
||||||
|
UNIQUE(role_id, rule),
|
||||||
|
FOREIGN KEY(project_id) REFERENCES projects(id) ON DELETE CASCADE,
|
||||||
|
FOREIGN KEY(role_id) REFERENCES project_has_roles(role_id) ON DELETE CASCADE
|
||||||
|
) ENGINE=InnoDB CHARSET=utf8
|
||||||
|
");
|
||||||
|
}
|
||||||
|
|
||||||
function version_113(PDO $pdo)
|
function version_113(PDO $pdo)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,22 @@ use PDO;
|
||||||
use Kanboard\Core\Security\Token;
|
use Kanboard\Core\Security\Token;
|
||||||
use Kanboard\Core\Security\Role;
|
use Kanboard\Core\Security\Role;
|
||||||
|
|
||||||
const VERSION = 92;
|
const VERSION = 93;
|
||||||
|
|
||||||
|
function version_93(PDO $pdo)
|
||||||
|
{
|
||||||
|
$pdo->exec("
|
||||||
|
CREATE TABLE project_role_has_restrictions (
|
||||||
|
restriction_id SERIAL PRIMARY KEY,
|
||||||
|
project_id INTEGER NOT NULL,
|
||||||
|
role_id INTEGER NOT NULL,
|
||||||
|
rule VARCHAR(255) NOT NULL,
|
||||||
|
UNIQUE(role_id, rule),
|
||||||
|
FOREIGN KEY(project_id) REFERENCES projects(id) ON DELETE CASCADE,
|
||||||
|
FOREIGN KEY(role_id) REFERENCES project_has_roles(role_id) ON DELETE CASCADE
|
||||||
|
)
|
||||||
|
");
|
||||||
|
}
|
||||||
|
|
||||||
function version_92(PDO $pdo)
|
function version_92(PDO $pdo)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,22 @@ use Kanboard\Core\Security\Token;
|
||||||
use Kanboard\Core\Security\Role;
|
use Kanboard\Core\Security\Role;
|
||||||
use PDO;
|
use PDO;
|
||||||
|
|
||||||
const VERSION = 104;
|
const VERSION = 105;
|
||||||
|
|
||||||
|
function version_105(PDO $pdo)
|
||||||
|
{
|
||||||
|
$pdo->exec("
|
||||||
|
CREATE TABLE project_role_has_restrictions (
|
||||||
|
restriction_id INTEGER PRIMARY KEY,
|
||||||
|
project_id INTEGER NOT NULL,
|
||||||
|
role_id INTEGER NOT NULL,
|
||||||
|
rule VARCHAR(255) NOT NULL,
|
||||||
|
UNIQUE(role_id, rule),
|
||||||
|
FOREIGN KEY(project_id) REFERENCES projects(id) ON DELETE CASCADE,
|
||||||
|
FOREIGN KEY(role_id) REFERENCES project_has_roles(role_id) ON DELETE CASCADE
|
||||||
|
)
|
||||||
|
");
|
||||||
|
}
|
||||||
|
|
||||||
function version_104(PDO $pdo)
|
function version_104(PDO $pdo)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -57,6 +57,7 @@ class ClassProvider implements ServiceProviderInterface
|
||||||
'ProjectMetadataModel',
|
'ProjectMetadataModel',
|
||||||
'ProjectGroupRoleModel',
|
'ProjectGroupRoleModel',
|
||||||
'ProjectRoleModel',
|
'ProjectRoleModel',
|
||||||
|
'ProjectRoleRestrictionModel',
|
||||||
'ProjectTaskDuplicationModel',
|
'ProjectTaskDuplicationModel',
|
||||||
'ProjectTaskPriorityModel',
|
'ProjectTaskPriorityModel',
|
||||||
'ProjectUserRoleModel',
|
'ProjectUserRoleModel',
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,7 @@ class HelperProvider implements ServiceProviderInterface
|
||||||
$container['helper']->register('url', '\Kanboard\Helper\UrlHelper');
|
$container['helper']->register('url', '\Kanboard\Helper\UrlHelper');
|
||||||
$container['helper']->register('user', '\Kanboard\Helper\UserHelper');
|
$container['helper']->register('user', '\Kanboard\Helper\UserHelper');
|
||||||
$container['helper']->register('avatar', '\Kanboard\Helper\AvatarHelper');
|
$container['helper']->register('avatar', '\Kanboard\Helper\AvatarHelper');
|
||||||
|
$container['helper']->register('projectRole', '\Kanboard\Helper\ProjectRoleHelper');
|
||||||
$container['helper']->register('projectHeader', '\Kanboard\Helper\ProjectHeaderHelper');
|
$container['helper']->register('projectHeader', '\Kanboard\Helper\ProjectHeaderHelper');
|
||||||
$container['helper']->register('projectActivity', '\Kanboard\Helper\ProjectActivityHelper');
|
$container['helper']->register('projectActivity', '\Kanboard\Helper\ProjectActivityHelper');
|
||||||
$container['helper']->register('mail', '\Kanboard\Helper\MailHelper');
|
$container['helper']->register('mail', '\Kanboard\Helper\MailHelper');
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,10 @@
|
||||||
<div class="dropdown">
|
<div class="dropdown">
|
||||||
<a href="#" class="dropdown-menu"><?= t('Restrictions for the role "%s"', $role['role']) ?> <i class="fa fa-caret-down"></i></a>
|
<a href="#" class="dropdown-menu"><?= t('Restrictions for the role "%s"', $role['role']) ?> <i class="fa fa-caret-down"></i></a>
|
||||||
<ul>
|
<ul>
|
||||||
|
<li>
|
||||||
|
<i class="fa fa-plus fa-fw" aria-hidden="true"></i>
|
||||||
|
<?= $this->url->link(t('Add a new project restriction'), 'ProjectRoleRestrictionController', 'create', array('project_id' => $project['id'], 'role_id' => $role['role_id']), false, 'popover') ?>
|
||||||
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<i class="fa fa-plus fa-fw" aria-hidden="true"></i>
|
<i class="fa fa-plus fa-fw" aria-hidden="true"></i>
|
||||||
<?= $this->url->link(t('Add a new column restriction'), 'ColumnMoveRestrictionController', 'create', array('project_id' => $project['id'], 'role_id' => $role['role_id']), false, 'popover') ?>
|
<?= $this->url->link(t('Add a new column restriction'), 'ColumnMoveRestrictionController', 'create', array('project_id' => $project['id'], 'role_id' => $role['role_id']), false, 'popover') ?>
|
||||||
|
|
@ -33,15 +37,26 @@
|
||||||
<?= t('Actions') ?>
|
<?= t('Actions') ?>
|
||||||
</th>
|
</th>
|
||||||
</tr>
|
</tr>
|
||||||
<?php if (empty($role['restrictions'])): ?>
|
<?php if (empty($role['project_restrictions']) && empty($role['column_restrictions'])): ?>
|
||||||
<tr>
|
<tr>
|
||||||
<td colspan="2"><?= t('There is no restriction for this role.') ?></td>
|
<td colspan="2"><?= t('There is no restriction for this role.') ?></td>
|
||||||
</tr>
|
</tr>
|
||||||
<?php else: ?>
|
<?php else: ?>
|
||||||
<?php foreach ($role['restrictions'] as $restriction): ?>
|
<?php foreach ($role['project_restrictions'] as $restriction): ?>
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
<?= t('Moving task from the column "%s" to "%s" is permitted', $restriction['src_column_title'], $restriction['dst_column_title']) ?>
|
<?= $this->text->e($restriction['title']) ?>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<i class="fa fa-trash-o fa-fw" aria-hidden="true"></i>
|
||||||
|
<?= $this->url->link(t('Remove'), 'ProjectRoleRestrictionController', 'confirm', array('project_id' => $project['id'], 'restriction_id' => $restriction['restriction_id']), false, 'popover') ?>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<?php endforeach ?>
|
||||||
|
<?php foreach ($role['column_restrictions'] as $restriction): ?>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<?= t('Only moving task from the column "%s" to "%s" is permitted', $restriction['src_column_title'], $restriction['dst_column_title']) ?>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<i class="fa fa-trash-o fa-fw" aria-hidden="true"></i>
|
<i class="fa fa-trash-o fa-fw" aria-hidden="true"></i>
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,19 @@
|
||||||
|
<section id="main">
|
||||||
|
<div class="page-header">
|
||||||
|
<h2><?= t('New project restriction for the role "%s"', $role['role']) ?></h2>
|
||||||
|
</div>
|
||||||
|
<form class="popover-form" method="post" action="<?= $this->url->href('ProjectRoleRestrictionController', 'save', array('project_id' => $project['id'])) ?>" autocomplete="off">
|
||||||
|
<?= $this->form->csrf() ?>
|
||||||
|
<?= $this->form->hidden('project_id', $values) ?>
|
||||||
|
<?= $this->form->hidden('role_id', $values) ?>
|
||||||
|
|
||||||
|
<?= $this->form->label(t('Restriction'), 'rule') ?>
|
||||||
|
<?= $this->form->select('rule', $restrictions, $values, $errors) ?>
|
||||||
|
|
||||||
|
<div class="form-actions">
|
||||||
|
<button type="submit" class="btn btn-blue"><?= t('Save') ?></button>
|
||||||
|
<?= t('or') ?>
|
||||||
|
<?= $this->url->link(t('cancel'), 'ProjectRoleController', 'show', array(), false, 'close-popover') ?>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</section>
|
||||||
|
|
@ -0,0 +1,14 @@
|
||||||
|
<div class="page-header">
|
||||||
|
<h2><?= t('Remove a project restriction') ?></h2>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="confirm">
|
||||||
|
<p class="alert alert-info">
|
||||||
|
<?= t('Do you really want to remove this project restriction: "%s"?', $this->text->in($restriction['rule'], $restrictions)) ?>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div class="form-actions">
|
||||||
|
<?= $this->url->link(t('Yes'), 'ProjectRoleRestrictionController', 'remove', array('project_id' => $project['id'], 'restriction_id' => $restriction['restriction_id']), true, 'btn btn-red') ?>
|
||||||
|
<?= t('or') ?> <?= $this->url->link(t('cancel'), 'ProjectRoleController', 'show', array('project_id' => $project['id']), false, 'close-popover') ?>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
@ -43,7 +43,7 @@
|
||||||
<i class="fa fa-clone fa-fw"></i>
|
<i class="fa fa-clone fa-fw"></i>
|
||||||
<?= $this->url->link(t('Move to another project'), 'TaskDuplicationController', 'move', array('task_id' => $task['id'], 'project_id' => $task['project_id']), false, 'popover') ?>
|
<?= $this->url->link(t('Move to another project'), 'TaskDuplicationController', 'move', array('task_id' => $task['id'], 'project_id' => $task['project_id']), false, 'popover') ?>
|
||||||
</li>
|
</li>
|
||||||
<?php if ($this->user->canRemoveTask($task)): ?>
|
<?php if ($this->projectRole->canRemoveTask($task)): ?>
|
||||||
<li>
|
<li>
|
||||||
<i class="fa fa-trash-o fa-fw"></i>
|
<i class="fa fa-trash-o fa-fw"></i>
|
||||||
<?= $this->url->link(t('Remove'), 'TaskSuppressionController', 'confirm', array('task_id' => $task['id'], 'project_id' => $task['project_id']), false, 'popover') ?>
|
<?= $this->url->link(t('Remove'), 'TaskSuppressionController', 'confirm', array('task_id' => $task['id'], 'project_id' => $task['project_id']), false, 'popover') ?>
|
||||||
|
|
|
||||||
|
|
@ -93,7 +93,7 @@
|
||||||
<?= $this->url->link(t('Open this task'), 'TaskStatusController', 'open', array('task_id' => $task['id'], 'project_id' => $task['project_id']), false, 'popover') ?>
|
<?= $this->url->link(t('Open this task'), 'TaskStatusController', 'open', array('task_id' => $task['id'], 'project_id' => $task['project_id']), false, 'popover') ?>
|
||||||
</li>
|
</li>
|
||||||
<?php endif ?>
|
<?php endif ?>
|
||||||
<?php if ($this->user->canRemoveTask($task)): ?>
|
<?php if ($this->projectRole->canRemoveTask($task)): ?>
|
||||||
<li>
|
<li>
|
||||||
<i class="fa fa-trash-o fa-fw"></i>
|
<i class="fa fa-trash-o fa-fw"></i>
|
||||||
<?= $this->url->link(t('Remove'), 'TaskSuppressionController', 'confirm', array('task_id' => $task['id'], 'project_id' => $task['project_id'], 'redirect' => 'board'), false, 'popover') ?>
|
<?= $this->url->link(t('Remove'), 'TaskSuppressionController', 'confirm', array('task_id' => $task['id'], 'project_id' => $task['project_id'], 'redirect' => 'board'), false, 'popover') ?>
|
||||||
|
|
|
||||||
|
|
@ -1,98 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
use Kanboard\Core\Security\Role;
|
|
||||||
use Kanboard\Helper\BoardHelper;
|
|
||||||
use Kanboard\Model\ColumnMoveRestrictionModel;
|
|
||||||
use Kanboard\Model\ProjectModel;
|
|
||||||
use Kanboard\Model\ProjectRoleModel;
|
|
||||||
use Kanboard\Model\ProjectUserRoleModel;
|
|
||||||
use Kanboard\Model\TaskCreationModel;
|
|
||||||
use Kanboard\Model\TaskFinderModel;
|
|
||||||
use Kanboard\Model\TaskStatusModel;
|
|
||||||
use Kanboard\Model\UserModel;
|
|
||||||
|
|
||||||
require_once __DIR__.'/../Base.php';
|
|
||||||
|
|
||||||
class BoardHelperTest extends Base
|
|
||||||
{
|
|
||||||
public function testIsDraggableWithProjectMember()
|
|
||||||
{
|
|
||||||
$boardHelper = new BoardHelper($this->container);
|
|
||||||
$projectModel = new ProjectModel($this->container);
|
|
||||||
$taskCreationModel = new TaskCreationModel($this->container);
|
|
||||||
$taskFinderModel = new TaskFinderModel($this->container);
|
|
||||||
$projectUserRole = new ProjectUserRoleModel($this->container);
|
|
||||||
$userModel = new UserModel($this->container);
|
|
||||||
|
|
||||||
$this->container['sessionStorage']->user = array(
|
|
||||||
'id' => 2,
|
|
||||||
'role' => Role::APP_USER,
|
|
||||||
);
|
|
||||||
|
|
||||||
$this->assertEquals(2, $userModel->create(array('username' => 'user')));
|
|
||||||
$this->assertEquals(1, $projectModel->create(array('name' => 'Test')));
|
|
||||||
$this->assertTrue($projectUserRole->addUser(1, 2, Role::PROJECT_MEMBER));
|
|
||||||
$this->assertEquals(1, $taskCreationModel->create(array('project_id' => 1, 'title' => 'test')));
|
|
||||||
|
|
||||||
$task = $taskFinderModel->getById(1);
|
|
||||||
$this->assertTrue($boardHelper->isDraggable($task));
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testIsDraggableWithClosedTask()
|
|
||||||
{
|
|
||||||
$boardHelper = new BoardHelper($this->container);
|
|
||||||
$projectModel = new ProjectModel($this->container);
|
|
||||||
$taskCreationModel = new TaskCreationModel($this->container);
|
|
||||||
$taskFinderModel = new TaskFinderModel($this->container);
|
|
||||||
$taskStatusModel = new TaskStatusModel($this->container);
|
|
||||||
$projectUserRole = new ProjectUserRoleModel($this->container);
|
|
||||||
$userModel = new UserModel($this->container);
|
|
||||||
|
|
||||||
$this->container['sessionStorage']->user = array(
|
|
||||||
'id' => 2,
|
|
||||||
'role' => Role::APP_USER,
|
|
||||||
);
|
|
||||||
|
|
||||||
$this->assertEquals(2, $userModel->create(array('username' => 'user')));
|
|
||||||
$this->assertEquals(1, $projectModel->create(array('name' => 'Test')));
|
|
||||||
$this->assertTrue($projectUserRole->addUser(1, 2, Role::PROJECT_MEMBER));
|
|
||||||
$this->assertEquals(1, $taskCreationModel->create(array('project_id' => 1, 'title' => 'test')));
|
|
||||||
$this->assertTrue($taskStatusModel->close(1));
|
|
||||||
|
|
||||||
$task = $taskFinderModel->getById(1);
|
|
||||||
$this->assertFalse($boardHelper->isDraggable($task));
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testIsDraggableWithColumnRestrictions()
|
|
||||||
{
|
|
||||||
$boardHelper = new BoardHelper($this->container);
|
|
||||||
$projectModel = new ProjectModel($this->container);
|
|
||||||
$taskCreationModel = new TaskCreationModel($this->container);
|
|
||||||
$taskFinderModel = new TaskFinderModel($this->container);
|
|
||||||
$projectUserRole = new ProjectUserRoleModel($this->container);
|
|
||||||
$userModel = new UserModel($this->container);
|
|
||||||
$projectRoleModel = new ProjectRoleModel($this->container);
|
|
||||||
$columnMoveRestrictionModel = new ColumnMoveRestrictionModel($this->container);
|
|
||||||
|
|
||||||
$this->container['sessionStorage']->user = array(
|
|
||||||
'id' => 2,
|
|
||||||
'role' => Role::APP_USER,
|
|
||||||
);
|
|
||||||
|
|
||||||
$this->assertEquals(2, $userModel->create(array('username' => 'user')));
|
|
||||||
$this->assertEquals(1, $projectModel->create(array('name' => 'Test')));
|
|
||||||
|
|
||||||
$this->assertEquals(1, $projectRoleModel->create(1, 'Custom Role'));
|
|
||||||
$this->assertEquals(1, $columnMoveRestrictionModel->create(1, 1, 2, 3));
|
|
||||||
|
|
||||||
$this->assertTrue($projectUserRole->addUser(1, 2, 'Custom Role'));
|
|
||||||
$this->assertEquals(1, $taskCreationModel->create(array('project_id' => 1, 'title' => 'test', 'column_id' => 2)));
|
|
||||||
$this->assertEquals(2, $taskCreationModel->create(array('project_id' => 1, 'title' => 'test', 'column_id' => 3)));
|
|
||||||
|
|
||||||
$task = $taskFinderModel->getById(1);
|
|
||||||
$this->assertTrue($boardHelper->isDraggable($task));
|
|
||||||
|
|
||||||
$task = $taskFinderModel->getById(2);
|
|
||||||
$this->assertFalse($boardHelper->isDraggable($task));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -0,0 +1,189 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
use Kanboard\Core\Security\Role;
|
||||||
|
use Kanboard\Core\User\UserSession;
|
||||||
|
use Kanboard\Helper\ProjectRoleHelper;
|
||||||
|
use Kanboard\Model\ColumnMoveRestrictionModel;
|
||||||
|
use Kanboard\Model\ProjectModel;
|
||||||
|
use Kanboard\Model\ProjectRoleModel;
|
||||||
|
use Kanboard\Model\ProjectUserRoleModel;
|
||||||
|
use Kanboard\Model\TaskCreationModel;
|
||||||
|
use Kanboard\Model\TaskFinderModel;
|
||||||
|
use Kanboard\Model\TaskStatusModel;
|
||||||
|
use Kanboard\Model\UserModel;
|
||||||
|
|
||||||
|
require_once __DIR__.'/../Base.php';
|
||||||
|
|
||||||
|
class ProjectRoleHelperTest extends Base
|
||||||
|
{
|
||||||
|
public function testIsDraggableWithProjectMember()
|
||||||
|
{
|
||||||
|
$projectRoleHelper = new ProjectRoleHelper($this->container);
|
||||||
|
$projectModel = new ProjectModel($this->container);
|
||||||
|
$taskCreationModel = new TaskCreationModel($this->container);
|
||||||
|
$taskFinderModel = new TaskFinderModel($this->container);
|
||||||
|
$projectUserRole = new ProjectUserRoleModel($this->container);
|
||||||
|
$userModel = new UserModel($this->container);
|
||||||
|
|
||||||
|
$this->container['sessionStorage']->user = array(
|
||||||
|
'id' => 2,
|
||||||
|
'role' => Role::APP_USER,
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->assertEquals(2, $userModel->create(array('username' => 'user')));
|
||||||
|
$this->assertEquals(1, $projectModel->create(array('name' => 'Test')));
|
||||||
|
$this->assertTrue($projectUserRole->addUser(1, 2, Role::PROJECT_MEMBER));
|
||||||
|
$this->assertEquals(1, $taskCreationModel->create(array('project_id' => 1, 'title' => 'test')));
|
||||||
|
|
||||||
|
$task = $taskFinderModel->getById(1);
|
||||||
|
$this->assertTrue($projectRoleHelper->isDraggable($task));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testIsDraggableWithClosedTask()
|
||||||
|
{
|
||||||
|
$projectRoleHelper = new ProjectRoleHelper($this->container);
|
||||||
|
$projectModel = new ProjectModel($this->container);
|
||||||
|
$taskCreationModel = new TaskCreationModel($this->container);
|
||||||
|
$taskFinderModel = new TaskFinderModel($this->container);
|
||||||
|
$taskStatusModel = new TaskStatusModel($this->container);
|
||||||
|
$projectUserRole = new ProjectUserRoleModel($this->container);
|
||||||
|
$userModel = new UserModel($this->container);
|
||||||
|
|
||||||
|
$this->container['sessionStorage']->user = array(
|
||||||
|
'id' => 2,
|
||||||
|
'role' => Role::APP_USER,
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->assertEquals(2, $userModel->create(array('username' => 'user')));
|
||||||
|
$this->assertEquals(1, $projectModel->create(array('name' => 'Test')));
|
||||||
|
$this->assertTrue($projectUserRole->addUser(1, 2, Role::PROJECT_MEMBER));
|
||||||
|
$this->assertEquals(1, $taskCreationModel->create(array('project_id' => 1, 'title' => 'test')));
|
||||||
|
$this->assertTrue($taskStatusModel->close(1));
|
||||||
|
|
||||||
|
$task = $taskFinderModel->getById(1);
|
||||||
|
$this->assertFalse($projectRoleHelper->isDraggable($task));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testIsDraggableWithColumnRestrictions()
|
||||||
|
{
|
||||||
|
$projectRoleHelper = new ProjectRoleHelper($this->container);
|
||||||
|
$projectModel = new ProjectModel($this->container);
|
||||||
|
$taskCreationModel = new TaskCreationModel($this->container);
|
||||||
|
$taskFinderModel = new TaskFinderModel($this->container);
|
||||||
|
$projectUserRole = new ProjectUserRoleModel($this->container);
|
||||||
|
$userModel = new UserModel($this->container);
|
||||||
|
$projectRoleModel = new ProjectRoleModel($this->container);
|
||||||
|
$columnMoveRestrictionModel = new ColumnMoveRestrictionModel($this->container);
|
||||||
|
|
||||||
|
$this->container['sessionStorage']->user = array(
|
||||||
|
'id' => 2,
|
||||||
|
'role' => Role::APP_USER,
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->assertEquals(2, $userModel->create(array('username' => 'user')));
|
||||||
|
$this->assertEquals(1, $projectModel->create(array('name' => 'Test')));
|
||||||
|
|
||||||
|
$this->assertEquals(1, $projectRoleModel->create(1, 'Custom Role'));
|
||||||
|
$this->assertEquals(1, $columnMoveRestrictionModel->create(1, 1, 2, 3));
|
||||||
|
|
||||||
|
$this->assertTrue($projectUserRole->addUser(1, 2, 'Custom Role'));
|
||||||
|
$this->assertEquals(1, $taskCreationModel->create(array('project_id' => 1, 'title' => 'test', 'column_id' => 2)));
|
||||||
|
$this->assertEquals(2, $taskCreationModel->create(array('project_id' => 1, 'title' => 'test', 'column_id' => 3)));
|
||||||
|
|
||||||
|
$task = $taskFinderModel->getById(1);
|
||||||
|
$this->assertTrue($projectRoleHelper->isDraggable($task));
|
||||||
|
|
||||||
|
$task = $taskFinderModel->getById(2);
|
||||||
|
$this->assertFalse($projectRoleHelper->isDraggable($task));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testCanRemoveTask()
|
||||||
|
{
|
||||||
|
$taskCreationModel = new TaskCreationModel($this->container);
|
||||||
|
$taskFinderModel = new TaskFinderModel($this->container);
|
||||||
|
$projectRoleHelper = new ProjectRoleHelper($this->container);
|
||||||
|
$projectModel = new ProjectModel($this->container);
|
||||||
|
$userModel = new UserModel($this->container);
|
||||||
|
$userSessionModel = new UserSession($this->container);
|
||||||
|
|
||||||
|
$this->assertNotFalse($userModel->create(array('username' => 'toto', 'password' => '123456')));
|
||||||
|
$this->assertNotFalse($userModel->create(array('username' => 'toto2', 'password' => '123456')));
|
||||||
|
$this->assertEquals(1, $projectModel->create(array('name' => 'Project #1')));
|
||||||
|
$this->assertEquals(1, $taskCreationModel->create(array('title' => 'TaskViewController #1', 'project_id' => 1, 'creator_id' => 1)));
|
||||||
|
$this->assertEquals(2, $taskCreationModel->create(array('title' => 'TaskViewController #2', 'project_id' => 1, 'creator_id' => 2)));
|
||||||
|
$this->assertEquals(3, $taskCreationModel->create(array('title' => 'TaskViewController #3', 'project_id' => 1, 'creator_id' => 3)));
|
||||||
|
$this->assertEquals(4, $taskCreationModel->create(array('title' => 'TaskViewController #4', 'project_id' => 1)));
|
||||||
|
|
||||||
|
// User #1 can remove everything
|
||||||
|
$user = $userModel->getById(1);
|
||||||
|
$this->assertNotEmpty($user);
|
||||||
|
$userSessionModel->initialize($user);
|
||||||
|
|
||||||
|
$task = $taskFinderModel->getById(1);
|
||||||
|
$this->assertNotEmpty($task);
|
||||||
|
$this->assertTrue($projectRoleHelper->canRemoveTask($task));
|
||||||
|
|
||||||
|
// User #2 can't remove the TaskViewController #1
|
||||||
|
$user = $userModel->getById(2);
|
||||||
|
$this->assertNotEmpty($user);
|
||||||
|
$userSessionModel->initialize($user);
|
||||||
|
|
||||||
|
$task = $taskFinderModel->getById(1);
|
||||||
|
$this->assertNotEmpty($task);
|
||||||
|
$this->assertFalse($projectRoleHelper->canRemoveTask($task));
|
||||||
|
|
||||||
|
// User #1 can remove everything
|
||||||
|
$user = $userModel->getById(1);
|
||||||
|
$this->assertNotEmpty($user);
|
||||||
|
$userSessionModel->initialize($user);
|
||||||
|
|
||||||
|
$task = $taskFinderModel->getById(2);
|
||||||
|
$this->assertNotEmpty($task);
|
||||||
|
$this->assertTrue($projectRoleHelper->canRemoveTask($task));
|
||||||
|
|
||||||
|
// User #2 can remove his own TaskViewController
|
||||||
|
$user = $userModel->getById(2);
|
||||||
|
$this->assertNotEmpty($user);
|
||||||
|
$userSessionModel->initialize($user);
|
||||||
|
|
||||||
|
$task = $taskFinderModel->getById(2);
|
||||||
|
$this->assertNotEmpty($task);
|
||||||
|
$this->assertTrue($projectRoleHelper->canRemoveTask($task));
|
||||||
|
|
||||||
|
// User #1 can remove everything
|
||||||
|
$user = $userModel->getById(1);
|
||||||
|
$this->assertNotEmpty($user);
|
||||||
|
$userSessionModel->initialize($user);
|
||||||
|
|
||||||
|
$task = $taskFinderModel->getById(3);
|
||||||
|
$this->assertNotEmpty($task);
|
||||||
|
$this->assertTrue($projectRoleHelper->canRemoveTask($task));
|
||||||
|
|
||||||
|
// User #2 can't remove the TaskViewController #3
|
||||||
|
$user = $userModel->getById(2);
|
||||||
|
$this->assertNotEmpty($user);
|
||||||
|
$userSessionModel->initialize($user);
|
||||||
|
|
||||||
|
$task = $taskFinderModel->getById(3);
|
||||||
|
$this->assertNotEmpty($task);
|
||||||
|
$this->assertFalse($projectRoleHelper->canRemoveTask($task));
|
||||||
|
|
||||||
|
// User #1 can remove everything
|
||||||
|
$user = $userModel->getById(1);
|
||||||
|
$this->assertNotEmpty($user);
|
||||||
|
$userSessionModel->initialize($user);
|
||||||
|
|
||||||
|
$task = $taskFinderModel->getById(4);
|
||||||
|
$this->assertNotEmpty($task);
|
||||||
|
$this->assertTrue($projectRoleHelper->canRemoveTask($task));
|
||||||
|
|
||||||
|
// User #2 can't remove the TaskViewController #4
|
||||||
|
$user = $userModel->getById(2);
|
||||||
|
$this->assertNotEmpty($user);
|
||||||
|
$userSessionModel->initialize($user);
|
||||||
|
|
||||||
|
$task = $taskFinderModel->getById(4);
|
||||||
|
$this->assertNotEmpty($task);
|
||||||
|
$this->assertFalse($projectRoleHelper->canRemoveTask($task));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -294,94 +294,4 @@ class UserHelperTest extends Base
|
||||||
$this->assertFalse($helper->hasProjectAccess('TaskViewController', 'show', 2));
|
$this->assertFalse($helper->hasProjectAccess('TaskViewController', 'show', 2));
|
||||||
$this->assertFalse($helper->hasProjectAccess('TaskCreationController', 'save', 2));
|
$this->assertFalse($helper->hasProjectAccess('TaskCreationController', 'save', 2));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testCanRemoveTask()
|
|
||||||
{
|
|
||||||
$taskCreationModel = new TaskCreationModel($this->container);
|
|
||||||
$taskFinderModel = new TaskFinderModel($this->container);
|
|
||||||
$helper = new UserHelper($this->container);
|
|
||||||
$projectModel = new ProjectModel($this->container);
|
|
||||||
$userModel = new UserModel($this->container);
|
|
||||||
$userSessionModel = new UserSession($this->container);
|
|
||||||
|
|
||||||
$this->assertNotFalse($userModel->create(array('username' => 'toto', 'password' => '123456')));
|
|
||||||
$this->assertNotFalse($userModel->create(array('username' => 'toto2', 'password' => '123456')));
|
|
||||||
$this->assertEquals(1, $projectModel->create(array('name' => 'Project #1')));
|
|
||||||
$this->assertEquals(1, $taskCreationModel->create(array('title' => 'TaskViewController #1', 'project_id' => 1, 'creator_id' => 1)));
|
|
||||||
$this->assertEquals(2, $taskCreationModel->create(array('title' => 'TaskViewController #2', 'project_id' => 1, 'creator_id' => 2)));
|
|
||||||
$this->assertEquals(3, $taskCreationModel->create(array('title' => 'TaskViewController #3', 'project_id' => 1, 'creator_id' => 3)));
|
|
||||||
$this->assertEquals(4, $taskCreationModel->create(array('title' => 'TaskViewController #4', 'project_id' => 1)));
|
|
||||||
|
|
||||||
// User #1 can remove everything
|
|
||||||
$user = $userModel->getById(1);
|
|
||||||
$this->assertNotEmpty($user);
|
|
||||||
$userSessionModel->initialize($user);
|
|
||||||
|
|
||||||
$task = $taskFinderModel->getById(1);
|
|
||||||
$this->assertNotEmpty($task);
|
|
||||||
$this->assertTrue($helper->canRemoveTask($task));
|
|
||||||
|
|
||||||
// User #2 can't remove the TaskViewController #1
|
|
||||||
$user = $userModel->getById(2);
|
|
||||||
$this->assertNotEmpty($user);
|
|
||||||
$userSessionModel->initialize($user);
|
|
||||||
|
|
||||||
$task = $taskFinderModel->getById(1);
|
|
||||||
$this->assertNotEmpty($task);
|
|
||||||
$this->assertFalse($helper->canRemoveTask($task));
|
|
||||||
|
|
||||||
// User #1 can remove everything
|
|
||||||
$user = $userModel->getById(1);
|
|
||||||
$this->assertNotEmpty($user);
|
|
||||||
$userSessionModel->initialize($user);
|
|
||||||
|
|
||||||
$task = $taskFinderModel->getById(2);
|
|
||||||
$this->assertNotEmpty($task);
|
|
||||||
$this->assertTrue($helper->canRemoveTask($task));
|
|
||||||
|
|
||||||
// User #2 can remove his own TaskViewController
|
|
||||||
$user = $userModel->getById(2);
|
|
||||||
$this->assertNotEmpty($user);
|
|
||||||
$userSessionModel->initialize($user);
|
|
||||||
|
|
||||||
$task = $taskFinderModel->getById(2);
|
|
||||||
$this->assertNotEmpty($task);
|
|
||||||
$this->assertTrue($helper->canRemoveTask($task));
|
|
||||||
|
|
||||||
// User #1 can remove everything
|
|
||||||
$user = $userModel->getById(1);
|
|
||||||
$this->assertNotEmpty($user);
|
|
||||||
$userSessionModel->initialize($user);
|
|
||||||
|
|
||||||
$task = $taskFinderModel->getById(3);
|
|
||||||
$this->assertNotEmpty($task);
|
|
||||||
$this->assertTrue($helper->canRemoveTask($task));
|
|
||||||
|
|
||||||
// User #2 can't remove the TaskViewController #3
|
|
||||||
$user = $userModel->getById(2);
|
|
||||||
$this->assertNotEmpty($user);
|
|
||||||
$userSessionModel->initialize($user);
|
|
||||||
|
|
||||||
$task = $taskFinderModel->getById(3);
|
|
||||||
$this->assertNotEmpty($task);
|
|
||||||
$this->assertFalse($helper->canRemoveTask($task));
|
|
||||||
|
|
||||||
// User #1 can remove everything
|
|
||||||
$user = $userModel->getById(1);
|
|
||||||
$this->assertNotEmpty($user);
|
|
||||||
$userSessionModel->initialize($user);
|
|
||||||
|
|
||||||
$task = $taskFinderModel->getById(4);
|
|
||||||
$this->assertNotEmpty($task);
|
|
||||||
$this->assertTrue($helper->canRemoveTask($task));
|
|
||||||
|
|
||||||
// User #2 can't remove the TaskViewController #4
|
|
||||||
$user = $userModel->getById(2);
|
|
||||||
$this->assertNotEmpty($user);
|
|
||||||
$userSessionModel->initialize($user);
|
|
||||||
|
|
||||||
$task = $taskFinderModel->getById(4);
|
|
||||||
$this->assertNotEmpty($task);
|
|
||||||
$this->assertFalse($helper->canRemoveTask($task));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue