diff --git a/PHPCI/Application.php b/PHPCI/Application.php index ecc71ad5..011e27e5 100644 --- a/PHPCI/Application.php +++ b/PHPCI/Application.php @@ -10,6 +10,7 @@ namespace PHPCI; use b8; +use b8\Exception\HttpException; use b8\Http\Response; use b8\Http\Response\RedirectResponse; use b8\View; @@ -51,6 +52,7 @@ class Application extends b8\Application $response->setResponseCode(401); $response->setContent(''); } else { + $_SESSION['login_redirect'] = substr($request->getPath(), 1); $response = new RedirectResponse($response); $response->setHeader('Location', PHPCI_URL.'session/login'); } @@ -69,7 +71,25 @@ class Application extends b8\Application */ public function handleRequest() { - $this->response = parent::handleRequest(); + try { + $this->response = parent::handleRequest(); + } catch (HttpException $ex) { + $this->config->set('page_title', 'Error'); + + $view = new View('exception'); + $view->exception = $ex; + + $this->response->setResponseCode($ex->getErrorCode()); + $this->response->setContent($view->render()); + } catch (\Exception $ex) { + $this->config->set('page_title', 'Error'); + + $view = new View('exception'); + $view->exception = $ex; + + $this->response->setResponseCode(500); + $this->response->setContent($view->render()); + } if (View::exists('layout') && $this->response->hasLayout()) { $view = new View('layout'); diff --git a/PHPCI/BuildFactory.php b/PHPCI/BuildFactory.php index 82ebc221..3f48eec0 100644 --- a/PHPCI/BuildFactory.php +++ b/PHPCI/BuildFactory.php @@ -21,11 +21,16 @@ class BuildFactory /** * @param $buildId * @return Build + * @throws \Exception */ public static function getBuildById($buildId) { $build = Factory::getStore('Build')->getById($buildId); + if (empty($build)) { + throw new \Exception('Build ID ' . $buildId . ' does not exist.'); + } + return self::getBuild($build); } diff --git a/PHPCI/Controller/BuildController.php b/PHPCI/Controller/BuildController.php index 3ebb8432..1dff5a15 100644 --- a/PHPCI/Controller/BuildController.php +++ b/PHPCI/Controller/BuildController.php @@ -10,6 +10,7 @@ namespace PHPCI\Controller; use b8; +use b8\Exception\HttpException\NotFoundException; use PHPCI\BuildFactory; use PHPCI\Model\Build; @@ -36,7 +37,16 @@ class BuildController extends \PHPCI\Controller */ public function view($buildId) { - $build = BuildFactory::getBuildById($buildId); + try { + $build = BuildFactory::getBuildById($buildId); + } catch (\Exception $ex) { + $build = null; + } + + if (empty($build)) { + throw new NotFoundException('Build with ID: ' . $buildId . ' does not exist.'); + } + $this->view->plugins = $this->getUiPlugins(); $this->view->build = $build; $this->view->data = $this->getBuildData($build); @@ -110,6 +120,10 @@ class BuildController extends \PHPCI\Controller { $copy = BuildFactory::getBuildById($buildId); + if (empty($copy)) { + throw new NotFoundException('Build with ID: ' . $buildId . ' does not exist.'); + } + $build = new Build(); $build->setProjectId($copy->getProjectId()); $build->setCommitId($copy->getCommitId()); @@ -134,11 +148,10 @@ class BuildController extends \PHPCI\Controller throw new \Exception('You do not have permission to do that.'); } - $build = BuildFactory::getBuildById($buildId); + $build = BuildFactory::getBuildById($buildId); - if (!$build) { - $this->response->setResponseCode(404); - return '404 - Not Found'; + if (empty($build)) { + throw new NotFoundException('Build with ID: ' . $buildId . ' does not exist.'); } $this->buildStore->delete($build); diff --git a/PHPCI/Controller/BuildStatusController.php b/PHPCI/Controller/BuildStatusController.php index 74a1fbad..8c34cd63 100644 --- a/PHPCI/Controller/BuildStatusController.php +++ b/PHPCI/Controller/BuildStatusController.php @@ -65,7 +65,8 @@ class BuildStatusController extends \PHPCI\Controller public function view($projectId) { $project = $this->projectStore->getById($projectId); - if (!$project) { + + if (empty($project)) { throw new NotFoundException('Project with id: ' . $projectId . ' not found'); } diff --git a/PHPCI/Controller/ProjectController.php b/PHPCI/Controller/ProjectController.php index eea5a7a8..90faf898 100644 --- a/PHPCI/Controller/ProjectController.php +++ b/PHPCI/Controller/ProjectController.php @@ -9,17 +9,17 @@ namespace PHPCI\Controller; +use b8; +use b8\Controller; +use b8\Form; +use b8\Exception\HttpException\ForbiddenException; +use b8\Exception\HttpException\NotFoundException; +use b8\Store; use PHPCI\BuildFactory; use PHPCI\Helper\Github; use PHPCI\Helper\SshKey; use PHPCI\Model\Build; use PHPCI\Model\Project; -use b8; -use b8\Config; -use b8\Controller; -use b8\Store; -use b8\Form; -use b8\Exception\HttpException\NotFoundException; /** * Project Controller - Allows users to create, edit and view projects. @@ -41,8 +41,8 @@ class ProjectController extends \PHPCI\Controller public function init() { - $this->buildStore = Store\Factory::getStore('Build'); - $this->projectStore = Store\Factory::getStore('Project'); + $this->buildStore = Store\Factory::getStore('Build'); + $this->projectStore = Store\Factory::getStore('Project'); } /** @@ -51,17 +51,18 @@ class ProjectController extends \PHPCI\Controller public function view($projectId) { $project = $this->projectStore->getById($projectId); - if (!$project) { + + if (empty($project)) { throw new NotFoundException('Project with id: ' . $projectId . ' not found'); } - $page = $this->getParam('p', 1); - $builds = $this->getLatestBuildsHtml($projectId, (($page - 1) * 10)); + $page = $this->getParam('p', 1); + $builds = $this->getLatestBuildsHtml($projectId, (($page - 1) * 10)); - $this->view->builds = $builds[0]; - $this->view->total = $builds[1]; - $this->view->project = $project; - $this->view->page = $page; + $this->view->builds = $builds[0]; + $this->view->total = $builds[1]; + $this->view->project = $project; + $this->view->page = $page; $this->config->set('page_title', $project->getTitle()); @@ -76,6 +77,10 @@ class ProjectController extends \PHPCI\Controller /* @var \PHPCI\Model\Project $project */ $project = $this->projectStore->getById($projectId); + if (empty($project)) { + throw new NotFoundException('Project with id: ' . $projectId . ' not found'); + } + $build = new Build(); $build->setProjectId($projectId); $build->setCommitId('Manual'); @@ -96,7 +101,7 @@ class ProjectController extends \PHPCI\Controller public function delete($projectId) { if (!$_SESSION['user']->getIsAdmin()) { - throw new \Exception('You do not have permission to do that.'); + throw new ForbiddenException('You do not have permission to do that.'); } $project = $this->projectStore->getById($projectId); @@ -120,10 +125,10 @@ class ProjectController extends \PHPCI\Controller */ protected function getLatestBuildsHtml($projectId, $start = 0) { - $criteria = array('project_id' => $projectId); - $order = array('id' => 'DESC'); - $builds = $this->buildStore->getWhere($criteria, 10, $start, array(), $order); - $view = new b8\View('BuildsTable'); + $criteria = array('project_id' => $projectId); + $order = array('id' => 'DESC'); + $builds = $this->buildStore->getWhere($criteria, 10, $start, array(), $order); + $view = new b8\View('BuildsTable'); foreach ($builds['items'] as &$build) { $build = BuildFactory::getBuild($build); @@ -142,7 +147,7 @@ class ProjectController extends \PHPCI\Controller $this->config->set('page_title', 'Add Project'); if (!$_SESSION['user']->getIsAdmin()) { - throw new \Exception('You do not have permission to do that.'); + throw new ForbiddenException('You do not have permission to do that.'); } $method = $this->request->getMethod(); @@ -210,31 +215,33 @@ class ProjectController extends \PHPCI\Controller public function edit($projectId) { if (!$_SESSION['user']->getIsAdmin()) { - throw new \Exception('You do not have permission to do that.'); + throw new ForbiddenException('You do not have permission to do that.'); } - $method = $this->request->getMethod(); - $project = $this->projectStore->getById($projectId); + $method = $this->request->getMethod(); + $project = $this->projectStore->getById($projectId); + + if (empty($project)) { + throw new NotFoundException('Project with id: ' . $projectId . ' not found'); + } $this->config->set('page_title', 'Edit: ' . $project->getTitle()); + $values = $project->getDataArray(); + $values['key'] = $values['git_key']; + $values['pubkey'] = $values['public_key']; + + if ($values['type'] == "gitlab") { + $accessInfo = $project->getAccessInformation(); + $reference = $accessInfo["user"].'@'.$accessInfo["domain"].':' . $project->getReference().".git"; + $values['reference'] = $reference; + } if ($method == 'POST') { $values = $this->getParams(); - } else { - $values = $project->getDataArray(); - $values['key'] = $values['git_key']; - $values['pubkey'] = $values['public_key']; - - if ($values['type'] == "gitlab") { - $accessInfo = $project->getAccessInformation(); - $reference = $accessInfo["user"].'@'.$accessInfo["domain"].':' . $project->getReference().".git"; - $values['reference'] = $reference; - } } - - $form = $this->projectForm($values, 'edit/' . $projectId); + $form = $this->projectForm($values, 'edit/' . $projectId); if ($method != 'POST' || ($method == 'POST' && !$form->validate())) { $view = new b8\View('ProjectForm'); diff --git a/PHPCI/Controller/SessionController.php b/PHPCI/Controller/SessionController.php index def6d4c4..48a70475 100644 --- a/PHPCI/Controller/SessionController.php +++ b/PHPCI/Controller/SessionController.php @@ -43,7 +43,7 @@ class SessionController extends \PHPCI\Controller if ($user && password_verify($this->getParam('password', ''), $user->getHash())) { $_SESSION['user_id'] = $user->getId(); - header('Location: ' . PHPCI_URL); + header('Location: ' . $this->getLoginRedirect()); die; } else { $isLoginFailure = true; @@ -159,4 +159,16 @@ MSG; return $this->view->render(); } + + protected function getLoginRedirect() + { + $rtn = PHPCI_URL; + + if (!empty($_SESSION['login_redirect'])) { + $rtn .= $_SESSION['login_redirect']; + $_SESSION['login_redirect'] = null; + } + + return $rtn; + } } diff --git a/PHPCI/Controller/UserController.php b/PHPCI/Controller/UserController.php index 817cb5e8..62b5d4d9 100644 --- a/PHPCI/Controller/UserController.php +++ b/PHPCI/Controller/UserController.php @@ -10,6 +10,8 @@ namespace PHPCI\Controller; use b8; +use b8\Exception\HttpException\ForbiddenException; +use b8\Exception\HttpException\NotFoundException; use b8\Form; use PHPCI\Controller; use PHPCI\Model\User; @@ -106,12 +108,11 @@ class UserController extends Controller public function add() { if (!$_SESSION['user']->getIsAdmin()) { - throw new \Exception('You do not have permission to do that.'); + throw new ForbiddenException('You do not have permission to do that.'); } $this->config->set('page_title', 'Add User'); - $method = $this->request->getMethod(); if ($method == 'POST') { @@ -132,7 +133,6 @@ class UserController extends Controller } $values = $form->getValues(); - $values['is_admin'] = $values['admin'] ? 1 : 0; $values['hash'] = password_hash($values['password'], PASSWORD_DEFAULT); $user = new User(); @@ -150,42 +150,40 @@ class UserController extends Controller public function edit($userId) { if (!$_SESSION['user']->getIsAdmin()) { - throw new \Exception('You do not have permission to do that.'); + throw new ForbiddenException('You do not have permission to do that.'); } - $method = $this->request->getMethod(); - $user = $this->userStore->getById($userId); + $method = $this->request->getMethod(); + $user = $this->userStore->getById($userId); - $this->config->set('page_title', 'Edit: ' . $user->getName()); - - - if ($method == 'POST') { - $values = $this->getParams(); - } else { - $values = $user->getDataArray(); - $values['admin'] = $values['is_admin']; + if (empty($user)) { + throw new NotFoundException('User with ID: ' . $userId . ' does not exist.'); } - $form = $this->userForm($values, 'edit/' . $userId); + $values = array_merge($user->getDataArray(), $this->getParams()); + $form = $this->userForm($values, 'edit/' . $userId); if ($method != 'POST' || ($method == 'POST' && !$form->validate())) { - $view = new b8\View('UserForm'); - $view->type = 'edit'; - $view->user = $user; - $view->form = $form; + $view = new b8\View('UserForm'); + $view->type = 'edit'; + $view->user = $user; + $view->form = $form; return $view->render(); } - $values = $form->getValues(); - $values['is_admin'] = $values['admin'] ? 1 : 0; - if (!empty($values['password'])) { $values['hash'] = password_hash($values['password'], PASSWORD_DEFAULT); } $user->setValues($values); - $user = $this->userStore->save($user); + + $isAdmin = $this->getParam('is_admin'); + if (empty($isAdmin)) { + $user->setIsAdmin(0); + } + + $this->userStore->save($user); header('Location: '.PHPCI_URL.'user'); die; @@ -216,13 +214,20 @@ class UserController extends Controller $form->addField($field); $field = new Form\Element\Password('password'); - $field->setRequired(true); - $field->setLabel('Password' . ($type == 'edit' ? ' (leave blank to keep current password)' : '')); + + if ($type == 'add') { + $field->setRequired(true); + $field->setLabel('Password'); + } else { + $field->setRequired(false); + $field->setLabel('Password (leave blank to keep current password)'); + } + $field->setClass('form-control'); $field->setContainerClass('form-group'); $form->addField($field); - $field = new Form\Element\Checkbox('admin'); + $field = new Form\Element\Checkbox('is_admin'); $field->setRequired(false); $field->setCheckedValue(1); $field->setLabel('Is this user an administrator?'); @@ -244,10 +249,15 @@ class UserController extends Controller public function delete($userId) { if (!$_SESSION['user']->getIsAdmin()) { - throw new \Exception('You do not have permission to do that.'); + throw new ForbiddenException('You do not have permission to do that.'); } $user = $this->userStore->getById($userId); + + if (empty($user)) { + throw new NotFoundException('User with ID: ' . $userId . ' does not exist.'); + } + $this->userStore->delete($user); header('Location: '.PHPCI_URL.'user'); diff --git a/PHPCI/Plugin/PhpDocblockChecker.php b/PHPCI/Plugin/PhpDocblockChecker.php index b41b8434..f2d91b4e 100755 --- a/PHPCI/Plugin/PhpDocblockChecker.php +++ b/PHPCI/Plugin/PhpDocblockChecker.php @@ -89,13 +89,7 @@ class PhpDocblockChecker implements PHPCI\Plugin, PHPCI\ZeroConfigPlugin */ public function execute() { - $ignore = ''; - if (count($this->ignore)) { - $ignore = ' --exclude="' . implode(',', $this->ignore) . '"'; - } - - var_dump($ignore); - + // Check that the binary exists: $checker = $this->phpci->findBinary('phpdoccheck'); if (!$checker) { @@ -103,9 +97,25 @@ class PhpDocblockChecker implements PHPCI\Plugin, PHPCI\ZeroConfigPlugin return false; } - $path = $this->phpci->buildPath . $this->path; + // Build ignore string: + $ignore = ''; + if (count($this->ignore)) { + $ignore = ' --exclude="' . implode(',', $this->ignore) . '"'; + } - $cmd = $checker . ' --json --directory="%s"%s%s%s'; + // Are we skipping any checks? + $add = ''; + if ($this->skipClasses) { + $add .= ' --skip-classes'; + } + + if ($this->skipMethods) { + $add .= ' --skip-methods'; + } + + // Build command string: + $path = $this->phpci->buildPath . $this->path; + $cmd = $checker . ' --json --directory="%s"%s%s'; // Disable exec output logging, as we don't want the XML report in the log: $this->phpci->logExecOutput(false); @@ -115,8 +125,7 @@ class PhpDocblockChecker implements PHPCI\Plugin, PHPCI\ZeroConfigPlugin $cmd, $path, $ignore, - ($this->skipClasses ? ' --skip-classes' : ''), - ($this->skipMethods ? ' --skip-methods' : '') + $add ); // Re-enable exec output logging: diff --git a/PHPCI/Plugin/PhpSpec.php b/PHPCI/Plugin/PhpSpec.php index c8a36253..c8ba27bc 100644 --- a/PHPCI/Plugin/PhpSpec.php +++ b/PHPCI/Plugin/PhpSpec.php @@ -58,7 +58,7 @@ class PhpSpec implements PHPCI\Plugin return false; } - $success = $this->phpci->executeCommand($phpspec . ' --format=pretty --no-code-generation'); + $success = $this->phpci->executeCommand($phpspec . ' --format=pretty --no-code-generation run'); chdir($curdir); diff --git a/PHPCI/View/exception.phtml b/PHPCI/View/exception.phtml new file mode 100644 index 00000000..1ecbe6a4 --- /dev/null +++ b/PHPCI/View/exception.phtml @@ -0,0 +1,9 @@ +