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
* @author Frederic Guillot
*
* @property \Model\Acl $acl
* @property \Model\UserSession $userSession
* @property \Model\Comment $comment
* @property \Model\Task $task
* @property \Model\TaskCreation $taskCreation

View File

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

View File

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

View File

@ -17,7 +17,7 @@ class Action extends Base
*/
public function index()
{
$project = $this->getProjectManagement();
$project = $this->getProject();
$this->response->html($this->projectLayout('action/index', array(
'values' => array('project_id' => $project['id']),
@ -42,7 +42,7 @@ class Action extends Base
*/
public function event()
{
$project = $this->getProjectManagement();
$project = $this->getProject();
$values = $this->request->getValues();
if (empty($values['action_name']) || empty($values['project_id'])) {
@ -64,7 +64,7 @@ class Action extends Base
*/
public function params()
{
$project = $this->getProjectManagement();
$project = $this->getProject();
$values = $this->request->getValues();
if (empty($values['action_name']) || empty($values['project_id']) || empty($values['event_name'])) {
@ -101,7 +101,7 @@ class Action extends Base
*/
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()
{
$project = $this->getProjectManagement();
$project = $this->getProject();
$this->response->html($this->projectLayout('action/remove', array(
'action' => $this->action->getById($this->request->getIntegerParam('action_id')),
@ -154,7 +154,7 @@ class Action extends Base
public function remove()
{
$this->checkCSRFParam();
$project = $this->getProjectManagement();
$project = $this->getProject();
$action = $this->action->getById($this->request->getIntegerParam('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)
{
$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);
return $this->template->layout('analytic/layout', $params);

View File

@ -34,7 +34,7 @@ class App extends Base
$direction = $this->request->getStringParam('direction');
$order = $this->request->getStringParam('order');
$user_id = $this->acl->getUserId();
$user_id = $this->userSession->getId();
$projects = $this->projectPermission->getMemberProjects($user_id);
$project_ids = array_keys($projects);
@ -191,8 +191,9 @@ class App extends Base
$this->response->html('<p>'.t('Nothing to preview...').'</p>');
}
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\TimeTracking $timeTracking
* @property \Model\User $user
* @property \Model\UserSession $userSession
* @property \Model\Webhook $webhook
*/
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
$this->response->csp(array('style-src' => "'self' 'unsafe-inline'"));
$this->response->nosniff();
@ -140,8 +137,32 @@ abstract class Base
if (ENABLE_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->request->isAjax()) {
@ -151,9 +172,8 @@ abstract class Base
$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->isPageAccessAllowed($controller, $action)) {
$this->response->redirect('?controller=user&action=forbidden');
if (! $this->acl->isAllowed($controller, $action, $this->request->getIntegerParam('project_id', 0))) {
$this->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
*
@ -252,7 +245,7 @@ abstract class Base
$content = $this->template->render($template, $params);
$params['task_content_for_layout'] = $content;
$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);
}
@ -270,8 +263,7 @@ abstract class Base
$content = $this->template->render($template, $params);
$params['project_content_for_layout'] = $content;
$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['is_owner'] = $this->projectPermission->isOwner($params['project']['id'], $this->acl->getUserId());
$params['board_selector'] = $this->projectPermission->getAllowedProjects($this->userSession->getId());
return $this->template->layout('project/layout', $params);
}
@ -286,12 +278,10 @@ abstract class Base
{
$task = $this->taskFinder->getDetails($this->request->getIntegerParam('task_id'));
if (! $task) {
if (! $task || $task['project_id'] != $this->request->getIntegerParam('project_id')) {
$this->notfound();
}
$this->checkProjectPermissions($task['project_id']);
return $task;
}
@ -312,29 +302,6 @@ abstract class Base
$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;
}
}

View File

@ -18,7 +18,7 @@ class Board extends Base
public function moveColumn()
{
$this->checkCSRFParam();
$project = $this->getProjectManagement();
$project = $this->getProject();
$column_id = $this->request->getIntegerParam('column_id');
$direction = $this->request->getStringParam('direction');
@ -54,7 +54,6 @@ class Board extends Base
public function updateAssignee()
{
$values = $this->request->getValues();
$this->checkProjectPermissions($values['project_id']);
list($valid,) = $this->taskValidator->validateAssigneeModification($values);
@ -93,7 +92,6 @@ class Board extends Base
public function updateCategory()
{
$values = $this->request->getValues();
$this->checkProjectPermissions($values['project_id']);
list($valid,) = $this->taskValidator->validateCategoryModification($values);
@ -144,16 +142,16 @@ class Board extends Base
*/
public function index()
{
$last_seen_project_id = $this->user->getLastSeenProjectId();
$favorite_project_id = $this->user->getFavoriteProjectId();
$last_seen_project_id = $this->userSession->getLastSeenProjectId();
$favorite_project_id = $this->userSession->getFavoriteProjectId();
$project_id = $last_seen_project_id ?: $favorite_project_id;
if (! $project_id) {
$projects = $this->projectPermission->getAllowedProjects($this->acl->getUserId());
$projects = $this->projectPermission->getAllowedProjects($this->userSession->getId());
if (empty($projects)) {
if ($this->acl->isAdminUser()) {
if ($this->userSession->isAdmin()) {
$this->redirectNoProject();
}
@ -175,12 +173,12 @@ class Board extends Base
public function show($project_id = 0)
{
$project = $this->getProject($project_id);
$projects = $this->projectPermission->getAllowedProjects($this->acl->getUserId());
$projects = $this->projectPermission->getAllowedProjects($this->userSession->getId());
$board_selector = $projects;
unset($board_selector[$project['id']]);
$this->user->storeLastSeenProjectId($project['id']);
$this->userSession->storeLastSeenProjectId($project['id']);
$this->response->html($this->template->layout('board/index', array(
'users' => $this->projectPermission->getMemberList($project['id'], true, true),
@ -202,7 +200,7 @@ class Board extends Base
*/
public function edit()
{
$project = $this->getProjectManagement();
$project = $this->getProject();
$columns = $this->board->getColumns($project['id']);
$values = array();
@ -227,7 +225,7 @@ class Board extends Base
*/
public function update()
{
$project = $this->getProjectManagement();
$project = $this->getProject();
$columns = $this->board->getColumns($project['id']);
$data = $this->request->getValues();
$values = $columns_list = array();
@ -267,7 +265,7 @@ class Board extends Base
*/
public function add()
{
$project = $this->getProjectManagement();
$project = $this->getProject();
$columns = $this->board->getColumnsList($project['id']);
$data = $this->request->getValues();
$values = array();
@ -305,7 +303,7 @@ class Board extends Base
*/
public function remove()
{
$project = $this->getProjectManagement();
$project = $this->getProject();
if ($this->request->getStringParam('remove') === 'yes') {
@ -341,7 +339,7 @@ class Board extends Base
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);
}
@ -385,7 +383,7 @@ class Board extends Base
$project_id = $this->request->getIntegerParam('project_id');
$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);
}
@ -413,7 +411,8 @@ class Board extends Base
{
$task = $this->getTask();
$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->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();
$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())
{
$project = $this->getProjectManagement();
$project = $this->getProject();
$this->response->html($this->projectLayout('category/index', array(
'categories' => $this->category->getList($project['id'], false),
@ -54,7 +54,7 @@ class Category extends Base
*/
public function save()
{
$project = $this->getProjectManagement();
$project = $this->getProject();
$values = $this->request->getValues();
list($valid, $errors) = $this->category->validateCreation($values);
@ -80,7 +80,7 @@ class Category extends Base
*/
public function edit(array $values = array(), array $errors = array())
{
$project = $this->getProjectManagement();
$project = $this->getProject();
$category = $this->getCategory($project['id']);
$this->response->html($this->projectLayout('category/edit', array(
@ -98,7 +98,7 @@ class Category extends Base
*/
public function update()
{
$project = $this->getProjectManagement();
$project = $this->getProject();
$values = $this->request->getValues();
list($valid, $errors) = $this->category->validateModification($values);
@ -124,7 +124,7 @@ class Category extends Base
*/
public function confirm()
{
$project = $this->getProjectManagement();
$project = $this->getProject();
$category = $this->getCategory($project['id']);
$this->response->html($this->projectLayout('category/remove', array(
@ -142,7 +142,7 @@ class Category extends Base
public function remove()
{
$this->checkCSRFParam();
$project = $this->getProjectManagement();
$project = $this->getProject();
$category = $this->getCategory($project['id']);
if ($this->category->remove($category['id'])) {

View File

@ -24,7 +24,7 @@ class Comment extends Base
$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(
'title' => t('Access Forbidden')
)));
@ -44,7 +44,7 @@ class Comment extends Base
if (empty($values)) {
$values = array(
'user_id' => $this->acl->getUserId(),
'user_id' => $this->userSession->getId(),
'task_id' => $task['id'],
);
}
@ -78,7 +78,7 @@ class Comment extends Base
$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);
@ -125,7 +125,7 @@ class Comment extends Base
$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);
@ -166,6 +166,6 @@ class Comment extends Base
$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)
{
$params['board_selector'] = $this->projectPermission->getAllowedProjects($this->acl->getUserId());
$params['board_selector'] = $this->projectPermission->getAllowedProjects($this->userSession->getId());
$params['values'] = $this->config->getAll();
$params['errors'] = array();
$params['config_content_for_layout'] = $this->template->render($template, $params);

View File

@ -37,11 +37,11 @@ class File extends Base
$task = $this->getTask();
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 {
$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->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']) {
$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->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()
{
$projects = $this->project->getAll($this->acl->isRegularUser());
$projects = $this->project->getAll(! $this->userSession->isAdmin());
$nb_projects = count($projects);
$active_projects = array();
$inactive_projects = array();
@ -32,7 +32,7 @@ class Project extends Base
}
$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,
'inactive_projects' => $inactive_projects,
'nb_projects' => $nb_projects,
@ -63,7 +63,7 @@ class Project extends Base
*/
public function exportTasks()
{
$project = $this->getProjectManagement();
$project = $this->getProject();
$from = $this->request->getStringParam('from');
$to = $this->request->getStringParam('to');
@ -96,7 +96,7 @@ class Project extends Base
*/
public function exportDailyProjectSummary()
{
$project = $this->getProjectManagement();
$project = $this->getProject();
$from = $this->request->getStringParam('from');
$to = $this->request->getStringParam('to');
@ -129,7 +129,7 @@ class Project extends Base
*/
public function share()
{
$project = $this->getProjectManagement();
$project = $this->getProject();
$switch = $this->request->getStringParam('switch');
if ($switch === 'enable' || $switch === 'disable') {
@ -158,7 +158,7 @@ class Project extends Base
*/
public function integration()
{
$project = $this->getProjectManagement();
$project = $this->getProject();
$this->response->html($this->projectLayout('project/integrations', array(
'project' => $project,
@ -174,7 +174,7 @@ class Project extends Base
*/
public function edit(array $values = array(), array $errors = array())
{
$project = $this->getProjectManagement();
$project = $this->getProject();
$this->response->html($this->projectLayout('project/edit', array(
'values' => empty($values) ? $project : $values,
@ -191,7 +191,7 @@ class Project extends Base
*/
public function update()
{
$project = $this->getProjectManagement();
$project = $this->getProject();
$values = $this->request->getValues();
list($valid, $errors) = $this->project->validateModification($values);
@ -216,7 +216,7 @@ class Project extends Base
*/
public function users()
{
$project = $this->getProjectManagement();
$project = $this->getProject();
$this->response->html($this->projectLayout('project/users', array(
'project' => $project,
@ -232,7 +232,7 @@ class Project extends Base
*/
public function allowEverybody()
{
$project = $this->getProjectManagement();
$project = $this->getProject();
$values = $this->request->getValues() + array('is_everybody_allowed' => 0);
list($valid,) = $this->projectPermission->validateProjectModification($values);
@ -257,12 +257,11 @@ class Project extends Base
public function allow()
{
$values = $this->request->getValues();
$this->checkProjectOwnerPermissions($values['project_id']);
list($valid,) = $this->projectPermission->validateUserModification($values);
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.'));
}
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
*/
public function setOwner()
public function role()
{
$this->checkCSRFParam();
@ -288,12 +287,11 @@ class Project extends Base
'is_owner' => $this->request->getIntegerParam('is_owner'),
);
$this->checkProjectOwnerPermissions($values['project_id']);
list($valid,) = $this->projectPermission->validateUserModification($values);
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.'));
}
else {
@ -318,12 +316,11 @@ class Project extends Base
'user_id' => $this->request->getIntegerParam('user_id'),
);
$this->checkProjectOwnerPermissions($values['project_id']);
list($valid,) = $this->projectPermission->validateUserModification($values);
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.'));
}
else {
@ -341,7 +338,7 @@ class Project extends Base
*/
public function remove()
{
$project = $this->getProjectManagement();
$project = $this->getProject();
if ($this->request->getStringParam('remove') === 'yes') {
@ -370,7 +367,7 @@ class Project extends Base
*/
public function duplicate()
{
$project = $this->getProjectManagement();
$project = $this->getProject();
if ($this->request->getStringParam('duplicate') === 'yes') {
@ -398,7 +395,7 @@ class Project extends Base
*/
public function disable()
{
$project = $this->getProjectManagement();
$project = $this->getProject();
if ($this->request->getStringParam('disable') === 'yes') {
@ -426,7 +423,7 @@ class Project extends Base
*/
public function enable()
{
$project = $this->getProjectManagement();
$project = $this->getProject();
if ($this->request->getStringParam('enable') === 'yes') {
@ -478,7 +475,7 @@ class Project extends Base
$project = $this->getProject();
$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']),
'project' => $project,
'title' => t('%s\'s activity', $project['name'])
@ -507,7 +504,7 @@ class Project extends Base
}
$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,
'nb_tasks' => $nb_tasks,
'pagination' => array(
@ -550,7 +547,7 @@ class Project extends Base
$nb_tasks = $this->taskPaginator->countClosedTasks($project['id']);
$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(
'controller' => 'project',
'action' => 'tasks',
@ -577,10 +574,10 @@ class Project extends Base
*/
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(
'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,
'errors' => $errors,
'title' => $is_private ? t('New private project') : t('New project'),
@ -599,7 +596,7 @@ class Project extends Base
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) {
$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) {
$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);
@ -124,7 +124,7 @@ class Subtask extends Base
$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);
@ -164,7 +164,7 @@ class Subtask extends Base
$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->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())
{
$project = $this->getProjectManagement();
$project = $this->getProject();
$this->response->html($this->projectLayout('swimlane/index', array(
'default_swimlane' => $this->swimlane->getDefault($project['id']),
@ -58,7 +58,7 @@ class Swimlane extends Base
*/
public function save()
{
$project = $this->getProjectManagement();
$project = $this->getProject();
$values = $this->request->getValues();
list($valid, $errors) = $this->swimlane->validateCreation($values);
@ -84,7 +84,7 @@ class Swimlane extends Base
*/
public function change()
{
$project = $this->getProjectManagement();
$project = $this->getProject();
$values = $this->request->getValues();
list($valid, $errors) = $this->swimlane->validateDefaultModification($values);
@ -110,7 +110,7 @@ class Swimlane extends Base
*/
public function edit(array $values = array(), array $errors = array())
{
$project = $this->getProjectManagement();
$project = $this->getProject();
$swimlane = $this->getSwimlane($project['id']);
$this->response->html($this->projectLayout('swimlane/edit', array(
@ -128,7 +128,7 @@ class Swimlane extends Base
*/
public function update()
{
$project = $this->getProjectManagement();
$project = $this->getProject();
$values = $this->request->getValues();
list($valid, $errors) = $this->swimlane->validateModification($values);
@ -154,7 +154,7 @@ class Swimlane extends Base
*/
public function confirm()
{
$project = $this->getProjectManagement();
$project = $this->getProject();
$swimlane = $this->getSwimlane($project['id']);
$this->response->html($this->projectLayout('swimlane/remove', array(
@ -172,7 +172,7 @@ class Swimlane extends Base
public function remove()
{
$this->checkCSRFParam();
$project = $this->getProjectManagement();
$project = $this->getProject();
$swimlane_id = $this->request->getIntegerParam('swimlane_id');
if ($this->swimlane->remove($project['id'], $swimlane_id)) {
@ -192,7 +192,7 @@ class Swimlane extends Base
public function disable()
{
$this->checkCSRFParam();
$project = $this->getProjectManagement();
$project = $this->getProject();
$swimlane_id = $this->request->getIntegerParam('swimlane_id');
if ($this->swimlane->disable($project['id'], $swimlane_id)) {
@ -212,7 +212,7 @@ class Swimlane extends Base
public function enable()
{
$this->checkCSRFParam();
$project = $this->getProjectManagement();
$project = $this->getProject();
$swimlane_id = $this->request->getIntegerParam('swimlane_id');
if ($this->swimlane->enable($project['id'], $swimlane_id)) {
@ -232,7 +232,7 @@ class Swimlane extends Base
public function moveup()
{
$this->checkCSRFParam();
$project = $this->getProjectManagement();
$project = $this->getProject();
$swimlane_id = $this->request->getIntegerParam('swimlane_id');
$this->swimlane->moveUp($project['id'], $swimlane_id);
@ -247,7 +247,7 @@ class Swimlane extends Base
public function movedown()
{
$this->checkCSRFParam();
$project = $this->getProjectManagement();
$project = $this->getProject();
$swimlane_id = $this->request->getIntegerParam('swimlane_id');
$this->swimlane->moveDown($project['id'], $swimlane_id);

View File

@ -126,9 +126,7 @@ class Task extends Base
{
$project = $this->getProject();
$values = $this->request->getValues();
$values['creator_id'] = $this->acl->getUserId();
$this->checkProjectPermissions($project['id']);
$values['creator_id'] = $this->userSession->getId();
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']);
}
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 {
@ -248,7 +246,7 @@ class Task extends Base
$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->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(
@ -297,7 +295,7 @@ class Task extends Base
$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(
@ -352,10 +350,10 @@ class Task extends Base
if ($task_id) {
$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 {
$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']);
}
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();
$values = $task;
$errors = array();
$projects_list = $this->projectPermission->getMemberProjects($this->acl->getUserId());
$projects_list = $this->projectPermission->getMemberProjects($this->userSession->getId());
unset($projects_list[$task['project_id']]);
@ -440,7 +438,7 @@ class Task extends Base
if ($this->taskDuplication->moveToProject($task['id'], $values['project_id'])) {
$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 {
$this->session->flashError(t('Unable to update your task.'));
@ -466,7 +464,7 @@ class Task extends Base
$task = $this->getTask();
$values = $task;
$errors = array();
$projects_list = $this->projectPermission->getMemberProjects($this->acl->getUserId());
$projects_list = $this->projectPermission->getMemberProjects($this->userSession->getId());
unset($projects_list[$task['project_id']]);
@ -479,7 +477,7 @@ class Task extends Base
$task_id = $this->taskDuplication->duplicateToProject($task['id'], $values['project_id']);
if ($task_id) {
$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 {
$this->session->flashError(t('Unable to create your task.'));

View File

@ -18,7 +18,7 @@ class User extends Base
public function logout()
{
$this->checkCSRFParam();
$this->authentication->backend('rememberMe')->destroy($this->acl->getUserId());
$this->authentication->backend('rememberMe')->destroy($this->userSession->getId());
$this->session->close();
$this->response->redirect('?controller=user&action=login');
}
@ -30,7 +30,7 @@ class User extends Base
*/
public function login(array $values = array(), array $errors = array())
{
if ($this->acl->isLogged()) {
if ($this->userSession->isLogged()) {
$this->response->redirect('?controller=app');
}
@ -78,7 +78,7 @@ class User extends Base
{
$content = $this->template->render($template, $params);
$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'])) {
$params['title'] = ($params['user']['name'] ?: $params['user']['username']).' (#'.$params['user']['id'].')';
@ -101,7 +101,7 @@ class User extends Base
$this->notfound();
}
if ($this->acl->isRegularUser() && $this->acl->getUserId() != $user['id']) {
if (! $this->userSession->isAdmin() && $this->userSession->getId() != $user['id']) {
$this->forbidden();
}
@ -125,7 +125,7 @@ class User extends Base
$this->response->html(
$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(),
'nb_users' => $nb_users,
'users' => $users,
@ -151,7 +151,7 @@ class User extends Base
public function create(array $values = array(), array $errors = 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(),
'errors' => $errors,
'values' => $values,
@ -328,7 +328,7 @@ class User extends Base
$values = $this->request->getValues();
if ($this->acl->isAdminUser()) {
if ($this->userSession->isAdmin()) {
$values += array('is_admin' => 0);
}
else {
@ -404,16 +404,16 @@ class User extends Base
if (is_array($profile)) {
// 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.'));
}
else {
$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'])) {
$this->response->redirect('?controller=app');
@ -441,14 +441,14 @@ class User extends Base
public function unlinkGoogle()
{
$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.'));
}
else {
$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 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.'));
}
else {
$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'])) {
$this->response->redirect('?controller=app');
@ -506,13 +506,13 @@ class User extends Base
$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.'));
}
else {
$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
* @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()
->setMarkupEscaped(true) # escapes markup (HTML)
->text($text);
// 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) {

View File

@ -3,7 +3,7 @@
namespace Model;
/**
* Acl model
* Access List
*
* @package model
* @author Frederic Guillot
@ -16,37 +16,59 @@ class Acl extends Base
* @access private
* @var array
*/
private $public_actions = array(
private $public_acl = array(
'user' => array('login', 'check', 'google', 'github'),
'task' => array('readonly'),
'board' => array('readonly'),
'project' => array('feed'),
'webhook' => array('task', 'github', 'gitlab'),
'webhook' => '*',
);
/**
* Controllers and actions allowed for regular users
* Controllers and actions for project members
*
* @access private
* @var array
*/
private $user_actions = array(
'app' => array('index', 'preview', 'status'),
'project' => array('index', 'show', 'exporttasks', 'exportdaily', 'share', 'edit', 'update', 'users', 'remove', 'duplicate', 'disable', 'enable', 'activity', 'search', 'tasks', 'create', 'save', 'revoke', 'setowner', 'allow'),
'board' => array('index', 'show', 'save', 'check', 'changeassignee', 'updateassignee', 'changecategory', 'updatecategory', 'movecolumn', 'edit', 'update', 'add', 'confirm', 'remove', 'subtasks', 'togglesubtask', 'attachments', 'comments', 'description'),
'user' => array('edit', 'forbidden', 'logout', 'show', 'external', 'unlinkgoogle', 'unlinkgithub', 'sessions', 'removesession', 'last', 'notifications', 'password'),
'comment' => array('create', 'save', 'confirm', 'remove', 'update', 'edit', 'forbidden'),
'file' => array('create', 'save', 'download', 'confirm', 'remove', 'open', 'image'),
'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'),
private $member_acl = array(
'board' => '*',
'comment' => '*',
'file' => '*',
'project' => array('show', 'tasks', 'search', 'activity'),
'subtask' => '*',
'task' => '*',
);
/**
* 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
* @param array $acl Acl list
@ -54,13 +76,27 @@ class Acl extends Base
* @param string $action Action name
* @return bool
*/
public function isAllowedAction(array $acl, $controller, $action)
public function matchAcl(array $acl, $controller, $action)
{
if (isset($acl[$controller])) {
return in_array($action, $acl[$controller]);
$action = strtolower($action);
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)
{
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
* @param string $controller Controller name
* @param string $action Action name
* @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
* @param string $controller Controller name
* @param string $action Action name
* @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
* @param string $controller Controller name
* @param string $action Action name
* @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
*
* @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
* Return true if the visitor is allowed to access to the given page
* We suppose the user already authenticated
*
* @access public
* @param string $controller Controller name
* @param string $action Action name
* @param integer $project_id Project id
* @return bool
*/
public function isLogged()
public function isAllowed($controller, $action, $project_id = 0)
{
return ! empty($this->session['user']);
}
/**
* 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;
// If you are admin you have access to everything
if ($this->userSession->isAdmin()) {
return true;
}
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;
}
/**
* 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)
public function isManagerActionAllowed($project_id)
{
return $this->isPublicAction($controller, $action) ||
$this->isAdminUser() ||
($this->isRegularUser() && $this->isUserAction($controller, $action));
if ($this->userSession->isAdmin()) {
return true;
}
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)
{
// 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 ($this->acl->isLogged()) {
if ($this->userSession->isLogged()) {
// We update each time the RememberMe cookie tokens
if ($this->backend('rememberMe')->hasCookie()) {
@ -117,7 +112,7 @@ class Authentication extends Base
if (! empty($values['remember_me'])) {
$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']);
}

View File

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

View File

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

View File

@ -109,7 +109,7 @@ class Project extends Base
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]);
}
}
@ -295,7 +295,7 @@ class Project extends Base
}
if ($add_user && $user_id) {
$this->projectPermission->allowUser($project_id, $user_id);
$this->projectPermission->addManager($project_id, $user_id);
}
$this->category->createDefaultCategories($project_id);

View File

@ -92,7 +92,7 @@ class ProjectPermission extends Base
* @param integer $project_id Project id
* @return array
*/
public function getOwners($project_id)
public function getManagers($project_id)
{
$users = $this->db
->table(self::TABLE)
@ -118,13 +118,13 @@ class ProjectPermission extends Base
$users = array(
'allowed' => array(),
'not_allowed' => array(),
'owners' => array(),
'managers' => array(),
);
$all_users = $this->user->getList();
$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) {
@ -137,14 +137,14 @@ class ProjectPermission extends Base
}
/**
* Allow a specific user for a given project
* Add a new project member
*
* @access public
* @param integer $project_id Project id
* @param integer $user_id User id
* @return bool
*/
public function allowUser($project_id, $user_id)
public function addMember($project_id, $user_id)
{
return $this->db
->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
* @param integer $project_id Project id
@ -160,7 +192,7 @@ class ProjectPermission extends Base
* @param integer $is_owner Is user owner of the project
* @return bool
*/
public function setOwner($project_id, $user_id, $is_owner = 1)
public function changeRole($project_id, $user_id, $is_owner)
{
return $this->db
->table(self::TABLE)
@ -169,23 +201,6 @@ class ProjectPermission extends Base
->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
*
@ -200,29 +215,29 @@ class ProjectPermission extends Base
return true;
}
return (bool) $this->db
return $this->db
->table(self::TABLE)
->eq('project_id', $project_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
* @param integer $project_id Project id
* @param integer $user_id User id
* @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)
->eq('project_id', $project_id)
->eq('user_id', $user_id)
->eq('is_owner', 1)
->count();
->count() === 1;
}
/**
@ -247,36 +262,11 @@ class ProjectPermission extends Base
*/
public function isEverybodyAllowed($project_id)
{
return (bool) $this->db
return $this->db
->table(Project::TABLE)
->eq('id', $project_id)
->eq('is_everybody_allowed', 1)
->count();
}
/**
* 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;
->count() === 1;
}
/**
@ -336,7 +326,7 @@ class ProjectPermission extends Base
$users = $this->getMembers($project_from);
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;
}
}

View File

@ -227,6 +227,7 @@ class SubTask extends Base
$subtasks = $db->table(SubTask::TABLE)
->columns('title', 'time_estimated')
->eq('task_id', $src_task_id)
->asc('id') // Explicit sorting for postgresql
->findAll();
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 projects ON projects.id = tasks.project_id
WHERE tasks.date_creation >= ? AND tasks.date_creation <= ? AND tasks.project_id = ?
ORDER BY tasks.id ASC
';
if (! is_numeric($from)) {

View File

@ -20,10 +20,10 @@ class TaskPermission extends Base
*/
public function canRemoveTask(array $task)
{
if ($this->acl->isAdminUser()) {
if ($this->userSession->isAdmin()) {
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;
}

View File

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

View File

@ -48,46 +48,11 @@ class User extends Base
*/
public function isAdmin($user_id)
{
$result = $this->db
return $this->db
->table(User::TABLE)
->eq('id', $user_id)
->eq('is_admin', 1)
->count();
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;
->count() === 1;
}
/**
@ -287,7 +252,7 @@ class User extends Base
$result = $this->db->table(self::TABLE)->eq('id', $values['id'])->update($values);
// 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();
}
@ -337,7 +302,7 @@ class User extends Base
public function updateSession(array $user = array())
{
if (empty($user)) {
$user = $this->getById($this->acl->getUserId());
$user = $this->getById($this->userSession->getId());
}
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 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)
{

View File

@ -5,7 +5,31 @@ namespace Schema;
use PDO;
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)
{

View File

@ -5,7 +5,31 @@ namespace Schema;
use Core\Security;
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)
{

View File

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

View File

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

View File

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

View File

@ -30,14 +30,14 @@ class ProjectActivitySubscriber extends Base implements EventSubscriberInterface
public function execute(GenericEvent $event)
{
// 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);
$this->projectActivity->createEvent(
$values['task']['project_id'],
$values['task']['id'],
$this->acl->getUserId(),
$this->userSession->getId(),
$event->getName(),
$values
);

View File

@ -1,12 +1,12 @@
<section id="main">
<div class="page-header">
<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>
<?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-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-cog fa-fw"></i><?= $this->a(t('Settings'), 'config', 'index') ?></li>
<?php endif ?>

View File

@ -14,7 +14,7 @@
<?= $this->a('#'.$project['id'], 'board', 'show', array('project_id' => $project['id']), false, 'dashboard-table-link') ?>
</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;
<?php endif ?>
<?= $this->a($this->e($project['name']), 'board', 'show', array('project_id' => $project['id'])) ?>

View File

@ -1,7 +1,7 @@
<section id="main">
<section>
<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() ?>

View File

@ -1,7 +1,7 @@
<section id="main">
<section>
<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() ?>

View File

@ -27,7 +27,7 @@
<i class="fa fa-line-chart fa-fw"></i>
<?= $this->a(t('Analytics'), 'analytic', 'tasks', array('project_id' => $project['id'])) ?>
</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>
<?= $this->a(t('Configure'), 'project', 'show', array('project_id' => $project['id'])) ?>
<?php endif ?>

View File

@ -4,7 +4,7 @@
trim($this->render('subtask/icons', array('subtask' => $subtask))) . $this->e($subtask['title']),
'board',
'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).']') ?>

View File

@ -1,5 +1,3 @@
<?php if ($not_editable): ?>
<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-category-id="<?= $task['category_id'] ?>"
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') ?>">
<?= $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']): ?>
<span class="task-board-reference" title="<?= t('Reference') ?>">
@ -48,12 +46,12 @@
</span>
<?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(
(! empty($task['owner_id']) ? t('Assigned to %s', $task['assignee_name'] ?: $task['assignee_username']) : t('Nobody assigned')),
'board',
'changeAssignee',
array('task_id' => $task['id']),
array('task_id' => $task['id'], 'project_id' => $task['project_id']),
false,
'assignee-popover',
t('Change assignee')
@ -78,7 +76,7 @@
$this->inList($task['category_id'], $categories),
'board',
'changeCategory',
array('task_id' => $task['id']),
array('task_id' => $task['id'], 'project_id' => $task['project_id']),
false,
'category-popover',
t('Change category')
@ -100,19 +98,19 @@
<div class="task-board-icons">
<?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 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 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 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)): ?>
<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: ?>

View File

@ -2,7 +2,7 @@
<h2><?= t('Add a comment') ?></h2>
</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->formHidden('task_id', $values) ?>
<?= $this->formHidden('user_id', $values) ?>
@ -30,7 +30,7 @@
<input type="submit" value="<?= t('Save') ?>" class="btn btn-blue"/>
<?php if (! isset($skip_cancel)): ?>
<?= 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 ?>
</div>
</form>

View File

@ -2,7 +2,7 @@
<h2><?= t('Edit a comment') ?></h2>
</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->formHidden('id', $values) ?>
@ -30,6 +30,6 @@
<div class="form-actions">
<input type="submit" value="<?= t('Update') ?>" class="btn btn-blue"/>
<?= 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>
</form>

View File

@ -10,8 +10,8 @@
<?= $this->render('comment/show', array('comment' => $comment, 'task' => $task, 'preview' => true)) ?>
<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') ?>
<?= $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>

View File

@ -9,12 +9,12 @@
<?php if (! isset($preview)): ?>
<ul class="comment-actions">
<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>
<?= $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>
<?= $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>
<?php endif ?>
</ul>
@ -33,7 +33,16 @@
)
) ?>
<?php else: ?>
<?= $this->markdown($comment['comment']) ?>
<?= $this->markdown(
$comment['comment'],
array(
'controller' => 'task',
'action' => 'show',
'params' => array(
'project_id' => $project['id']
)
)
) ?>
<?php endif ?>
</div>

View File

@ -2,13 +2,13 @@
<h2><?= t('Attach a document') ?></h2>
</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() ?>
<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-actions">
<input type="submit" value="<?= t('Save') ?>" class="btn btn-blue"/>
<?= 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>
</form>

View File

@ -1,6 +1,6 @@
<div class="page-header">
<h2><?= $this->e($file['name']) ?></h2>
<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>

View File

@ -8,8 +8,8 @@
</p>
<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') ?>
<?= $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>

View File

@ -8,12 +8,12 @@
<ul class="task-show-files">
<?php foreach ($files as $file): ?>
<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">
<?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 ?>
<?= $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>
</li>
<?php endforeach ?>

View File

@ -44,7 +44,7 @@
<?php endif ?>
<li>
<?= $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>
</ul>
</nav>

View File

@ -1,7 +1,7 @@
<section id="main">
<div class="page-header">
<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>
<?php endif ?>
<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>
<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">
<?= $project_content_for_layout ?>

View File

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

View File

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

View File

@ -2,7 +2,7 @@
<h2><?= t('Add a sub-task') ?></h2>
</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() ?>
@ -22,6 +22,6 @@
<div class="form-actions">
<input type="submit" value="<?= t('Save') ?>" class="btn btn-blue"/>
<?= 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>
</form>

View File

@ -2,7 +2,7 @@
<h2><?= t('Edit a sub-task') ?></h2>
</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() ?>
@ -27,6 +27,6 @@
<div class="form-actions">
<input type="submit" value="<?= t('Save') ?>" class="btn btn-blue"/>
<?= 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>
</form>

View File

@ -12,6 +12,6 @@
<div class="form-actions">
<?= $this->a(t('Yes'), 'subtask', 'remove', array('task_id' => $task['id'], 'subtask_id' => $subtask['id']), true, 'btn btn-red') ?>
<?= 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>

View File

@ -21,7 +21,7 @@
<td>
<?php if (! isset($not_editable)): ?>
<?= $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: ?>
<?= $this->render('subtask/icons', array('subtask' => $subtask)) . $this->e($subtask['status_name']) ?>
<?php endif ?>
@ -57,7 +57,7 @@
</table>
<?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->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').'"')) ?>

View File

@ -8,8 +8,8 @@
</p>
<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') ?>
<?= $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>

View File

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

View File

@ -8,8 +8,8 @@
</p>
<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') ?>
<?= $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>

View File

@ -17,7 +17,7 @@
<div class="form-actions">
<input type="submit" value="<?= t('Save') ?>" class="btn btn-blue"/>
<?= 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>
</form>

View File

@ -2,7 +2,7 @@
<h2><?= t('Edit a task') ?></h2>
</div>
<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() ?>
@ -61,7 +61,7 @@
<?php if ($ajax): ?>
<?= $this->a(t('cancel'), 'board', 'show', array('project_id' => $task['project_id'])) ?>
<?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 ?>
</div>
</form>

View File

@ -2,7 +2,7 @@
<h2><?= t('Edit the description') ?></h2>
</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->formHidden('id', $values) ?>
@ -32,7 +32,7 @@
<?php if ($ajax): ?>
<?= $this->a(t('cancel'), 'board', 'show', array('project_id' => $task['project_id'])) ?>
<?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 ?>
</div>
</form>

View File

@ -17,7 +17,7 @@
<div class="form-actions">
<input type="submit" value="<?= t('Save') ?>" class="btn btn-blue"/>
<?= 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>
</form>

View File

@ -8,8 +8,8 @@
</p>
<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') ?>
<?= $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>

View File

@ -8,8 +8,8 @@
</p>
<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') ?>
<?= $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>

View File

@ -1,5 +1,5 @@
<?= $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('subtask/show', array('task' => $task, 'subtasks' => $subtasks)) ?>
<?= $this->render('task/timesheet', array('timesheet' => $timesheet)) ?>

View File

@ -6,7 +6,16 @@
<article class="markdown task-show-description">
<?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: ?>
<?= $this->markdown(
$task['description'],

View File

@ -2,22 +2,22 @@
<h2><?= t('Actions') ?></h2>
<ul>
<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>
<?= $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>
<?= $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>
<?= $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>
<?= $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>
<?= $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>
<?= $this->a(t('Duplicate'), 'task', 'duplicate', array('task_id' => $task['id'], 'project_id' => $task['project_id'])) ?>
@ -30,14 +30,14 @@
</li>
<li>
<?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: ?>
<?= $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 ?>
</li>
<?php if (! $hide_remove_menu): ?>
<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>
<?php endif ?>
</ul>

View File

@ -13,7 +13,7 @@
<?php foreach ($tasks as $task): ?>
<tr>
<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>
<?= $this->inList($task['column_id'], $columns) ?>
@ -22,7 +22,7 @@
<?= $this->inList($task['category_id'], $categories, '') ?>
</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>
<?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->formHidden('id', $values) ?>

View File

@ -20,7 +20,7 @@
<?= $this->formLabel(t('Default project'), 'default_project_id') ?>
<?= $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/>
<?php endif ?>

View File

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

View File

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

View File

@ -1,6 +1,6 @@
<section id="main">
<div class="page-header">
<?php if ($this->acl->isAdminUser()): ?>
<?php if ($this->userSession->isAdmin()): ?>
<ul>
<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>

View File

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

View File

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

View File

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

View File

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

View File

@ -14,5 +14,5 @@ for ($i = 0; $i < 100; $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'
));
$permissionModel->allowUser($project_id, 1);
$permissionModel->addMember($project_id, 1);
for ($i = 0; $i <= 5; $i++) {
$userModel->create(array(

View File

@ -2,111 +2,222 @@
require_once __DIR__.'/Base.php';
use Core\Session;
use Model\Acl;
use Model\Project;
use Model\ProjectPermission;
use Model\User;
class AclTest extends Base
{
public function testAllowedAction()
public function testMatchAcl()
{
$acl_rules = array(
'controller1' => array('action1', 'action3'),
'controller3' => '*',
'controller5' => '-',
'controller6' => array(),
);
$acl = new Acl($this->container);
$this->assertTrue($acl->isAllowedAction($acl_rules, 'controller1', 'action1'));
$this->assertTrue($acl->isAllowedAction($acl_rules, 'controller1', 'action3'));
$this->assertFalse($acl->isAllowedAction($acl_rules, 'controller1', 'action2'));
$this->assertFalse($acl->isAllowedAction($acl_rules, 'controller2', 'action2'));
$this->assertFalse($acl->isAllowedAction($acl_rules, 'controller2', 'action3'));
$this->assertTrue($acl->matchAcl($acl_rules, 'controller1', 'aCtiOn1'));
$this->assertTrue($acl->matchAcl($acl_rules, 'controller1', 'action1'));
$this->assertTrue($acl->matchAcl($acl_rules, 'controller1', 'action3'));
$this->assertFalse($acl->matchAcl($acl_rules, 'controller1', 'action2'));
$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);
$_SESSION = array();
$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());
$this->assertTrue($acl->isPublicAction('board', 'readonly'));
$this->assertFalse($acl->isPublicAction('board', 'show'));
}
public function testIsUser()
public function testAdminActions()
{
$acl = new Acl($this->container);
$_SESSION = array();
$this->assertFalse($acl->isRegularUser());
$_SESSION = array('user' => array());
$this->assertFalse($acl->isRegularUser());
$_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());
$this->assertFalse($acl->isAdminAction('board', 'show'));
$this->assertFalse($acl->isAdminAction('task', 'show'));
$this->assertTrue($acl->isAdminAction('config', 'api'));
$this->assertTrue($acl->isAdminAction('config', 'anything'));
$this->assertTrue($acl->isAdminAction('config', 'anything'));
$this->assertTrue($acl->isAdminAction('user', 'save'));
}
public function testIsPageAllowed()
public function testManagerActions()
{
$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
$_SESSION = array();
$this->assertFalse($acl->isPageAccessAllowed('user', 'create'));
$this->assertFalse($acl->isPageAccessAllowed('user', 'save'));
$this->assertFalse($acl->isPageAccessAllowed('user', 'remove'));
$this->assertFalse($acl->isPageAccessAllowed('user', 'confirm'));
$this->assertFalse($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'));
public function testPageAccessNoSession()
{
$acl = new Acl($this->container);
$this->assertFalse($acl->isAllowed('board', 'readonly'));
$this->assertFalse($acl->isAllowed('task', 'show'));
$this->assertFalse($acl->isAllowed('config', 'application'));
$this->assertFalse($acl->isAllowed('project', 'users'));
$this->assertFalse($acl->isAllowed('task', 'remove'));
$this->assertTrue($acl->isAllowed('app', 'index'));
}
// Regular user
$_SESSION = array('user' => array('is_admin' => false));
$this->assertFalse($acl->isPageAccessAllowed('user', 'create'));
$this->assertFalse($acl->isPageAccessAllowed('user', 'save'));
$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'));
public function testPageAccessEmptySession()
{
$acl = new Acl($this->container);
$session = new Session;
// Admin user
$_SESSION = array('user' => array('is_admin' => true));
$this->assertTrue($acl->isPageAccessAllowed('user', 'create'));
$this->assertTrue($acl->isPageAccessAllowed('user', 'save'));
$this->assertTrue($acl->isPageAccessAllowed('user', 'remove'));
$this->assertTrue($acl->isPageAccessAllowed('user', 'confirm'));
$this->assertTrue($acl->isPageAccessAllowed('app', 'index'));
$this->assertTrue($acl->isPageAccessAllowed('user', 'index'));
$this->assertTrue($acl->isPageAccessAllowed('user', 'login'));
$this->assertTrue($acl->isPageAccessAllowed('user', 'check'));
$this->assertTrue($acl->isPageAccessAllowed('task', 'add'));
$this->assertTrue($acl->isPageAccessAllowed('board', 'readonly'));
$session['user'] = array();
$this->assertFalse($acl->isAllowed('board', 'readonly'));
$this->assertFalse($acl->isAllowed('task', 'show'));
$this->assertFalse($acl->isAllowed('config', 'application'));
$this->assertFalse($acl->isAllowed('project', 'users'));
$this->assertFalse($acl->isAllowed('task', 'remove'));
$this->assertTrue($acl->isAllowed('app', 'index'));
}
public function testPageAccessAdminUser()
{
$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\TaskFinder;
use Model\Project;
use Model\Acl;
use Model\UserSession;
class ActionTaskAssignCurrentUser extends Base
{
@ -52,9 +52,9 @@ class ActionTaskAssignCurrentUser extends Base
$tc = new TaskCreation($this->container);
$tf = new TaskFinder($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, $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>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')
);

View File

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

View File

@ -62,14 +62,14 @@ class ProjectPermissionTest extends Base
$this->assertEquals(1, $p->create(array('name' => 'UnitTest')));
// We allow the admin user
$this->assertTrue($pp->allowUser(1, 1));
$this->assertTrue($pp->allowUser(1, 2));
$this->assertTrue($pp->addMember(1, 1));
$this->assertTrue($pp->addMember(1, 2));
// Non-existant project
$this->assertFalse($pp->allowUser(50, 1));
$this->assertFalse($pp->addMember(50, 1));
// Non-existant user
$this->assertFalse($pp->allowUser(1, 50));
$this->assertFalse($pp->addMember(1, 50));
// Both users should be allowed
$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')));
// 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
$this->assertEmpty($pp->getMembers(1));
@ -99,7 +99,7 @@ class ProjectPermissionTest extends Base
$this->assertFalse($pp->isUserAllowed(1, 2));
// 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)
$this->assertTrue($pp->isUserAllowed(1, 1));
@ -109,13 +109,13 @@ class ProjectPermissionTest extends Base
$this->assertEquals(array('2' => 'unittest'), $pp->getMembers(1));
// 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->assertTrue($pp->isUserAllowed(1, 1));
$this->assertTrue($pp->isUserAllowed(1, 2));
// We revoke the regular user
$this->assertTrue($pp->revokeUser(1, 2));
$this->assertTrue($pp->revokeMember(1, 2));
// Only admin should be allowed
$this->assertTrue($pp->isUserAllowed(1, 1));
@ -125,7 +125,7 @@ class ProjectPermissionTest extends Base
$this->assertEquals(array('1' => 'admin'), $pp->getMembers(1));
// We revoke the admin user
$this->assertTrue($pp->revokeUser(1, 1));
$this->assertTrue($pp->revokeMember(1, 1));
$this->assertEmpty($pp->getMembers(1));
// Only admin should be allowed again
@ -133,6 +133,42 @@ class ProjectPermissionTest extends Base
$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()
{
$p = new Project($this->container);
@ -151,7 +187,7 @@ class ProjectPermissionTest extends Base
);
// We allow only the regular user
$this->assertTrue($pp->allowUser(1, 2));
$this->assertTrue($pp->addMember(1, 2));
$this->assertEquals(
array(0 => 'Unassigned', 2 => 'unittest'),
@ -159,7 +195,7 @@ class ProjectPermissionTest extends Base
);
// We allow the admin user
$this->assertTrue($pp->allowUser(1, 1));
$this->assertTrue($pp->addMember(1, 1));
$this->assertEquals(
array(0 => 'Unassigned', 1 => 'admin', 2 => 'unittest'),
@ -167,7 +203,7 @@ class ProjectPermissionTest extends Base
);
// We revoke only the regular user
$this->assertTrue($pp->revokeUser(1, 2));
$this->assertTrue($pp->revokeMember(1, 2));
$this->assertEquals(
array(0 => 'Unassigned', 1 => 'admin'),
@ -175,7 +211,7 @@ class ProjectPermissionTest extends Base
);
// We revoke only the admin user, we should have everybody
$this->assertTrue($pp->revokeUser(1, 1));
$this->assertTrue($pp->revokeMember(1, 1));
$this->assertEquals(
array(0 => 'Unassigned'),

View File

@ -240,8 +240,8 @@ class TaskDuplicationTest extends Base
// We create a new user for our project
$user = new User($this->container);
$this->assertNotFalse($user->create(array('username' => 'unittest#1', 'password' => 'unittest')));
$this->assertTrue($pp->allowUser(1, 2));
$this->assertTrue($pp->allowUser(2, 2));
$this->assertTrue($pp->addMember(1, 2));
$this->assertTrue($pp->addMember(2, 2));
$this->assertTrue($pp->isUserAllowed(1, 2));
$this->assertTrue($pp->isUserAllowed(2, 2));
@ -363,8 +363,8 @@ class TaskDuplicationTest extends Base
// We create a new user for our project
$this->assertNotFalse($user->create(array('username' => 'unittest#1', 'password' => 'unittest')));
$this->assertTrue($pp->allowUser(1, 2));
$this->assertTrue($pp->allowUser(2, 2));
$this->assertTrue($pp->addMember(1, 2));
$this->assertTrue($pp->addMember(2, 2));
$this->assertTrue($pp->isUserAllowed(1, 2));
$this->assertTrue($pp->isUserAllowed(2, 2));
@ -398,8 +398,8 @@ class TaskDuplicationTest extends Base
// We create a new user for our project
$this->assertNotFalse($user->create(array('username' => 'unittest#1', 'password' => 'unittest')));
$this->assertTrue($pp->allowUser(1, 2));
$this->assertTrue($pp->allowUser(2, 2));
$this->assertTrue($pp->addMember(1, 2));
$this->assertTrue($pp->addMember(2, 2));
$this->assertTrue($pp->isUserAllowed(1, 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'));
$this->assertEquals($i, count($rows));
$this->assertEquals('Task Id', $rows[0][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());
}
}