summaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
authorFrederic Guillot <fred@kanboard.net>2015-07-29 17:42:48 -0400
committerFrederic Guillot <fred@kanboard.net>2015-07-29 17:42:48 -0400
commitf595fb2786d884dbaf7ec87d53cee920a0655f0e (patch)
tree0da808ef2f679affa51eff80e172787098c13731 /app
parent2eeb58ae0321f584652714080649302c3f83a831 (diff)
Add first draft of the user api
Diffstat (limited to 'app')
-rw-r--r--app/Api/Action.php2
-rw-r--r--app/Api/App.php2
-rw-r--r--app/Api/Auth.php40
-rw-r--r--app/Api/Base.php104
-rw-r--r--app/Api/Board.php1
-rw-r--r--app/Api/Category.php2
-rw-r--r--app/Api/Comment.php2
-rw-r--r--app/Api/File.php2
-rw-r--r--app/Api/Link.php2
-rw-r--r--app/Api/Me.php55
-rw-r--r--app/Api/Project.php25
-rw-r--r--app/Api/ProjectPermission.php2
-rw-r--r--app/Api/Subtask.php2
-rw-r--r--app/Api/Swimlane.php2
-rw-r--r--app/Api/Task.php30
-rw-r--r--app/Api/TaskLink.php2
-rw-r--r--app/Api/User.php2
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)
{