diff --git a/PHPCI/Controller/PluginController.php b/PHPCI/Controller/PluginController.php index 0dd3f2b4..22b25bfc 100644 --- a/PHPCI/Controller/PluginController.php +++ b/PHPCI/Controller/PluginController.php @@ -47,6 +47,10 @@ class PluginController extends \PHPCI\Controller public function index() { + if (!$_SESSION['user']->getIsAdmin()) { + throw new \Exception('You do not have permission to do that.'); + } + $this->view->canWrite = is_writable(APPLICATION_PATH . 'composer.json'); $this->view->canInstall = $this->canInstall; $this->view->required = $this->required; @@ -60,6 +64,10 @@ class PluginController extends \PHPCI\Controller public function remove() { + if (!$_SESSION['user']->getIsAdmin()) { + throw new \Exception('You do not have permission to do that.'); + } + $package = $this->getParam('package', null); $json = $this->getComposerJson(); @@ -81,6 +89,10 @@ class PluginController extends \PHPCI\Controller public function install() { + if (!$_SESSION['user']->getIsAdmin()) { + throw new \Exception('You do not have permission to do that.'); + } + $package = $this->getParam('package', null); $version = $this->getParam('version', '*'); diff --git a/PHPCI/Controller/ProjectController.php b/PHPCI/Controller/ProjectController.php index db684051..1a4fc496 100644 --- a/PHPCI/Controller/ProjectController.php +++ b/PHPCI/Controller/ProjectController.php @@ -12,6 +12,7 @@ namespace PHPCI\Controller; use PHPCI\Model\Build; use PHPCI\Model\Project; use b8; +use b8\Config; use b8\Controller; use b8\Store; use b8\Form; @@ -87,7 +88,7 @@ class ProjectController extends \PHPCI\Controller throw new \Exception('You do not have permission to do that.'); } - $project = $this->projectStore->getById($projectId); + $project = $this->projectStore->getById($projectId); $this->projectStore->delete($project); header('Location: '.PHPCI_URL); @@ -127,7 +128,6 @@ class ProjectController extends \PHPCI\Controller } $method = $this->request->getMethod(); - $this->handleGithubResponse(); if ($method == 'POST') { $values = $this->getParams(); @@ -154,10 +154,10 @@ class ProjectController extends \PHPCI\Controller $pub = file_get_contents($keyFile . '.pub'); $prv = file_get_contents($keyFile); - $values = array('key' => $prv, 'pubkey' => $pub, 'token' => $_SESSION['github_token']); + $values = array('key' => $prv, 'pubkey' => $pub); } - $form = $this->projectForm($values); + $form = $this->projectForm($values); if ($method != 'POST' || ($method == 'POST' && !$form->validate())) { $view = new b8\View('ProjectForm'); @@ -165,12 +165,11 @@ class ProjectController extends \PHPCI\Controller $view->project = null; $view->form = $form; $view->key = $pub; - $view->token = $_SESSION['github_token']; return $view->render(); } - $values = $form->getValues(); + $values = $form->getValues(); if ($values['type'] == "gitlab") { preg_match('`^(.*)@(.*):(.*)/(.*)\.git`', $values['reference'], $matches); @@ -192,33 +191,6 @@ class ProjectController extends \PHPCI\Controller die; } - /** - * Handles log in with Github - */ - protected function handleGithubResponse() - { - $github = \b8\Config::getInstance()->get('phpci.github'); - $code = $this->getParam('code', null); - - if (!is_null($code)) { - $http = new \b8\HttpClient(); - $url = 'https://github.com/login/oauth/access_token'; - $params = array('client_id' => $github['id'], 'client_secret' => $github['secret'], 'code' => $code); - $resp = $http->post($url, $params); - - if ($resp['success']) { - parse_str($resp['body'], $resp); - $_SESSION['github_token'] = $resp['access_token']; - header('Location: '.PHPCI_URL.'project/add'); - die; - } - } - - if (!isset($_SESSION['github_token'])) { - $_SESSION['github_token'] = null; - } - } - /** * Edit a project. Handles both the form and processing. */ @@ -236,6 +208,7 @@ class ProjectController extends \PHPCI\Controller } else { $values = $project->getDataArray(); $values['key'] = $values['git_key']; + if ($values['type'] == "gitlab") { $accessInfo = $project->getAccessInformation(); $reference = $accessInfo["user"].'@'.$accessInfo["domain"].':' . $project->getReference().".git"; @@ -284,7 +257,6 @@ class ProjectController extends \PHPCI\Controller $form->setMethod('POST'); $form->setAction(PHPCI_URL.'project/' . $type); $form->addField(new Form\Element\Csrf('csrf')); - $form->addField(new Form\Element\Hidden('token')); $form->addField(new Form\Element\Hidden('pubkey')); $options = array( @@ -306,14 +278,16 @@ class ProjectController extends \PHPCI\Controller $field->setContainerClass('form-group'); $form->addField($field); - if (isset($_SESSION['github_token'])) { - $field = new Form\Element\Select('github'); - $field->setLabel('Choose a Github repository:'); - $field->setClass('form-control'); - $field->setContainerClass('form-group'); - $field->setOptions($this->getGithubRepositories()); - $form->addField($field); - } + + $container = new Form\ControlGroup('github-container'); + $container->setClass('github-container'); + + $field = new Form\Element\Select('github'); + $field->setLabel('Choose a Github repository:'); + $field->setClass('form-control'); + $field->setContainerClass('form-group'); + $container->addField($field); + $form->addField($container); $field = new Form\Element\Text('reference'); $field->setRequired(true); @@ -351,21 +325,48 @@ class ProjectController extends \PHPCI\Controller /** * Get an array of repositories from Github's API. */ - protected function getGithubRepositories() + protected function githubRepositories() { - $http = new \b8\HttpClient(); - $url = 'https://api.github.com/user/repos'; - $res = $http->get($url, array('type' => 'all', 'access_token' => $_SESSION['github_token'])); + $token = Config::getInstance()->get('phpci.github.token'); - $rtn = array(); - $rtn['choose'] = 'Select a repository...'; - if ($res['success']) { - foreach ($res['body'] as $repo) { - $rtn[$repo['full_name']] = $repo['full_name']; - } + if (!$token) { + die(json_encode(null)); } - return $rtn; + $cache = \b8\Cache::getCache(\b8\Cache::TYPE_APC); + $rtn = $cache->get('phpci_github_repos'); + + if (!$rtn) { + $orgs = $this->doGithubApiRequest('/user/orgs', array('access_token' => $token)); + + $params = array('type' => 'all', 'access_token' => $token); + $repos = array(); + $repos['user'] = $this->doGithubApiRequest('/user/repos', $params); + + + foreach ($orgs as $org) { + $repos[$org['login']] = $this->doGithubApiRequest('/orgs/'.$org['login'].'/repos', $params); + } + + $rtn = array(); + foreach ($repos as $repoGroup) { + foreach ($repoGroup as $repo) { + $rtn['repos'][] = $repo['full_name']; + } + } + + $cache->set('phpci_github_repos', $rtn); + } + + die(json_encode($rtn)); + } + + protected function doGithubApiRequest($url, $params) + { + $http = new \b8\HttpClient('https://api.github.com'); + $res = $http->get($url, $params); + + return $res['body']; } protected function getReferenceValidator($values) diff --git a/PHPCI/Controller/SettingsController.php b/PHPCI/Controller/SettingsController.php new file mode 100644 index 00000000..d0582f6a --- /dev/null +++ b/PHPCI/Controller/SettingsController.php @@ -0,0 +1,140 @@ + + * @package PHPCI + * @subpackage Web + */ +class SettingsController extends Controller +{ + protected $settings; + + public function init() + { + parent::init(); + + $parser = new Parser(); + $yaml = file_get_contents(APPLICATION_PATH . 'PHPCI/config.yml'); + $this->settings = $parser->parse($yaml); + } + + public function index() + { + $this->view->settings = $this->settings; + $this->view->github = $this->getGithubForm(); + + if (!empty($this->settings['phpci']['github']['token'])) { + $this->view->githubUser = $this->getGithubUser($this->settings['phpci']['github']['token']); + } + + return $this->view->render(); + } + + public function github() + { + $this->settings['phpci']['github']['id'] = $this->getParam('githubid', ''); + $this->settings['phpci']['github']['secret'] = $this->getParam('githubsecret', ''); + + $this->storeSettings(); + + header('Location: ' . PHPCI_URL . 'settings?saved=1'); + die; + } + + /** + * Github redirects users back to this URL when t + */ + public function githubCallback() + { + $code = $this->getParam('code', null); + $github = $this->settings['phpci']['github']; + + if (!is_null($code)) { + $http = new HttpClient(); + $url = 'https://github.com/login/oauth/access_token'; + $params = array('client_id' => $github['id'], 'client_secret' => $github['secret'], 'code' => $code); + $resp = $http->post($url, $params); + + if ($resp['success']) { + parse_str($resp['body'], $resp); + + $this->settings['phpci']['github']['token'] = $resp['access_token']; + $this->storeSettings(); + + header('Location: ' . PHPCI_URL . 'settings?linked=1'); + die; + } + } + + + header('Location: ' . PHPCI_URL . 'settings?linked=2'); + die; + } + + protected function storeSettings() + { + $dumper = new Dumper(); + $yaml = $dumper->dump($this->settings); + file_put_contents(APPLICATION_PATH . 'PHPCI/config.yml', $yaml); + } + + protected function getGithubForm() + { + $form = new Form(); + $form->setMethod('POST'); + $form->setAction(PHPCI_URL . 'settings/github'); + $form->addField(new Form\Element\Csrf('csrf')); + + $field = new Form\Element\Text('githubid'); + $field->setRequired(true); + $field->setPattern('[a-zA-Z0-9]+'); + $field->setLabel('Application ID'); + $field->setClass('form-control'); + $field->setContainerClass('form-group'); + $field->setValue($this->settings['phpci']['github']['id']); + $form->addField($field); + + $field = new Form\Element\Text('githubsecret'); + $field->setRequired(true); + $field->setPattern('[a-zA-Z0-9]+'); + $field->setLabel('Application Secret'); + $field->setClass('form-control'); + $field->setContainerClass('form-group'); + $field->setValue($this->settings['phpci']['github']['secret']); + $form->addField($field); + + + $field = new Form\Element\Submit(); + $field->setValue('Save »'); + $field->setClass('btn btn-success pull-right'); + $form->addField($field); + + return $form; + } + + protected function getGithubUser($token) + { + $http = new HttpClient('https://api.github.com'); + $user = $http->get('/user', array('access_token' => $token)); + + return $user['body']; + } +} diff --git a/PHPCI/Model/Build/GithubBuild.php b/PHPCI/Model/Build/GithubBuild.php index 1b41fb75..98d7a8eb 100644 --- a/PHPCI/Model/Build/GithubBuild.php +++ b/PHPCI/Model/Build/GithubBuild.php @@ -40,13 +40,14 @@ class GithubBuild extends RemoteGitBuild */ public function sendStatusPostback() { - $project = $this->getProject(); + $token = \b8\Config::getInstance()->get('phpci.github.token'); - // The postback will only work if we have an access token. - if (!$project->getToken()) { + if (empty($token)) { return; } + $project = $this->getProject(); + $url = 'https://api.github.com/repos/'.$project->getReference().'/statuses/'.$this->getCommitId(); $http = new \b8\HttpClient(); @@ -71,7 +72,7 @@ class GithubBuild extends RemoteGitBuild $params = array( 'state' => $status, 'target_url' => $phpciUrl . '/build/view/' . $this->getId()); $headers = array( - 'Authorization: token ' . $project->getToken(), + 'Authorization: token ' . $token, 'Content-Type: application/x-www-form-urlencoded' ); diff --git a/PHPCI/View/Home/index.phtml b/PHPCI/View/Home/index.phtml index 452ec7c6..d372786d 100644 --- a/PHPCI/View/Home/index.phtml +++ b/PHPCI/View/Home/index.phtml @@ -5,8 +5,6 @@
+ Your settings have been saved. +
+ + + ++ Your Github account has been linked. +
+ + + ++ Your Github account could not be linked. +
+ + ++ Before you can start using Github, you need to sign in and grant PHPCI access to your account. +
+ + + ++ PHPCI is successfully linked to Github account + + = $githubUser['name']; ?> + +
+ +If you own the application you would like to use, you can find this information within your + applications settings area.
+