summaryrefslogtreecommitdiff
path: root/app/Controller
diff options
context:
space:
mode:
authorNala Ginrut <nalaginrut@gmail.com>2014-06-19 15:18:13 +0800
committerNala Ginrut <nalaginrut@gmail.com>2014-06-19 15:18:13 +0800
commitbfd1db41367f7931016931a94cf1b67396481c79 (patch)
tree2d696f2d8eca9ed2e4561c61c16584952d9f7b0b /app/Controller
parentd0944e682d5a3491f72c5b566248b87fbaff032a (diff)
parentefdc959c555872677e599d2ff12e1263d719f3f2 (diff)
Merge remote-tracking branch 'upstream/master'
Diffstat (limited to 'app/Controller')
-rw-r--r--app/Controller/Action.php1
-rw-r--r--app/Controller/Base.php26
-rw-r--r--app/Controller/Board.php76
-rw-r--r--app/Controller/Category.php1
-rw-r--r--app/Controller/Comment.php1
-rw-r--r--app/Controller/Config.php4
-rw-r--r--app/Controller/File.php12
-rw-r--r--app/Controller/Project.php18
-rw-r--r--app/Controller/Subtask.php186
-rw-r--r--app/Controller/Task.php4
-rw-r--r--app/Controller/User.php20
11 files changed, 289 insertions, 60 deletions
diff --git a/app/Controller/Action.php b/app/Controller/Action.php
index 2aa85c14..11dc3b29 100644
--- a/app/Controller/Action.php
+++ b/app/Controller/Action.php
@@ -129,6 +129,7 @@ class Action extends Base
*/
public function remove()
{
+ $this->checkCSRFParam();
$action = $this->action->getById($this->request->getIntegerParam('action_id'));
if ($action && $this->action->remove($action['id'])) {
diff --git a/app/Controller/Base.php b/app/Controller/Base.php
index b21d9b8f..9b695a82 100644
--- a/app/Controller/Base.php
+++ b/app/Controller/Base.php
@@ -3,6 +3,7 @@
namespace Controller;
use Core\Registry;
+use Core\Security;
use Core\Translator;
use Model\LastLogin;
@@ -23,6 +24,7 @@ use Model\LastLogin;
* @property \Model\Ldap $ldap
* @property \Model\Project $project
* @property \Model\RememberMe $rememberMe
+ * @property \Model\SubTask $subTask
* @property \Model\Task $task
* @property \Model\User $user
*/
@@ -160,6 +162,28 @@ abstract class Base
}
/**
+ * Application forbidden page
+ *
+ * @access public
+ */
+ public function forbidden()
+ {
+ $this->response->html($this->template->layout('app_forbidden', array('title' => t('Access Forbidden'))));
+ }
+
+ /**
+ * Check if the CSRF token from the URL is correct
+ *
+ * @access protected
+ */
+ protected function checkCSRFParam()
+ {
+ if (! Security::validateCSRFToken($this->request->getStringParam('csrf_token'))) {
+ $this->forbidden();
+ }
+ }
+
+ /**
* Check if the current user have access to the given project
*
* @access protected
@@ -170,7 +194,7 @@ abstract class Base
if ($this->acl->isRegularUser()) {
if ($project_id > 0 && ! $this->project->isUserAllowed($project_id, $this->acl->getUserId())) {
- $this->response->redirect('?controller=project&action=forbidden');
+ $this->forbidden();
}
}
}
diff --git a/app/Controller/Board.php b/app/Controller/Board.php
index 53fdeab9..67072895 100644
--- a/app/Controller/Board.php
+++ b/app/Controller/Board.php
@@ -4,6 +4,7 @@ namespace Controller;
use Model\Project as ProjectModel;
use Model\User as UserModel;
+use Core\Security;
/**
* Board controller
@@ -20,6 +21,7 @@ class Board extends Base
*/
public function moveUp()
{
+ $this->checkCSRFParam();
$project_id = $this->request->getIntegerParam('project_id');
$column_id = $this->request->getIntegerParam('column_id');
@@ -35,6 +37,7 @@ class Board extends Base
*/
public function moveDown()
{
+ $this->checkCSRFParam();
$project_id = $this->request->getIntegerParam('project_id');
$column_id = $this->request->getIntegerParam('column_id');
@@ -344,6 +347,7 @@ class Board extends Base
*/
public function remove()
{
+ $this->checkCSRFParam();
$column = $this->board->getColumn($this->request->getIntegerParam('column_id'));
if ($column && $this->board->removeColumn($column['id'])) {
@@ -362,25 +366,31 @@ class Board extends Base
*/
public function save()
{
- $project_id = $this->request->getIntegerParam('project_id');
- $values = $this->request->getValues();
+ if ($this->request->isAjax()) {
- if ($project_id > 0 && ! $this->project->isUserAllowed($project_id, $this->acl->getUserId())) {
- $this->response->text('Not Authorized', 401);
- }
+ $project_id = $this->request->getIntegerParam('project_id');
+ $values = $this->request->getValues();
- if (isset($values['positions'])) {
- $this->board->saveTasksPosition($values['positions']);
- }
+ if ($project_id > 0 && ! $this->project->isUserAllowed($project_id, $this->acl->getUserId())) {
+ $this->response->text('Not Authorized', 401);
+ }
+
+ if (isset($values['positions'])) {
+ $this->board->saveTasksPosition($values['positions']);
+ }
- $this->response->html(
- $this->template->load('board_show', array(
- 'current_project_id' => $project_id,
- 'board' => $this->board->get($project_id),
- 'categories' => $this->category->getList($project_id, false),
- )),
- 201
- );
+ $this->response->html(
+ $this->template->load('board_show', array(
+ 'current_project_id' => $project_id,
+ 'board' => $this->board->get($project_id),
+ 'categories' => $this->category->getList($project_id, false),
+ )),
+ 201
+ );
+ }
+ else {
+ $this->response->status(401);
+ }
}
/**
@@ -390,24 +400,30 @@ class Board extends Base
*/
public function check()
{
- $project_id = $this->request->getIntegerParam('project_id');
- $timestamp = $this->request->getIntegerParam('timestamp');
+ if ($this->request->isAjax()) {
- if ($project_id > 0 && ! $this->project->isUserAllowed($project_id, $this->acl->getUserId())) {
- $this->response->text('Not Authorized', 401);
- }
+ $project_id = $this->request->getIntegerParam('project_id');
+ $timestamp = $this->request->getIntegerParam('timestamp');
- if ($this->project->isModifiedSince($project_id, $timestamp)) {
- $this->response->html(
- $this->template->load('board_show', array(
- 'current_project_id' => $project_id,
- 'board' => $this->board->get($project_id),
- 'categories' => $this->category->getList($project_id, false),
- ))
- );
+ if ($project_id > 0 && ! $this->project->isUserAllowed($project_id, $this->acl->getUserId())) {
+ $this->response->text('Not Authorized', 401);
+ }
+
+ if ($this->project->isModifiedSince($project_id, $timestamp)) {
+ $this->response->html(
+ $this->template->load('board_show', array(
+ 'current_project_id' => $project_id,
+ 'board' => $this->board->get($project_id),
+ 'categories' => $this->category->getList($project_id, false),
+ ))
+ );
+ }
+ else {
+ $this->response->status(304);
+ }
}
else {
- $this->response->status(304);
+ $this->response->status(401);
}
}
}
diff --git a/app/Controller/Category.php b/app/Controller/Category.php
index f96c1d4a..9b73f207 100644
--- a/app/Controller/Category.php
+++ b/app/Controller/Category.php
@@ -175,6 +175,7 @@ class Category extends Base
*/
public function remove()
{
+ $this->checkCSRFParam();
$project = $this->getProject();
$category = $this->getCategory($project['id']);
diff --git a/app/Controller/Comment.php b/app/Controller/Comment.php
index 47eaf6b6..a0a11fc8 100644
--- a/app/Controller/Comment.php
+++ b/app/Controller/Comment.php
@@ -178,6 +178,7 @@ class Comment extends Base
*/
public function remove()
{
+ $this->checkCSRFParam();
$task = $this->getTask();
$comment = $this->getComment();
diff --git a/app/Controller/Config.php b/app/Controller/Config.php
index b4a5b8d3..daa57790 100644
--- a/app/Controller/Config.php
+++ b/app/Controller/Config.php
@@ -76,6 +76,7 @@ class Config extends Base
*/
public function downloadDb()
{
+ $this->checkCSRFParam();
$this->response->forceDownload('db.sqlite.gz');
$this->response->binary($this->config->downloadDatabase());
}
@@ -87,6 +88,7 @@ class Config extends Base
*/
public function optimizeDb()
{
+ $this->checkCSRFParam();
$this->config->optimizeDatabase();
$this->session->flash(t('Database optimization done.'));
$this->response->redirect('?controller=config');
@@ -99,6 +101,7 @@ class Config extends Base
*/
public function tokens()
{
+ $this->checkCSRFParam();
$this->config->regenerateTokens();
$this->session->flash(t('All tokens have been regenerated.'));
$this->response->redirect('?controller=config');
@@ -111,6 +114,7 @@ class Config extends Base
*/
public function removeRememberMeToken()
{
+ $this->checkCSRFParam();
$this->rememberMe->remove($this->request->getIntegerParam('id'));
$this->response->redirect('?controller=config&action=index#remember-me');
}
diff --git a/app/Controller/File.php b/app/Controller/File.php
index 1604ab13..3c8c32d1 100644
--- a/app/Controller/File.php
+++ b/app/Controller/File.php
@@ -24,6 +24,7 @@ class File extends Base
$this->response->html($this->taskLayout('file_new', array(
'task' => $task,
'menu' => 'tasks',
+ 'max_size' => ini_get('upload_max_filesize'),
'title' => t('Attach a document')
)));
}
@@ -36,8 +37,14 @@ class File extends Base
public function save()
{
$task = $this->getTask();
- $this->file->upload($task['project_id'], $task['id'], 'files');
- $this->response->redirect('?controller=task&action=show&task_id='.$task['id'].'#attachments');
+
+ if ($this->file->upload($task['project_id'], $task['id'], 'files') === true) {
+ $this->response->redirect('?controller=task&action=show&task_id='.$task['id'].'#attachments');
+ }
+ else {
+ $this->session->flashError(t('Unable to upload the file.'));
+ $this->response->redirect('?controller=file&action=create&task_id='.$task['id']);
+ }
}
/**
@@ -104,6 +111,7 @@ class File extends Base
*/
public function remove()
{
+ $this->checkCSRFParam();
$task = $this->getTask();
$file = $this->file->getById($this->request->getIntegerParam('file_id'));
diff --git a/app/Controller/Project.php b/app/Controller/Project.php
index e539f364..0de67691 100644
--- a/app/Controller/Project.php
+++ b/app/Controller/Project.php
@@ -13,19 +13,6 @@ use Model\Task as TaskModel;
class Project extends Base
{
/**
- * Display access forbidden page
- *
- * @access public
- */
- public function forbidden()
- {
- $this->response->html($this->template->layout('project_forbidden', array(
- 'menu' => 'projects',
- 'title' => t('Access Forbidden')
- )));
- }
-
- /**
* Task search for a given project
*
* @access public
@@ -254,6 +241,7 @@ class Project extends Base
*/
public function remove()
{
+ $this->checkCSRFParam();
$project_id = $this->request->getIntegerParam('project_id');
if ($project_id && $this->project->remove($project_id)) {
@@ -272,6 +260,7 @@ class Project extends Base
*/
public function enable()
{
+ $this->checkCSRFParam();
$project_id = $this->request->getIntegerParam('project_id');
if ($project_id && $this->project->enable($project_id)) {
@@ -290,6 +279,7 @@ class Project extends Base
*/
public function disable()
{
+ $this->checkCSRFParam();
$project_id = $this->request->getIntegerParam('project_id');
if ($project_id && $this->project->disable($project_id)) {
@@ -353,6 +343,8 @@ class Project extends Base
*/
public function revoke()
{
+ $this->checkCSRFParam();
+
$values = array(
'project_id' => $this->request->getIntegerParam('project_id'),
'user_id' => $this->request->getIntegerParam('user_id'),
diff --git a/app/Controller/Subtask.php b/app/Controller/Subtask.php
new file mode 100644
index 00000000..1c217fa2
--- /dev/null
+++ b/app/Controller/Subtask.php
@@ -0,0 +1,186 @@
+<?php
+
+namespace Controller;
+
+/**
+ * SubTask controller
+ *
+ * @package controller
+ * @author Frederic Guillot
+ */
+class Subtask extends Base
+{
+ /**
+ * Get the current subtask
+ *
+ * @access private
+ * @return array
+ */
+ private function getSubtask()
+ {
+ $subtask = $this->subTask->getById($this->request->getIntegerParam('subtask_id'));
+
+ if (! $subtask) {
+ $this->notfound();
+ }
+
+ return $subtask;
+ }
+
+ /**
+ * Creation form
+ *
+ * @access public
+ */
+ public function create()
+ {
+ $task = $this->getTask();
+
+ $this->response->html($this->taskLayout('subtask_create', array(
+ 'values' => array(
+ 'task_id' => $task['id'],
+ ),
+ 'errors' => array(),
+ 'users_list' => $this->project->getUsersList($task['project_id']),
+ 'task' => $task,
+ 'menu' => 'tasks',
+ 'title' => t('Add a sub-task')
+ )));
+ }
+
+ /**
+ * Validation and creation
+ *
+ * @access public
+ */
+ public function save()
+ {
+ $task = $this->getTask();
+ $values = $this->request->getValues();
+
+ list($valid, $errors) = $this->subTask->validate($values);
+
+ if ($valid) {
+
+ if ($this->subTask->create($values)) {
+ $this->session->flash(t('Sub-task added successfully.'));
+ }
+ else {
+ $this->session->flashError(t('Unable to create your sub-task.'));
+ }
+
+ if (isset($values['another_subtask']) && $values['another_subtask'] == 1) {
+ $this->response->redirect('?controller=subtask&action=create&task_id='.$task['id']);
+ }
+
+ $this->response->redirect('?controller=task&action=show&task_id='.$task['id'].'#subtasks');
+ }
+
+ $this->response->html($this->taskLayout('subtask_create', array(
+ 'values' => $values,
+ 'errors' => $errors,
+ 'users_list' => $this->project->getUsersList($task['project_id']),
+ 'task' => $task,
+ 'menu' => 'tasks',
+ 'title' => t('Add a sub-task')
+ )));
+ }
+
+ /**
+ * Edit form
+ *
+ * @access public
+ */
+ public function edit()
+ {
+ $task = $this->getTask();
+ $subtask = $this->getSubTask();
+
+ $this->response->html($this->taskLayout('subtask_edit', array(
+ 'values' => $subtask,
+ 'errors' => array(),
+ 'users_list' => $this->project->getUsersList($task['project_id']),
+ 'status_list' => $this->subTask->getStatusList(),
+ 'subtask' => $subtask,
+ 'task' => $task,
+ 'menu' => 'tasks',
+ 'title' => t('Edit a sub-task')
+ )));
+ }
+
+ /**
+ * Update and validate a subtask
+ *
+ * @access public
+ */
+ public function update()
+ {
+ $task = $this->getTask();
+ $subtask = $this->getSubtask();
+
+ $values = $this->request->getValues();
+ list($valid, $errors) = $this->subTask->validate($values);
+
+ if ($valid) {
+
+ if ($this->subTask->update($values)) {
+ $this->session->flash(t('Sub-task updated successfully.'));
+ }
+ else {
+ $this->session->flashError(t('Unable to update your sub-task.'));
+ }
+
+ $this->response->redirect('?controller=task&action=show&task_id='.$task['id'].'#subtasks');
+ }
+
+ $this->response->html($this->taskLayout('subtask_edit', array(
+ 'values' => $values,
+ 'errors' => $errors,
+ 'users_list' => $this->project->getUsersList($task['project_id']),
+ 'status_list' => $this->subTask->getStatusList(),
+ 'subtask' => $subtask,
+ 'task' => $task,
+ 'menu' => 'tasks',
+ 'title' => t('Edit a sub-task')
+ )));
+ }
+
+ /**
+ * Confirmation dialog before removing a subtask
+ *
+ * @access public
+ */
+ public function confirm()
+ {
+ $task = $this->getTask();
+ $subtask = $this->getSubtask();
+
+ $this->response->html($this->taskLayout('subtask_remove', array(
+ 'subtask' => $subtask,
+ 'task' => $task,
+ 'menu' => 'tasks',
+ 'title' => t('Remove a sub-task')
+ )));
+ }
+
+ /**
+ * Remove a subtask
+ *
+ * @access public
+ */
+ public function remove()
+ {
+ $this->checkCSRFParam();
+ $task = $this->getTask();
+ $subtask = $this->getSubtask();
+
+ if ($this->subTask->remove($subtask['id'])) {
+ $this->session->flash(t('Sub-task removed successfully.'));
+ }
+ else {
+ $this->session->flashError(t('Unable to remove this sub-task.'));
+ }
+
+ $this->response->redirect('?controller=task&action=show&task_id='.$task['id'].'#subtasks');
+ }
+}
diff --git a/app/Controller/Task.php b/app/Controller/Task.php
index 8230eef3..d44ba268 100644
--- a/app/Controller/Task.php
+++ b/app/Controller/Task.php
@@ -62,6 +62,7 @@ class Task extends Base
$this->response->html($this->taskLayout('task_show', array(
'files' => $this->file->getAll($task['id']),
'comments' => $this->comment->getAll($task['id']),
+ 'subtasks' => $this->subTask->getAll($task['id']),
'task' => $task,
'columns_list' => $this->board->getColumnsList($task['project_id']),
'colors_list' => $this->task->getColors(),
@@ -217,6 +218,7 @@ class Task extends Base
*/
public function close()
{
+ $this->checkCSRFParam();
$task = $this->getTask();
if ($this->task->close($task['id'])) {
@@ -251,6 +253,7 @@ class Task extends Base
*/
public function open()
{
+ $this->checkCSRFParam();
$task = $this->getTask();
if ($this->task->open($task['id'])) {
@@ -285,6 +288,7 @@ class Task extends Base
*/
public function remove()
{
+ $this->checkCSRFParam();
$task = $this->getTask();
if ($this->task->remove($task['id'])) {
diff --git a/app/Controller/User.php b/app/Controller/User.php
index e3fd8253..fca33b28 100644
--- a/app/Controller/User.php
+++ b/app/Controller/User.php
@@ -11,25 +11,13 @@ namespace Controller;
class User extends Base
{
/**
- * Display access forbidden page
- *
- * @access public
- */
- public function forbidden()
- {
- $this->response->html($this->template->layout('user_forbidden', array(
- 'menu' => 'users',
- 'title' => t('Access Forbidden')
- )));
- }
-
- /**
* Logout and destroy session
*
* @access public
*/
public function logout()
{
+ $this->checkCSRFParam();
$this->rememberMe->destroy($this->acl->getUserId());
$this->session->close();
$this->response->redirect('?controller=user&action=login');
@@ -42,7 +30,9 @@ class User extends Base
*/
public function login()
{
- if (isset($_SESSION['user'])) $this->response->redirect('?controller=app');
+ if (isset($_SESSION['user'])) {
+ $this->response->redirect('?controller=app');
+ }
$this->response->html($this->template->layout('user_login', array(
'errors' => array(),
@@ -236,6 +226,7 @@ class User extends Base
*/
public function remove()
{
+ $this->checkCSRFParam();
$user_id = $this->request->getIntegerParam('user_id');
if ($user_id && $this->user->remove($user_id)) {
@@ -298,6 +289,7 @@ class User extends Base
*/
public function unlinkGoogle()
{
+ $this->checkCSRFParam();
if ($this->google->unlink($this->acl->getUserId())) {
$this->session->flash(t('Your Google Account is not linked anymore to your profile.'));
}