1
0
Fork 0

Always check for OAuth token in git config, fixes #1243

pull/1186/merge
Jordi Boggiano 2012-10-22 17:11:34 +02:00
parent b4bcc5b5c8
commit bebd1ce9c7
5 changed files with 66 additions and 32 deletions

View File

@ -80,7 +80,11 @@ class FileDownloader implements DownloaderInterface
if (404 === $e->getCode() && 'github.com' === parse_url($processUrl, PHP_URL_HOST)) {
$message = "\n".'Could not fetch '.$processUrl.', enter your GitHub credentials to access private repos';
$gitHubUtil = new GitHub($this->io, $this->config, null, $this->rfs);
$gitHubUtil->authorizeOAuth('github.com', $message);
if (!$gitHubUtil->authorizeOAuth('github.com')
&& (!$this->io->isInteractive() || !$gitHubUtil->authorizeOAuthInteractively('github.com', $message))
) {
throw $e;
}
$this->rfs->copy(parse_url($processUrl, PHP_URL_HOST), $processUrl, $fileName);
} else {
throw $e;

View File

@ -285,19 +285,24 @@ class GitDownloader extends VcsDownloader
$command = call_user_func($commandCallable, $url);
if (0 !== $this->process->execute($command, $handler)) {
// private github repository without git access, try https with auth
if (preg_match('{^git@(github.com):(.+?)\.git$}i', $url, $match) && $this->io->isInteractive()) {
if (preg_match('{^git@(github.com):(.+?)\.git$}i', $url, $match)) {
if (!$this->io->hasAuthorization($match[1])) {
$message = 'Cloning failed using an ssh key for authentication, enter your GitHub credentials to access private repos';
$gitHubUtil = new GitHub($this->io, $this->config, $this->process);
$gitHubUtil->authorizeOAuth($match[1], $message);
$message = 'Cloning failed using an ssh key for authentication, enter your GitHub credentials to access private repos';
if (!$gitHubUtil->authorizeOAuth($match[1]) && $this->io->isInteractive()) {
$gitHubUtil->authorizeOAuthInteractively($match[1], $message);
}
}
$auth = $this->io->getAuthorization($match[1]);
$url = 'https://'.$auth['username'] . ':' . $auth['password'] . '@'.$match[1].'/'.$match[2].'.git';
if ($this->io->hasAuthorization($match[1])) {
$auth = $this->io->getAuthorization($match[1]);
$url = 'https://'.$auth['username'] . ':' . $auth['password'] . '@'.$match[1].'/'.$match[2].'.git';
$command = call_user_func($commandCallable, $url);
if (0 === $this->process->execute($command, $handler)) {
return;
$command = call_user_func($commandCallable, $url);
if (0 === $this->process->execute($command, $handler)) {
return;
}
}
}

View File

@ -244,6 +244,8 @@ class GitHubDriver extends VcsDriver
try {
return parent::getContents($url);
} catch (TransportException $e) {
$gitHubUtil = new GitHub($this->io, $this->config, $this->process, $this->remoteFilesystem);
switch ($e->getCode()) {
case 401:
case 404:
@ -252,17 +254,25 @@ class GitHubDriver extends VcsDriver
throw $e;
}
if (!$this->io->isInteractive()) {
return $this->attemptCloneFallback($e);
if ($gitHubUtil->authorizeOAuth($this->originUrl)) {
return parent::getContents($url);
}
$this->authorizeOAuth('Your GitHub credentials are required to fetch private repository metadata (<info>'.$this->url.'</info>)');
if (!$this->io->isInteractive()) {
return $this->attemptCloneFallback();
}
$gitHubUtil->authorizeOAuthInteractively($this->originUrl, 'Your GitHub credentials are required to fetch private repository metadata (<info>'.$this->url.'</info>)');
return parent::getContents($url);
case 403:
if (!$this->io->hasAuthorization($this->originUrl) && $gitHubUtil->authorizeOAuth($this->originUrl)) {
return parent::getContents($url);
}
if (!$this->io->isInteractive() && $fetchingRepoData) {
return $this->attemptCloneFallback($e);
return $this->attemptCloneFallback();
}
$rateLimited = false;
@ -278,7 +288,7 @@ class GitHubDriver extends VcsDriver
throw $e;
}
$this->authorizeOAuth('API limit exhausted. Enter your GitHub credentials to get a larger API limit (<info>'.$this->url.'</info>)');
$gitHubUtil->authorizeOAuthInteractively($this->originUrl, 'API limit exhausted. Enter your GitHub credentials to get a larger API limit (<info>'.$this->url.'</info>)');
return parent::getContents($url);
}
@ -346,10 +356,4 @@ class GitHubDriver extends VcsDriver
throw $e;
}
}
protected function authorizeOAuth($message)
{
$gitHubUtil = new GitHub($this->io, $this->config, $this->process, $this->remoteFilesystem);
$gitHubUtil->authorizeOAuth($this->originUrl, $message);
}
}

View File

@ -44,20 +44,36 @@ class GitHub
}
/**
* Authorizes a GitHub domain via OAuth
* Attempts to authorize a GitHub domain via OAuth
*
* @param string $originUrl The host this GitHub instance is located at
* @param string $message The reason this authorization is required
* @return bool true on success
*/
public function authorizeOAuth($originUrl, $message = null)
public function authorizeOAuth($originUrl)
{
if ('github.com' !== $originUrl) {
return false;
}
// if available use token from git config
if (0 === $this->process->execute('git config github.accesstoken', $output)) {
$this->io->setAuthorization($originUrl, trim($output), 'x-oauth-basic');
return;
return true;
}
return false;
}
/**
* Authorizes a GitHub domain interactively via OAuth
*
* @param string $originUrl The host this GitHub instance is located at
* @param string $message The reason this authorization is required
* @return bool true on success
*/
public function authorizeOAuthInteractively($originUrl, $message = null)
{
$attemptCounter = 0;
if ($message) {
@ -105,7 +121,7 @@ class GitHub
$githubTokens[$originUrl] = $contents['token'];
$this->config->getConfigSource()->addConfigSetting('github-oauth', $githubTokens);
return;
return true;
}
throw new \RuntimeException("Invalid GitHub credentials 5 times in a row, aborting.");

View File

@ -264,30 +264,35 @@ class GitHubDriverTest extends \PHPUnit_Framework_TestCase
$process->expects($this->at(0))
->method('execute')
->with($this->stringContains($repoSshUrl))
->will($this->returnValue(0));
->with($this->equalTo('git config github.accesstoken'))
->will($this->returnValue(1));
$process->expects($this->at(1))
->method('execute')
->with($this->stringContains('git tag'));
->with($this->stringContains($repoSshUrl))
->will($this->returnValue(0));
$process->expects($this->at(2))
->method('execute')
->with($this->stringContains('git tag'));
$process->expects($this->at(3))
->method('splitLines')
->will($this->returnValue(array($identifier)));
$process->expects($this->at(3))
$process->expects($this->at(4))
->method('execute')
->with($this->stringContains('git branch --no-color --no-abbrev -v'));
$process->expects($this->at(4))
$process->expects($this->at(5))
->method('splitLines')
->will($this->returnValue(array(' test_master edf93f1fccaebd8764383dc12016d0a1a9672d89 Fix test & behavior')));
$process->expects($this->at(5))
$process->expects($this->at(6))
->method('execute')
->with($this->stringContains('git branch --no-color'));
$process->expects($this->at(6))
$process->expects($this->at(7))
->method('splitLines')
->will($this->returnValue(array('* test_master')));