diff options
Diffstat (limited to 'app/Api/Middleware/AuthenticationApiMiddleware.php')
-rw-r--r-- | app/Api/Middleware/AuthenticationApiMiddleware.php | 130 |
1 files changed, 130 insertions, 0 deletions
diff --git a/app/Api/Middleware/AuthenticationApiMiddleware.php b/app/Api/Middleware/AuthenticationApiMiddleware.php new file mode 100644 index 00000000..5f63e1a1 --- /dev/null +++ b/app/Api/Middleware/AuthenticationApiMiddleware.php @@ -0,0 +1,130 @@ +<?php + +namespace Kanboard\Api\Middleware; + +use JsonRPC\Exception\AccessDeniedException; +use JsonRPC\Exception\AuthenticationFailureException; +use JsonRPC\MiddlewareInterface; +use Kanboard\Core\Base; + +/** + * Class AuthenticationApiMiddleware + * + * @package Kanboard\Api\Middleware + * @author Frederic Guillot + */ +class AuthenticationApiMiddleware extends Base implements MiddlewareInterface +{ + private $user_allowed_procedures = array( + 'getMe', + 'getMyDashboard', + 'getMyActivityStream', + 'createMyPrivateProject', + 'getMyProjectsList', + 'getMyProjects', + 'getMyOverdueTasks', + ); + + private $both_allowed_procedures = array( + 'getTimezone', + 'getVersion', + 'getDefaultTaskColor', + 'getDefaultTaskColors', + 'getColorList', + 'getProjectById', + 'getTask', + 'getTaskByReference', + 'getAllTasks', + 'openTask', + 'closeTask', + 'moveTaskPosition', + 'createTask', + 'updateTask', + 'getBoard', + 'getProjectActivity', + 'getOverdueTasksByProject', + 'searchTasks', + ); + + /** + * Execute Middleware + * + * @access public + * @param string $username + * @param string $password + * @param string $procedureName + * @throws AccessDeniedException + * @throws AuthenticationFailureException + */ + public function execute($username, $password, $procedureName) + { + $this->dispatcher->dispatch('app.bootstrap'); + + if ($this->isUserAuthenticated($username, $password)) { + $this->checkProcedurePermission(true, $procedureName); + $this->userSession->initialize($this->userModel->getByUsername($username)); + } elseif ($this->isAppAuthenticated($username, $password)) { + $this->checkProcedurePermission(false, $procedureName); + } else { + $this->logger->error('API authentication failure for '.$username); + throw new AuthenticationFailureException('Wrong credentials'); + } + } + + /** + * Check user credentials + * + * @access public + * @param string $username + * @param string $password + * @return boolean + */ + private function isUserAuthenticated($username, $password) + { + return $username !== 'jsonrpc' && + ! $this->userLockingModel->isLocked($username) && + $this->authenticationManager->passwordAuthentication($username, $password); + } + + /** + * Check administrative credentials + * + * @access public + * @param string $username + * @param string $password + * @return boolean + */ + private function isAppAuthenticated($username, $password) + { + return $username === 'jsonrpc' && $password === $this->getApiToken(); + } + + /** + * Get API Token + * + * @access private + * @return string + */ + private function getApiToken() + { + if (defined('API_AUTHENTICATION_TOKEN')) { + return API_AUTHENTICATION_TOKEN; + } + + return $this->configModel->get('api_token'); + } + + public function checkProcedurePermission($is_user, $procedure) + { + $is_both_procedure = in_array($procedure, $this->both_allowed_procedures); + $is_user_procedure = in_array($procedure, $this->user_allowed_procedures); + + if ($is_user && ! $is_both_procedure && ! $is_user_procedure) { + throw new AccessDeniedException('Permission denied'); + } elseif (! $is_user && ! $is_both_procedure && $is_user_procedure) { + throw new AccessDeniedException('Permission denied'); + } + + $this->logger->debug('API call: '.$procedure); + } +} |