Removed Github configuration from ProjectController / ProjectForm and added it to a new settings area.

This commit is contained in:
Dan Cryer 2013-10-11 21:51:23 +01:00
parent cc86e85adb
commit 2a47b08fec
10 changed files with 331 additions and 87 deletions

View file

@ -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', '*');

View file

@ -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)

View file

@ -0,0 +1,140 @@
<?php
/**
* PHPCI - Continuous Integration for PHP
*
* @copyright Copyright 2013, Block 8 Limited.
* @license https://github.com/Block8/PHPCI/blob/master/LICENSE.md
* @link http://www.phptesting.org/
*/
namespace PHPCI\Controller;
use b8;
use b8\Form;
use b8\HttpClient;
use PHPCI\Controller;
use PHPCI\Model\Build;
use Symfony\Component\Yaml\Dumper;
use Symfony\Component\Yaml\Parser;
/**
* Settings Controller
* @author Dan Cryer <dan@block8.co.uk>
* @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 &raquo;');
$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'];
}
}

View file

@ -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'
);

View file

@ -5,8 +5,6 @@
<div class="col-lg-3">
<ul class="nav nav-pills nav-stacked">
<li class="active"><a href="<?= PHPCI_URL ?>"><i class="icon-home"></i> Dashboard</a></li>
<li><a href="<?= PHPCI_URL ?>user"><i class="icon-user"></i> Users</a></li>
<li><a href="<?= PHPCI_URL ?>plugin"><i class="icon-user"></i> Manage Plugins</a></li>
</ul>
<?php if (count($projects)): ?>

View file

@ -175,6 +175,3 @@
</div><!-- /.modal-content -->
</div><!-- /.modal-dialog -->
</div><!-- /.modal -->
<div id="loading">Loading...</div>

View file

@ -0,0 +1,62 @@
<?php if (isset($_GET['saved'])): ?>
<p class="alert alert-success" style="margin-bottom: 20px;">
Your settings have been saved.
</p>
<?php endif; ?>
<?php if (isset($_GET['linked']) && $_GET['linked'] == 1): ?>
<p class="alert alert-success" style="margin-bottom: 20px;">
Your Github account has been linked.
</p>
<?php endif; ?>
<?php if (isset($_GET['linked']) && $_GET['linked'] == 2): ?>
<p class="alert alert-danger" style="margin-bottom: 20px;">
Your Github account could not be linked.
</p>
<?php endif; ?>
<div class="box">
<div class="row">
<div class="col-lg-12">
<h3 class="title">Github Application</h3>
<?php
$id = $settings['phpci']['github']['id'];
$returnTo = PHPCI_URL . 'settings/github-callback';
$githubUri = 'https://github.com/login/oauth/authorize?client_id='.$id.'&scope=repo&redirect_uri=' . $returnTo;
?>
<?php if (!empty($id) && empty($settings['phpci']['github']['token'])): ?>
<p class="alert alert-warning clearfix">
Before you can start using Github, you need to <a href="<?= $githubUri; ?>">sign in</a> and grant PHPCI access to your account.
</p>
<?php endif; ?>
<?php if (!empty($id) && !empty($settings['phpci']['github']['token'])): ?>
<p class="alert alert-success">
PHPCI is successfully linked to Github account
<strong>
<a href="<?= $githubUser['html_url']; ?>"><?= $githubUser['name']; ?></a>
</strong>
</p>
<?php endif; ?>
</div>
<div class="col-lg-8">
<?php print $github; ?>
</div>
<div class="col-lg-4">
<div class="panel panel-info">
<div class="panel-heading">
<h3 class="panel-title">Where to find these...</h3>
</div>
<div class="panel-body">
<p>If you own the application you would like to use, you can find this information within your
<a href="https://github.com/settings/applications">applications</a> settings area.</p>
</div>
</div>
</div>
</div>
</div>

View file

@ -6,7 +6,7 @@
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href='//fonts.googleapis.com/css?family=Roboto:300&subset=latin,latin-ext' rel='stylesheet' type='text/css'>
<link href='//fonts.googleapis.com/css?family=Roboto:300,500&subset=latin,latin-ext' rel='stylesheet' type='text/css'>
<link rel="stylesheet" type="text/css" href="<?= PHPCI_URL ?>assets/css/bootstrap.min.css">
<link rel="stylesheet" type="text/css" href="<?= PHPCI_URL ?>assets/css/phpci.css">
@ -36,12 +36,25 @@
<div class="nav-collapse collapse navbar-responsive-collapse">
<ul class="nav navbar-nav pull-right">
<li><a href="<?= PHPCI_URL ?>session/logout">Log out</a></li>
</ul>
<li><p class="navbar-text"><strong><?php print $this->User()->getName(); ?></strong></p></li>
<li><a href="<?php print PHPCI_URL ?>session/logout">Log out</a></li>
<?php if ($this->User()->getIsAdmin()): ?>
<li>
<div class="btn-group">
<a class="btn btn-success navbar-btn" href="<?= PHPCI_URL ?>project/add">Add Project</a>
<?php if($this->User()->getIsAdmin()): ?>
<a class="btn btn-success navbar-btn pull-right" href="<?= PHPCI_URL ?>project/add">Add Project</a>
<?php endif; ?>
<button type="button" class="btn navbar-btn btn-default dropdown-toggle" data-toggle="dropdown">
Admin <span class="caret"></span>
</button>
<ul class="dropdown-menu" role="menu">
<li><a href="/settings">Settings</a></li>
<li><a href="/plugin">Manage Plugins</a></li>
<li><a href="/user">Manage Users</a></li>
</ul>
</div>
</li>
<?php endif; ?>
</ul>
</div>
@ -52,5 +65,7 @@
<div id="content" class="container">
<?php print $content; ?>
</div>
<div id="loading">Loading...</div>
</body>
</html>

View file

@ -7,6 +7,14 @@ body
padding-top: 70px;
}
strong, th, .control-label {
font-weight: 500;
}
.btn, .dropdown-menu>li>a, .controls, .controls input, .controls label {
font-weight: 300;
}
#content
{
-border: 10px solid #369;
@ -61,6 +69,11 @@ td .label {
padding: 0;
}
h2 {
color: #246;
font-size: 1.8em;
}
.icon-build-ok
{
background: url('../img/icon-build-ok.png') no-repeat top left;
@ -81,13 +94,6 @@ td .label {
background: url('../img/icon-build-running.png') no-repeat top left;
}
h3
{
border-bottom: 1px solid #f0f0f0;
margin-top: 0;
padding-top: 0;
}
.navbar-brand {
padding: 10px 15px;
}
@ -102,7 +108,9 @@ h3
border-bottom: 1px solid #eee;
cursor: move;
font-size: 1.2em;
padding: 8px;
margin: 0;
margin-bottom: 20px;
padding: 8px 0;
}
.box .box-content {

View file

@ -18,6 +18,8 @@ function confirmDelete(url)
*/
function setupProjectForm()
{
$('.github-container').hide();
$('#element-reference').change(function()
{
var el = $(this);
@ -41,18 +43,26 @@ function setupProjectForm()
$('#element-type').change(function()
{
if(!window.github_app_id || $(this).val() != 'github' || window.github_token) {
return;
}
// Show sign in with Github button.
var el = $('#element-reference');
var rtn = window.return_url;
var url = 'https://github.com/login/oauth/authorize?client_id=' + window.github_app_id + '&scope=repo&redirect_uri=' + rtn;
var btn = $('<a>').addClass('btn btn-inverse').text('Sign in with Github').attr('href', url);
if ($(this).val() == 'github') {
$('#loading').show();
el.after(btn);
el.remove();
$.getJSON(window.PHPCI_URL + 'project/github-repositories', function (data) {
$('#loading').hide();
if (data.repos) {
$('#element-github').empty();
for (var i in data.repos) {
var name = data.repos[i];
$('#element-github').append($('<option></option>').text(name).val(name));
}
$('.github-container').slideDown();
}
});
} else {
$('.github-container').slideUp();
}
});
$('#element-github').change(function()