diff options
author | Frederic Guillot <fred@kanboard.net> | 2016-09-18 21:19:48 -0400 |
---|---|---|
committer | Frederic Guillot <fred@kanboard.net> | 2016-09-18 21:19:48 -0400 |
commit | 3043163747b13ce1942b2e55977cf7c5417021de (patch) | |
tree | 31552d8bfdf3b7a6eedfaded116b863e980f86b4 /app/Model | |
parent | 4bc83646b0b15bff9ae55083121f66b7a89e433d (diff) |
Add column restrictions to custom project roles
Diffstat (limited to 'app/Model')
-rw-r--r-- | app/Model/ColumnRestrictionModel.php | 152 | ||||
-rw-r--r-- | app/Model/ProjectPermissionModel.php | 9 | ||||
-rw-r--r-- | app/Model/ProjectRoleModel.php | 36 | ||||
-rw-r--r-- | app/Model/ProjectRoleRestrictionModel.php | 44 | ||||
-rw-r--r-- | app/Model/ProjectUserRoleModel.php | 2 | ||||
-rw-r--r-- | app/Model/TaskFinderModel.php | 1 |
6 files changed, 196 insertions, 48 deletions
diff --git a/app/Model/ColumnRestrictionModel.php b/app/Model/ColumnRestrictionModel.php new file mode 100644 index 00000000..92b2ac60 --- /dev/null +++ b/app/Model/ColumnRestrictionModel.php @@ -0,0 +1,152 @@ +<?php + +namespace Kanboard\Model; + +use Kanboard\Core\Base; + +/** + * Class ColumnRestrictionModel + * + * @package Kanboard\Model + * @author Frederic Guillot + */ +class ColumnRestrictionModel extends Base +{ + const TABLE = 'column_has_restrictions'; + + const RULE_ALLOW_TASK_CREATION = 'allow.task_creation'; + const RULE_ALLOW_TASK_OPEN_CLOSE = 'allow.task_open_close'; + const RULE_BLOCK_TASK_CREATION = 'block.task_creation'; + const RULE_BLOCK_TASK_OPEN_CLOSE = 'block.task_open_close'; + + /** + * Get rules + * + * @return array + */ + public function getRules() + { + return array( + self::RULE_ALLOW_TASK_CREATION => t('Task creation is permitted for this column'), + self::RULE_ALLOW_TASK_OPEN_CLOSE => t('Closing or opening a task is permitted for this column'), + self::RULE_BLOCK_TASK_CREATION => t('Task creation is blocked for this column'), + self::RULE_BLOCK_TASK_OPEN_CLOSE => t('Closing or opening a task is blocked for this column'), + ); + } + + /** + * Fetch one restriction + * + * @param int $project_id + * @param int $restriction_id + * @return array|null + */ + public function getById($project_id, $restriction_id) + { + return $this->db + ->table(self::TABLE) + ->columns( + self::TABLE.'.restriction_id', + self::TABLE.'.project_id', + self::TABLE.'.role_id', + self::TABLE.'.column_id', + self::TABLE.'.rule', + 'pr.role', + 'c.title as column_title' + ) + ->left(ColumnModel::TABLE, 'c', 'id', self::TABLE, 'column_id') + ->left(ProjectRoleModel::TABLE, 'pr', 'role_id', self::TABLE, 'role_id') + ->eq(self::TABLE.'.project_id', $project_id) + ->eq(self::TABLE.'.restriction_id', $restriction_id) + ->findOne(); + } + + /** + * Get all project column 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.'.column_id', + self::TABLE.'.rule', + 'pr.role', + 'c.title as column_title' + ) + ->left(ColumnModel::TABLE, 'c', 'id', self::TABLE, 'column_id') + ->left(ProjectRoleModel::TABLE, 'pr', 'role_id', self::TABLE, 'role_id') + ->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) + { + return $this->db + ->table(self::TABLE) + ->columns( + self::TABLE.'.restriction_id', + self::TABLE.'.project_id', + self::TABLE.'.role_id', + self::TABLE.'.column_id', + self::TABLE.'.rule', + 'pr.role' + ) + ->eq(self::TABLE.'.project_id', $project_id) + ->eq('pr.role', $role) + ->left(ProjectRoleModel::TABLE, 'pr', 'role_id', self::TABLE, 'role_id') + ->findAll(); + } + + /** + * Create a new column restriction + * + * @param int $project_id + * @param int $role_id + * @param int $column_id + * @param int $rule + * @return bool|int + */ + public function create($project_id, $role_id, $column_id, $rule) + { + return $this->db + ->table(self::TABLE) + ->persist(array( + 'project_id' => $project_id, + 'role_id' => $role_id, + 'column_id' => $column_id, + 'rule' => $rule, + )); + } + + /** + * Remove a permission + * + * @param int $restriction_id + * @return bool + */ + public function remove($restriction_id) + { + return $this->db->table(self::TABLE)->eq('restriction_id', $restriction_id)->remove(); + } +} diff --git a/app/Model/ProjectPermissionModel.php b/app/Model/ProjectPermissionModel.php index 4882343d..25b6a382 100644 --- a/app/Model/ProjectPermissionModel.php +++ b/app/Model/ProjectPermissionModel.php @@ -122,8 +122,13 @@ class ProjectPermissionModel extends Base */ public function isAssignable($project_id, $user_id) { - return $this->userModel->isActive($user_id) && - in_array($this->projectUserRoleModel->getUserRole($project_id, $user_id), array(Role::PROJECT_MEMBER, Role::PROJECT_MANAGER)); + if ($this->userModel->isActive($user_id)) { + $role = $this->projectUserRoleModel->getUserRole($project_id, $user_id); + + return ! empty($role) && $role !== Role::PROJECT_VIEWER; + } + + return false; } /** diff --git a/app/Model/ProjectRoleModel.php b/app/Model/ProjectRoleModel.php index ed86d6ed..962ff44f 100644 --- a/app/Model/ProjectRoleModel.php +++ b/app/Model/ProjectRoleModel.php @@ -71,10 +71,14 @@ class ProjectRoleModel extends Base { $roles = $this->getAll($project_id); - $column_restrictions = $this->columnMoveRestrictionModel->getAll($project_id); + $column_restrictions = $this->columnRestrictionModel->getAll($project_id); $column_restrictions = array_column_index($column_restrictions, 'role_id'); array_merge_relation($roles, $column_restrictions, 'column_restrictions', 'role_id'); + $column_move_restrictions = $this->columnMoveRestrictionModel->getAll($project_id); + $column_move_restrictions = array_column_index($column_move_restrictions, 'role_id'); + array_merge_relation($roles, $column_move_restrictions, 'column_move_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'); @@ -109,13 +113,41 @@ class ProjectRoleModel extends Base */ public function update($role_id, $project_id, $role) { - return $this->db + $this->db->startTransaction(); + + $previousRole = $this->getById($project_id, $role_id); + + $r1 = $this->db + ->table(ProjectUserRoleModel::TABLE) + ->eq('project_id', $project_id) + ->eq('role', $previousRole['role']) + ->update(array( + 'role' => $role + )); + + $r2 = $this->db + ->table(ProjectGroupRoleModel::TABLE) + ->eq('project_id', $project_id) + ->eq('role', $previousRole['role']) + ->update(array( + 'role' => $role + )); + + $r3 = $this->db ->table(self::TABLE) ->eq('role_id', $role_id) ->eq('project_id', $project_id) ->update(array( 'role' => $role, )); + + if ($r1 && $r2 && $r3) { + $this->db->closeTransaction(); + return true; + } + + $this->db->cancelTransaction(); + return false; } /** diff --git a/app/Model/ProjectRoleRestrictionModel.php b/app/Model/ProjectRoleRestrictionModel.php index 7679f650..dc8abf79 100644 --- a/app/Model/ProjectRoleRestrictionModel.php +++ b/app/Model/ProjectRoleRestrictionModel.php @@ -17,15 +17,6 @@ class ProjectRoleRestrictionModel extends Base const RULE_TASK_CREATION = 'task_creation'; const RULE_TASK_OPEN_CLOSE = 'task_open_close'; - protected $ruleMapping = array( - self::RULE_TASK_CREATION => array( - array('controller' => 'TaskCreationController', 'method' => '*'), - ), - self::RULE_TASK_OPEN_CLOSE => array( - array('controller' => 'TaskStatusController', 'method' => '*'), - ) - ); - /** * Get rules * @@ -91,7 +82,7 @@ class ProjectRoleRestrictionModel extends Base */ public function getAllByRole($project_id, $role) { - $rules = $this->db + return $this->db ->table(self::TABLE) ->columns( self::TABLE.'.restriction_id', @@ -104,12 +95,6 @@ class ProjectRoleRestrictionModel extends Base ->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; } /** @@ -140,31 +125,4 @@ class ProjectRoleRestrictionModel extends Base { 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; - } } diff --git a/app/Model/ProjectUserRoleModel.php b/app/Model/ProjectUserRoleModel.php index a0df0cfa..76094431 100644 --- a/app/Model/ProjectUserRoleModel.php +++ b/app/Model/ProjectUserRoleModel.php @@ -166,7 +166,7 @@ class ProjectUserRoleModel extends Base ->join(UserModel::TABLE, 'id', 'user_id') ->eq(UserModel::TABLE.'.is_active', 1) ->eq(self::TABLE.'.project_id', $project_id) - ->in(self::TABLE.'.role', array(Role::PROJECT_MANAGER, Role::PROJECT_MEMBER)) + ->neq(self::TABLE.'.role', Role::PROJECT_VIEWER) ->findAll(); $groupMembers = $this->projectGroupRoleModel->getAssignableUsers($project_id); diff --git a/app/Model/TaskFinderModel.php b/app/Model/TaskFinderModel.php index 3c32e140..3185afb7 100644 --- a/app/Model/TaskFinderModel.php +++ b/app/Model/TaskFinderModel.php @@ -67,6 +67,7 @@ class TaskFinderModel extends Base TaskModel::TABLE.'.date_due', TaskModel::TABLE.'.date_creation', TaskModel::TABLE.'.project_id', + TaskModel::TABLE.'.column_id', TaskModel::TABLE.'.color_id', TaskModel::TABLE.'.priority', TaskModel::TABLE.'.time_spent', |