diff options
Diffstat (limited to 'app')
-rw-r--r-- | app/Api/Action.php | 2 | ||||
-rw-r--r-- | app/Api/App.php | 2 | ||||
-rw-r--r-- | app/Api/Auth.php | 40 | ||||
-rw-r--r-- | app/Api/Base.php | 104 | ||||
-rw-r--r-- | app/Api/Board.php | 1 | ||||
-rw-r--r-- | app/Api/Category.php | 2 | ||||
-rw-r--r-- | app/Api/Comment.php | 2 | ||||
-rw-r--r-- | app/Api/File.php | 2 | ||||
-rw-r--r-- | app/Api/Link.php | 2 | ||||
-rw-r--r-- | app/Api/Me.php | 55 | ||||
-rw-r--r-- | app/Api/Project.php | 25 | ||||
-rw-r--r-- | app/Api/ProjectPermission.php | 2 | ||||
-rw-r--r-- | app/Api/Subtask.php | 2 | ||||
-rw-r--r-- | app/Api/Swimlane.php | 2 | ||||
-rw-r--r-- | app/Api/Task.php | 30 | ||||
-rw-r--r-- | app/Api/TaskLink.php | 2 | ||||
-rw-r--r-- | app/Api/User.php | 2 |
17 files changed, 208 insertions, 69 deletions
diff --git a/app/Api/Action.php b/app/Api/Action.php index 6187b776..a67e915c 100644 --- a/app/Api/Action.php +++ b/app/Api/Action.php @@ -8,7 +8,7 @@ namespace Api; * @package api * @author Frederic Guillot */ -class Action extends Base +class Action extends \Core\Base { public function getAvailableActions() { diff --git a/app/Api/App.php b/app/Api/App.php index 2fc32e91..24da4dd9 100644 --- a/app/Api/App.php +++ b/app/Api/App.php @@ -8,7 +8,7 @@ namespace Api; * @package api * @author Frederic Guillot */ -class App extends Base +class App extends \Core\Base { public function getTimezone() { diff --git a/app/Api/Auth.php b/app/Api/Auth.php new file mode 100644 index 00000000..9d401746 --- /dev/null +++ b/app/Api/Auth.php @@ -0,0 +1,40 @@ +<?php + +namespace Api; + +use JsonRPC\AuthenticationFailure; +use Symfony\Component\EventDispatcher\Event; + +/** + * Base class + * + * @package api + * @author Frederic Guillot + */ +class Auth extends Base +{ + /** + * Check api credentials + * + * @access public + * @param string $username + * @param string $password + * @param string $class + * @param string $method + */ + public function checkCredentials($username, $password, $class, $method) + { + $this->container['dispatcher']->dispatch('api.bootstrap', new Event); + + if ($username !== 'jsonrpc' && $this->authentication->authenticate($username, $password)) { + $this->checkProcedurePermission(true, $method); + $this->userSession->refresh($this->user->getByUsername($username)); + } + else if ($username === 'jsonrpc' && $password === $this->config->get('api_token')) { + $this->checkProcedurePermission(false, $method); + } + else { + throw new AuthenticationFailure('Wrong credentials'); + } + } +} diff --git a/app/Api/Base.php b/app/Api/Base.php index 445b35be..723b60b7 100644 --- a/app/Api/Base.php +++ b/app/Api/Base.php @@ -3,7 +3,7 @@ namespace Api; use JsonRPC\AuthenticationFailure; -use Symfony\Component\EventDispatcher\Event; +use JsonRPC\AccessDeniedException; /** * Base class @@ -13,21 +13,97 @@ use Symfony\Component\EventDispatcher\Event; */ abstract class Base extends \Core\Base { - /** - * Check api credentials - * - * @access public - * @param string $username - * @param string $password - * @param string $class - * @param string $method - */ - public function authentication($username, $password, $class, $method) + private $user_allowed_procedures = array( + 'getMe', + 'getMyDashboard', + 'getMyActivityStream', + 'createMyPrivateProject', + 'getMyProjectsList', + ); + + private $both_allowed_procedures = array( + 'getTimezone', + 'getVersion', + 'getProjectById', + 'getTask', + 'getTaskByReference', + 'getAllTasks', + 'openTask', + 'closeTask', + 'moveTaskPosition', + 'createTask', + 'updateTask', + 'getBoard', + ); + + 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'); + } + else if (! $is_user && ! $is_both_procedure && $is_user_procedure) { + throw new AccessDeniedException('Permission denied'); + } + } + + public function checkProjectPermission($project_id) { - $this->container['dispatcher']->dispatch('api.bootstrap', new Event); + if ($this->userSession->isLogged() && ! $this->projectPermission->isUserAllowed($project_id, $this->userSession->getId())) { + throw new AccessDeniedException('Permission denied'); + } + } + + public function checkTaskPermission($task_id) + { + if ($this->userSession->isLogged()) { + $this->checkProjectPermission($this->taskFinder->getProjectId($task_id)); + } + } - if (! ($username === 'jsonrpc' && $password === $this->config->get('api_token'))) { - throw new AuthenticationFailure('Wrong credentials'); + protected function formatTask($task) + { + if (! empty($task)) { + $task['url'] = $this->helper->url->to('task', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id']), '', true); } + + return $task; + } + + protected function formatTasks($tasks) + { + if (! empty($tasks)) { + foreach ($tasks as &$task) { + $task = $this->formatTask($task); + } + } + + return $tasks; + } + + protected function formatProject($project) + { + if (! empty($project)) { + $project['url'] = array( + 'board' => $this->helper->url->to('board', 'show', array('project_id' => $project['id']), '', true), + 'calendar' => $this->helper->url->to('calendar', 'show', array('project_id' => $project['id']), '', true), + 'list' => $this->helper->url->to('listing', 'show', array('project_id' => $project['id']), '', true), + ); + } + + return $project; + } + + protected function formatProjects($projects) + { + if (! empty($projects)) { + foreach ($projects as &$project) { + $project = $this->formatProject($project); + } + } + + return $projects; } } diff --git a/app/Api/Board.php b/app/Api/Board.php index 163131b6..93b99cce 100644 --- a/app/Api/Board.php +++ b/app/Api/Board.php @@ -12,6 +12,7 @@ class Board extends Base { public function getBoard($project_id) { + $this->checkProjectPermission($project_id); return $this->board->getBoard($project_id); } diff --git a/app/Api/Category.php b/app/Api/Category.php index f457ddf1..ad3c5ef9 100644 --- a/app/Api/Category.php +++ b/app/Api/Category.php @@ -8,7 +8,7 @@ namespace Api; * @package api * @author Frederic Guillot */ -class Category extends Base +class Category extends \Core\Base { public function getCategory($category_id) { diff --git a/app/Api/Comment.php b/app/Api/Comment.php index 19b84383..e40968b9 100644 --- a/app/Api/Comment.php +++ b/app/Api/Comment.php @@ -8,7 +8,7 @@ namespace Api; * @package api * @author Frederic Guillot */ -class Comment extends Base +class Comment extends \Core\Base { public function getComment($comment_id) { diff --git a/app/Api/File.php b/app/Api/File.php index 5b82179c..97aa9d82 100644 --- a/app/Api/File.php +++ b/app/Api/File.php @@ -8,7 +8,7 @@ namespace Api; * @package api * @author Frederic Guillot */ -class File extends Base +class File extends \Core\Base { public function getFile($file_id) { diff --git a/app/Api/Link.php b/app/Api/Link.php index b9084784..d883013d 100644 --- a/app/Api/Link.php +++ b/app/Api/Link.php @@ -8,7 +8,7 @@ namespace Api; * @package api * @author Frederic Guillot */ -class Link extends Base +class Link extends \Core\Base { /** * Get a link by id diff --git a/app/Api/Me.php b/app/Api/Me.php new file mode 100644 index 00000000..29a8052a --- /dev/null +++ b/app/Api/Me.php @@ -0,0 +1,55 @@ +<?php + +namespace Api; + +use Model\Subtask as SubtaskModel; +use Model\Task as TaskModel; + +/** + * Me API controller + * + * @package api + * @author Frederic Guillot + */ +class Me extends Base +{ + public function getMe() + { + return $this->session['user']; + } + + public function getMyDashboard() + { + $user_id = $this->userSession->getId(); + $projects = $this->project->getQueryColumnStats($this->projectPermission->getActiveMemberProjectIds($user_id))->findAll(); + $tasks = $this->taskFinder->getUserQuery($user_id)->findAll(); + + return array( + 'projects' => $this->formatProjects($projects), + 'tasks' => $this->formatTasks($tasks), + 'subtasks' => $this->subtask->getUserQuery($user_id, array(SubTaskModel::STATUS_TODO, SubtaskModel::STATUS_INPROGRESS))->findAll(), + ); + } + + public function getMyActivityStream() + { + return $this->projectActivity->getProjects($this->projectPermission->getActiveMemberProjectIds($this->userSession->getId()), 100); + } + + public function createMyPrivateProject($name, $description = null) + { + $values = array( + 'name' => $name, + 'description' => $description, + 'is_private' => 1, + ); + + list($valid,) = $this->project->validateCreation($values); + return $valid ? $this->project->create($values, $this->userSession->getId(), true) : false; + } + + public function getMyProjectsList() + { + return $this->projectPermission->getMemberProjects($this->userSession->getId()); + } +} diff --git a/app/Api/Project.php b/app/Api/Project.php index 4e4e10b8..c3ae503c 100644 --- a/app/Api/Project.php +++ b/app/Api/Project.php @@ -12,6 +12,7 @@ class Project extends Base { public function getProjectById($project_id) { + $this->checkProjectPermission($project_id); return $this->formatProject($this->project->getById($project_id)); } @@ -82,28 +83,4 @@ class Project extends Base list($valid,) = $this->project->validateModification($values); return $valid && $this->project->update($values); } - - private function formatProject($project) - { - if (! empty($project)) { - $project['url'] = array( - 'board' => $this->helper->url->to('board', 'show', array('project_id' => $project['id']), '', true), - 'calendar' => $this->helper->url->to('calendar', 'show', array('project_id' => $project['id']), '', true), - 'list' => $this->helper->url->to('listing', 'show', array('project_id' => $project['id']), '', true), - ); - } - - return $project; - } - - private function formatProjects($projects) - { - if (! empty($projects)) { - foreach ($projects as &$project) { - $project = $this->formatProject($project); - } - } - - return $projects; - } } diff --git a/app/Api/ProjectPermission.php b/app/Api/ProjectPermission.php index a31faf3d..7dd2dec6 100644 --- a/app/Api/ProjectPermission.php +++ b/app/Api/ProjectPermission.php @@ -8,7 +8,7 @@ namespace Api; * @package api * @author Frederic Guillot */ -class ProjectPermission extends Base +class ProjectPermission extends \Core\Base { public function getMembers($project_id) { diff --git a/app/Api/Subtask.php b/app/Api/Subtask.php index 2e6c30f2..2b8e7a1f 100644 --- a/app/Api/Subtask.php +++ b/app/Api/Subtask.php @@ -8,7 +8,7 @@ namespace Api; * @package api * @author Frederic Guillot */ -class Subtask extends Base +class Subtask extends \Core\Base { public function getSubtask($subtask_id) { diff --git a/app/Api/Swimlane.php b/app/Api/Swimlane.php index 322b0805..fb40841f 100644 --- a/app/Api/Swimlane.php +++ b/app/Api/Swimlane.php @@ -8,7 +8,7 @@ namespace Api; * @package api * @author Frederic Guillot */ -class Swimlane extends Base +class Swimlane extends \Core\Base { public function getActiveSwimlanes($project_id) { diff --git a/app/Api/Task.php b/app/Api/Task.php index 3b8c1ec8..946a9e88 100644 --- a/app/Api/Task.php +++ b/app/Api/Task.php @@ -14,16 +14,19 @@ class Task extends Base { public function getTask($task_id) { + $this->checkTaskPermission($task_id); return $this->formatTask($this->taskFinder->getById($task_id)); } public function getTaskByReference($project_id, $reference) { + $this->checkProjectPermission($project_id); return $this->formatTask($this->taskFinder->getByReference($project_id, $reference)); } public function getAllTasks($project_id, $status_id = TaskModel::STATUS_OPEN) { + $this->checkProjectPermission($project_id); return $this->formatTasks($this->taskFinder->getAll($project_id, $status_id)); } @@ -34,11 +37,13 @@ class Task extends Base public function openTask($task_id) { + $this->checkTaskPermission($task_id); return $this->taskStatus->open($task_id); } public function closeTask($task_id) { + $this->checkTaskPermission($task_id); return $this->taskStatus->close($task_id); } @@ -49,6 +54,7 @@ class Task extends Base public function moveTaskPosition($project_id, $task_id, $column_id, $position, $swimlane_id = 0) { + $this->checkProjectPermission($project_id); return $this->taskPosition->movePosition($project_id, $task_id, $column_id, $position, $swimlane_id); } @@ -57,6 +63,8 @@ class Task extends Base $recurrence_status = 0, $recurrence_trigger = 0, $recurrence_factor = 0, $recurrence_timeframe = 0, $recurrence_basedate = 0, $reference = '') { + $this->checkProjectPermission($project_id); + $values = array( 'title' => $title, 'project_id' => $project_id, @@ -87,6 +95,8 @@ class Task extends Base $recurrence_status = null, $recurrence_trigger = null, $recurrence_factor = null, $recurrence_timeframe = null, $recurrence_basedate = null, $reference = null) { + $this->checkTaskPermission($id); + $values = array( 'id' => $id, 'title' => $title, @@ -115,24 +125,4 @@ class Task extends Base list($valid) = $this->taskValidator->validateApiModification($values); return $valid && $this->taskModification->update($values); } - - private function formatTask($task) - { - if (! empty($task)) { - $task['url'] = $this->helper->url->to('task', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id']), '', true); - } - - return $task; - } - - private function formatTasks($tasks) - { - if (! empty($tasks)) { - foreach ($tasks as &$task) { - $task = $this->formatTask($task); - } - } - - return $tasks; - } } diff --git a/app/Api/TaskLink.php b/app/Api/TaskLink.php index c3e1a83c..6b23d051 100644 --- a/app/Api/TaskLink.php +++ b/app/Api/TaskLink.php @@ -8,7 +8,7 @@ namespace Api; * @package api * @author Frederic Guillot */ -class TaskLink extends Base +class TaskLink extends \Core\Base { /** * Get a task link diff --git a/app/Api/User.php b/app/Api/User.php index 0f0f4e59..7409a41b 100644 --- a/app/Api/User.php +++ b/app/Api/User.php @@ -10,7 +10,7 @@ use Auth\Ldap; * @package api * @author Frederic Guillot */ -class User extends Base +class User extends \Core\Base { public function getUser($user_id) { |