diff options
Diffstat (limited to 'app/Controller/Base.php')
-rw-r--r-- | app/Controller/Base.php | 259 |
1 files changed, 128 insertions, 131 deletions
diff --git a/app/Controller/Base.php b/app/Controller/Base.php index a955b12c..884c439c 100644 --- a/app/Controller/Base.php +++ b/app/Controller/Base.php @@ -2,11 +2,7 @@ namespace Kanboard\Controller; -use Pimple\Container; -use Kanboard\Core\Security; -use Kanboard\Core\Request; -use Kanboard\Core\Response; -use Symfony\Component\EventDispatcher\Event; +use Kanboard\Core\Security\Role; /** * Base controller @@ -17,54 +13,22 @@ use Symfony\Component\EventDispatcher\Event; abstract class Base extends \Kanboard\Core\Base { /** - * Request instance - * - * @accesss protected - * @var \Kanboard\Core\Request - */ - protected $request; - - /** - * Response instance - * - * @accesss protected - * @var \Kanboard\Core\Response - */ - protected $response; - - /** - * Constructor - * - * @access public - * @param \Pimple\Container $container - */ - public function __construct(Container $container) - { - $this->container = $container; - $this->request = new Request; - $this->response = new Response; - - if (DEBUG) { - $this->container['logger']->debug('START_REQUEST='.$_SERVER['REQUEST_URI']); - } - } - - /** - * Destructor + * Method executed before each action * * @access public */ - public function __destruct() + public function beforeAction() { - if (DEBUG) { - foreach ($this->container['db']->getLogMessages() as $message) { - $this->container['logger']->debug($message); - } + $this->sessionManager->open(); + $this->dispatcher->dispatch('app.bootstrap'); + $this->sendHeaders(); + $this->authenticationManager->checkCurrentSession(); - $this->container['logger']->debug('SQL_QUERIES={nb}', array('nb' => $this->container['db']->nbQueries)); - $this->container['logger']->debug('RENDERING={time}', array('time' => microtime(true) - @$_SERVER['REQUEST_TIME_FLOAT'])); - $this->container['logger']->debug('MEMORY='.$this->helper->text->bytes(memory_get_usage())); - $this->container['logger']->debug('END_REQUEST='.$_SERVER['REQUEST_URI']); + if (! $this->applicationAuthorization->isAllowed($this->router->getController(), $this->router->getAction(), Role::APP_PUBLIC)) { + $this->handleAuthentication(); + $this->handlePostAuthentication(); + $this->checkApplicationAuthorization(); + $this->checkProjectAuthorization(); } } @@ -73,7 +37,7 @@ abstract class Base extends \Kanboard\Core\Base * * @access private */ - private function sendHeaders($action) + private function sendHeaders() { // HTTP secure headers $this->response->csp($this->container['cspRules']); @@ -81,7 +45,7 @@ abstract class Base extends \Kanboard\Core\Base $this->response->xss(); // Allow the public board iframe inclusion - if (ENABLE_XFRAME && $action !== 'readonly') { + if (ENABLE_XFRAME && $this->router->getAction() !== 'readonly') { $this->response->xframe(); } @@ -91,53 +55,34 @@ abstract class Base extends \Kanboard\Core\Base } /** - * Method executed before each action - * - * @access public - */ - public function beforeAction($controller, $action) - { - // Start the session - $this->session->open($this->helper->url->dir()); - $this->sendHeaders($action); - $this->container['dispatcher']->dispatch('session.bootstrap', new Event); - - if (! $this->acl->isPublicAction($controller, $action)) { - $this->handleAuthentication(); - $this->handle2FA($controller, $action); - $this->handleAuthorization($controller, $action); - - $this->session['has_subtask_inprogress'] = $this->subtask->hasSubtaskInProgress($this->userSession->getId()); - } - } - - /** * Check authentication * - * @access public + * @access private */ - public function handleAuthentication() + private function handleAuthentication() { - if (! $this->authentication->isAuthenticated()) { + if (! $this->userSession->isLogged() && ! $this->authenticationManager->preAuthentication()) { if ($this->request->isAjax()) { $this->response->text('Not Authorized', 401); } - $this->session['login_redirect'] = $this->request->getUri(); + $this->sessionStorage->redirectAfterLogin = $this->request->getUri(); $this->response->redirect($this->helper->url->to('auth', 'login')); } } /** - * Check 2FA + * Handle Post-Authentication (2FA) * - * @access public + * @access private */ - public function handle2FA($controller, $action) + private function handlePostAuthentication() { + $controller = strtolower($this->router->getController()); + $action = strtolower($this->router->getAction()); $ignore = ($controller === 'twofactor' && in_array($action, array('code', 'check'))) || ($controller === 'auth' && $action === 'logout'); - if ($ignore === false && $this->userSession->has2FA() && ! $this->userSession->check2FA()) { + if ($ignore === false && $this->userSession->hasPostAuthentication() && ! $this->userSession->isPostAuthenticationValidated()) { if ($this->request->isAjax()) { $this->response->text('Not Authorized', 401); } @@ -147,11 +92,23 @@ abstract class Base extends \Kanboard\Core\Base } /** - * Check page access and authorization + * Check application authorization * - * @access public + * @access private */ - public function handleAuthorization($controller, $action) + private function checkApplicationAuthorization() + { + if (! $this->helper->user->hasAccess($this->router->getController(), $this->router->getAction())) { + $this->forbidden(); + } + } + + /** + * Check project authorization + * + * @access private + */ + private function checkProjectAuthorization() { $project_id = $this->request->getIntegerParam('project_id'); $task_id = $this->request->getIntegerParam('task_id'); @@ -161,7 +118,7 @@ abstract class Base extends \Kanboard\Core\Base $project_id = $this->taskFinder->getProjectId($task_id); } - if (! $this->acl->isAllowed($controller, $action, $project_id)) { + if ($project_id > 0 && ! $this->helper->user->hasProjectAccess($this->router->getController(), $this->router->getAction(), $project_id)) { $this->forbidden(); } } @@ -169,12 +126,12 @@ abstract class Base extends \Kanboard\Core\Base /** * Application not found page (404 error) * - * @access public + * @access protected * @param boolean $no_layout Display the layout or not */ - public function notfound($no_layout = false) + protected function notfound($no_layout = false) { - $this->response->html($this->template->layout('app/notfound', array( + $this->response->html($this->helper->layout->app('app/notfound', array( 'title' => t('Page not found'), 'no_layout' => $no_layout, ))); @@ -183,12 +140,16 @@ abstract class Base extends \Kanboard\Core\Base /** * Application forbidden page * - * @access public + * @access protected * @param boolean $no_layout Display the layout or not */ - public function forbidden($no_layout = false) + protected function forbidden($no_layout = false) { - $this->response->html($this->template->layout('app/forbidden', array( + if ($this->request->isAjax()) { + $this->response->text('Access Forbidden', 403); + } + + $this->response->html($this->helper->layout->app('app/forbidden', array( 'title' => t('Access Forbidden'), 'no_layout' => $no_layout, ))); @@ -201,7 +162,7 @@ abstract class Base extends \Kanboard\Core\Base */ protected function checkCSRFParam() { - if (! Security::validateCSRFToken($this->request->getStringParam('csrf_token'))) { + if (! $this->token->validateCSRFToken($this->request->getStringParam('csrf_token'))) { $this->forbidden(); } } @@ -219,43 +180,6 @@ abstract class Base extends \Kanboard\Core\Base } /** - * Common layout for task views - * - * @access protected - * @param string $template Template name - * @param array $params Template parameters - * @return string - */ - protected function taskLayout($template, array $params) - { - $content = $this->template->render($template, $params); - $params['task_content_for_layout'] = $content; - $params['title'] = $params['task']['project_name'].' > '.$params['task']['title']; - $params['board_selector'] = $this->projectPermission->getAllowedProjects($this->userSession->getId()); - - return $this->template->layout('task/layout', $params); - } - - /** - * Common layout for project views - * - * @access protected - * @param string $template Template name - * @param array $params Template parameters - * @return string - */ - protected function projectLayout($template, array $params, $sidebar_template = 'project/sidebar') - { - $content = $this->template->render($template, $params); - $params['project_content_for_layout'] = $content; - $params['title'] = $params['project']['name'] === $params['title'] ? $params['title'] : $params['project']['name'].' > '.$params['title']; - $params['board_selector'] = $this->projectPermission->getAllowedProjects($this->userSession->getId()); - $params['sidebar_template'] = $sidebar_template; - - return $this->template->layout('project/layout', $params); - } - - /** * Common method to get a task for task views * * @access protected @@ -278,6 +202,36 @@ abstract class Base extends \Kanboard\Core\Base } /** + * Get Task or Project file + * + * @access protected + */ + protected function getFile() + { + $task_id = $this->request->getIntegerParam('task_id'); + $file_id = $this->request->getIntegerParam('file_id'); + $model = 'projectFile'; + + if ($task_id > 0) { + $model = 'taskFile'; + $project_id = $this->taskFinder->getProjectId($task_id); + + if ($project_id !== $this->request->getIntegerParam('project_id')) { + $this->forbidden(); + } + } + + $file = $this->$model->getById($file_id); + + if (empty($file)) { + $this->notfound(); + } + + $file['model'] = $model; + return $file; + } + + /** * Common method to get a project * * @access protected @@ -287,11 +241,10 @@ abstract class Base extends \Kanboard\Core\Base protected function getProject($project_id = 0) { $project_id = $this->request->getIntegerParam('project_id', $project_id); - $project = $this->project->getById($project_id); + $project = $this->project->getByIdWithOwner($project_id); if (empty($project)) { - $this->session->flashError(t('Project not found.')); - $this->response->redirect($this->helper->url->to('project', 'index')); + $this->notfound(); } return $project; @@ -319,15 +272,35 @@ abstract class Base extends \Kanboard\Core\Base } /** + * Get the current subtask + * + * @access protected + * @return array + */ + protected function getSubtask() + { + $subtask = $this->subtask->getById($this->request->getIntegerParam('subtask_id')); + + if (empty($subtask)) { + $this->notfound(); + } + + return $subtask; + } + + /** * Common method to get project filters * * @access protected + * @param string $controller + * @param string $action + * @return array */ protected function getProjectFilters($controller, $action) { $project = $this->getProject(); $search = $this->request->getStringParam('search', $this->userSession->getFilters($project['id'])); - $board_selector = $this->projectPermission->getAllowedProjects($this->userSession->getId()); + $board_selector = $this->projectUserRole->getActiveProjectsByUser($this->userSession->getId()); unset($board_selector[$project['id']]); $filters = array( @@ -344,6 +317,30 @@ abstract class Base extends \Kanboard\Core\Base 'board_selector' => $board_selector, 'filters' => $filters, 'title' => $project['name'], + 'description' => $this->getProjectDescription($project), ); } + + /** + * Get project description + * + * @access protected + * @param array &$project + * @return string + */ + protected function getProjectDescription(array &$project) + { + if ($project['owner_id'] > 0) { + $description = t('Project owner: ').'**'.$this->template->e($project['owner_name'] ?: $project['owner_username']).'**'.PHP_EOL.PHP_EOL; + + if (! empty($project['description'])) { + $description .= '***'.PHP_EOL.PHP_EOL; + $description .= $project['description']; + } + } else { + $description = $project['description']; + } + + return $description; + } } |