Acl refactoring

This commit is contained in:
Frédéric Guillot
2014-12-31 12:37:15 -05:00
parent 66f150d887
commit 772804add8
93 changed files with 943 additions and 626 deletions

View File

@@ -11,7 +11,7 @@ use Pimple\Container;
* @package action * @package action
* @author Frederic Guillot * @author Frederic Guillot
* *
* @property \Model\Acl $acl * @property \Model\UserSession $userSession
* @property \Model\Comment $comment * @property \Model\Comment $comment
* @property \Model\Task $task * @property \Model\Task $task
* @property \Model\TaskCreation $taskCreation * @property \Model\TaskCreation $taskCreation

View File

@@ -62,13 +62,13 @@ class TaskAssignCurrentUser extends Base
*/ */
public function doAction(array $data) public function doAction(array $data)
{ {
if (! $this->acl->isLogged()) { if (! $this->userSession->isLogged()) {
return false; return false;
} }
$values = array( $values = array(
'id' => $data['task_id'], 'id' => $data['task_id'],
'owner_id' => $this->acl->getUserId(), 'owner_id' => $this->userSession->getId(),
); );
return $this->taskModification->update($values); return $this->taskModification->update($values);

View File

@@ -102,11 +102,10 @@ class RememberMe extends Base
// Create the session // Create the session
$this->user->updateSession($this->user->getById($record['user_id'])); $this->user->updateSession($this->user->getById($record['user_id']));
$this->acl->isRememberMe(true);
$this->container['dispatcher']->dispatch( $this->container['dispatcher']->dispatch(
'auth.success', 'auth.success',
new AuthEvent(self::AUTH_NAME, $this->acl->getUserId()) new AuthEvent(self::AUTH_NAME, $this->userSession->getId())
); );
return true; return true;

View File

@@ -17,7 +17,7 @@ class Action extends Base
*/ */
public function index() public function index()
{ {
$project = $this->getProjectManagement(); $project = $this->getProject();
$this->response->html($this->projectLayout('action/index', array( $this->response->html($this->projectLayout('action/index', array(
'values' => array('project_id' => $project['id']), 'values' => array('project_id' => $project['id']),
@@ -42,7 +42,7 @@ class Action extends Base
*/ */
public function event() public function event()
{ {
$project = $this->getProjectManagement(); $project = $this->getProject();
$values = $this->request->getValues(); $values = $this->request->getValues();
if (empty($values['action_name']) || empty($values['project_id'])) { if (empty($values['action_name']) || empty($values['project_id'])) {
@@ -64,7 +64,7 @@ class Action extends Base
*/ */
public function params() public function params()
{ {
$project = $this->getProjectManagement(); $project = $this->getProject();
$values = $this->request->getValues(); $values = $this->request->getValues();
if (empty($values['action_name']) || empty($values['project_id']) || empty($values['event_name'])) { if (empty($values['action_name']) || empty($values['project_id']) || empty($values['event_name'])) {
@@ -101,7 +101,7 @@ class Action extends Base
*/ */
public function create() public function create()
{ {
$this->doCreation($this->getProjectManagement(), $this->request->getValues()); $this->doCreation($this->getProject(), $this->request->getValues());
} }
/** /**
@@ -135,7 +135,7 @@ class Action extends Base
*/ */
public function confirm() public function confirm()
{ {
$project = $this->getProjectManagement(); $project = $this->getProject();
$this->response->html($this->projectLayout('action/remove', array( $this->response->html($this->projectLayout('action/remove', array(
'action' => $this->action->getById($this->request->getIntegerParam('action_id')), 'action' => $this->action->getById($this->request->getIntegerParam('action_id')),
@@ -154,7 +154,7 @@ class Action extends Base
public function remove() public function remove()
{ {
$this->checkCSRFParam(); $this->checkCSRFParam();
$project = $this->getProjectManagement(); $project = $this->getProject();
$action = $this->action->getById($this->request->getIntegerParam('action_id')); $action = $this->action->getById($this->request->getIntegerParam('action_id'));
if ($action && $this->action->remove($action['id'])) { if ($action && $this->action->remove($action['id'])) {

View File

@@ -20,7 +20,7 @@ class Analytic extends Base
*/ */
private function layout($template, array $params) private function layout($template, array $params)
{ {
$params['board_selector'] = $this->projectPermission->getAllowedProjects($this->acl->getUserId()); $params['board_selector'] = $this->projectPermission->getAllowedProjects($this->userSession->getId());
$params['analytic_content_for_layout'] = $this->template->render($template, $params); $params['analytic_content_for_layout'] = $this->template->render($template, $params);
return $this->template->layout('analytic/layout', $params); return $this->template->layout('analytic/layout', $params);

View File

@@ -34,7 +34,7 @@ class App extends Base
$direction = $this->request->getStringParam('direction'); $direction = $this->request->getStringParam('direction');
$order = $this->request->getStringParam('order'); $order = $this->request->getStringParam('order');
$user_id = $this->acl->getUserId(); $user_id = $this->userSession->getId();
$projects = $this->projectPermission->getMemberProjects($user_id); $projects = $this->projectPermission->getMemberProjects($user_id);
$project_ids = array_keys($projects); $project_ids = array_keys($projects);
@@ -191,8 +191,9 @@ class App extends Base
$this->response->html('<p>'.t('Nothing to preview...').'</p>'); $this->response->html('<p>'.t('Nothing to preview...').'</p>');
} }
else { else {
$this->response->html($this->template->markdown($payload['text'])); $this->response->html(
$this->template->markdown($payload['text'])
);
} }
} }
} }

View File

@@ -51,6 +51,7 @@ use Symfony\Component\EventDispatcher\Event;
* @property \Model\SubtaskHistory $subtaskHistory * @property \Model\SubtaskHistory $subtaskHistory
* @property \Model\TimeTracking $timeTracking * @property \Model\TimeTracking $timeTracking
* @property \Model\User $user * @property \Model\User $user
* @property \Model\UserSession $userSession
* @property \Model\Webhook $webhook * @property \Model\Webhook $webhook
*/ */
abstract class Base abstract class Base
@@ -117,16 +118,12 @@ abstract class Base
} }
/** /**
* Method executed before each action * Send HTTP headers
* *
* @access public * @access private
*/ */
public function beforeAction($controller, $action) private function sendHeaders($action)
{ {
// Start the session
$this->session->open(BASE_URL_DIRECTORY);
$this->container['dispatcher']->dispatch('session.bootstrap', new Event);
// HTTP secure headers // HTTP secure headers
$this->response->csp(array('style-src' => "'self' 'unsafe-inline'")); $this->response->csp(array('style-src' => "'self' 'unsafe-inline'"));
$this->response->nosniff(); $this->response->nosniff();
@@ -140,8 +137,32 @@ abstract class Base
if (ENABLE_HSTS) { if (ENABLE_HSTS) {
$this->response->hsts(); $this->response->hsts();
} }
}
// Authentication /**
* Method executed before each action
*
* @access public
*/
public function beforeAction($controller, $action)
{
// Start the session
$this->session->open(BASE_URL_DIRECTORY);
$this->sendHeaders($action);
$this->container['dispatcher']->dispatch('session.bootstrap', new Event);
if (! $this->acl->isPublicAction($controller, $action)) {
$this->handleAuthenticatedUser($controller, $action);
}
}
/**
* Check page access and authentication
*
* @access public
*/
public function handleAuthenticatedUser($controller, $action)
{
if (! $this->authentication->isAuthenticated($controller, $action)) { if (! $this->authentication->isAuthenticated($controller, $action)) {
if ($this->request->isAjax()) { if ($this->request->isAjax()) {
@@ -151,9 +172,8 @@ abstract class Base
$this->response->redirect('?controller=user&action=login&redirect_query='.urlencode($this->request->getQueryString())); $this->response->redirect('?controller=user&action=login&redirect_query='.urlencode($this->request->getQueryString()));
} }
// Check if the user is allowed to see this page if (! $this->acl->isAllowed($controller, $action, $this->request->getIntegerParam('project_id', 0))) {
if (! $this->acl->isPageAccessAllowed($controller, $action)) { $this->forbidden();
$this->response->redirect('?controller=user&action=forbidden');
} }
} }
@@ -197,33 +217,6 @@ abstract class Base
} }
} }
/**
* Check if the current user have access to the given project
*
* @access protected
* @param integer $project_id Project id
*/
protected function checkProjectPermissions($project_id)
{
if ($this->acl->isRegularUser() && ! $this->projectPermission->isUserAllowed($project_id, $this->acl->getUserId())) {
$this->forbidden();
}
}
/**
* Check if the current user is owner of the given project
*
* @access protected
* @param integer $project_id Project id
*/
protected function checkProjectOwnerPermissions($project_id)
{
if (! $this->acl->isAdminUser() &&
! ($this->acl->isRegularUser() && $this->projectPermission->isOwner($project_id, $this->acl->getUserId()))) {
$this->forbidden();
}
}
/** /**
* Redirection when there is no project in the database * Redirection when there is no project in the database
* *
@@ -252,7 +245,7 @@ abstract class Base
$content = $this->template->render($template, $params); $content = $this->template->render($template, $params);
$params['task_content_for_layout'] = $content; $params['task_content_for_layout'] = $content;
$params['title'] = $params['task']['project_name'].' &gt; '.$params['task']['title']; $params['title'] = $params['task']['project_name'].' &gt; '.$params['task']['title'];
$params['board_selector'] = $this->projectPermission->getAllowedProjects($this->acl->getUserId()); $params['board_selector'] = $this->projectPermission->getAllowedProjects($this->userSession->getId());
return $this->template->layout('task/layout', $params); return $this->template->layout('task/layout', $params);
} }
@@ -270,8 +263,7 @@ abstract class Base
$content = $this->template->render($template, $params); $content = $this->template->render($template, $params);
$params['project_content_for_layout'] = $content; $params['project_content_for_layout'] = $content;
$params['title'] = $params['project']['name'] === $params['title'] ? $params['title'] : $params['project']['name'].' &gt; '.$params['title']; $params['title'] = $params['project']['name'] === $params['title'] ? $params['title'] : $params['project']['name'].' &gt; '.$params['title'];
$params['board_selector'] = $this->projectPermission->getAllowedProjects($this->acl->getUserId()); $params['board_selector'] = $this->projectPermission->getAllowedProjects($this->userSession->getId());
$params['is_owner'] = $this->projectPermission->isOwner($params['project']['id'], $this->acl->getUserId());
return $this->template->layout('project/layout', $params); return $this->template->layout('project/layout', $params);
} }
@@ -286,12 +278,10 @@ abstract class Base
{ {
$task = $this->taskFinder->getDetails($this->request->getIntegerParam('task_id')); $task = $this->taskFinder->getDetails($this->request->getIntegerParam('task_id'));
if (! $task) { if (! $task || $task['project_id'] != $this->request->getIntegerParam('project_id')) {
$this->notfound(); $this->notfound();
} }
$this->checkProjectPermissions($task['project_id']);
return $task; return $task;
} }
@@ -312,29 +302,6 @@ abstract class Base
$this->response->redirect('?controller=project'); $this->response->redirect('?controller=project');
} }
$this->checkProjectPermissions($project['id']);
return $project;
}
/**
* Common method to get a project with administration rights
*
* @access protected
* @return array
*/
protected function getProjectManagement()
{
$project = $this->project->getById($this->request->getIntegerParam('project_id'));
if (! $project) {
$this->notfound();
}
if ($this->acl->isRegularUser() && ! $this->projectPermission->adminAllowed($project['id'], $this->acl->getUserId())) {
$this->forbidden();
}
return $project; return $project;
} }
} }

View File

@@ -18,7 +18,7 @@ class Board extends Base
public function moveColumn() public function moveColumn()
{ {
$this->checkCSRFParam(); $this->checkCSRFParam();
$project = $this->getProjectManagement(); $project = $this->getProject();
$column_id = $this->request->getIntegerParam('column_id'); $column_id = $this->request->getIntegerParam('column_id');
$direction = $this->request->getStringParam('direction'); $direction = $this->request->getStringParam('direction');
@@ -54,7 +54,6 @@ class Board extends Base
public function updateAssignee() public function updateAssignee()
{ {
$values = $this->request->getValues(); $values = $this->request->getValues();
$this->checkProjectPermissions($values['project_id']);
list($valid,) = $this->taskValidator->validateAssigneeModification($values); list($valid,) = $this->taskValidator->validateAssigneeModification($values);
@@ -93,7 +92,6 @@ class Board extends Base
public function updateCategory() public function updateCategory()
{ {
$values = $this->request->getValues(); $values = $this->request->getValues();
$this->checkProjectPermissions($values['project_id']);
list($valid,) = $this->taskValidator->validateCategoryModification($values); list($valid,) = $this->taskValidator->validateCategoryModification($values);
@@ -144,16 +142,16 @@ class Board extends Base
*/ */
public function index() public function index()
{ {
$last_seen_project_id = $this->user->getLastSeenProjectId(); $last_seen_project_id = $this->userSession->getLastSeenProjectId();
$favorite_project_id = $this->user->getFavoriteProjectId(); $favorite_project_id = $this->userSession->getFavoriteProjectId();
$project_id = $last_seen_project_id ?: $favorite_project_id; $project_id = $last_seen_project_id ?: $favorite_project_id;
if (! $project_id) { if (! $project_id) {
$projects = $this->projectPermission->getAllowedProjects($this->acl->getUserId()); $projects = $this->projectPermission->getAllowedProjects($this->userSession->getId());
if (empty($projects)) { if (empty($projects)) {
if ($this->acl->isAdminUser()) { if ($this->userSession->isAdmin()) {
$this->redirectNoProject(); $this->redirectNoProject();
} }
@@ -175,12 +173,12 @@ class Board extends Base
public function show($project_id = 0) public function show($project_id = 0)
{ {
$project = $this->getProject($project_id); $project = $this->getProject($project_id);
$projects = $this->projectPermission->getAllowedProjects($this->acl->getUserId()); $projects = $this->projectPermission->getAllowedProjects($this->userSession->getId());
$board_selector = $projects; $board_selector = $projects;
unset($board_selector[$project['id']]); unset($board_selector[$project['id']]);
$this->user->storeLastSeenProjectId($project['id']); $this->userSession->storeLastSeenProjectId($project['id']);
$this->response->html($this->template->layout('board/index', array( $this->response->html($this->template->layout('board/index', array(
'users' => $this->projectPermission->getMemberList($project['id'], true, true), 'users' => $this->projectPermission->getMemberList($project['id'], true, true),
@@ -202,7 +200,7 @@ class Board extends Base
*/ */
public function edit() public function edit()
{ {
$project = $this->getProjectManagement(); $project = $this->getProject();
$columns = $this->board->getColumns($project['id']); $columns = $this->board->getColumns($project['id']);
$values = array(); $values = array();
@@ -227,7 +225,7 @@ class Board extends Base
*/ */
public function update() public function update()
{ {
$project = $this->getProjectManagement(); $project = $this->getProject();
$columns = $this->board->getColumns($project['id']); $columns = $this->board->getColumns($project['id']);
$data = $this->request->getValues(); $data = $this->request->getValues();
$values = $columns_list = array(); $values = $columns_list = array();
@@ -267,7 +265,7 @@ class Board extends Base
*/ */
public function add() public function add()
{ {
$project = $this->getProjectManagement(); $project = $this->getProject();
$columns = $this->board->getColumnsList($project['id']); $columns = $this->board->getColumnsList($project['id']);
$data = $this->request->getValues(); $data = $this->request->getValues();
$values = array(); $values = array();
@@ -305,7 +303,7 @@ class Board extends Base
*/ */
public function remove() public function remove()
{ {
$project = $this->getProjectManagement(); $project = $this->getProject();
if ($this->request->getStringParam('remove') === 'yes') { if ($this->request->getStringParam('remove') === 'yes') {
@@ -341,7 +339,7 @@ class Board extends Base
return $this->response->status(403); return $this->response->status(403);
} }
if (! $this->projectPermission->isUserAllowed($project_id, $this->acl->getUserId())) { if (! $this->projectPermission->isUserAllowed($project_id, $this->userSession->getId())) {
$this->response->text('Forbidden', 403); $this->response->text('Forbidden', 403);
} }
@@ -385,7 +383,7 @@ class Board extends Base
$project_id = $this->request->getIntegerParam('project_id'); $project_id = $this->request->getIntegerParam('project_id');
$timestamp = $this->request->getIntegerParam('timestamp'); $timestamp = $this->request->getIntegerParam('timestamp');
if (! $this->projectPermission->isUserAllowed($project_id, $this->acl->getUserId())) { if (! $this->projectPermission->isUserAllowed($project_id, $this->userSession->getId())) {
$this->response->text('Forbidden', 403); $this->response->text('Forbidden', 403);
} }
@@ -413,7 +411,8 @@ class Board extends Base
{ {
$task = $this->getTask(); $task = $this->getTask();
$this->response->html($this->template->render('board/subtasks', array( $this->response->html($this->template->render('board/subtasks', array(
'subtasks' => $this->subTask->getAll($task['id']) 'subtasks' => $this->subTask->getAll($task['id']),
'task' => $task,
))); )));
} }
@@ -428,7 +427,8 @@ class Board extends Base
$this->subTask->toggleStatus($this->request->getIntegerParam('subtask_id')); $this->subTask->toggleStatus($this->request->getIntegerParam('subtask_id'));
$this->response->html($this->template->render('board/subtasks', array( $this->response->html($this->template->render('board/subtasks', array(
'subtasks' => $this->subTask->getAll($task['id']) 'subtasks' => $this->subTask->getAll($task['id']),
'task' => $task,
))); )));
} }
@@ -442,7 +442,8 @@ class Board extends Base
$task = $this->getTask(); $task = $this->getTask();
$this->response->html($this->template->render('board/files', array( $this->response->html($this->template->render('board/files', array(
'files' => $this->file->getAll($task['id']) 'files' => $this->file->getAll($task['id']),
'task' => $task,
))); )));
} }

View File

@@ -36,7 +36,7 @@ class Category extends Base
*/ */
public function index(array $values = array(), array $errors = array()) public function index(array $values = array(), array $errors = array())
{ {
$project = $this->getProjectManagement(); $project = $this->getProject();
$this->response->html($this->projectLayout('category/index', array( $this->response->html($this->projectLayout('category/index', array(
'categories' => $this->category->getList($project['id'], false), 'categories' => $this->category->getList($project['id'], false),
@@ -54,7 +54,7 @@ class Category extends Base
*/ */
public function save() public function save()
{ {
$project = $this->getProjectManagement(); $project = $this->getProject();
$values = $this->request->getValues(); $values = $this->request->getValues();
list($valid, $errors) = $this->category->validateCreation($values); list($valid, $errors) = $this->category->validateCreation($values);
@@ -80,7 +80,7 @@ class Category extends Base
*/ */
public function edit(array $values = array(), array $errors = array()) public function edit(array $values = array(), array $errors = array())
{ {
$project = $this->getProjectManagement(); $project = $this->getProject();
$category = $this->getCategory($project['id']); $category = $this->getCategory($project['id']);
$this->response->html($this->projectLayout('category/edit', array( $this->response->html($this->projectLayout('category/edit', array(
@@ -98,7 +98,7 @@ class Category extends Base
*/ */
public function update() public function update()
{ {
$project = $this->getProjectManagement(); $project = $this->getProject();
$values = $this->request->getValues(); $values = $this->request->getValues();
list($valid, $errors) = $this->category->validateModification($values); list($valid, $errors) = $this->category->validateModification($values);
@@ -124,7 +124,7 @@ class Category extends Base
*/ */
public function confirm() public function confirm()
{ {
$project = $this->getProjectManagement(); $project = $this->getProject();
$category = $this->getCategory($project['id']); $category = $this->getCategory($project['id']);
$this->response->html($this->projectLayout('category/remove', array( $this->response->html($this->projectLayout('category/remove', array(
@@ -142,7 +142,7 @@ class Category extends Base
public function remove() public function remove()
{ {
$this->checkCSRFParam(); $this->checkCSRFParam();
$project = $this->getProjectManagement(); $project = $this->getProject();
$category = $this->getCategory($project['id']); $category = $this->getCategory($project['id']);
if ($this->category->remove($category['id'])) { if ($this->category->remove($category['id'])) {

View File

@@ -24,7 +24,7 @@ class Comment extends Base
$this->notfound(); $this->notfound();
} }
if (! $this->acl->isAdminUser() && $comment['user_id'] != $this->acl->getUserId()) { if (! $this->userSession->isAdmin() && $comment['user_id'] != $this->userSession->getId()) {
$this->response->html($this->template->layout('comment/forbidden', array( $this->response->html($this->template->layout('comment/forbidden', array(
'title' => t('Access Forbidden') 'title' => t('Access Forbidden')
))); )));
@@ -44,7 +44,7 @@ class Comment extends Base
if (empty($values)) { if (empty($values)) {
$values = array( $values = array(
'user_id' => $this->acl->getUserId(), 'user_id' => $this->userSession->getId(),
'task_id' => $task['id'], 'task_id' => $task['id'],
); );
} }
@@ -78,7 +78,7 @@ class Comment extends Base
$this->session->flashError(t('Unable to create your comment.')); $this->session->flashError(t('Unable to create your comment.'));
} }
$this->response->redirect('?controller=task&action=show&task_id='.$task['id'].'#comments'); $this->response->redirect('?controller=task&action=show&task_id='.$task['id'].'&project_id='.$task['project_id'].'#comments');
} }
$this->create($values, $errors); $this->create($values, $errors);
@@ -125,7 +125,7 @@ class Comment extends Base
$this->session->flashError(t('Unable to update your comment.')); $this->session->flashError(t('Unable to update your comment.'));
} }
$this->response->redirect('?controller=task&action=show&task_id='.$task['id'].'#comment-'.$comment['id']); $this->response->redirect('?controller=task&action=show&task_id='.$task['id'].'&project_id='.$task['project_id'].'#comment-'.$comment['id']);
} }
$this->edit($values, $errors); $this->edit($values, $errors);
@@ -166,6 +166,6 @@ class Comment extends Base
$this->session->flashError(t('Unable to remove this comment.')); $this->session->flashError(t('Unable to remove this comment.'));
} }
$this->response->redirect('?controller=task&action=show&task_id='.$task['id'].'#comments'); $this->response->redirect('?controller=task&action=show&task_id='.$task['id'].'&project_id='.$task['project_id'].'#comments');
} }
} }

View File

@@ -20,7 +20,7 @@ class Config extends Base
*/ */
private function layout($template, array $params) private function layout($template, array $params)
{ {
$params['board_selector'] = $this->projectPermission->getAllowedProjects($this->acl->getUserId()); $params['board_selector'] = $this->projectPermission->getAllowedProjects($this->userSession->getId());
$params['values'] = $this->config->getAll(); $params['values'] = $this->config->getAll();
$params['errors'] = array(); $params['errors'] = array();
$params['config_content_for_layout'] = $this->template->render($template, $params); $params['config_content_for_layout'] = $this->template->render($template, $params);

View File

@@ -37,11 +37,11 @@ class File extends Base
$task = $this->getTask(); $task = $this->getTask();
if ($this->file->upload($task['project_id'], $task['id'], 'files') === true) { if ($this->file->upload($task['project_id'], $task['id'], 'files') === true) {
$this->response->redirect('?controller=task&action=show&task_id='.$task['id'].'#attachments'); $this->response->redirect('?controller=task&action=show&task_id='.$task['id'].'&project_id='.$task['project_id'].'#attachments');
} }
else { else {
$this->session->flashError(t('Unable to upload the file.')); $this->session->flashError(t('Unable to upload the file.'));
$this->response->redirect('?controller=file&action=create&task_id='.$task['id']); $this->response->redirect('?controller=file&action=create&task_id='.$task['id'].'&project_id='.$task['project_id']);
} }
} }
@@ -61,7 +61,7 @@ class File extends Base
$this->response->binary(file_get_contents($filename)); $this->response->binary(file_get_contents($filename));
} }
$this->response->redirect('?controller=task&action=show&task_id='.$task['id']); $this->response->redirect('?controller=task&action=show&task_id='.$task['id'].'&project_id='.$task['project_id']);
} }
/** /**
@@ -76,7 +76,8 @@ class File extends Base
if ($file['task_id'] == $task['id']) { if ($file['task_id'] == $task['id']) {
$this->response->html($this->template->render('file/open', array( $this->response->html($this->template->render('file/open', array(
'file' => $file 'file' => $file,
'task' => $task,
))); )));
} }
} }
@@ -119,7 +120,7 @@ class File extends Base
$this->session->flashError(t('Unable to remove this file.')); $this->session->flashError(t('Unable to remove this file.'));
} }
$this->response->redirect('?controller=task&action=show&task_id='.$task['id']); $this->response->redirect('?controller=task&action=show&task_id='.$task['id'].'&project_id='.$task['project_id']);
} }
/** /**

View File

@@ -17,7 +17,7 @@ class Project extends Base
*/ */
public function index() public function index()
{ {
$projects = $this->project->getAll($this->acl->isRegularUser()); $projects = $this->project->getAll(! $this->userSession->isAdmin());
$nb_projects = count($projects); $nb_projects = count($projects);
$active_projects = array(); $active_projects = array();
$inactive_projects = array(); $inactive_projects = array();
@@ -32,7 +32,7 @@ class Project extends Base
} }
$this->response->html($this->template->layout('project/index', array( $this->response->html($this->template->layout('project/index', array(
'board_selector' => $this->projectPermission->getAllowedProjects($this->acl->getUserId()), 'board_selector' => $this->projectPermission->getAllowedProjects($this->userSession->getId()),
'active_projects' => $active_projects, 'active_projects' => $active_projects,
'inactive_projects' => $inactive_projects, 'inactive_projects' => $inactive_projects,
'nb_projects' => $nb_projects, 'nb_projects' => $nb_projects,
@@ -63,7 +63,7 @@ class Project extends Base
*/ */
public function exportTasks() public function exportTasks()
{ {
$project = $this->getProjectManagement(); $project = $this->getProject();
$from = $this->request->getStringParam('from'); $from = $this->request->getStringParam('from');
$to = $this->request->getStringParam('to'); $to = $this->request->getStringParam('to');
@@ -96,7 +96,7 @@ class Project extends Base
*/ */
public function exportDailyProjectSummary() public function exportDailyProjectSummary()
{ {
$project = $this->getProjectManagement(); $project = $this->getProject();
$from = $this->request->getStringParam('from'); $from = $this->request->getStringParam('from');
$to = $this->request->getStringParam('to'); $to = $this->request->getStringParam('to');
@@ -129,7 +129,7 @@ class Project extends Base
*/ */
public function share() public function share()
{ {
$project = $this->getProjectManagement(); $project = $this->getProject();
$switch = $this->request->getStringParam('switch'); $switch = $this->request->getStringParam('switch');
if ($switch === 'enable' || $switch === 'disable') { if ($switch === 'enable' || $switch === 'disable') {
@@ -158,7 +158,7 @@ class Project extends Base
*/ */
public function integration() public function integration()
{ {
$project = $this->getProjectManagement(); $project = $this->getProject();
$this->response->html($this->projectLayout('project/integrations', array( $this->response->html($this->projectLayout('project/integrations', array(
'project' => $project, 'project' => $project,
@@ -174,7 +174,7 @@ class Project extends Base
*/ */
public function edit(array $values = array(), array $errors = array()) public function edit(array $values = array(), array $errors = array())
{ {
$project = $this->getProjectManagement(); $project = $this->getProject();
$this->response->html($this->projectLayout('project/edit', array( $this->response->html($this->projectLayout('project/edit', array(
'values' => empty($values) ? $project : $values, 'values' => empty($values) ? $project : $values,
@@ -191,7 +191,7 @@ class Project extends Base
*/ */
public function update() public function update()
{ {
$project = $this->getProjectManagement(); $project = $this->getProject();
$values = $this->request->getValues(); $values = $this->request->getValues();
list($valid, $errors) = $this->project->validateModification($values); list($valid, $errors) = $this->project->validateModification($values);
@@ -216,7 +216,7 @@ class Project extends Base
*/ */
public function users() public function users()
{ {
$project = $this->getProjectManagement(); $project = $this->getProject();
$this->response->html($this->projectLayout('project/users', array( $this->response->html($this->projectLayout('project/users', array(
'project' => $project, 'project' => $project,
@@ -232,7 +232,7 @@ class Project extends Base
*/ */
public function allowEverybody() public function allowEverybody()
{ {
$project = $this->getProjectManagement(); $project = $this->getProject();
$values = $this->request->getValues() + array('is_everybody_allowed' => 0); $values = $this->request->getValues() + array('is_everybody_allowed' => 0);
list($valid,) = $this->projectPermission->validateProjectModification($values); list($valid,) = $this->projectPermission->validateProjectModification($values);
@@ -257,12 +257,11 @@ class Project extends Base
public function allow() public function allow()
{ {
$values = $this->request->getValues(); $values = $this->request->getValues();
$this->checkProjectOwnerPermissions($values['project_id']);
list($valid,) = $this->projectPermission->validateUserModification($values); list($valid,) = $this->projectPermission->validateUserModification($values);
if ($valid) { if ($valid) {
if ($this->projectPermission->allowUser($values['project_id'], $values['user_id'])) { if ($this->projectPermission->addMember($values['project_id'], $values['user_id'])) {
$this->session->flash(t('Project updated successfully.')); $this->session->flash(t('Project updated successfully.'));
} }
else { else {
@@ -274,11 +273,11 @@ class Project extends Base
} }
/** /**
* Set ownership for a specific user (admin only) * Change the role of a project member
* *
* @access public * @access public
*/ */
public function setOwner() public function role()
{ {
$this->checkCSRFParam(); $this->checkCSRFParam();
@@ -288,12 +287,11 @@ class Project extends Base
'is_owner' => $this->request->getIntegerParam('is_owner'), 'is_owner' => $this->request->getIntegerParam('is_owner'),
); );
$this->checkProjectOwnerPermissions($values['project_id']);
list($valid,) = $this->projectPermission->validateUserModification($values); list($valid,) = $this->projectPermission->validateUserModification($values);
if ($valid) { if ($valid) {
if ($this->projectPermission->setOwner($values['project_id'], $values['user_id'], $values['is_owner'])) { if ($this->projectPermission->changeRole($values['project_id'], $values['user_id'], $values['is_owner'])) {
$this->session->flash(t('Project updated successfully.')); $this->session->flash(t('Project updated successfully.'));
} }
else { else {
@@ -318,12 +316,11 @@ class Project extends Base
'user_id' => $this->request->getIntegerParam('user_id'), 'user_id' => $this->request->getIntegerParam('user_id'),
); );
$this->checkProjectOwnerPermissions($values['project_id']);
list($valid,) = $this->projectPermission->validateUserModification($values); list($valid,) = $this->projectPermission->validateUserModification($values);
if ($valid) { if ($valid) {
if ($this->projectPermission->revokeUser($values['project_id'], $values['user_id'])) { if ($this->projectPermission->revokeMember($values['project_id'], $values['user_id'])) {
$this->session->flash(t('Project updated successfully.')); $this->session->flash(t('Project updated successfully.'));
} }
else { else {
@@ -341,7 +338,7 @@ class Project extends Base
*/ */
public function remove() public function remove()
{ {
$project = $this->getProjectManagement(); $project = $this->getProject();
if ($this->request->getStringParam('remove') === 'yes') { if ($this->request->getStringParam('remove') === 'yes') {
@@ -370,7 +367,7 @@ class Project extends Base
*/ */
public function duplicate() public function duplicate()
{ {
$project = $this->getProjectManagement(); $project = $this->getProject();
if ($this->request->getStringParam('duplicate') === 'yes') { if ($this->request->getStringParam('duplicate') === 'yes') {
@@ -398,7 +395,7 @@ class Project extends Base
*/ */
public function disable() public function disable()
{ {
$project = $this->getProjectManagement(); $project = $this->getProject();
if ($this->request->getStringParam('disable') === 'yes') { if ($this->request->getStringParam('disable') === 'yes') {
@@ -426,7 +423,7 @@ class Project extends Base
*/ */
public function enable() public function enable()
{ {
$project = $this->getProjectManagement(); $project = $this->getProject();
if ($this->request->getStringParam('enable') === 'yes') { if ($this->request->getStringParam('enable') === 'yes') {
@@ -478,7 +475,7 @@ class Project extends Base
$project = $this->getProject(); $project = $this->getProject();
$this->response->html($this->template->layout('project/activity', array( $this->response->html($this->template->layout('project/activity', array(
'board_selector' => $this->projectPermission->getAllowedProjects($this->acl->getUserId()), 'board_selector' => $this->projectPermission->getAllowedProjects($this->userSession->getId()),
'events' => $this->projectActivity->getProject($project['id']), 'events' => $this->projectActivity->getProject($project['id']),
'project' => $project, 'project' => $project,
'title' => t('%s\'s activity', $project['name']) 'title' => t('%s\'s activity', $project['name'])
@@ -507,7 +504,7 @@ class Project extends Base
} }
$this->response->html($this->template->layout('project/search', array( $this->response->html($this->template->layout('project/search', array(
'board_selector' => $this->projectPermission->getAllowedProjects($this->acl->getUserId()), 'board_selector' => $this->projectPermission->getAllowedProjects($this->userSession->getId()),
'tasks' => $tasks, 'tasks' => $tasks,
'nb_tasks' => $nb_tasks, 'nb_tasks' => $nb_tasks,
'pagination' => array( 'pagination' => array(
@@ -550,7 +547,7 @@ class Project extends Base
$nb_tasks = $this->taskPaginator->countClosedTasks($project['id']); $nb_tasks = $this->taskPaginator->countClosedTasks($project['id']);
$this->response->html($this->template->layout('project/tasks', array( $this->response->html($this->template->layout('project/tasks', array(
'board_selector' => $this->projectPermission->getAllowedProjects($this->acl->getUserId()), 'board_selector' => $this->projectPermission->getAllowedProjects($this->userSession->getId()),
'pagination' => array( 'pagination' => array(
'controller' => 'project', 'controller' => 'project',
'action' => 'tasks', 'action' => 'tasks',
@@ -577,10 +574,10 @@ class Project extends Base
*/ */
public function create(array $values = array(), array $errors = array()) public function create(array $values = array(), array $errors = array())
{ {
$is_private = $this->request->getIntegerParam('private', $this->acl->isRegularUser()); $is_private = $this->request->getIntegerParam('private', ! $this->userSession->isAdmin());
$this->response->html($this->template->layout('project/new', array( $this->response->html($this->template->layout('project/new', array(
'board_selector' => $this->projectPermission->getAllowedProjects($this->acl->getUserId()), 'board_selector' => $this->projectPermission->getAllowedProjects($this->userSession->getId()),
'values' => empty($values) ? array('is_private' => $is_private) : $values, 'values' => empty($values) ? array('is_private' => $is_private) : $values,
'errors' => $errors, 'errors' => $errors,
'title' => $is_private ? t('New private project') : t('New project'), 'title' => $is_private ? t('New private project') : t('New project'),
@@ -599,7 +596,7 @@ class Project extends Base
if ($valid) { if ($valid) {
$project_id = $this->project->create($values, $this->acl->getUserId(), true); $project_id = $this->project->create($values, $this->userSession->getId(), true);
if ($project_id) { if ($project_id) {
$this->session->flash(t('Your project have been created successfully.')); $this->session->flash(t('Your project have been created successfully.'));

View File

@@ -73,10 +73,10 @@ class Subtask extends Base
} }
if (isset($values['another_subtask']) && $values['another_subtask'] == 1) { if (isset($values['another_subtask']) && $values['another_subtask'] == 1) {
$this->response->redirect('?controller=subtask&action=create&task_id='.$task['id'].'&another_subtask=1'); $this->response->redirect('?controller=subtask&action=create&task_id='.$task['id'].'&another_subtask=1&project_id='.$task['project_id']);
} }
$this->response->redirect('?controller=task&action=show&task_id='.$task['id'].'#subtasks'); $this->response->redirect('?controller=task&action=show&task_id='.$task['id'].'&project_id='.$task['project_id'].'#subtasks');
} }
$this->create($values, $errors); $this->create($values, $errors);
@@ -124,7 +124,7 @@ class Subtask extends Base
$this->session->flashError(t('Unable to update your sub-task.')); $this->session->flashError(t('Unable to update your sub-task.'));
} }
$this->response->redirect('?controller=task&action=show&task_id='.$task['id'].'#subtasks'); $this->response->redirect('?controller=task&action=show&task_id='.$task['id'].'&project_id='.$task['project_id'].'#subtasks');
} }
$this->edit($values, $errors); $this->edit($values, $errors);
@@ -164,7 +164,7 @@ class Subtask extends Base
$this->session->flashError(t('Unable to remove this sub-task.')); $this->session->flashError(t('Unable to remove this sub-task.'));
} }
$this->response->redirect('?controller=task&action=show&task_id='.$task['id'].'#subtasks'); $this->response->redirect('?controller=task&action=show&task_id='.$task['id'].'&project_id='.$task['project_id'].'#subtasks');
} }
/** /**
@@ -181,6 +181,6 @@ class Subtask extends Base
$this->session->flashError(t('Unable to update your sub-task.')); $this->session->flashError(t('Unable to update your sub-task.'));
} }
$this->response->redirect('?controller=task&action=show&task_id='.$task['id'].'#subtasks'); $this->response->redirect('?controller=task&action=show&task_id='.$task['id'].'&project_id='.$task['project_id'].'#subtasks');
} }
} }

View File

@@ -38,7 +38,7 @@ class Swimlane extends Base
*/ */
public function index(array $values = array(), array $errors = array()) public function index(array $values = array(), array $errors = array())
{ {
$project = $this->getProjectManagement(); $project = $this->getProject();
$this->response->html($this->projectLayout('swimlane/index', array( $this->response->html($this->projectLayout('swimlane/index', array(
'default_swimlane' => $this->swimlane->getDefault($project['id']), 'default_swimlane' => $this->swimlane->getDefault($project['id']),
@@ -58,7 +58,7 @@ class Swimlane extends Base
*/ */
public function save() public function save()
{ {
$project = $this->getProjectManagement(); $project = $this->getProject();
$values = $this->request->getValues(); $values = $this->request->getValues();
list($valid, $errors) = $this->swimlane->validateCreation($values); list($valid, $errors) = $this->swimlane->validateCreation($values);
@@ -84,7 +84,7 @@ class Swimlane extends Base
*/ */
public function change() public function change()
{ {
$project = $this->getProjectManagement(); $project = $this->getProject();
$values = $this->request->getValues(); $values = $this->request->getValues();
list($valid, $errors) = $this->swimlane->validateDefaultModification($values); list($valid, $errors) = $this->swimlane->validateDefaultModification($values);
@@ -110,7 +110,7 @@ class Swimlane extends Base
*/ */
public function edit(array $values = array(), array $errors = array()) public function edit(array $values = array(), array $errors = array())
{ {
$project = $this->getProjectManagement(); $project = $this->getProject();
$swimlane = $this->getSwimlane($project['id']); $swimlane = $this->getSwimlane($project['id']);
$this->response->html($this->projectLayout('swimlane/edit', array( $this->response->html($this->projectLayout('swimlane/edit', array(
@@ -128,7 +128,7 @@ class Swimlane extends Base
*/ */
public function update() public function update()
{ {
$project = $this->getProjectManagement(); $project = $this->getProject();
$values = $this->request->getValues(); $values = $this->request->getValues();
list($valid, $errors) = $this->swimlane->validateModification($values); list($valid, $errors) = $this->swimlane->validateModification($values);
@@ -154,7 +154,7 @@ class Swimlane extends Base
*/ */
public function confirm() public function confirm()
{ {
$project = $this->getProjectManagement(); $project = $this->getProject();
$swimlane = $this->getSwimlane($project['id']); $swimlane = $this->getSwimlane($project['id']);
$this->response->html($this->projectLayout('swimlane/remove', array( $this->response->html($this->projectLayout('swimlane/remove', array(
@@ -172,7 +172,7 @@ class Swimlane extends Base
public function remove() public function remove()
{ {
$this->checkCSRFParam(); $this->checkCSRFParam();
$project = $this->getProjectManagement(); $project = $this->getProject();
$swimlane_id = $this->request->getIntegerParam('swimlane_id'); $swimlane_id = $this->request->getIntegerParam('swimlane_id');
if ($this->swimlane->remove($project['id'], $swimlane_id)) { if ($this->swimlane->remove($project['id'], $swimlane_id)) {
@@ -192,7 +192,7 @@ class Swimlane extends Base
public function disable() public function disable()
{ {
$this->checkCSRFParam(); $this->checkCSRFParam();
$project = $this->getProjectManagement(); $project = $this->getProject();
$swimlane_id = $this->request->getIntegerParam('swimlane_id'); $swimlane_id = $this->request->getIntegerParam('swimlane_id');
if ($this->swimlane->disable($project['id'], $swimlane_id)) { if ($this->swimlane->disable($project['id'], $swimlane_id)) {
@@ -212,7 +212,7 @@ class Swimlane extends Base
public function enable() public function enable()
{ {
$this->checkCSRFParam(); $this->checkCSRFParam();
$project = $this->getProjectManagement(); $project = $this->getProject();
$swimlane_id = $this->request->getIntegerParam('swimlane_id'); $swimlane_id = $this->request->getIntegerParam('swimlane_id');
if ($this->swimlane->enable($project['id'], $swimlane_id)) { if ($this->swimlane->enable($project['id'], $swimlane_id)) {
@@ -232,7 +232,7 @@ class Swimlane extends Base
public function moveup() public function moveup()
{ {
$this->checkCSRFParam(); $this->checkCSRFParam();
$project = $this->getProjectManagement(); $project = $this->getProject();
$swimlane_id = $this->request->getIntegerParam('swimlane_id'); $swimlane_id = $this->request->getIntegerParam('swimlane_id');
$this->swimlane->moveUp($project['id'], $swimlane_id); $this->swimlane->moveUp($project['id'], $swimlane_id);
@@ -247,7 +247,7 @@ class Swimlane extends Base
public function movedown() public function movedown()
{ {
$this->checkCSRFParam(); $this->checkCSRFParam();
$project = $this->getProjectManagement(); $project = $this->getProject();
$swimlane_id = $this->request->getIntegerParam('swimlane_id'); $swimlane_id = $this->request->getIntegerParam('swimlane_id');
$this->swimlane->moveDown($project['id'], $swimlane_id); $this->swimlane->moveDown($project['id'], $swimlane_id);

View File

@@ -126,9 +126,7 @@ class Task extends Base
{ {
$project = $this->getProject(); $project = $this->getProject();
$values = $this->request->getValues(); $values = $this->request->getValues();
$values['creator_id'] = $this->acl->getUserId(); $values['creator_id'] = $this->userSession->getId();
$this->checkProjectPermissions($project['id']);
list($valid, $errors) = $this->taskValidator->validateCreation($values); list($valid, $errors) = $this->taskValidator->validateCreation($values);
@@ -207,7 +205,7 @@ class Task extends Base
$this->response->redirect('?controller=board&action=show&project_id='.$task['project_id']); $this->response->redirect('?controller=board&action=show&project_id='.$task['project_id']);
} }
else { else {
$this->response->redirect('?controller=task&action=show&task_id='.$task['id']); $this->response->redirect('?controller=task&action=show&task_id='.$task['id'].'&project_id='.$task['project_id']);
} }
} }
else { else {
@@ -248,7 +246,7 @@ class Task extends Base
$this->session->flashError(t('Unable to update your task.')); $this->session->flashError(t('Unable to update your task.'));
} }
$this->response->redirect('?controller=task&action=show&task_id='.$task['id']); $this->response->redirect('?controller=task&action=show&task_id='.$task['id'].'&project_id='.$task['project_id']);
} }
/** /**
@@ -270,7 +268,7 @@ class Task extends Base
$this->session->flashError(t('Unable to close this task.')); $this->session->flashError(t('Unable to close this task.'));
} }
$this->response->redirect('?controller=task&action=show&task_id='.$task['id']); $this->response->redirect('?controller=task&action=show&task_id='.$task['id'].'&project_id='.$task['project_id']);
} }
$this->response->html($this->taskLayout('task/close', array( $this->response->html($this->taskLayout('task/close', array(
@@ -297,7 +295,7 @@ class Task extends Base
$this->session->flashError(t('Unable to open this task.')); $this->session->flashError(t('Unable to open this task.'));
} }
$this->response->redirect('?controller=task&action=show&task_id='.$task['id']); $this->response->redirect('?controller=task&action=show&task_id='.$task['id'].'&project_id='.$task['project_id']);
} }
$this->response->html($this->taskLayout('task/open', array( $this->response->html($this->taskLayout('task/open', array(
@@ -352,10 +350,10 @@ class Task extends Base
if ($task_id) { if ($task_id) {
$this->session->flash(t('Task created successfully.')); $this->session->flash(t('Task created successfully.'));
$this->response->redirect('?controller=task&action=show&task_id='.$task_id); $this->response->redirect('?controller=task&action=show&task_id='.$task_id.'&project_id='.$task['project_id']);
} else { } else {
$this->session->flashError(t('Unable to create this task.')); $this->session->flashError(t('Unable to create this task.'));
$this->response->redirect('?controller=task&action=duplicate&task_id='.$task['id']); $this->response->redirect('?controller=task&action=duplicate&task_id='.$task['id'].'&project_id='.$task['project_id']);
} }
} }
@@ -393,7 +391,7 @@ class Task extends Base
$this->response->redirect('?controller=board&action=show&project_id='.$task['project_id']); $this->response->redirect('?controller=board&action=show&project_id='.$task['project_id']);
} }
else { else {
$this->response->redirect('?controller=task&action=show&task_id='.$task['id']); $this->response->redirect('?controller=task&action=show&task_id='.$task['id'].'&project_id='.$task['project_id']);
} }
} }
} }
@@ -427,7 +425,7 @@ class Task extends Base
$task = $this->getTask(); $task = $this->getTask();
$values = $task; $values = $task;
$errors = array(); $errors = array();
$projects_list = $this->projectPermission->getMemberProjects($this->acl->getUserId()); $projects_list = $this->projectPermission->getMemberProjects($this->userSession->getId());
unset($projects_list[$task['project_id']]); unset($projects_list[$task['project_id']]);
@@ -440,7 +438,7 @@ class Task extends Base
if ($this->taskDuplication->moveToProject($task['id'], $values['project_id'])) { if ($this->taskDuplication->moveToProject($task['id'], $values['project_id'])) {
$this->session->flash(t('Task updated successfully.')); $this->session->flash(t('Task updated successfully.'));
$this->response->redirect('?controller=task&action=show&task_id='.$task['id']); $this->response->redirect('?controller=task&action=show&task_id='.$task['id'].'&project_id='.$task['project_id']);
} }
else { else {
$this->session->flashError(t('Unable to update your task.')); $this->session->flashError(t('Unable to update your task.'));
@@ -466,7 +464,7 @@ class Task extends Base
$task = $this->getTask(); $task = $this->getTask();
$values = $task; $values = $task;
$errors = array(); $errors = array();
$projects_list = $this->projectPermission->getMemberProjects($this->acl->getUserId()); $projects_list = $this->projectPermission->getMemberProjects($this->userSession->getId());
unset($projects_list[$task['project_id']]); unset($projects_list[$task['project_id']]);
@@ -479,7 +477,7 @@ class Task extends Base
$task_id = $this->taskDuplication->duplicateToProject($task['id'], $values['project_id']); $task_id = $this->taskDuplication->duplicateToProject($task['id'], $values['project_id']);
if ($task_id) { if ($task_id) {
$this->session->flash(t('Task created successfully.')); $this->session->flash(t('Task created successfully.'));
$this->response->redirect('?controller=task&action=show&task_id='.$task_id); $this->response->redirect('?controller=task&action=show&task_id='.$task_id.'&project_id='.$task['project_id']);
} }
else { else {
$this->session->flashError(t('Unable to create your task.')); $this->session->flashError(t('Unable to create your task.'));

View File

@@ -18,7 +18,7 @@ class User extends Base
public function logout() public function logout()
{ {
$this->checkCSRFParam(); $this->checkCSRFParam();
$this->authentication->backend('rememberMe')->destroy($this->acl->getUserId()); $this->authentication->backend('rememberMe')->destroy($this->userSession->getId());
$this->session->close(); $this->session->close();
$this->response->redirect('?controller=user&action=login'); $this->response->redirect('?controller=user&action=login');
} }
@@ -30,7 +30,7 @@ class User extends Base
*/ */
public function login(array $values = array(), array $errors = array()) public function login(array $values = array(), array $errors = array())
{ {
if ($this->acl->isLogged()) { if ($this->userSession->isLogged()) {
$this->response->redirect('?controller=app'); $this->response->redirect('?controller=app');
} }
@@ -78,7 +78,7 @@ class User extends Base
{ {
$content = $this->template->render($template, $params); $content = $this->template->render($template, $params);
$params['user_content_for_layout'] = $content; $params['user_content_for_layout'] = $content;
$params['board_selector'] = $this->projectPermission->getAllowedProjects($this->acl->getUserId()); $params['board_selector'] = $this->projectPermission->getAllowedProjects($this->userSession->getId());
if (isset($params['user'])) { if (isset($params['user'])) {
$params['title'] = ($params['user']['name'] ?: $params['user']['username']).' (#'.$params['user']['id'].')'; $params['title'] = ($params['user']['name'] ?: $params['user']['username']).' (#'.$params['user']['id'].')';
@@ -101,7 +101,7 @@ class User extends Base
$this->notfound(); $this->notfound();
} }
if ($this->acl->isRegularUser() && $this->acl->getUserId() != $user['id']) { if (! $this->userSession->isAdmin() && $this->userSession->getId() != $user['id']) {
$this->forbidden(); $this->forbidden();
} }
@@ -125,7 +125,7 @@ class User extends Base
$this->response->html( $this->response->html(
$this->template->layout('user/index', array( $this->template->layout('user/index', array(
'board_selector' => $this->projectPermission->getAllowedProjects($this->acl->getUserId()), 'board_selector' => $this->projectPermission->getAllowedProjects($this->userSession->getId()),
'projects' => $this->project->getList(), 'projects' => $this->project->getList(),
'nb_users' => $nb_users, 'nb_users' => $nb_users,
'users' => $users, 'users' => $users,
@@ -151,7 +151,7 @@ class User extends Base
public function create(array $values = array(), array $errors = array()) public function create(array $values = array(), array $errors = array())
{ {
$this->response->html($this->template->layout('user/new', array( $this->response->html($this->template->layout('user/new', array(
'board_selector' => $this->projectPermission->getAllowedProjects($this->acl->getUserId()), 'board_selector' => $this->projectPermission->getAllowedProjects($this->userSession->getId()),
'projects' => $this->project->getList(), 'projects' => $this->project->getList(),
'errors' => $errors, 'errors' => $errors,
'values' => $values, 'values' => $values,
@@ -328,7 +328,7 @@ class User extends Base
$values = $this->request->getValues(); $values = $this->request->getValues();
if ($this->acl->isAdminUser()) { if ($this->userSession->isAdmin()) {
$values += array('is_admin' => 0); $values += array('is_admin' => 0);
} }
else { else {
@@ -404,16 +404,16 @@ class User extends Base
if (is_array($profile)) { if (is_array($profile)) {
// If the user is already logged, link the account otherwise authenticate // If the user is already logged, link the account otherwise authenticate
if ($this->acl->isLogged()) { if ($this->userSession->isLogged()) {
if ($this->authentication->backend('google')->updateUser($this->acl->getUserId(), $profile)) { if ($this->authentication->backend('google')->updateUser($this->userSession->getId(), $profile)) {
$this->session->flash(t('Your Google Account is linked to your profile successfully.')); $this->session->flash(t('Your Google Account is linked to your profile successfully.'));
} }
else { else {
$this->session->flashError(t('Unable to link your Google Account.')); $this->session->flashError(t('Unable to link your Google Account.'));
} }
$this->response->redirect('?controller=user&action=external&user_id='.$this->acl->getUserId()); $this->response->redirect('?controller=user&action=external&user_id='.$this->userSession->getId());
} }
else if ($this->authentication->backend('google')->authenticate($profile['id'])) { else if ($this->authentication->backend('google')->authenticate($profile['id'])) {
$this->response->redirect('?controller=app'); $this->response->redirect('?controller=app');
@@ -441,14 +441,14 @@ class User extends Base
public function unlinkGoogle() public function unlinkGoogle()
{ {
$this->checkCSRFParam(); $this->checkCSRFParam();
if ($this->authentication->backend('google')->unlink($this->acl->getUserId())) { if ($this->authentication->backend('google')->unlink($this->userSession->getId())) {
$this->session->flash(t('Your Google Account is not linked anymore to your profile.')); $this->session->flash(t('Your Google Account is not linked anymore to your profile.'));
} }
else { else {
$this->session->flashError(t('Unable to unlink your Google Account.')); $this->session->flashError(t('Unable to unlink your Google Account.'));
} }
$this->response->redirect('?controller=user&action=external&user_id='.$this->acl->getUserId()); $this->response->redirect('?controller=user&action=external&user_id='.$this->userSession->getId());
} }
/** /**
@@ -466,16 +466,16 @@ class User extends Base
if (is_array($profile)) { if (is_array($profile)) {
// If the user is already logged, link the account otherwise authenticate // If the user is already logged, link the account otherwise authenticate
if ($this->acl->isLogged()) { if ($this->userSession->isLogged()) {
if ($this->authentication->backend('gitHub')->updateUser($this->acl->getUserId(), $profile)) { if ($this->authentication->backend('gitHub')->updateUser($this->userSession->getId(), $profile)) {
$this->session->flash(t('Your GitHub account was successfully linked to your profile.')); $this->session->flash(t('Your GitHub account was successfully linked to your profile.'));
} }
else { else {
$this->session->flashError(t('Unable to link your GitHub Account.')); $this->session->flashError(t('Unable to link your GitHub Account.'));
} }
$this->response->redirect('?controller=user&action=external&user_id='.$this->acl->getUserId()); $this->response->redirect('?controller=user&action=external&user_id='.$this->userSession->getId());
} }
else if ($this->authentication->backend('gitHub')->authenticate($profile['id'])) { else if ($this->authentication->backend('gitHub')->authenticate($profile['id'])) {
$this->response->redirect('?controller=app'); $this->response->redirect('?controller=app');
@@ -506,13 +506,13 @@ class User extends Base
$this->authentication->backend('gitHub')->revokeGitHubAccess(); $this->authentication->backend('gitHub')->revokeGitHubAccess();
if ($this->authentication->backend('gitHub')->unlink($this->acl->getUserId())) { if ($this->authentication->backend('gitHub')->unlink($this->userSession->getId())) {
$this->session->flash(t('Your GitHub account is no longer linked to your profile.')); $this->session->flash(t('Your GitHub account is no longer linked to your profile.'));
} }
else { else {
$this->session->flashError(t('Unable to unlink your GitHub Account.')); $this->session->flashError(t('Unable to unlink your GitHub Account.'));
} }
$this->response->redirect('?controller=user&action=external&user_id='.$this->acl->getUserId()); $this->response->redirect('?controller=user&action=external&user_id='.$this->userSession->getId());
} }
} }

View File

@@ -498,14 +498,14 @@ class Helper
* @param array $link Link parameters for replacement * @param array $link Link parameters for replacement
* @return string * @return string
*/ */
public function markdown($text, array $link = array('controller' => 'task', 'action' => 'show', 'params' => array())) public function markdown($text, array $link = array())
{ {
$html = Parsedown::instance() $html = Parsedown::instance()
->setMarkupEscaped(true) # escapes markup (HTML) ->setMarkupEscaped(true) # escapes markup (HTML)
->text($text); ->text($text);
// Replace task #123 by a link to the task // Replace task #123 by a link to the task
if (preg_match_all('!#(\d+)!i', $html, $matches, PREG_SET_ORDER)) { if (! empty($link) && preg_match_all('!#(\d+)!i', $html, $matches, PREG_SET_ORDER)) {
foreach ($matches as $match) { foreach ($matches as $match) {

View File

@@ -3,7 +3,7 @@
namespace Model; namespace Model;
/** /**
* Acl model * Access List
* *
* @package model * @package model
* @author Frederic Guillot * @author Frederic Guillot
@@ -16,37 +16,59 @@ class Acl extends Base
* @access private * @access private
* @var array * @var array
*/ */
private $public_actions = array( private $public_acl = array(
'user' => array('login', 'check', 'google', 'github'), 'user' => array('login', 'check', 'google', 'github'),
'task' => array('readonly'), 'task' => array('readonly'),
'board' => array('readonly'), 'board' => array('readonly'),
'project' => array('feed'), 'project' => array('feed'),
'webhook' => array('task', 'github', 'gitlab'), 'webhook' => '*',
); );
/** /**
* Controllers and actions allowed for regular users * Controllers and actions for project members
* *
* @access private * @access private
* @var array * @var array
*/ */
private $user_actions = array( private $member_acl = array(
'app' => array('index', 'preview', 'status'), 'board' => '*',
'project' => array('index', 'show', 'exporttasks', 'exportdaily', 'share', 'edit', 'update', 'users', 'remove', 'duplicate', 'disable', 'enable', 'activity', 'search', 'tasks', 'create', 'save', 'revoke', 'setowner', 'allow'), 'comment' => '*',
'board' => array('index', 'show', 'save', 'check', 'changeassignee', 'updateassignee', 'changecategory', 'updatecategory', 'movecolumn', 'edit', 'update', 'add', 'confirm', 'remove', 'subtasks', 'togglesubtask', 'attachments', 'comments', 'description'), 'file' => '*',
'user' => array('edit', 'forbidden', 'logout', 'show', 'external', 'unlinkgoogle', 'unlinkgithub', 'sessions', 'removesession', 'last', 'notifications', 'password'), 'project' => array('show', 'tasks', 'search', 'activity'),
'comment' => array('create', 'save', 'confirm', 'remove', 'update', 'edit', 'forbidden'), 'subtask' => '*',
'file' => array('create', 'save', 'download', 'confirm', 'remove', 'open', 'image'), 'task' => '*',
'subtask' => array('create', 'save', 'edit', 'update', 'confirm', 'remove', 'togglestatus'),
'task' => array('show', 'create', 'save', 'edit', 'update', 'close', 'open', 'duplicate', 'remove', 'description', 'move', 'copy', 'time'),
'category' => array('index', 'save', 'edit', 'update', 'confirm', 'remove'),
'action' => array('index', 'event', 'params', 'create', 'confirm', 'remove'),
'analytic' => array('tasks', 'users', 'cfd'),
'swimlane' => array('index', 'save', 'change', 'edit', 'update', 'confirm', 'remove', 'disable', 'enable', 'moveup', 'movedown'),
); );
/** /**
* Return true if the specified controller/action is allowed according to the given acl * Controllers and actions for project managers
*
* @access private
* @var array
*/
private $manager_acl = array(
'action' => '*',
'analytic' => '*',
'board' => array('movecolumn', 'edit', 'update', 'add', 'remove'),
'category' => '*',
'project' => array('edit', 'update', 'exporttasks', 'exportdailyprojectsummary', 'share', 'integration', 'users', 'alloweverybody', 'allow', 'setowner', 'revoke', 'duplicate', 'disable', 'enable'),
'swimlane' => '*',
'task' => array('remove'),
);
/**
* Controllers and actions for admins
*
* @access private
* @var array
*/
private $admin_acl = array(
'user' => array('index', 'create', 'save', 'remove'),
'config' => '*',
'project' => array('remove'),
);
/**
* Return true if the specified controller/action match the given acl
* *
* @access public * @access public
* @param array $acl Acl list * @param array $acl Acl list
@@ -54,13 +76,27 @@ class Acl extends Base
* @param string $action Action name * @param string $action Action name
* @return bool * @return bool
*/ */
public function isAllowedAction(array $acl, $controller, $action) public function matchAcl(array $acl, $controller, $action)
{ {
if (isset($acl[$controller])) { $action = strtolower($action);
return in_array($action, $acl[$controller]); return isset($acl[$controller]) && $this->hasAction($action, $acl[$controller]);
}
/**
* Return true if the specified action is inside the list of actions
*
* @access public
* @param string $action Action name
* @param mixed $action Actions list
* @return bool
*/
public function hasAction($action, $actions)
{
if (is_array($actions)) {
return in_array($action, $actions);
} }
return false; return $actions === '*';
} }
/** /**
@@ -73,105 +109,95 @@ class Acl extends Base
*/ */
public function isPublicAction($controller, $action) public function isPublicAction($controller, $action)
{ {
return $this->isAllowedAction($this->public_actions, $controller, $action); return $this->matchAcl($this->public_acl, $controller, $action);
} }
/** /**
* Return true if the given action is allowed for a regular user * Return true if the given action is for admins
* *
* @access public * @access public
* @param string $controller Controller name * @param string $controller Controller name
* @param string $action Action name * @param string $action Action name
* @return bool * @return bool
*/ */
public function isUserAction($controller, $action) public function isAdminAction($controller, $action)
{ {
return $this->isAllowedAction($this->user_actions, $controller, $action); return $this->matchAcl($this->admin_acl, $controller, $action);
} }
/** /**
* Return true if the logged user is admin * Return true if the given action is for project managers
* *
* @access public * @access public
* @param string $controller Controller name
* @param string $action Action name
* @return bool * @return bool
*/ */
public function isAdminUser() public function isManagerAction($controller, $action)
{ {
return isset($this->session['user']['is_admin']) && $this->session['user']['is_admin'] === true; return $this->matchAcl($this->manager_acl, $controller, $action);
} }
/** /**
* Return true if the logged user is not admin * Return true if the given action is for project members
* *
* @access public * @access public
* @param string $controller Controller name
* @param string $action Action name
* @return bool * @return bool
*/ */
public function isRegularUser() public function isMemberAction($controller, $action)
{ {
return isset($this->session['user']['is_admin']) && $this->session['user']['is_admin'] === false; return $this->matchAcl($this->member_acl, $controller, $action);
} }
/** /**
* Get the connected user id * Return true if the visitor is allowed to access to the given page
* * We suppose the user already authenticated
* @access public
* @return integer
*/
public function getUserId()
{
return isset($this->session['user']['id']) ? (int) $this->session['user']['id'] : 0;
}
/**
* Check if the given user_id is the connected user
*
* @param integer $user_id User id
* @return boolean
*/
public function isCurrentUser($user_id)
{
return $this->acl->getUserId() == $user_id;
}
/**
* Check is the user is connected
* *
* @access public * @access public
* @param string $controller Controller name
* @param string $action Action name
* @param integer $project_id Project id
* @return bool * @return bool
*/ */
public function isLogged() public function isAllowed($controller, $action, $project_id = 0)
{ {
return ! empty($this->session['user']); // If you are admin you have access to everything
} if ($this->userSession->isAdmin()) {
return true;
/**
* Check is the user was authenticated with the RememberMe or set the value
*
* @access public
* @param bool $value Set true if the user use the RememberMe
* @return bool
*/
public function isRememberMe($value = null)
{
if ($value !== null) {
$this->session['is_remember_me'] = $value;
} }
return empty($this->session['is_remember_me']) ? false : $this->session['is_remember_me']; // If you access to an admin action, your are not allowed
if ($this->isAdminAction($controller, $action)) {
return false;
}
// Check project manager permissions
if ($this->isManagerAction($controller, $action)) {
return $this->isManagerActionAllowed($project_id);
}
// Check project member permissions
if ($this->isMemberAction($controller, $action)) {
return $this->isMemberActionAllowed($project_id);
}
// Other applications actions are allowed
return true;
} }
/** public function isManagerActionAllowed($project_id)
* Check if an action is allowed for the logged user
*
* @access public
* @param string $controller Controller name
* @param string $action Action name
* @return bool
*/
public function isPageAccessAllowed($controller, $action)
{ {
return $this->isPublicAction($controller, $action) || if ($this->userSession->isAdmin()) {
$this->isAdminUser() || return true;
($this->isRegularUser() && $this->isUserAction($controller, $action)); }
return $project_id > 0 && $this->projectPermission->isManager($project_id, $this->userSession->getId());
}
public function isMemberActionAllowed($project_id)
{
return $project_id > 0 && $this->projectPermission->isMember($project_id, $this->userSession->getId());
} }
} }

View File

@@ -41,13 +41,8 @@ class Authentication extends Base
*/ */
public function isAuthenticated($controller, $action) public function isAuthenticated($controller, $action)
{ {
// If the action is public we don't need to do any checks
if ($this->acl->isPublicAction($controller, $action)) {
return true;
}
// If the user is already logged it's ok // If the user is already logged it's ok
if ($this->acl->isLogged()) { if ($this->userSession->isLogged()) {
// We update each time the RememberMe cookie tokens // We update each time the RememberMe cookie tokens
if ($this->backend('rememberMe')->hasCookie()) { if ($this->backend('rememberMe')->hasCookie()) {
@@ -117,7 +112,7 @@ class Authentication extends Base
if (! empty($values['remember_me'])) { if (! empty($values['remember_me'])) {
$credentials = $this->backend('rememberMe') $credentials = $this->backend('rememberMe')
->create($this->acl->getUserId(), Request::getIpAddress(), Request::getUserAgent()); ->create($this->userSession->getId(), Request::getIpAddress(), Request::getUserAgent());
$this->backend('rememberMe')->writeCookie($credentials['token'], $credentials['sequence'], $credentials['expiration']); $this->backend('rememberMe')->writeCookie($credentials['token'], $credentials['sequence'], $credentials['expiration']);
} }

View File

@@ -39,6 +39,7 @@ use Pimple\Container;
* @property \Model\TaskValidator $taskValidator * @property \Model\TaskValidator $taskValidator
* @property \Model\TimeTracking $timeTracking * @property \Model\TimeTracking $timeTracking
* @property \Model\User $user * @property \Model\User $user
* @property \Model\UserSession $userSession
* @property \Model\Webhook $webhook * @property \Model\Webhook $webhook
*/ */
abstract class Base abstract class Base

View File

@@ -66,7 +66,7 @@ class Notification extends Base
{ {
// Exclude the connected user // Exclude the connected user
if (Session::isOpen()) { if (Session::isOpen()) {
$exclude_users[] = $this->acl->getUserId(); $exclude_users[] = $this->userSession->getId();
} }
$users = $this->getUsersWithNotification($project_id, $exclude_users); $users = $this->getUsersWithNotification($project_id, $exclude_users);

View File

@@ -109,7 +109,7 @@ class Project extends Base
foreach ($projects as $key => $project) { foreach ($projects as $key => $project) {
if (! $this->projectPermission->isUserAllowed($project['id'], $this->acl->getUserId())) { if (! $this->projectPermission->isUserAllowed($project['id'], $this->userSession->getId())) {
unset($projects[$key]); unset($projects[$key]);
} }
} }
@@ -295,7 +295,7 @@ class Project extends Base
} }
if ($add_user && $user_id) { if ($add_user && $user_id) {
$this->projectPermission->allowUser($project_id, $user_id); $this->projectPermission->addManager($project_id, $user_id);
} }
$this->category->createDefaultCategories($project_id); $this->category->createDefaultCategories($project_id);

View File

@@ -92,7 +92,7 @@ class ProjectPermission extends Base
* @param integer $project_id Project id * @param integer $project_id Project id
* @return array * @return array
*/ */
public function getOwners($project_id) public function getManagers($project_id)
{ {
$users = $this->db $users = $this->db
->table(self::TABLE) ->table(self::TABLE)
@@ -118,13 +118,13 @@ class ProjectPermission extends Base
$users = array( $users = array(
'allowed' => array(), 'allowed' => array(),
'not_allowed' => array(), 'not_allowed' => array(),
'owners' => array(), 'managers' => array(),
); );
$all_users = $this->user->getList(); $all_users = $this->user->getList();
$users['allowed'] = $this->getMembers($project_id); $users['allowed'] = $this->getMembers($project_id);
$users['owners'] = $this->getOwners($project_id); $users['managers'] = $this->getManagers($project_id);
foreach ($all_users as $user_id => $username) { foreach ($all_users as $user_id => $username) {
@@ -137,14 +137,14 @@ class ProjectPermission extends Base
} }
/** /**
* Allow a specific user for a given project * Add a new project member
* *
* @access public * @access public
* @param integer $project_id Project id * @param integer $project_id Project id
* @param integer $user_id User id * @param integer $user_id User id
* @return bool * @return bool
*/ */
public function allowUser($project_id, $user_id) public function addMember($project_id, $user_id)
{ {
return $this->db return $this->db
->table(self::TABLE) ->table(self::TABLE)
@@ -152,7 +152,39 @@ class ProjectPermission extends Base
} }
/** /**
* Make the specific user owner of the given project * Remove a member
*
* @access public
* @param integer $project_id Project id
* @param integer $user_id User id
* @return bool
*/
public function revokeMember($project_id, $user_id)
{
return $this->db
->table(self::TABLE)
->eq('project_id', $project_id)
->eq('user_id', $user_id)
->remove();
}
/**
* Add a project manager
*
* @access public
* @param integer $project_id Project id
* @param integer $user_id User id
* @return bool
*/
public function addManager($project_id, $user_id)
{
return $this->db
->table(self::TABLE)
->save(array('project_id' => $project_id, 'user_id' => $user_id, 'is_owner' => 1));
}
/**
* Change the role of a member
* *
* @access public * @access public
* @param integer $project_id Project id * @param integer $project_id Project id
@@ -160,7 +192,7 @@ class ProjectPermission extends Base
* @param integer $is_owner Is user owner of the project * @param integer $is_owner Is user owner of the project
* @return bool * @return bool
*/ */
public function setOwner($project_id, $user_id, $is_owner = 1) public function changeRole($project_id, $user_id, $is_owner)
{ {
return $this->db return $this->db
->table(self::TABLE) ->table(self::TABLE)
@@ -169,23 +201,6 @@ class ProjectPermission extends Base
->update(array('is_owner' => $is_owner)); ->update(array('is_owner' => $is_owner));
} }
/**
* Revoke a specific user for a given project
*
* @access public
* @param integer $project_id Project id
* @param integer $user_id User id
* @return bool
*/
public function revokeUser($project_id, $user_id)
{
return $this->db
->table(self::TABLE)
->eq('project_id', $project_id)
->eq('user_id', $user_id)
->remove();
}
/** /**
* Check if a specific user is member of a project * Check if a specific user is member of a project
* *
@@ -200,29 +215,29 @@ class ProjectPermission extends Base
return true; return true;
} }
return (bool) $this->db return $this->db
->table(self::TABLE) ->table(self::TABLE)
->eq('project_id', $project_id) ->eq('project_id', $project_id)
->eq('user_id', $user_id) ->eq('user_id', $user_id)
->count(); ->count() === 1;
} }
/** /**
* Check if a specific user is owner of a given project * Check if a specific user is manager of a given project
* *
* @access public * @access public
* @param integer $project_id Project id * @param integer $project_id Project id
* @param integer $user_id User id * @param integer $user_id User id
* @return bool * @return bool
*/ */
public function isOwner($project_id, $user_id) public function isManager($project_id, $user_id)
{ {
return (bool) $this->db return $this->db
->table(self::TABLE) ->table(self::TABLE)
->eq('project_id', $project_id) ->eq('project_id', $project_id)
->eq('user_id', $user_id) ->eq('user_id', $user_id)
->eq('is_owner', 1) ->eq('is_owner', 1)
->count(); ->count() === 1;
} }
/** /**
@@ -247,36 +262,11 @@ class ProjectPermission extends Base
*/ */
public function isEverybodyAllowed($project_id) public function isEverybodyAllowed($project_id)
{ {
return (bool) $this->db return $this->db
->table(Project::TABLE) ->table(Project::TABLE)
->eq('id', $project_id) ->eq('id', $project_id)
->eq('is_everybody_allowed', 1) ->eq('is_everybody_allowed', 1)
->count(); ->count() === 1;
}
/**
* Check if a specific user is allowed to manage a project
*
* @access public
* @param integer $project_id Project id
* @param integer $user_id User id
* @return bool
*/
public function adminAllowed($project_id, $user_id)
{
if ($this->user->isAdmin($user_id)) {
return true;
}
if ($this->isUserAllowed($project_id, $user_id) && $this->project->isPrivate($project_id)) {
return true;
}
if ($this->isOwner($project_id, $user_id)) {
return true;
}
return false;
} }
/** /**
@@ -336,7 +326,7 @@ class ProjectPermission extends Base
$users = $this->getMembers($project_from); $users = $this->getMembers($project_from);
foreach ($users as $user_id => $name) { foreach ($users as $user_id => $name) {
if (! $this->allowUser($project_to, $user_id)) { if (! $this->addMember($project_to, $user_id)) { // TODO: Duplicate managers
return false; return false;
} }
} }

View File

@@ -227,6 +227,7 @@ class SubTask extends Base
$subtasks = $db->table(SubTask::TABLE) $subtasks = $db->table(SubTask::TABLE)
->columns('title', 'time_estimated') ->columns('title', 'time_estimated')
->eq('task_id', $src_task_id) ->eq('task_id', $src_task_id)
->asc('id') // Explicit sorting for postgresql
->findAll(); ->findAll();
foreach ($subtasks as &$subtask) { foreach ($subtasks as &$subtask) {

View File

@@ -73,6 +73,7 @@ class TaskExport extends Base
LEFT JOIN columns ON columns.id = tasks.column_id LEFT JOIN columns ON columns.id = tasks.column_id
LEFT JOIN projects ON projects.id = tasks.project_id LEFT JOIN projects ON projects.id = tasks.project_id
WHERE tasks.date_creation >= ? AND tasks.date_creation <= ? AND tasks.project_id = ? WHERE tasks.date_creation >= ? AND tasks.date_creation <= ? AND tasks.project_id = ?
ORDER BY tasks.id ASC
'; ';
if (! is_numeric($from)) { if (! is_numeric($from)) {

View File

@@ -20,10 +20,10 @@ class TaskPermission extends Base
*/ */
public function canRemoveTask(array $task) public function canRemoveTask(array $task)
{ {
if ($this->acl->isAdminUser()) { if ($this->userSession->isAdmin()) {
return true; return true;
} }
else if (isset($task['creator_id']) && $task['creator_id'] == $this->acl->getUserId()) { else if (isset($task['creator_id']) && $task['creator_id'] == $this->userSession->getId()) {
return true; return true;
} }

View File

@@ -72,6 +72,7 @@ class TaskPosition extends Base
->eq('column_id', $board_column_id) ->eq('column_id', $board_column_id)
->neq('id', $task_id) ->neq('id', $task_id)
->asc('position') ->asc('position')
->asc('id') // Fix Postgresql unit test
->findAllByColumn('id'); ->findAllByColumn('id');
} }

View File

@@ -48,46 +48,11 @@ class User extends Base
*/ */
public function isAdmin($user_id) public function isAdmin($user_id)
{ {
$result = $this->db return $this->db
->table(User::TABLE) ->table(User::TABLE)
->eq('id', $user_id) ->eq('id', $user_id)
->eq('is_admin', 1) ->eq('is_admin', 1)
->count(); ->count() === 1;
return $result > 0;
}
/**
* Get the default project from the session
*
* @access public
* @return integer
*/
public function getFavoriteProjectId()
{
return isset($this->session['user']['default_project_id']) ? $this->session['user']['default_project_id'] : 0;
}
/**
* Get the last seen project from the session
*
* @access public
* @return integer
*/
public function getLastSeenProjectId()
{
return empty($this->session['last_show_project_id']) ? 0 : $this->session['last_show_project_id'];
}
/**
* Set the last seen project from the session
*
* @access public
* @@param integer $project_id Project id
*/
public function storeLastSeenProjectId($project_id)
{
$this->session['last_show_project_id'] = (int) $project_id;
} }
/** /**
@@ -287,7 +252,7 @@ class User extends Base
$result = $this->db->table(self::TABLE)->eq('id', $values['id'])->update($values); $result = $this->db->table(self::TABLE)->eq('id', $values['id'])->update($values);
// If the user is connected refresh his session // If the user is connected refresh his session
if (Session::isOpen() && $this->acl->getUserId() == $values['id']) { if (Session::isOpen() && $this->userSession->getId() == $values['id']) {
$this->updateSession(); $this->updateSession();
} }
@@ -337,7 +302,7 @@ class User extends Base
public function updateSession(array $user = array()) public function updateSession(array $user = array())
{ {
if (empty($user)) { if (empty($user)) {
$user = $this->getById($this->acl->getUserId()); $user = $this->getById($this->userSession->getId());
} }
if (isset($user['password'])) { if (isset($user['password'])) {

89
app/Model/UserSession.php Normal file
View File

@@ -0,0 +1,89 @@
<?php
namespace Model;
/**
* User Session
*
* @package model
* @author Frederic Guillot
*/
class UserSession extends Base
{
/**
* Return true if the logged user is admin
*
* @access public
* @return bool
*/
public function isAdmin()
{
return isset($this->session['user']['is_admin']) && $this->session['user']['is_admin'] === true;
}
/**
* Get the connected user id
*
* @access public
* @return integer
*/
public function getId()
{
return isset($this->session['user']['id']) ? (int) $this->session['user']['id'] : 0;
}
/**
* Check if the given user_id is the connected user
*
* @param integer $user_id User id
* @return boolean
*/
public function isCurrentUser($user_id)
{
return $this->getId() == $user_id;
}
/**
* Check is the user is connected
*
* @access public
* @return bool
*/
public function isLogged()
{
return ! empty($this->session['user']);
}
/**
* Get the last seen project from the session
*
* @access public
* @return integer
*/
public function getLastSeenProjectId()
{
return empty($this->session['last_show_project_id']) ? 0 : $this->session['last_show_project_id'];
}
/**
* Get the default project from the session
*
* @access public
* @return integer
*/
public function getFavoriteProjectId()
{
return isset($this->session['user']['default_project_id']) ? $this->session['user']['default_project_id'] : 0;
}
/**
* Set the last seen project from the session
*
* @access public
* @param integer $project_id Project id
*/
public function storeLastSeenProjectId($project_id)
{
$this->session['last_show_project_id'] = (int) $project_id;
}
}

View File

@@ -5,7 +5,31 @@ namespace Schema;
use PDO; use PDO;
use Core\Security; use Core\Security;
const VERSION = 39; const VERSION = 40;
function version_40($pdo)
{
// Avoid some full table scans
$pdo->exec('CREATE INDEX users_admin_idx ON users(is_admin)');
$pdo->exec('CREATE INDEX columns_project_idx ON columns(project_id)');
$pdo->exec('CREATE INDEX tasks_project_idx ON tasks(project_id)');
$pdo->exec('CREATE INDEX swimlanes_project_idx ON swimlanes(project_id)');
$pdo->exec('CREATE INDEX categories_project_idx ON project_has_categories(project_id)');
$pdo->exec('CREATE INDEX subtasks_task_idx ON task_has_subtasks(task_id)');
$pdo->exec('CREATE INDEX files_task_idx ON task_has_files(task_id)');
$pdo->exec('CREATE INDEX comments_task_idx ON comments(task_id)');
// Set the ownership for all private projects
$rq = $pdo->prepare('SELECT id FROM projects WHERE is_private=1');
$rq->execute();
$project_ids = $rq->fetchAll(PDO::FETCH_COLUMN, 0);
$rq = $pdo->prepare('UPDATE project_has_users SET is_owner=1 WHERE project_id=?');
foreach ($project_ids as $project_id) {
$rq->execute(array($project_id));
}
}
function version_39($pdo) function version_39($pdo)
{ {

View File

@@ -5,7 +5,31 @@ namespace Schema;
use PDO; use PDO;
use Core\Security; use Core\Security;
const VERSION = 20; const VERSION = 21;
function version_21($pdo)
{
// Avoid some full table scans
$pdo->exec('CREATE INDEX users_admin_idx ON users(is_admin)');
$pdo->exec('CREATE INDEX columns_project_idx ON columns(project_id)');
$pdo->exec('CREATE INDEX tasks_project_idx ON tasks(project_id)');
$pdo->exec('CREATE INDEX swimlanes_project_idx ON swimlanes(project_id)');
$pdo->exec('CREATE INDEX categories_project_idx ON project_has_categories(project_id)');
$pdo->exec('CREATE INDEX subtasks_task_idx ON task_has_subtasks(task_id)');
$pdo->exec('CREATE INDEX files_task_idx ON task_has_files(task_id)');
$pdo->exec('CREATE INDEX comments_task_idx ON comments(task_id)');
// Set the ownership for all private projects
$rq = $pdo->prepare("SELECT id FROM projects WHERE is_private='1'");
$rq->execute();
$project_ids = $rq->fetchAll(PDO::FETCH_COLUMN, 0);
$rq = $pdo->prepare('UPDATE project_has_users SET is_owner=1 WHERE project_id=?');
foreach ($project_ids as $project_id) {
$rq->execute(array($project_id));
}
}
function version_20($pdo) function version_20($pdo)
{ {

View File

@@ -5,7 +5,31 @@ namespace Schema;
use Core\Security; use Core\Security;
use PDO; use PDO;
const VERSION = 38; const VERSION = 39;
function version_39($pdo)
{
// Avoid some full table scans
$pdo->exec('CREATE INDEX users_admin_idx ON users(is_admin)');
$pdo->exec('CREATE INDEX columns_project_idx ON columns(project_id)');
$pdo->exec('CREATE INDEX tasks_project_idx ON tasks(project_id)');
$pdo->exec('CREATE INDEX swimlanes_project_idx ON swimlanes(project_id)');
$pdo->exec('CREATE INDEX categories_project_idx ON project_has_categories(project_id)');
$pdo->exec('CREATE INDEX subtasks_task_idx ON task_has_subtasks(task_id)');
$pdo->exec('CREATE INDEX files_task_idx ON task_has_files(task_id)');
$pdo->exec('CREATE INDEX comments_task_idx ON comments(task_id)');
// Set the ownership for all private projects
$rq = $pdo->prepare('SELECT id FROM projects WHERE is_private=1');
$rq->execute();
$project_ids = $rq->fetchAll(PDO::FETCH_COLUMN, 0);
$rq = $pdo->prepare('UPDATE project_has_users SET is_owner=1 WHERE project_id=?');
foreach ($project_ids as $project_id) {
$rq->execute(array($project_id));
}
}
function version_38($pdo) function version_38($pdo)
{ {

View File

@@ -46,6 +46,7 @@ class ClassProvider implements ServiceProviderInterface
'TaskValidator', 'TaskValidator',
'TimeTracking', 'TimeTracking',
'User', 'User',
'UserSession',
'Webhook', 'Webhook',
), ),
'Core' => array( 'Core' => array(

View File

@@ -19,6 +19,7 @@ use Pimple\Container;
* @property \Model\Task $task * @property \Model\Task $task
* @property \Model\TaskExport $taskExport * @property \Model\TaskExport $taskExport
* @property \Model\TaskFinder $taskFinder * @property \Model\TaskFinder $taskFinder
* @property \Model\UserSession $userSession
*/ */
abstract class Base abstract class Base
{ {

View File

@@ -16,7 +16,7 @@ class BootstrapSubscriber extends Base implements EventSubscriberInterface
public function setup() public function setup()
{ {
$this->container['config']->setupTranslations(); $this->config->setupTranslations();
$this->container['config']->setupTimezone(); $this->config->setupTimezone();
} }
} }

View File

@@ -30,14 +30,14 @@ class ProjectActivitySubscriber extends Base implements EventSubscriberInterface
public function execute(GenericEvent $event) public function execute(GenericEvent $event)
{ {
// Executed only when someone is logged // Executed only when someone is logged
if ($this->container['acl']->isLogged() && isset($event['task_id'])) { if ($this->userSession->isLogged() && isset($event['task_id'])) {
$values = $this->getValues($event); $values = $this->getValues($event);
$this->projectActivity->createEvent( $this->projectActivity->createEvent(
$values['task']['project_id'], $values['task']['project_id'],
$values['task']['id'], $values['task']['id'],
$this->acl->getUserId(), $this->userSession->getId(),
$event->getName(), $event->getName(),
$values $values
); );

View File

@@ -1,12 +1,12 @@
<section id="main"> <section id="main">
<div class="page-header"> <div class="page-header">
<ul> <ul>
<?php if ($this->acl->isAdminUser()): ?> <?php if ($this->userSession->isAdmin()): ?>
<li><i class="fa fa-plus fa-fw"></i><?= $this->a(t('New project'), 'project', 'create') ?></li> <li><i class="fa fa-plus fa-fw"></i><?= $this->a(t('New project'), 'project', 'create') ?></li>
<?php endif ?> <?php endif ?>
<li><i class="fa fa-lock fa-fw"></i><?= $this->a(t('New private project'), 'project', 'create', array('private' => 1)) ?></li> <li><i class="fa fa-lock fa-fw"></i><?= $this->a(t('New private project'), 'project', 'create', array('private' => 1)) ?></li>
<li><i class="fa fa-folder fa-fw"></i><?= $this->a(t('Project management'), 'project', 'index') ?></li> <li><i class="fa fa-folder fa-fw"></i><?= $this->a(t('Project management'), 'project', 'index') ?></li>
<?php if ($this->acl->isAdminUser()): ?> <?php if ($this->userSession->isAdmin()): ?>
<li><i class="fa fa-user fa-fw"></i><?= $this->a(t('User management'), 'user', 'index') ?></li> <li><i class="fa fa-user fa-fw"></i><?= $this->a(t('User management'), 'user', 'index') ?></li>
<li><i class="fa fa-cog fa-fw"></i><?= $this->a(t('Settings'), 'config', 'index') ?></li> <li><i class="fa fa-cog fa-fw"></i><?= $this->a(t('Settings'), 'config', 'index') ?></li>
<?php endif ?> <?php endif ?>

View File

@@ -14,7 +14,7 @@
<?= $this->a('#'.$project['id'], 'board', 'show', array('project_id' => $project['id']), false, 'dashboard-table-link') ?> <?= $this->a('#'.$project['id'], 'board', 'show', array('project_id' => $project['id']), false, 'dashboard-table-link') ?>
</td> </td>
<td> <td>
<?php if ($this->projectPermission->adminAllowed($project['id'], $this->acl->getUserId())): ?> <?php if ($this->projectPermission->isManager($project['id'], $this->userSession->getId())): ?>
<?= $this->a('<i class="fa fa-cog"></i>', 'project', 'show', array('project_id' => $project['id']), false, 'dashboard-table-link', t('Settings')) ?>&nbsp; <?= $this->a('<i class="fa fa-cog"></i>', 'project', 'show', array('project_id' => $project['id']), false, 'dashboard-table-link', t('Settings')) ?>&nbsp;
<?php endif ?> <?php endif ?>
<?= $this->a($this->e($project['name']), 'board', 'show', array('project_id' => $project['id'])) ?> <?= $this->a($this->e($project['name']), 'board', 'show', array('project_id' => $project['id'])) ?>

View File

@@ -1,7 +1,7 @@
<section id="main"> <section id="main">
<section> <section>
<h3><?= t('Change assignee for the task "%s"', $values['title']) ?></h3> <h3><?= t('Change assignee for the task "%s"', $values['title']) ?></h3>
<form method="post" action="<?= $this->u('board', 'updateAssignee', array('task_id' => $values['id'])) ?>"> <form method="post" action="<?= $this->u('board', 'updateAssignee', array('task_id' => $values['id'], 'project_id' => $values['project_id'])) ?>">
<?= $this->formCsrf() ?> <?= $this->formCsrf() ?>

View File

@@ -1,7 +1,7 @@
<section id="main"> <section id="main">
<section> <section>
<h3><?= t('Change category for the task "%s"', $values['title']) ?></h3> <h3><?= t('Change category for the task "%s"', $values['title']) ?></h3>
<form method="post" action="<?= $this->u('board', 'updateCategory', array('task_id' => $values['id'])) ?>"> <form method="post" action="<?= $this->u('board', 'updateCategory', array('task_id' => $values['id'], 'project_id' => $values['project_id'])) ?>">
<?= $this->formCsrf() ?> <?= $this->formCsrf() ?>

View File

@@ -27,7 +27,7 @@
<i class="fa fa-line-chart fa-fw"></i> <i class="fa fa-line-chart fa-fw"></i>
<?= $this->a(t('Analytics'), 'analytic', 'tasks', array('project_id' => $project['id'])) ?> <?= $this->a(t('Analytics'), 'analytic', 'tasks', array('project_id' => $project['id'])) ?>
</li> </li>
<?php if ($this->projectPermission->adminAllowed($project['id'], $this->acl->getUserId())): ?> <?php if ($this->acl->isManagerActionAllowed($project['id'])): ?>
<li><i class="fa fa-cog fa-fw"></i> <li><i class="fa fa-cog fa-fw"></i>
<?= $this->a(t('Configure'), 'project', 'show', array('project_id' => $project['id'])) ?> <?= $this->a(t('Configure'), 'project', 'show', array('project_id' => $project['id'])) ?>
<?php endif ?> <?php endif ?>

View File

@@ -4,7 +4,7 @@
trim($this->render('subtask/icons', array('subtask' => $subtask))) . $this->e($subtask['title']), trim($this->render('subtask/icons', array('subtask' => $subtask))) . $this->e($subtask['title']),
'board', 'board',
'toggleSubtask', 'toggleSubtask',
array('task_id' => $subtask['task_id'], 'subtask_id' => $subtask['id']) array('task_id' => $subtask['task_id'], 'project_id' => $task['project_id'], 'subtask_id' => $subtask['id'])
) ?> ) ?>
<?= $this->e(empty($subtask['username']) ? '' : ' ['.$this->getFullname($subtask).']') ?> <?= $this->e(empty($subtask['username']) ? '' : ' ['.$this->getFullname($subtask).']') ?>

View File

@@ -1,5 +1,3 @@
<?php if ($not_editable): ?> <?php if ($not_editable): ?>
<div class="task-board task-<?= $task['color_id'] ?> <?= $task['date_modification'] > time() - $board_highlight_period ? 'task-board-recent' : '' ?>"> <div class="task-board task-<?= $task['color_id'] ?> <?= $task['date_modification'] > time() - $board_highlight_period ? 'task-board-recent' : '' ?>">
@@ -37,10 +35,10 @@
data-owner-id="<?= $task['owner_id'] ?>" data-owner-id="<?= $task['owner_id'] ?>"
data-category-id="<?= $task['category_id'] ?>" data-category-id="<?= $task['category_id'] ?>"
data-due-date="<?= $task['date_due'] ?>" data-due-date="<?= $task['date_due'] ?>"
data-task-url="<?= $this->u('task', 'show', array('task_id' => $task['id'])) ?>" data-task-url="<?= $this->u('task', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>"
title="<?= t('View this task') ?>"> title="<?= t('View this task') ?>">
<?= $this->a('#'.$task['id'], 'task', 'edit', array('task_id' => $task['id']), false, 'task-edit-popover', t('Edit this task')) ?> <?= $this->a('#'.$task['id'], 'task', 'edit', array('task_id' => $task['id'], 'project_id' => $task['project_id']), false, 'task-edit-popover', t('Edit this task')) ?>
<?php if ($task['reference']): ?> <?php if ($task['reference']): ?>
<span class="task-board-reference" title="<?= t('Reference') ?>"> <span class="task-board-reference" title="<?= t('Reference') ?>">
@@ -48,12 +46,12 @@
</span> </span>
<?php endif ?> <?php endif ?>
<span class="task-board-user <?= $this->acl->isCurrentUser($task['owner_id']) ? 'task-board-current-user' : '' ?>"> <span class="task-board-user <?= $this->userSession->isCurrentUser($task['owner_id']) ? 'task-board-current-user' : '' ?>">
<?= $this->a( <?= $this->a(
(! empty($task['owner_id']) ? t('Assigned to %s', $task['assignee_name'] ?: $task['assignee_username']) : t('Nobody assigned')), (! empty($task['owner_id']) ? t('Assigned to %s', $task['assignee_name'] ?: $task['assignee_username']) : t('Nobody assigned')),
'board', 'board',
'changeAssignee', 'changeAssignee',
array('task_id' => $task['id']), array('task_id' => $task['id'], 'project_id' => $task['project_id']),
false, false,
'assignee-popover', 'assignee-popover',
t('Change assignee') t('Change assignee')
@@ -78,7 +76,7 @@
$this->inList($task['category_id'], $categories), $this->inList($task['category_id'], $categories),
'board', 'board',
'changeCategory', 'changeCategory',
array('task_id' => $task['id']), array('task_id' => $task['id'], 'project_id' => $task['project_id']),
false, false,
'category-popover', 'category-popover',
t('Change category') t('Change category')
@@ -100,19 +98,19 @@
<div class="task-board-icons"> <div class="task-board-icons">
<?php if (! empty($task['nb_subtasks'])): ?> <?php if (! empty($task['nb_subtasks'])): ?>
<span title="<?= t('Sub-Tasks') ?>" class="task-board-tooltip" data-href="<?= $this->u('board', 'subtasks', array('task_id' => $task['id'])) ?>"><?= $task['nb_completed_subtasks'].'/'.$task['nb_subtasks'] ?> <i class="fa fa-bars"></i></span> <span title="<?= t('Sub-Tasks') ?>" class="task-board-tooltip" data-href="<?= $this->u('board', 'subtasks', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>"><?= $task['nb_completed_subtasks'].'/'.$task['nb_subtasks'] ?> <i class="fa fa-bars"></i></span>
<?php endif ?> <?php endif ?>
<?php if (! empty($task['nb_files'])): ?> <?php if (! empty($task['nb_files'])): ?>
<span title="<?= t('Attachments') ?>" class="task-board-tooltip" data-href="<?= $this->u('board', 'attachments', array('task_id' => $task['id'])) ?>"><?= $task['nb_files'] ?> <i class="fa fa-paperclip"></i></span> <span title="<?= t('Attachments') ?>" class="task-board-tooltip" data-href="<?= $this->u('board', 'attachments', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>"><?= $task['nb_files'] ?> <i class="fa fa-paperclip"></i></span>
<?php endif ?> <?php endif ?>
<?php if (! empty($task['nb_comments'])): ?> <?php if (! empty($task['nb_comments'])): ?>
<span title="<?= p($task['nb_comments'], t('%d comment', $task['nb_comments']), t('%d comments', $task['nb_comments'])) ?>" class="task-board-tooltip" data-href="<?= $this->u('board', 'comments', array('task_id' => $task['id'])) ?>"><?= $task['nb_comments'] ?> <i class="fa fa-comment-o"></i></span> <span title="<?= p($task['nb_comments'], t('%d comment', $task['nb_comments']), t('%d comments', $task['nb_comments'])) ?>" class="task-board-tooltip" data-href="<?= $this->u('board', 'comments', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>"><?= $task['nb_comments'] ?> <i class="fa fa-comment-o"></i></span>
<?php endif ?> <?php endif ?>
<?php if (! empty($task['description'])): ?> <?php if (! empty($task['description'])): ?>
<span title="<?= t('Description') ?>" class="task-board-tooltip" data-href="<?= $this->u('board', 'description', array('task_id' => $task['id'])) ?>"> <span title="<?= t('Description') ?>" class="task-board-tooltip" data-href="<?= $this->u('board', 'description', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>">
<?php if (! isset($not_editable)): ?> <?php if (! isset($not_editable)): ?>
<a class="task-description-popover" href="?controller=task&amp;action=description&amp;task_id=<?= $task['id'] ?>"><i class="fa fa-file-text-o" data-href="?controller=task&amp;action=description&amp;task_id=<?= $task['id'] ?>"></i></a> <a class="task-description-popover" href="?controller=task&amp;action=description&amp;task_id=<?= $task['id'] ?>"><i class="fa fa-file-text-o" data-href="?controller=task&amp;action=description&amp;task_id=<?= $task['id'] ?>"></i></a>
<?php else: ?> <?php else: ?>

View File

@@ -2,7 +2,7 @@
<h2><?= t('Add a comment') ?></h2> <h2><?= t('Add a comment') ?></h2>
</div> </div>
<form method="post" action="<?= $this->u('comment', 'save', array('task_id' => $task['id'])) ?>" autocomplete="off"> <form method="post" action="<?= $this->u('comment', 'save', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>" autocomplete="off">
<?= $this->formCsrf() ?> <?= $this->formCsrf() ?>
<?= $this->formHidden('task_id', $values) ?> <?= $this->formHidden('task_id', $values) ?>
<?= $this->formHidden('user_id', $values) ?> <?= $this->formHidden('user_id', $values) ?>
@@ -30,7 +30,7 @@
<input type="submit" value="<?= t('Save') ?>" class="btn btn-blue"/> <input type="submit" value="<?= t('Save') ?>" class="btn btn-blue"/>
<?php if (! isset($skip_cancel)): ?> <?php if (! isset($skip_cancel)): ?>
<?= t('or') ?> <?= t('or') ?>
<?= $this->a(t('cancel'), 'task', 'show', array('task_id' => $task['id'])) ?> <?= $this->a(t('cancel'), 'task', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>
<?php endif ?> <?php endif ?>
</div> </div>
</form> </form>

View File

@@ -2,7 +2,7 @@
<h2><?= t('Edit a comment') ?></h2> <h2><?= t('Edit a comment') ?></h2>
</div> </div>
<form method="post" action="<?= $this->u('comment', 'update', array('task_id' => $task['id'], 'comment_id' => $comment['id'])) ?>" autocomplete="off"> <form method="post" action="<?= $this->u('comment', 'update', array('task_id' => $task['id'], 'project_id' => $task['project_id'], 'comment_id' => $comment['id'])) ?>" autocomplete="off">
<?= $this->formCsrf() ?> <?= $this->formCsrf() ?>
<?= $this->formHidden('id', $values) ?> <?= $this->formHidden('id', $values) ?>
@@ -30,6 +30,6 @@
<div class="form-actions"> <div class="form-actions">
<input type="submit" value="<?= t('Update') ?>" class="btn btn-blue"/> <input type="submit" value="<?= t('Update') ?>" class="btn btn-blue"/>
<?= t('or') ?> <?= t('or') ?>
<?= $this->a(t('cancel'), 'task', 'show', array('task_id' => $task['id'])) ?> <?= $this->a(t('cancel'), 'task', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>
</div> </div>
</form> </form>

View File

@@ -10,8 +10,8 @@
<?= $this->render('comment/show', array('comment' => $comment, 'task' => $task, 'preview' => true)) ?> <?= $this->render('comment/show', array('comment' => $comment, 'task' => $task, 'preview' => true)) ?>
<div class="form-actions"> <div class="form-actions">
<?= $this->a(t('Yes'), 'comment', 'remove', array('task_id' => $task['id'], 'comment_id' => $comment['id']), true, 'btn btn-red') ?> <?= $this->a(t('Yes'), 'comment', 'remove', array('task_id' => $task['id'], 'project_id' => $task['project_id'], 'comment_id' => $comment['id']), true, 'btn btn-red') ?>
<?= t('or') ?> <?= t('or') ?>
<?= $this->a(t('cancel'), 'task', 'show', array('task_id' => $task['id'])) ?> <?= $this->a(t('cancel'), 'task', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>
</div> </div>
</div> </div>

View File

@@ -9,12 +9,12 @@
<?php if (! isset($preview)): ?> <?php if (! isset($preview)): ?>
<ul class="comment-actions"> <ul class="comment-actions">
<li><a href="#comment-<?= $comment['id'] ?>"><?= t('link') ?></a></li> <li><a href="#comment-<?= $comment['id'] ?>"><?= t('link') ?></a></li>
<?php if ((! isset($not_editable) || ! $not_editable) && ($this->acl->isAdminUser() || $this->acl->isCurrentUser($comment['user_id']))): ?> <?php if ((! isset($not_editable) || ! $not_editable) && ($this->userSession->isAdmin() || $this->userSession->isCurrentUser($comment['user_id']))): ?>
<li> <li>
<?= $this->a(t('remove'), 'comment', 'confirm', array('task_id' => $task['id'], 'comment_id' => $comment['id'])) ?> <?= $this->a(t('remove'), 'comment', 'confirm', array('task_id' => $task['id'], 'project_id' => $task['project_id'], 'comment_id' => $comment['id'])) ?>
</li> </li>
<li> <li>
<?= $this->a(t('edit'), 'comment', 'edit', array('task_id' => $task['id'], 'comment_id' => $comment['id'])) ?> <?= $this->a(t('edit'), 'comment', 'edit', array('task_id' => $task['id'], 'project_id' => $task['project_id'], 'comment_id' => $comment['id'])) ?>
</li> </li>
<?php endif ?> <?php endif ?>
</ul> </ul>
@@ -33,7 +33,16 @@
) )
) ?> ) ?>
<?php else: ?> <?php else: ?>
<?= $this->markdown($comment['comment']) ?> <?= $this->markdown(
$comment['comment'],
array(
'controller' => 'task',
'action' => 'show',
'params' => array(
'project_id' => $project['id']
)
)
) ?>
<?php endif ?> <?php endif ?>
</div> </div>

View File

@@ -2,13 +2,13 @@
<h2><?= t('Attach a document') ?></h2> <h2><?= t('Attach a document') ?></h2>
</div> </div>
<form action="<?= $this->u('file', 'save', array('task_id' => $task['id'])) ?>" method="post" enctype="multipart/form-data"> <form action="<?= $this->u('file', 'save', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>" method="post" enctype="multipart/form-data">
<?= $this->formCsrf() ?> <?= $this->formCsrf() ?>
<input type="file" name="files[]" multiple /> <input type="file" name="files[]" multiple />
<div class="form-help"><?= t('Maximum size: ') ?><?= is_integer($max_size) ? $this->formatBytes($max_size) : $max_size ?></div> <div class="form-help"><?= t('Maximum size: ') ?><?= is_integer($max_size) ? $this->formatBytes($max_size) : $max_size ?></div>
<div class="form-actions"> <div class="form-actions">
<input type="submit" value="<?= t('Save') ?>" class="btn btn-blue"/> <input type="submit" value="<?= t('Save') ?>" class="btn btn-blue"/>
<?= t('or') ?> <?= t('or') ?>
<?= $this->a(t('cancel'), 'task', 'show', array('task_id' => $task['id'])) ?> <?= $this->a(t('cancel'), 'task', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>
</div> </div>
</form> </form>

View File

@@ -1,6 +1,6 @@
<div class="page-header"> <div class="page-header">
<h2><?= $this->e($file['name']) ?></h2> <h2><?= $this->e($file['name']) ?></h2>
<div class="task-file-viewer"> <div class="task-file-viewer">
<img src="<?= $this->u('file', 'image', array('file_id' => $file['id'], 'task_id' => $file['task_id'])) ?>" alt="<?= $this->e($file['name']) ?>"/> <img src="<?= $this->u('file', 'image', array('file_id' => $file['id'], 'project_id' => $task['project_id'], 'task_id' => $file['task_id'])) ?>" alt="<?= $this->e($file['name']) ?>"/>
</div> </div>
</div> </div>

View File

@@ -8,8 +8,8 @@
</p> </p>
<div class="form-actions"> <div class="form-actions">
<?= $this->a(t('Yes'), 'file', 'remove', array('task_id' => $task['id'], 'file_id' => $file['id']), true, 'btn btn-red') ?> <?= $this->a(t('Yes'), 'file', 'remove', array('task_id' => $task['id'], 'project_id' => $task['project_id'], 'file_id' => $file['id']), true, 'btn btn-red') ?>
<?= t('or') ?> <?= t('or') ?>
<?= $this->a(t('cancel'), 'task', 'show', array('task_id' => $task['id'])) ?> <?= $this->a(t('cancel'), 'task', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>
</div> </div>
</div> </div>

View File

@@ -8,12 +8,12 @@
<ul class="task-show-files"> <ul class="task-show-files">
<?php foreach ($files as $file): ?> <?php foreach ($files as $file): ?>
<li> <li>
<?= $this->a($this->e($file['name']), 'file', 'download', array('task_id' => $task['id'], 'file_id' => $file['id'])) ?> <?= $this->a($this->e($file['name']), 'file', 'download', array('task_id' => $task['id'], 'project_id' => $task['project_id'], 'file_id' => $file['id'])) ?>
<span class="task-show-file-actions"> <span class="task-show-file-actions">
<?php if ($file['is_image']): ?> <?php if ($file['is_image']): ?>
<?= $this->a(t('open'), 'file', 'open', array('task_id' => $task['id'], 'file_id' => $file['id']), false, 'file-popover') ?>, <?= $this->a(t('open'), 'file', 'open', array('task_id' => $task['id'], 'project_id' => $task['project_id'], 'file_id' => $file['id']), false, 'file-popover') ?>,
<?php endif ?> <?php endif ?>
<?= $this->a(t('remove'), 'file', 'confirm', array('task_id' => $task['id'], 'file_id' => $file['id'])) ?> <?= $this->a(t('remove'), 'file', 'confirm', array('task_id' => $task['id'], 'project_id' => $task['project_id'], 'file_id' => $file['id'])) ?>
</span> </span>
</li> </li>
<?php endforeach ?> <?php endforeach ?>

View File

@@ -44,7 +44,7 @@
<?php endif ?> <?php endif ?>
<li> <li>
<?= $this->a(t('Logout'), 'user', 'logout', array(), true) ?> <?= $this->a(t('Logout'), 'user', 'logout', array(), true) ?>
<span class="username hide-tablet">(<?= $this->a($this->e($this->getFullname()), 'user', 'show', array('user_id' => $this->acl->getUserId())) ?>)</span> <span class="username hide-tablet">(<?= $this->a($this->e($this->getFullname()), 'user', 'show', array('user_id' => $this->userSession->getId())) ?>)</span>
</li> </li>
</ul> </ul>
</nav> </nav>

View File

@@ -1,7 +1,7 @@
<section id="main"> <section id="main">
<div class="page-header"> <div class="page-header">
<ul> <ul>
<?php if ($this->acl->isAdminUser()): ?> <?php if ($this->userSession->isAdmin()): ?>
<li><i class="fa fa-plus fa-fw"></i><?= $this->a(t('New project'), 'project', 'create') ?></li> <li><i class="fa fa-plus fa-fw"></i><?= $this->a(t('New project'), 'project', 'create') ?></li>
<?php endif ?> <?php endif ?>
<li><i class="fa fa-lock fa-fw"></i><?= $this->a(t('New private project'), 'project', 'create', array('private' => 1)) ?></li> <li><i class="fa fa-lock fa-fw"></i><?= $this->a(t('New private project'), 'project', 'create', array('private' => 1)) ?></li>

View File

@@ -7,7 +7,7 @@
</div> </div>
<section class="sidebar-container" id="project-section"> <section class="sidebar-container" id="project-section">
<?= $this->render('project/sidebar', array('project' => $project, 'is_owner' => $is_owner)) ?> <?= $this->render('project/sidebar', array('project' => $project)) ?>
<div class="sidebar-content"> <div class="sidebar-content">
<?= $project_content_for_layout ?> <?= $project_content_for_layout ?>

View File

@@ -5,7 +5,7 @@
<?= $this->a(t('Summary'), 'project', 'show', array('project_id' => $project['id'])) ?> <?= $this->a(t('Summary'), 'project', 'show', array('project_id' => $project['id'])) ?>
</li> </li>
<?php if ($this->acl->isAdminUser() || $project['is_private']): ?> <?php if ($this->acl->isManagerActionAllowed($project['id'])): ?>
<li> <li>
<?= $this->a(t('Public access'), 'project', 'share', array('project_id' => $project['id'])) ?> <?= $this->a(t('Public access'), 'project', 'share', array('project_id' => $project['id'])) ?>
</li> </li>
@@ -15,27 +15,23 @@
<li> <li>
<?= $this->a(t('Edit project'), 'project', 'edit', array('project_id' => $project['id'])) ?> <?= $this->a(t('Edit project'), 'project', 'edit', array('project_id' => $project['id'])) ?>
</li> </li>
<li>
<?= $this->a(t('Edit board'), 'board', 'edit', array('project_id' => $project['id'])) ?>
</li>
<li>
<?= $this->a(t('Category management'), 'category', 'index', array('project_id' => $project['id'])) ?>
</li>
<li>
<?= $this->a(t('Swimlanes'), 'swimlane', 'index', array('project_id' => $project['id'])) ?>
</li>
<?php if ($project['is_private'] == 0): ?>
<li>
<?= $this->a(t('User management'), 'project', 'users', array('project_id' => $project['id'])) ?>
</li>
<?php endif ?> <?php endif ?>
<?php if ($this->acl->isAdminUser() || $is_owner || $project['is_private']): ?> <li>
<li> <?= $this->a(t('Automatic actions'), 'action', 'index', array('project_id' => $project['id'])) ?>
<?= $this->a(t('Edit board'), 'board', 'edit', array('project_id' => $project['id'])) ?> </li>
</li>
<li>
<?= $this->a(t('Category management'), 'category', 'index', array('project_id' => $project['id'])) ?>
</li>
<li>
<?= $this->a(t('Swimlanes'), 'swimlane', 'index', array('project_id' => $project['id'])) ?>
</li>
<?php if ($project['is_private'] == 0): ?>
<li>
<?= $this->a(t('User management'), 'project', 'users', array('project_id' => $project['id'])) ?>
</li>
<?php endif ?>
<li>
<?= $this->a(t('Automatic actions'), 'action', 'index', array('project_id' => $project['id'])) ?>
</li>
<?php endif ?>
<?php if ($this->acl->isAdminUser() || $project['is_private']): ?>
<li> <li>
<?= $this->a(t('Duplicate'), 'project', 'duplicate', array('project_id' => $project['id']), true) ?> <?= $this->a(t('Duplicate'), 'project', 'duplicate', array('project_id' => $project['id']), true) ?>
</li> </li>
@@ -46,13 +42,15 @@
<?= $this->a(t('Enable'), 'project', 'enable', array('project_id' => $project['id']), true) ?> <?= $this->a(t('Enable'), 'project', 'enable', array('project_id' => $project['id']), true) ?>
<?php endif ?> <?php endif ?>
</li> </li>
<li> <?php if ($this->userSession->isAdmin()): ?>
<?= $this->a(t('Remove'), 'project', 'remove', array('project_id' => $project['id'])) ?> <li>
</li> <?= $this->a(t('Remove'), 'project', 'remove', array('project_id' => $project['id'])) ?>
</li>
<?php endif ?>
<?php endif ?> <?php endif ?>
</ul> </ul>
<?php if ($this->acl->isAdminUser() || $project['is_private']): ?> <?php if ($this->acl->isManagerActionAllowed($project['id'])): ?>
<h2><?= t('Exports') ?></h2> <h2><?= t('Exports') ?></h2>
<ul> <ul>
<li> <li>

View File

@@ -18,15 +18,15 @@
<?php foreach ($users['allowed'] as $user_id => $username): ?> <?php foreach ($users['allowed'] as $user_id => $username): ?>
<tr> <tr>
<td><?= $this->e($username) ?></td> <td><?= $this->e($username) ?></td>
<td><?= isset($users['owners'][$user_id]) ? t('Project manager') : t('Project member') ?></td> <td><?= isset($users['managers'][$user_id]) ? t('Project manager') : t('Project member') ?></td>
<td> <td>
<ul> <ul>
<li><?= $this->a(t('Revoke'), 'project', 'revoke', array('project_id' => $project['id'], 'user_id' => $user_id), true) ?></li> <li><?= $this->a(t('Revoke'), 'project', 'revoke', array('project_id' => $project['id'], 'user_id' => $user_id), true) ?></li>
<li> <li>
<?php if (isset($users['owners'][$user_id])): ?> <?php if (isset($users['managers'][$user_id])): ?>
<?= $this->a(t('Set project member'), 'project', 'setOwner', array('project_id' => $project['id'], 'user_id' => $user_id, 'is_owner' => 0), true) ?> <?= $this->a(t('Set project member'), 'project', 'role', array('project_id' => $project['id'], 'user_id' => $user_id, 'is_owner' => 0), true) ?>
<?php else: ?> <?php else: ?>
<?= $this->a(t('Set project manager'), 'project', 'setOwner', array('project_id' => $project['id'], 'user_id' => $user_id, 'is_owner' => 1), true) ?> <?= $this->a(t('Set project manager'), 'project', 'role', array('project_id' => $project['id'], 'user_id' => $user_id, 'is_owner' => 1), true) ?>
<?php endif ?> <?php endif ?>
</li> </li>
</ul> </ul>

View File

@@ -2,7 +2,7 @@
<h2><?= t('Add a sub-task') ?></h2> <h2><?= t('Add a sub-task') ?></h2>
</div> </div>
<form method="post" action="<?= $this->u('subtask', 'save', array('task_id' => $task['id'])) ?>" autocomplete="off"> <form method="post" action="<?= $this->u('subtask', 'save', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>" autocomplete="off">
<?= $this->formCsrf() ?> <?= $this->formCsrf() ?>
@@ -22,6 +22,6 @@
<div class="form-actions"> <div class="form-actions">
<input type="submit" value="<?= t('Save') ?>" class="btn btn-blue"/> <input type="submit" value="<?= t('Save') ?>" class="btn btn-blue"/>
<?= t('or') ?> <?= t('or') ?>
<?= $this->a(t('cancel'), 'task', 'show', array('task_id' => $task['id'])) ?> <?= $this->a(t('cancel'), 'task', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>
</div> </div>
</form> </form>

View File

@@ -2,7 +2,7 @@
<h2><?= t('Edit a sub-task') ?></h2> <h2><?= t('Edit a sub-task') ?></h2>
</div> </div>
<form method="post" action="<?= $this->u('subtask', 'update', array('task_id' => $task['id'], 'subtask_id' => $subtask['id'])) ?>" autocomplete="off"> <form method="post" action="<?= $this->u('subtask', 'update', array('task_id' => $task['id'], 'project_id' => $task['project_id'], 'subtask_id' => $subtask['id'])) ?>" autocomplete="off">
<?= $this->formCsrf() ?> <?= $this->formCsrf() ?>
@@ -27,6 +27,6 @@
<div class="form-actions"> <div class="form-actions">
<input type="submit" value="<?= t('Save') ?>" class="btn btn-blue"/> <input type="submit" value="<?= t('Save') ?>" class="btn btn-blue"/>
<?= t('or') ?> <?= t('or') ?>
<?= $this->a(t('cancel'), 'task', 'show', array('task_id' => $task['id'])) ?> <?= $this->a(t('cancel'), 'task', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>
</div> </div>
</form> </form>

View File

@@ -12,6 +12,6 @@
<div class="form-actions"> <div class="form-actions">
<?= $this->a(t('Yes'), 'subtask', 'remove', array('task_id' => $task['id'], 'subtask_id' => $subtask['id']), true, 'btn btn-red') ?> <?= $this->a(t('Yes'), 'subtask', 'remove', array('task_id' => $task['id'], 'subtask_id' => $subtask['id']), true, 'btn btn-red') ?>
<?= t('or') ?> <?= t('or') ?>
<?= $this->a(t('cancel'), 'task', 'show', array('task_id' => $task['id'])) ?> <?= $this->a(t('cancel'), 'task', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>
</div> </div>
</div> </div>

View File

@@ -21,7 +21,7 @@
<td> <td>
<?php if (! isset($not_editable)): ?> <?php if (! isset($not_editable)): ?>
<?= $this->a(trim($this->render('subtask/icons', array('subtask' => $subtask))) . $this->e($subtask['status_name']), <?= $this->a(trim($this->render('subtask/icons', array('subtask' => $subtask))) . $this->e($subtask['status_name']),
'subtask', 'toggleStatus', array('task_id' => $task['id'], 'subtask_id' => $subtask['id'])) ?> 'subtask', 'toggleStatus', array('task_id' => $task['id'], 'project_id' => $task['project_id'], 'subtask_id' => $subtask['id'])) ?>
<?php else: ?> <?php else: ?>
<?= $this->render('subtask/icons', array('subtask' => $subtask)) . $this->e($subtask['status_name']) ?> <?= $this->render('subtask/icons', array('subtask' => $subtask)) . $this->e($subtask['status_name']) ?>
<?php endif ?> <?php endif ?>
@@ -57,7 +57,7 @@
</table> </table>
<?php if (! isset($not_editable)): ?> <?php if (! isset($not_editable)): ?>
<form method="post" action="<?= $this->u('subtask', 'save', array('task_id' => $task['id'])) ?>" autocomplete="off"> <form method="post" action="<?= $this->u('subtask', 'save', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>" autocomplete="off">
<?= $this->formCsrf() ?> <?= $this->formCsrf() ?>
<?= $this->formHidden('task_id', array('task_id' => $task['id'])) ?> <?= $this->formHidden('task_id', array('task_id' => $task['id'])) ?>
<?= $this->formText('title', array(), array(), array('required', 'placeholder="'.t('Type here to create a new sub-task').'"')) ?> <?= $this->formText('title', array(), array(), array('required', 'placeholder="'.t('Type here to create a new sub-task').'"')) ?>

View File

@@ -8,8 +8,8 @@
</p> </p>
<div class="form-actions"> <div class="form-actions">
<?= $this->a(t('Yes'), 'task', 'close', array('task_id' => $task['id'], 'confirmation' => 'yes'), true, 'btn btn-red') ?> <?= $this->a(t('Yes'), 'task', 'close', array('task_id' => $task['id'], 'project_id' => $task['project_id'], 'confirmation' => 'yes'), true, 'btn btn-red') ?>
<?= t('or') ?> <?= t('or') ?>
<?= $this->a(t('cancel'), 'task', 'show', array('task_id' => $task['id'])) ?> <?= $this->a(t('cancel'), 'task', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>
</div> </div>
</div> </div>

View File

@@ -18,7 +18,7 @@
<?= $this->render('comment/create', array( <?= $this->render('comment/create', array(
'skip_cancel' => true, 'skip_cancel' => true,
'values' => array( 'values' => array(
'user_id' => $this->acl->getUserId(), 'user_id' => $this->userSession->getId(),
'task_id' => $task['id'], 'task_id' => $task['id'],
), ),
'errors' => array(), 'errors' => array(),

View File

@@ -8,8 +8,8 @@
</p> </p>
<div class="form-actions"> <div class="form-actions">
<?= $this->a(t('Yes'), 'task', 'duplicate', array('task_id' => $task['id'], 'confirmation' => 'yes'), true, 'btn btn-red') ?> <?= $this->a(t('Yes'), 'task', 'duplicate', array('task_id' => $task['id'], 'project_id' => $task['project_id'], 'confirmation' => 'yes'), true, 'btn btn-red') ?>
<?= t('or') ?> <?= t('or') ?>
<?= $this->a(t('cancel'), 'task', 'show', array('task_id' => $task['id'])) ?> <?= $this->a(t('cancel'), 'task', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>
</div> </div>
</div> </div>

View File

@@ -17,7 +17,7 @@
<div class="form-actions"> <div class="form-actions">
<input type="submit" value="<?= t('Save') ?>" class="btn btn-blue"/> <input type="submit" value="<?= t('Save') ?>" class="btn btn-blue"/>
<?= t('or') ?> <?= t('or') ?>
<?= $this->a(t('cancel'), 'task', 'show', array('task_id' => $task['id'])) ?> <?= $this->a(t('cancel'), 'task', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>
</div> </div>
</form> </form>

View File

@@ -2,7 +2,7 @@
<h2><?= t('Edit a task') ?></h2> <h2><?= t('Edit a task') ?></h2>
</div> </div>
<section id="task-section"> <section id="task-section">
<form method="post" action="<?= $this->u('task', 'update', array('task_id' => $task['id'], 'ajax' => $ajax)) ?>" autocomplete="off"> <form method="post" action="<?= $this->u('task', 'update', array('task_id' => $task['id'], 'project_id' => $task['project_id'], 'ajax' => $ajax)) ?>" autocomplete="off">
<?= $this->formCsrf() ?> <?= $this->formCsrf() ?>
@@ -61,7 +61,7 @@
<?php if ($ajax): ?> <?php if ($ajax): ?>
<?= $this->a(t('cancel'), 'board', 'show', array('project_id' => $task['project_id'])) ?> <?= $this->a(t('cancel'), 'board', 'show', array('project_id' => $task['project_id'])) ?>
<?php else: ?> <?php else: ?>
<?= $this->a(t('cancel'), 'task', 'show', array('task_id' => $task['id'])) ?> <?= $this->a(t('cancel'), 'task', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>
<?php endif ?> <?php endif ?>
</div> </div>
</form> </form>

View File

@@ -2,7 +2,7 @@
<h2><?= t('Edit the description') ?></h2> <h2><?= t('Edit the description') ?></h2>
</div> </div>
<form method="post" action="<?= $this->u('task', 'description', array('task_id' => $task['id'], 'ajax' => $ajax)) ?>" autocomplete="off"> <form method="post" action="<?= $this->u('task', 'description', array('task_id' => $task['id'], 'project_id' => $task['project_id'], 'ajax' => $ajax)) ?>" autocomplete="off">
<?= $this->formCsrf() ?> <?= $this->formCsrf() ?>
<?= $this->formHidden('id', $values) ?> <?= $this->formHidden('id', $values) ?>
@@ -32,7 +32,7 @@
<?php if ($ajax): ?> <?php if ($ajax): ?>
<?= $this->a(t('cancel'), 'board', 'show', array('project_id' => $task['project_id'])) ?> <?= $this->a(t('cancel'), 'board', 'show', array('project_id' => $task['project_id'])) ?>
<?php else: ?> <?php else: ?>
<?= $this->a(t('cancel'), 'task', 'show', array('task_id' => $task['id'])) ?> <?= $this->a(t('cancel'), 'task', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>
<?php endif ?> <?php endif ?>
</div> </div>
</form> </form>

View File

@@ -17,7 +17,7 @@
<div class="form-actions"> <div class="form-actions">
<input type="submit" value="<?= t('Save') ?>" class="btn btn-blue"/> <input type="submit" value="<?= t('Save') ?>" class="btn btn-blue"/>
<?= t('or') ?> <?= t('or') ?>
<?= $this->a(t('cancel'), 'task', 'show', array('task_id' => $task['id'])) ?> <?= $this->a(t('cancel'), 'task', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>
</div> </div>
</form> </form>

View File

@@ -8,8 +8,8 @@
</p> </p>
<div class="form-actions"> <div class="form-actions">
<?= $this->a(t('Yes'), 'task', 'open', array('task_id' => $task['id'], 'confirmation' => 'yes'), true, 'btn btn-red') ?> <?= $this->a(t('Yes'), 'task', 'open', array('task_id' => $task['id'], 'project_id' => $task['project_id'], 'confirmation' => 'yes'), true, 'btn btn-red') ?>
<?= t('or') ?> <?= t('or') ?>
<?= $this->a(t('cancel'), 'task', 'show', array('task_id' => $task['id'])) ?> <?= $this->a(t('cancel'), 'task', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>
</div> </div>
</div> </div>

View File

@@ -8,8 +8,8 @@
</p> </p>
<div class="form-actions"> <div class="form-actions">
<?= $this->a(t('Yes'), 'task', 'remove', array('task_id' => $task['id'], 'confirmation' => 'yes'), true, 'btn btn-red') ?> <?= $this->a(t('Yes'), 'task', 'remove', array('task_id' => $task['id'], 'project_id' => $task['project_id'], 'confirmation' => 'yes'), true, 'btn btn-red') ?>
<?= t('or') ?> <?= t('or') ?>
<?= $this->a(t('cancel'), 'task', 'show', array('task_id' => $task['id'])) ?> <?= $this->a(t('cancel'), 'task', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>
</div> </div>
</div> </div>

View File

@@ -1,5 +1,5 @@
<?= $this->render('task/details', array('task' => $task, 'project' => $project)) ?> <?= $this->render('task/details', array('task' => $task, 'project' => $project)) ?>
<?= $this->render('task/time', array('values' => $values, 'date_format' => $date_format, 'date_formats' => $date_formats)) ?> <?= $this->render('task/time', array('task' => $task, 'values' => $values, 'date_format' => $date_format, 'date_formats' => $date_formats)) ?>
<?= $this->render('task/show_description', array('task' => $task)) ?> <?= $this->render('task/show_description', array('task' => $task)) ?>
<?= $this->render('subtask/show', array('task' => $task, 'subtasks' => $subtasks)) ?> <?= $this->render('subtask/show', array('task' => $task, 'subtasks' => $subtasks)) ?>
<?= $this->render('task/timesheet', array('timesheet' => $timesheet)) ?> <?= $this->render('task/timesheet', array('timesheet' => $timesheet)) ?>

View File

@@ -6,7 +6,16 @@
<article class="markdown task-show-description"> <article class="markdown task-show-description">
<?php if (! isset($is_public)): ?> <?php if (! isset($is_public)): ?>
<?= $this->markdown($task['description']) ?> <?= $this->markdown(
$task['description'],
array(
'controller' => 'task',
'action' => 'show',
'params' => array(
'project_id' => $task['project_id']
)
)
) ?>
<?php else: ?> <?php else: ?>
<?= $this->markdown( <?= $this->markdown(
$task['description'], $task['description'],

View File

@@ -2,22 +2,22 @@
<h2><?= t('Actions') ?></h2> <h2><?= t('Actions') ?></h2>
<ul> <ul>
<li> <li>
<?= $this->a(t('Summary'), 'task', 'show', array('task_id' => $task['id'])) ?> <?= $this->a(t('Summary'), 'task', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>
</li> </li>
<li> <li>
<?= $this->a(t('Edit the task'), 'task', 'edit', array('task_id' => $task['id'])) ?> <?= $this->a(t('Edit the task'), 'task', 'edit', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>
</li> </li>
<li> <li>
<?= $this->a(t('Edit the description'), 'task', 'description', array('task_id' => $task['id'])) ?> <?= $this->a(t('Edit the description'), 'task', 'description', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>
</li> </li>
<li> <li>
<?= $this->a(t('Add a sub-task'), 'subtask', 'create', array('task_id' => $task['id'])) ?> <?= $this->a(t('Add a sub-task'), 'subtask', 'create', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>
</li> </li>
<li> <li>
<?= $this->a(t('Add a comment'), 'comment', 'create', array('task_id' => $task['id'])) ?> <?= $this->a(t('Add a comment'), 'comment', 'create', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>
</li> </li>
<li> <li>
<?= $this->a(t('Attach a document'), 'file', 'create', array('task_id' => $task['id'])) ?> <?= $this->a(t('Attach a document'), 'file', 'create', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>
</li> </li>
<li> <li>
<?= $this->a(t('Duplicate'), 'task', 'duplicate', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?> <?= $this->a(t('Duplicate'), 'task', 'duplicate', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>
@@ -30,14 +30,14 @@
</li> </li>
<li> <li>
<?php if ($task['is_active'] == 1): ?> <?php if ($task['is_active'] == 1): ?>
<?= $this->a(t('Close this task'), 'task', 'close', array('task_id' => $task['id'])) ?> <?= $this->a(t('Close this task'), 'task', 'close', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>
<?php else: ?> <?php else: ?>
<?= $this->a(t('Open this task'), 'task', 'open', array('task_id' => $task['id'])) ?> <?= $this->a(t('Open this task'), 'task', 'open', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>
<?php endif ?> <?php endif ?>
</li> </li>
<?php if (! $hide_remove_menu): ?> <?php if (! $hide_remove_menu): ?>
<li> <li>
<?= $this->a(t('Remove'), 'task', 'remove', array('task_id' => $task['id'])) ?> <?= $this->a(t('Remove'), 'task', 'remove', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>
</li> </li>
<?php endif ?> <?php endif ?>
</ul> </ul>

View File

@@ -13,7 +13,7 @@
<?php foreach ($tasks as $task): ?> <?php foreach ($tasks as $task): ?>
<tr> <tr>
<td class="task-table task-<?= $task['color_id'] ?>"> <td class="task-table task-<?= $task['color_id'] ?>">
<?= $this->a('#'.$this->e($task['id']), 'task', 'show', array('task_id' => $task['id']), false, '', t('View this task')) ?> <?= $this->a('#'.$this->e($task['id']), 'task', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id']), false, '', t('View this task')) ?>
</td> </td>
<td> <td>
<?= $this->inList($task['column_id'], $columns) ?> <?= $this->inList($task['column_id'], $columns) ?>
@@ -22,7 +22,7 @@
<?= $this->inList($task['category_id'], $categories, '') ?> <?= $this->inList($task['category_id'], $categories, '') ?>
</td> </td>
<td> <td>
<?= $this->a($this->e($task['title']), 'task', 'show', array('task_id' => $task['id']), false, '', t('View this task')) ?> <?= $this->a($this->e($task['title']), 'task', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id']), false, '', t('View this task')) ?>
</td> </td>
<td> <td>
<?php if ($task['assignee_username']): ?> <?php if ($task['assignee_username']): ?>

View File

@@ -1,4 +1,4 @@
<form method="post" action="<?= $this->u('task', 'time', array('task_id' => $values['id'])) ?>" class="form-inline task-time-form" autocomplete="off"> <form method="post" action="<?= $this->u('task', 'time', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>" class="form-inline task-time-form" autocomplete="off">
<?= $this->formCsrf() ?> <?= $this->formCsrf() ?>
<?= $this->formHidden('id', $values) ?> <?= $this->formHidden('id', $values) ?>

View File

@@ -20,7 +20,7 @@
<?= $this->formLabel(t('Default project'), 'default_project_id') ?> <?= $this->formLabel(t('Default project'), 'default_project_id') ?>
<?= $this->formSelect('default_project_id', $projects, $values, $errors) ?><br/> <?= $this->formSelect('default_project_id', $projects, $values, $errors) ?><br/>
<?php if ($this->acl->isAdminUser()): ?> <?php if ($this->userSession->isAdmin()): ?>
<?= $this->formCheckbox('is_admin', t('Administrator'), 1, isset($values['is_admin']) && $values['is_admin'] == 1 ? true : false) ?><br/> <?= $this->formCheckbox('is_admin', t('Administrator'), 1, isset($values['is_admin']) && $values['is_admin'] == 1 ? true : false) ?><br/>
<?php endif ?> <?php endif ?>

View File

@@ -6,7 +6,7 @@
<h3><i class="fa fa-google"></i> <?= t('Google Account') ?></h3> <h3><i class="fa fa-google"></i> <?= t('Google Account') ?></h3>
<p class="listing"> <p class="listing">
<?php if ($this->acl->isCurrentUser($user['id'])): ?> <?php if ($this->userSession->isCurrentUser($user['id'])): ?>
<?php if (empty($user['google_id'])): ?> <?php if (empty($user['google_id'])): ?>
<?= $this->a(t('Link my Google Account'), 'user', 'google', array(), true) ?> <?= $this->a(t('Link my Google Account'), 'user', 'google', array(), true) ?>
<?php else: ?> <?php else: ?>
@@ -22,7 +22,7 @@
<h3><i class="fa fa-github"></i> <?= t('Github Account') ?></h3> <h3><i class="fa fa-github"></i> <?= t('Github Account') ?></h3>
<p class="listing"> <p class="listing">
<?php if ($this->acl->isCurrentUser($user['id'])): ?> <?php if ($this->userSession->isCurrentUser($user['id'])): ?>
<?php if (empty($user['github_id'])): ?> <?php if (empty($user['github_id'])): ?>
<?= $this->a(t('Link my GitHub Account'), 'user', 'github', array(), true) ?> <?= $this->a(t('Link my GitHub Account'), 'user', 'github', array(), true) ?>
<?php else: ?> <?php else: ?>

View File

@@ -1,6 +1,6 @@
<section id="main"> <section id="main">
<div class="page-header"> <div class="page-header">
<?php if ($this->acl->isAdminUser()): ?> <?php if ($this->userSession->isAdmin()): ?>
<ul> <ul>
<li><i class="fa fa-plus fa-fw"></i><?= $this->a(t('New user'), 'user', 'create') ?></li> <li><i class="fa fa-plus fa-fw"></i><?= $this->a(t('New user'), 'user', 'create') ?></li>
</ul> </ul>

View File

@@ -1,6 +1,6 @@
<section id="main"> <section id="main">
<div class="page-header"> <div class="page-header">
<?php if ($this->acl->isAdminUser()): ?> <?php if ($this->userSession->isAdmin()): ?>
<ul> <ul>
<li><i class="fa fa-user fa-fw"></i><?= $this->a(t('All users'), 'user', 'index') ?></li> <li><i class="fa fa-user fa-fw"></i><?= $this->a(t('All users'), 'user', 'index') ?></li>
<li><i class="fa fa-plus fa-fw"></i><?= $this->a(t('New user'), 'user', 'create') ?></li> <li><i class="fa fa-plus fa-fw"></i><?= $this->a(t('New user'), 'user', 'create') ?></li>

View File

@@ -5,7 +5,7 @@
<?= $this->a(t('Summary'), 'user', 'show', array('user_id' => $user['id'])) ?> <?= $this->a(t('Summary'), 'user', 'show', array('user_id' => $user['id'])) ?>
</li> </li>
<?php if ($this->acl->isAdminUser() || $this->acl->isCurrentUser($user['id'])): ?> <?php if ($this->userSession->isAdmin() || $this->userSession->isCurrentUser($user['id'])): ?>
<li> <li>
<?= $this->a(t('Edit profile'), 'user', 'edit', array('user_id' => $user['id'])) ?> <?= $this->a(t('Edit profile'), 'user', 'edit', array('user_id' => $user['id'])) ?>
</li> </li>
@@ -30,7 +30,7 @@
</li> </li>
<?php endif ?> <?php endif ?>
<?php if ($this->acl->isAdminUser() && ! $this->acl->isCurrentUser($user['id'])): ?> <?php if ($this->userSession->isAdmin() && ! $this->userSession->isCurrentUser($user['id'])): ?>
<li> <li>
<?= $this->a(t('Remove'), 'user', 'remove', array('user_id' => $user['id'])) ?> <?= $this->a(t('Remove'), 'user', 'remove', array('user_id' => $user['id'])) ?>
</li> </li>

View File

@@ -74,6 +74,7 @@
} }
} }
#main .alert,
.page .alert { .page .alert {
margin-top: 10px; margin-top: 10px;
} }

View File

@@ -523,9 +523,11 @@ a.btn-blue:focus,
} }
} }
#main .alert,
.page .alert { .page .alert {
margin-top: 10px; margin-top: 10px;
}/* tooltip */ }
/* tooltip */
.tooltip-arrow:after { .tooltip-arrow:after {
background: #fff; background: #fff;
border: 1px solid #aaaaaa; border: 1px solid #aaaaaa;

View File

@@ -63,8 +63,8 @@ $server->bind('removeColumn', $container['board'], 'removeColumn');
* Project permissions procedures * Project permissions procedures
*/ */
$server->bind('getMembers', $container['projectPermission'], 'getMembers'); $server->bind('getMembers', $container['projectPermission'], 'getMembers');
$server->bind('revokeUser', $container['projectPermission'], 'revokeUser'); $server->bind('revokeUser', $container['projectPermission'], 'revokeMember');
$server->bind('allowUser', $container['projectPermission'], 'allowUser'); $server->bind('allowUser', $container['projectPermission'], 'addMember');
/** /**
* Task procedures * Task procedures

View File

@@ -14,5 +14,5 @@ for ($i = 0; $i < 100; $i++) {
'name' => 'Project #'.$i 'name' => 'Project #'.$i
)); ));
$permissionModel->allowUser($id, 1); $permissionModel->addMember($id, 1);
} }

View File

@@ -21,7 +21,7 @@ $project_id = $projectModel->create(array(
'name' => 'Project #1' 'name' => 'Project #1'
)); ));
$permissionModel->allowUser($project_id, 1); $permissionModel->addMember($project_id, 1);
for ($i = 0; $i <= 5; $i++) { for ($i = 0; $i <= 5; $i++) {
$userModel->create(array( $userModel->create(array(

View File

@@ -2,111 +2,222 @@
require_once __DIR__.'/Base.php'; require_once __DIR__.'/Base.php';
use Core\Session;
use Model\Acl; use Model\Acl;
use Model\Project;
use Model\ProjectPermission;
use Model\User;
class AclTest extends Base class AclTest extends Base
{ {
public function testAllowedAction() public function testMatchAcl()
{ {
$acl_rules = array( $acl_rules = array(
'controller1' => array('action1', 'action3'), 'controller1' => array('action1', 'action3'),
'controller3' => '*',
'controller5' => '-',
'controller6' => array(),
); );
$acl = new Acl($this->container); $acl = new Acl($this->container);
$this->assertTrue($acl->isAllowedAction($acl_rules, 'controller1', 'action1')); $this->assertTrue($acl->matchAcl($acl_rules, 'controller1', 'aCtiOn1'));
$this->assertTrue($acl->isAllowedAction($acl_rules, 'controller1', 'action3')); $this->assertTrue($acl->matchAcl($acl_rules, 'controller1', 'action1'));
$this->assertFalse($acl->isAllowedAction($acl_rules, 'controller1', 'action2')); $this->assertTrue($acl->matchAcl($acl_rules, 'controller1', 'action3'));
$this->assertFalse($acl->isAllowedAction($acl_rules, 'controller2', 'action2')); $this->assertFalse($acl->matchAcl($acl_rules, 'controller1', 'action2'));
$this->assertFalse($acl->isAllowedAction($acl_rules, 'controller2', 'action3')); $this->assertFalse($acl->matchAcl($acl_rules, 'controller2', 'action2'));
$this->assertFalse($acl->matchAcl($acl_rules, 'controller2', 'action3'));
$this->assertTrue($acl->matchAcl($acl_rules, 'controller3', 'anything'));
$this->assertFalse($acl->matchAcl($acl_rules, 'controller4', 'anything'));
$this->assertFalse($acl->matchAcl($acl_rules, 'controller5', 'anything'));
$this->assertFalse($acl->matchAcl($acl_rules, 'controller6', 'anything'));
} }
public function testIsAdmin() public function testPublicActions()
{ {
$acl = new Acl($this->container); $acl = new Acl($this->container);
$this->assertTrue($acl->isPublicAction('board', 'readonly'));
$_SESSION = array(); $this->assertFalse($acl->isPublicAction('board', 'show'));
$this->assertFalse($acl->isAdminUser());
$_SESSION = array('user' => array());
$this->assertFalse($acl->isAdminUser());
$_SESSION = array('user' => array('is_admin' => '1'));
$this->assertFalse($acl->isAdminUser());
$_SESSION = array('user' => array('is_admin' => false));
$this->assertFalse($acl->isAdminUser());
$_SESSION = array('user' => array('is_admin' => '2'));
$this->assertFalse($acl->isAdminUser());
$_SESSION = array('user' => array('is_admin' => true));
$this->assertTrue($acl->isAdminUser());
} }
public function testIsUser() public function testAdminActions()
{ {
$acl = new Acl($this->container); $acl = new Acl($this->container);
$this->assertFalse($acl->isAdminAction('board', 'show'));
$_SESSION = array(); $this->assertFalse($acl->isAdminAction('task', 'show'));
$this->assertFalse($acl->isRegularUser()); $this->assertTrue($acl->isAdminAction('config', 'api'));
$this->assertTrue($acl->isAdminAction('config', 'anything'));
$_SESSION = array('user' => array()); $this->assertTrue($acl->isAdminAction('config', 'anything'));
$this->assertFalse($acl->isRegularUser()); $this->assertTrue($acl->isAdminAction('user', 'save'));
$_SESSION = array('user' => array('is_admin' => true));
$this->assertFalse($acl->isRegularUser());
$_SESSION = array('user' => array('is_admin' => true));
$this->assertFalse($acl->isRegularUser());
$_SESSION = array('user' => array('is_admin' => '2'));
$this->assertFalse($acl->isRegularUser());
$_SESSION = array('user' => array('is_admin' => false));
$this->assertTrue($acl->isRegularUser());
} }
public function testIsPageAllowed() public function testManagerActions()
{ {
$acl = new Acl($this->container); $acl = new Acl($this->container);
$this->assertFalse($acl->isManagerAction('board', 'readonly'));
$this->assertFalse($acl->isManagerAction('project', 'remove'));
$this->assertFalse($acl->isManagerAction('project', 'show'));
$this->assertTrue($acl->isManagerAction('project', 'disable'));
$this->assertTrue($acl->isManagerAction('category', 'index'));
$this->assertTrue($acl->isManagerAction('project', 'users'));
$this->assertTrue($acl->isManagerAction('task', 'remove'));
$this->assertFalse($acl->isManagerAction('app', 'index'));
}
// Public access public function testPageAccessNoSession()
$_SESSION = array(); {
$this->assertFalse($acl->isPageAccessAllowed('user', 'create')); $acl = new Acl($this->container);
$this->assertFalse($acl->isPageAccessAllowed('user', 'save')); $this->assertFalse($acl->isAllowed('board', 'readonly'));
$this->assertFalse($acl->isPageAccessAllowed('user', 'remove')); $this->assertFalse($acl->isAllowed('task', 'show'));
$this->assertFalse($acl->isPageAccessAllowed('user', 'confirm')); $this->assertFalse($acl->isAllowed('config', 'application'));
$this->assertFalse($acl->isPageAccessAllowed('app', 'index')); $this->assertFalse($acl->isAllowed('project', 'users'));
$this->assertFalse($acl->isPageAccessAllowed('user', 'index')); $this->assertFalse($acl->isAllowed('task', 'remove'));
$this->assertTrue($acl->isPageAccessAllowed('user', 'login')); $this->assertTrue($acl->isAllowed('app', 'index'));
$this->assertTrue($acl->isPageAccessAllowed('user', 'check')); }
$this->assertTrue($acl->isPageAccessAllowed('webhook', 'task'));
$this->assertTrue($acl->isPageAccessAllowed('board', 'readonly'));
// Regular user public function testPageAccessEmptySession()
$_SESSION = array('user' => array('is_admin' => false)); {
$this->assertFalse($acl->isPageAccessAllowed('user', 'create')); $acl = new Acl($this->container);
$this->assertFalse($acl->isPageAccessAllowed('user', 'save')); $session = new Session;
$this->assertFalse($acl->isPageAccessAllowed('user', 'remove'));
$this->assertFalse($acl->isPageAccessAllowed('user', 'confirm'));
$this->assertTrue($acl->isPageAccessAllowed('app', 'index'));
$this->assertFalse($acl->isPageAccessAllowed('user', 'index'));
$this->assertTrue($acl->isPageAccessAllowed('user', 'login'));
$this->assertTrue($acl->isPageAccessAllowed('user', 'check'));
$this->assertTrue($acl->isPageAccessAllowed('webhook', 'task'));
$this->assertTrue($acl->isPageAccessAllowed('board', 'readonly'));
// Admin user $session['user'] = array();
$_SESSION = array('user' => array('is_admin' => true));
$this->assertTrue($acl->isPageAccessAllowed('user', 'create')); $this->assertFalse($acl->isAllowed('board', 'readonly'));
$this->assertTrue($acl->isPageAccessAllowed('user', 'save')); $this->assertFalse($acl->isAllowed('task', 'show'));
$this->assertTrue($acl->isPageAccessAllowed('user', 'remove')); $this->assertFalse($acl->isAllowed('config', 'application'));
$this->assertTrue($acl->isPageAccessAllowed('user', 'confirm')); $this->assertFalse($acl->isAllowed('project', 'users'));
$this->assertTrue($acl->isPageAccessAllowed('app', 'index')); $this->assertFalse($acl->isAllowed('task', 'remove'));
$this->assertTrue($acl->isPageAccessAllowed('user', 'index')); $this->assertTrue($acl->isAllowed('app', 'index'));
$this->assertTrue($acl->isPageAccessAllowed('user', 'login')); }
$this->assertTrue($acl->isPageAccessAllowed('user', 'check'));
$this->assertTrue($acl->isPageAccessAllowed('task', 'add')); public function testPageAccessAdminUser()
$this->assertTrue($acl->isPageAccessAllowed('board', 'readonly')); {
$acl = new Acl($this->container);
$session = new Session;
$session['user'] = array(
'is_admin' => true,
);
$this->assertTrue($acl->isAllowed('board', 'readonly'));
$this->assertTrue($acl->isAllowed('task', 'readonly'));
$this->assertTrue($acl->isAllowed('webhook', 'github'));
$this->assertTrue($acl->isAllowed('task', 'show'));
$this->assertTrue($acl->isAllowed('task', 'update'));
$this->assertTrue($acl->isAllowed('project', 'show'));
$this->assertTrue($acl->isAllowed('config', 'application'));
$this->assertTrue($acl->isAllowed('project', 'users'));
$this->assertTrue($acl->isAllowed('category', 'edit'));
$this->assertTrue($acl->isAllowed('task', 'remove'));
$this->assertTrue($acl->isAllowed('app', 'index'));
}
public function testPageAccessManager()
{
$acl = new Acl($this->container);
$p = new Project($this->container);
$pp = new ProjectPermission($this->container);
$u = new User($this->container);
$session = new Session;
// We create our user
$this->assertEquals(2, $u->create(array('username' => 'unittest', 'password' => 'unittest')));
// We create a project and set our user as project manager
$this->assertEquals(1, $p->create(array('name' => 'UnitTest'), 2, true));
$this->assertTrue($pp->isMember(1, 2));
$this->assertTrue($pp->isManager(1, 2));
// We fake a session for him
$session['user'] = array(
'id' => 2,
'is_admin' => false,
);
$this->assertTrue($acl->isAllowed('board', 'readonly', 1));
$this->assertTrue($acl->isAllowed('task', 'readonly', 1));
$this->assertTrue($acl->isAllowed('webhook', 'github', 1));
$this->assertTrue($acl->isAllowed('task', 'show', 1));
$this->assertFalse($acl->isAllowed('task', 'show', 2));
$this->assertTrue($acl->isAllowed('task', 'update', 1));
$this->assertTrue($acl->isAllowed('project', 'show', 1));
$this->assertFalse($acl->isAllowed('config', 'application', 1));
$this->assertTrue($acl->isAllowed('project', 'users', 1));
$this->assertFalse($acl->isAllowed('project', 'users', 2));
$this->assertTrue($acl->isAllowed('category', 'edit', 1));
$this->assertTrue($acl->isAllowed('task', 'remove', 1));
$this->assertTrue($acl->isAllowed('app', 'index', 1));
}
public function testPageAccessMember()
{
$acl = new Acl($this->container);
$p = new Project($this->container);
$pp = new ProjectPermission($this->container);
$u = new User($this->container);
// We create our user
$this->assertEquals(2, $u->create(array('username' => 'unittest', 'password' => 'unittest')));
// We create a project and set our user as member
$this->assertEquals(1, $p->create(array('name' => 'UnitTest1')));
$this->assertEquals(2, $p->create(array('name' => 'UnitTest2')));
$this->assertTrue($pp->addMember(1, 2));
$this->assertTrue($pp->isMember(1, 2));
$this->assertFalse($pp->isManager(1, 2));
$session = new Session;
$session['user'] = array(
'id' => 2,
'is_admin' => false,
);
$this->assertTrue($acl->isAllowed('board', 'readonly', 1));
$this->assertTrue($acl->isAllowed('task', 'readonly', 1));
$this->assertTrue($acl->isAllowed('webhook', 'github', 1));
$this->assertFalse($acl->isAllowed('board', 'show', 2));
$this->assertTrue($acl->isAllowed('board', 'show', 1));
$this->assertFalse($acl->isAllowed('task', 'show', 2));
$this->assertTrue($acl->isAllowed('task', 'show', 1));
$this->assertTrue($acl->isAllowed('task', 'update', 1));
$this->assertTrue($acl->isAllowed('project', 'show', 1));
$this->assertFalse($acl->isAllowed('config', 'application', 1));
$this->assertFalse($acl->isAllowed('project', 'users', 1));
$this->assertFalse($acl->isAllowed('task', 'remove', 1));
$this->assertTrue($acl->isAllowed('app', 'index', 1));
}
public function testPageAccessNotMember()
{
$acl = new Acl($this->container);
$p = new Project($this->container);
$pp = new ProjectPermission($this->container);
$u = new User($this->container);
// We create our user
$this->assertEquals(2, $u->create(array('username' => 'unittest', 'password' => 'unittest')));
// We create a project and set our user as member
$this->assertEquals(1, $p->create(array('name' => 'UnitTest1')));
$this->assertEquals(2, $p->create(array('name' => 'UnitTest2')));
$this->assertFalse($pp->isMember(1, 2));
$this->assertFalse($pp->isManager(1, 2));
$session = new Session;
$session['user'] = array(
'id' => 2,
'is_admin' => false,
);
$this->assertFalse($acl->isAllowed('board', 'show', 2));
$this->assertFalse($acl->isAllowed('board', 'show', 1));
$this->assertFalse($acl->isAllowed('task', 'show', 1));
$this->assertFalse($acl->isAllowed('task', 'update', 1));
$this->assertFalse($acl->isAllowed('project', 'show', 1));
$this->assertFalse($acl->isAllowed('config', 'application', 1));
$this->assertFalse($acl->isAllowed('project', 'users', 1));
$this->assertFalse($acl->isAllowed('task', 'remove', 1));
$this->assertTrue($acl->isAllowed('app', 'index', 1));
} }
} }

View File

@@ -7,7 +7,7 @@ use Model\Task;
use Model\TaskCreation; use Model\TaskCreation;
use Model\TaskFinder; use Model\TaskFinder;
use Model\Project; use Model\Project;
use Model\Acl; use Model\UserSession;
class ActionTaskAssignCurrentUser extends Base class ActionTaskAssignCurrentUser extends Base
{ {
@@ -52,9 +52,9 @@ class ActionTaskAssignCurrentUser extends Base
$tc = new TaskCreation($this->container); $tc = new TaskCreation($this->container);
$tf = new TaskFinder($this->container); $tf = new TaskFinder($this->container);
$p = new Project($this->container); $p = new Project($this->container);
$a = new Acl($this->container); $us = new UserSession($this->container);
$this->assertEquals(5, $a->getUserId()); $this->assertEquals(5, $us->getId());
$this->assertEquals(1, $p->create(array('name' => 'test'))); $this->assertEquals(1, $p->create(array('name' => 'test')));
$this->assertEquals(1, $tc->create(array('title' => 'test', 'project_id' => 1, 'column_id' => 1))); $this->assertEquals(1, $tc->create(array('title' => 'test', 'project_id' => 1, 'column_id' => 1)));

View File

@@ -13,7 +13,7 @@ class HelperTest extends Base
$this->assertEquals('<p>Test</p>', $h->markdown('Test')); $this->assertEquals('<p>Test</p>', $h->markdown('Test'));
$this->assertEquals( $this->assertEquals(
'<p>Task <a href="?controller=task&amp;action=show&amp;task_id=123" class="" title="" >#123</a></p>', '<p>Task #123</p>',
$h->markdown('Task #123') $h->markdown('Task #123')
); );

View File

@@ -35,10 +35,10 @@ class NotificationTest extends Base
$this->assertEmpty($n->getUsersWithNotification(1)); $this->assertEmpty($n->getUsersWithNotification(1));
// We allow all users to be member of our projects // We allow all users to be member of our projects
$this->assertTrue($pp->allowUser(1, 1)); $this->assertTrue($pp->addMember(1, 1));
$this->assertTrue($pp->allowUser(1, 2)); $this->assertTrue($pp->addMember(1, 2));
$this->assertTrue($pp->allowUser(1, 3)); $this->assertTrue($pp->addMember(1, 3));
$this->assertTrue($pp->allowUser(1, 4)); $this->assertTrue($pp->addMember(1, 4));
$this->assertNotEmpty($pp->getMembers(1)); $this->assertNotEmpty($pp->getMembers(1));
$users = $n->getUsersWithNotification(1); $users = $n->getUsersWithNotification(1);
@@ -73,15 +73,15 @@ class NotificationTest extends Base
$this->assertNotFalse($u->create(array('username' => 'user4'))); $this->assertNotFalse($u->create(array('username' => 'user4')));
// We allow all users to be member of our projects // We allow all users to be member of our projects
$this->assertTrue($pp->allowUser(1, 1)); $this->assertTrue($pp->addMember(1, 1));
$this->assertTrue($pp->allowUser(1, 2)); $this->assertTrue($pp->addMember(1, 2));
$this->assertTrue($pp->allowUser(1, 3)); $this->assertTrue($pp->addMember(1, 3));
$this->assertTrue($pp->allowUser(1, 4)); $this->assertTrue($pp->addMember(1, 4));
$this->assertTrue($pp->allowUser(2, 1)); $this->assertTrue($pp->addMember(2, 1));
$this->assertTrue($pp->allowUser(2, 2)); $this->assertTrue($pp->addMember(2, 2));
$this->assertTrue($pp->allowUser(2, 3)); $this->assertTrue($pp->addMember(2, 3));
$this->assertTrue($pp->allowUser(2, 4)); $this->assertTrue($pp->addMember(2, 4));
$users = $n->getUsersList(1); $users = $n->getUsersList(1);
$this->assertNotEmpty($users); $this->assertNotEmpty($users);

View File

@@ -62,14 +62,14 @@ class ProjectPermissionTest extends Base
$this->assertEquals(1, $p->create(array('name' => 'UnitTest'))); $this->assertEquals(1, $p->create(array('name' => 'UnitTest')));
// We allow the admin user // We allow the admin user
$this->assertTrue($pp->allowUser(1, 1)); $this->assertTrue($pp->addMember(1, 1));
$this->assertTrue($pp->allowUser(1, 2)); $this->assertTrue($pp->addMember(1, 2));
// Non-existant project // Non-existant project
$this->assertFalse($pp->allowUser(50, 1)); $this->assertFalse($pp->addMember(50, 1));
// Non-existant user // Non-existant user
$this->assertFalse($pp->allowUser(1, 50)); $this->assertFalse($pp->addMember(1, 50));
// Both users should be allowed // Both users should be allowed
$this->assertEquals(array('1' => 'admin', '2' => 'unittest'), $pp->getMembers(1)); $this->assertEquals(array('1' => 'admin', '2' => 'unittest'), $pp->getMembers(1));
@@ -89,7 +89,7 @@ class ProjectPermissionTest extends Base
$this->assertEquals(1, $p->create(array('name' => 'UnitTest'))); $this->assertEquals(1, $p->create(array('name' => 'UnitTest')));
// We revoke our admin user (not existing row) // We revoke our admin user (not existing row)
$this->assertFalse($pp->revokeUser(1, 1)); $this->assertFalse($pp->revokeMember(1, 1));
// We should have nobody in the users list // We should have nobody in the users list
$this->assertEmpty($pp->getMembers(1)); $this->assertEmpty($pp->getMembers(1));
@@ -99,7 +99,7 @@ class ProjectPermissionTest extends Base
$this->assertFalse($pp->isUserAllowed(1, 2)); $this->assertFalse($pp->isUserAllowed(1, 2));
// We allow only the regular user // We allow only the regular user
$this->assertTrue($pp->allowUser(1, 2)); $this->assertTrue($pp->addMember(1, 2));
// All users should be allowed (admin and regular) // All users should be allowed (admin and regular)
$this->assertTrue($pp->isUserAllowed(1, 1)); $this->assertTrue($pp->isUserAllowed(1, 1));
@@ -109,13 +109,13 @@ class ProjectPermissionTest extends Base
$this->assertEquals(array('2' => 'unittest'), $pp->getMembers(1)); $this->assertEquals(array('2' => 'unittest'), $pp->getMembers(1));
// We allow our admin, we should have both in the list // We allow our admin, we should have both in the list
$this->assertTrue($pp->allowUser(1, 1)); $this->assertTrue($pp->addMember(1, 1));
$this->assertEquals(array('1' => 'admin', '2' => 'unittest'), $pp->getMembers(1)); $this->assertEquals(array('1' => 'admin', '2' => 'unittest'), $pp->getMembers(1));
$this->assertTrue($pp->isUserAllowed(1, 1)); $this->assertTrue($pp->isUserAllowed(1, 1));
$this->assertTrue($pp->isUserAllowed(1, 2)); $this->assertTrue($pp->isUserAllowed(1, 2));
// We revoke the regular user // We revoke the regular user
$this->assertTrue($pp->revokeUser(1, 2)); $this->assertTrue($pp->revokeMember(1, 2));
// Only admin should be allowed // Only admin should be allowed
$this->assertTrue($pp->isUserAllowed(1, 1)); $this->assertTrue($pp->isUserAllowed(1, 1));
@@ -125,7 +125,7 @@ class ProjectPermissionTest extends Base
$this->assertEquals(array('1' => 'admin'), $pp->getMembers(1)); $this->assertEquals(array('1' => 'admin'), $pp->getMembers(1));
// We revoke the admin user // We revoke the admin user
$this->assertTrue($pp->revokeUser(1, 1)); $this->assertTrue($pp->revokeMember(1, 1));
$this->assertEmpty($pp->getMembers(1)); $this->assertEmpty($pp->getMembers(1));
// Only admin should be allowed again // Only admin should be allowed again
@@ -133,6 +133,42 @@ class ProjectPermissionTest extends Base
$this->assertFalse($pp->isUserAllowed(1, 2)); $this->assertFalse($pp->isUserAllowed(1, 2));
} }
public function testManager()
{
$p = new Project($this->container);
$pp = new ProjectPermission($this->container);
$u = new User($this->container);
$this->assertEquals(2, $u->create(array('username' => 'unittest', 'password' => 'unittest')));
$this->assertEquals(1, $p->create(array('name' => 'UnitTest1')));
$this->assertFalse($pp->isMember(1, 2));
$this->assertFalse($pp->isManager(1, 2));
$this->assertEquals(2, $p->create(array('name' => 'UnitTest2'), 1, true));
$this->assertFalse($pp->isMember(2, 2));
$this->assertFalse($pp->isManager(2, 2));
$this->assertEquals(3, $p->create(array('name' => 'UnitTest3'), 2, true));
$this->assertTrue($pp->isMember(3, 2));
$this->assertTrue($pp->isManager(3, 2));
$this->assertEquals(4, $p->create(array('name' => 'UnitTest4')));
$this->assertTrue($pp->addManager(4, 2));
$this->assertTrue($pp->isMember(4, 2));
$this->assertTrue($pp->isManager(4, 2));
$this->assertEquals(5, $p->create(array('name' => 'UnitTest5')));
$this->assertTrue($pp->addMember(5, 2));
$this->assertTrue($pp->changeRole(5, 2, 1));
$this->assertTrue($pp->isMember(5, 2));
$this->assertTrue($pp->isManager(5, 2));
$this->assertTrue($pp->changeRole(5, 2, 0));
$this->assertTrue($pp->isMember(5, 2));
$this->assertFalse($pp->isManager(5, 2));
}
public function testUsersList() public function testUsersList()
{ {
$p = new Project($this->container); $p = new Project($this->container);
@@ -151,7 +187,7 @@ class ProjectPermissionTest extends Base
); );
// We allow only the regular user // We allow only the regular user
$this->assertTrue($pp->allowUser(1, 2)); $this->assertTrue($pp->addMember(1, 2));
$this->assertEquals( $this->assertEquals(
array(0 => 'Unassigned', 2 => 'unittest'), array(0 => 'Unassigned', 2 => 'unittest'),
@@ -159,7 +195,7 @@ class ProjectPermissionTest extends Base
); );
// We allow the admin user // We allow the admin user
$this->assertTrue($pp->allowUser(1, 1)); $this->assertTrue($pp->addMember(1, 1));
$this->assertEquals( $this->assertEquals(
array(0 => 'Unassigned', 1 => 'admin', 2 => 'unittest'), array(0 => 'Unassigned', 1 => 'admin', 2 => 'unittest'),
@@ -167,7 +203,7 @@ class ProjectPermissionTest extends Base
); );
// We revoke only the regular user // We revoke only the regular user
$this->assertTrue($pp->revokeUser(1, 2)); $this->assertTrue($pp->revokeMember(1, 2));
$this->assertEquals( $this->assertEquals(
array(0 => 'Unassigned', 1 => 'admin'), array(0 => 'Unassigned', 1 => 'admin'),
@@ -175,7 +211,7 @@ class ProjectPermissionTest extends Base
); );
// We revoke only the admin user, we should have everybody // We revoke only the admin user, we should have everybody
$this->assertTrue($pp->revokeUser(1, 1)); $this->assertTrue($pp->revokeMember(1, 1));
$this->assertEquals( $this->assertEquals(
array(0 => 'Unassigned'), array(0 => 'Unassigned'),

View File

@@ -240,8 +240,8 @@ class TaskDuplicationTest extends Base
// We create a new user for our project // We create a new user for our project
$user = new User($this->container); $user = new User($this->container);
$this->assertNotFalse($user->create(array('username' => 'unittest#1', 'password' => 'unittest'))); $this->assertNotFalse($user->create(array('username' => 'unittest#1', 'password' => 'unittest')));
$this->assertTrue($pp->allowUser(1, 2)); $this->assertTrue($pp->addMember(1, 2));
$this->assertTrue($pp->allowUser(2, 2)); $this->assertTrue($pp->addMember(2, 2));
$this->assertTrue($pp->isUserAllowed(1, 2)); $this->assertTrue($pp->isUserAllowed(1, 2));
$this->assertTrue($pp->isUserAllowed(2, 2)); $this->assertTrue($pp->isUserAllowed(2, 2));
@@ -363,8 +363,8 @@ class TaskDuplicationTest extends Base
// We create a new user for our project // We create a new user for our project
$this->assertNotFalse($user->create(array('username' => 'unittest#1', 'password' => 'unittest'))); $this->assertNotFalse($user->create(array('username' => 'unittest#1', 'password' => 'unittest')));
$this->assertTrue($pp->allowUser(1, 2)); $this->assertTrue($pp->addMember(1, 2));
$this->assertTrue($pp->allowUser(2, 2)); $this->assertTrue($pp->addMember(2, 2));
$this->assertTrue($pp->isUserAllowed(1, 2)); $this->assertTrue($pp->isUserAllowed(1, 2));
$this->assertTrue($pp->isUserAllowed(2, 2)); $this->assertTrue($pp->isUserAllowed(2, 2));
@@ -398,8 +398,8 @@ class TaskDuplicationTest extends Base
// We create a new user for our project // We create a new user for our project
$this->assertNotFalse($user->create(array('username' => 'unittest#1', 'password' => 'unittest'))); $this->assertNotFalse($user->create(array('username' => 'unittest#1', 'password' => 'unittest')));
$this->assertTrue($pp->allowUser(1, 2)); $this->assertTrue($pp->addMember(1, 2));
$this->assertTrue($pp->allowUser(2, 2)); $this->assertTrue($pp->addMember(2, 2));
$this->assertTrue($pp->isUserAllowed(1, 2)); $this->assertTrue($pp->isUserAllowed(1, 2));
$this->assertTrue($pp->isUserAllowed(2, 2)); $this->assertTrue($pp->isUserAllowed(2, 2));

View File

@@ -48,6 +48,7 @@ class TaskExportTest extends Base
} }
$rows = $e->export(1, strtotime('-1 day'), strtotime('+1 day')); $rows = $e->export(1, strtotime('-1 day'), strtotime('+1 day'));
$this->assertEquals($i, count($rows)); $this->assertEquals($i, count($rows));
$this->assertEquals('Task Id', $rows[0][0]); $this->assertEquals('Task Id', $rows[0][0]);
$this->assertEquals(1, $rows[1][0]); $this->assertEquals(1, $rows[1][0]);

View File

@@ -0,0 +1,45 @@
<?php
require_once __DIR__.'/Base.php';
use Core\Session;
use Model\UserSession;
class UserSessionTest extends Base
{
public function testIsAdmin()
{
$s = new Session;
$us = new UserSession($this->container);
$this->assertFalse($us->isAdmin());
$s['user'] = array();
$this->assertFalse($us->isAdmin());
$s['user'] = array('is_admin' => '1');
$this->assertFalse($us->isAdmin());
$s['user'] = array('is_admin' => false);
$this->assertFalse($us->isAdmin());
$s['user'] = array('is_admin' => '2');
$this->assertFalse($us->isAdmin());
$s['user'] = array('is_admin' => true);
$this->assertTrue($us->isAdmin());
}
public function testLastSeenProject()
{
$us = new UserSession($this->container);
$this->assertEquals(0, $us->getLastSeenProjectId());
$us->storeLastSeenProjectId(33);
$this->assertEquals(33, $us->getLastSeenProjectId());
$us->storeLastSeenProjectId(66);
$this->assertEquals(66, $us->getLastSeenProjectId());
}
}