Merge remote-tracking branch 'stefangr/fix_minor_bitbucket_oauth_issues'
commit
8ffe224c0d
|
@ -161,6 +161,8 @@ class Bitbucket
|
||||||
"consumer-secret" => $consumerSecret,
|
"consumer-secret" => $consumerSecret,
|
||||||
);
|
);
|
||||||
$this->config->getAuthConfigSource()->addConfigSetting('bitbucket-oauth.'.$originUrl, $consumer);
|
$this->config->getAuthConfigSource()->addConfigSetting('bitbucket-oauth.'.$originUrl, $consumer);
|
||||||
|
// Remove conflicting basic auth credentials (if available)
|
||||||
|
$this->config->getAuthConfigSource()->removeConfigSetting('http-basic.' . $originUrl);
|
||||||
|
|
||||||
$this->io->writeError('<info>Consumer stored successfully.</info>');
|
$this->io->writeError('<info>Consumer stored successfully.</info>');
|
||||||
|
|
||||||
|
|
|
@ -175,6 +175,24 @@ class RemoteFilesystem
|
||||||
return $value;
|
return $value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array $headers array of returned headers
|
||||||
|
* @return string|null
|
||||||
|
*/
|
||||||
|
public function findContentType(array $headers)
|
||||||
|
{
|
||||||
|
$value = null;
|
||||||
|
foreach ($headers as $header) {
|
||||||
|
if (preg_match('/^Content-type:\s*([^;]+)/i', $header, $match)) {
|
||||||
|
// In case of redirects, http_response_headers contains the headers of all responses
|
||||||
|
// so we can not return directly and need to keep iterating
|
||||||
|
$value = $match[1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $value;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get file content or copy action.
|
* Get file content or copy action.
|
||||||
*
|
*
|
||||||
|
@ -334,8 +352,21 @@ class RemoteFilesystem
|
||||||
}
|
}
|
||||||
|
|
||||||
$statusCode = null;
|
$statusCode = null;
|
||||||
|
$contentType = null;
|
||||||
if (!empty($http_response_header[0])) {
|
if (!empty($http_response_header[0])) {
|
||||||
$statusCode = $this->findStatusCode($http_response_header);
|
$statusCode = $this->findStatusCode($http_response_header);
|
||||||
|
$contentType = $this->findContentType($http_response_header);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($originUrl === 'bitbucket.org' &&
|
||||||
|
preg_match('/\.zip$/', $fileUrl) &&
|
||||||
|
$contentType === 'text/html'
|
||||||
|
) {
|
||||||
|
// The received content is a login page asking to authenticate
|
||||||
|
$result = false;
|
||||||
|
if ($this->retryAuthFailure) {
|
||||||
|
$this->promptAuthAndRetry(401);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// handle 3xx redirects for php<5.6, 304 Not Modified is excluded
|
// handle 3xx redirects for php<5.6, 304 Not Modified is excluded
|
||||||
|
@ -575,24 +606,30 @@ class RemoteFilesystem
|
||||||
throw new TransportException('Could not authenticate against '.$this->originUrl, 401);
|
throw new TransportException('Could not authenticate against '.$this->originUrl, 401);
|
||||||
}
|
}
|
||||||
} elseif ($this->config && $this->originUrl === 'bitbucket.org') {
|
} elseif ($this->config && $this->originUrl === 'bitbucket.org') {
|
||||||
if (! $this->io->hasAuthentication($this->originUrl)) {
|
$askForOAuthToken = true;
|
||||||
$message = "\n".'Could not fetch ' . $this->fileUrl . ', please create a bitbucket OAuth token to access private repos';
|
if ($this->io->hasAuthentication($this->originUrl)) {
|
||||||
$bitBucketUtil = new Bitbucket($this->io, $this->config);
|
|
||||||
if (! $bitBucketUtil->authorizeOAuth($this->originUrl)
|
|
||||||
&& (! $this->io->isInteractive() || !$bitBucketUtil->authorizeOAuthInteractively($this->originUrl, $message))
|
|
||||||
) {
|
|
||||||
throw new TransportException('Could not authenticate against ' . $this->originUrl, 401);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
$auth = $this->io->getAuthentication($this->originUrl);
|
$auth = $this->io->getAuthentication($this->originUrl);
|
||||||
if ($auth['username'] !== 'x-token-auth') {
|
if ($auth['username'] !== 'x-token-auth') {
|
||||||
$bitbucketUtil = new Bitbucket($this->io, $this->config);
|
$bitbucketUtil = new Bitbucket($this->io, $this->config);
|
||||||
$token = $bitbucketUtil->requestToken($this->originUrl, $auth['username'], $auth['password']);
|
$token = $bitbucketUtil->requestToken($this->originUrl, $auth['username'], $auth['password']);
|
||||||
$this->io->setAuthentication($this->originUrl, 'x-token-auth', $token['access_token']);
|
if (! empty($token)) {
|
||||||
|
$this->io->setAuthentication($this->originUrl, 'x-token-auth', $token['access_token']);
|
||||||
|
$askForOAuthToken = false;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
throw new TransportException('Could not authenticate against ' . $this->originUrl, 401);
|
throw new TransportException('Could not authenticate against ' . $this->originUrl, 401);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($askForOAuthToken) {
|
||||||
|
$message = "\n".'Could not fetch ' . $this->fileUrl . ', please create a bitbucket OAuth token to ' . ($httpStatus === 401 ? 'to access private repos' : 'to go over the API rate limit');
|
||||||
|
$bitBucketUtil = new Bitbucket($this->io, $this->config);
|
||||||
|
if (! $bitBucketUtil->authorizeOAuth($this->originUrl)
|
||||||
|
&& (! $this->io->isInteractive() || !$bitBucketUtil->authorizeOAuthInteractively($this->originUrl, $message))
|
||||||
|
) {
|
||||||
|
throw new TransportException('Could not authenticate against ' . $this->originUrl, 401);
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// 404s are only handled for github
|
// 404s are only handled for github
|
||||||
if ($httpStatus === 404) {
|
if ($httpStatus === 404) {
|
||||||
|
|
|
@ -164,10 +164,11 @@ class BitbucketTest extends \PHPUnit_Framework_TestCase
|
||||||
->willReturn(sprintf('{}', $this->token))
|
->willReturn(sprintf('{}', $this->token))
|
||||||
;
|
;
|
||||||
|
|
||||||
|
$authJson = $this->getAuthJsonMock();
|
||||||
$this->config
|
$this->config
|
||||||
->expects($this->exactly(2))
|
->expects($this->exactly(3))
|
||||||
->method('getAuthConfigSource')
|
->method('getAuthConfigSource')
|
||||||
->willReturn($this->getAuthJsonMock())
|
->willReturn($authJson)
|
||||||
;
|
;
|
||||||
$this->config
|
$this->config
|
||||||
->expects($this->once())
|
->expects($this->once())
|
||||||
|
@ -175,6 +176,20 @@ class BitbucketTest extends \PHPUnit_Framework_TestCase
|
||||||
->willReturn($this->getConfJsonMock())
|
->willReturn($this->getConfJsonMock())
|
||||||
;
|
;
|
||||||
|
|
||||||
|
$authJson->expects($this->once())
|
||||||
|
->method('addConfigSetting')
|
||||||
|
->with(
|
||||||
|
'bitbucket-oauth.'.$this->origin,
|
||||||
|
array(
|
||||||
|
'consumer-key' => $this->consumer_key,
|
||||||
|
'consumer-secret' => $this->consumer_secret
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
$authJson->expects($this->once())
|
||||||
|
->method('removeConfigSetting')
|
||||||
|
->with('http-basic.'.$this->origin);
|
||||||
|
|
||||||
$this->assertTrue($this->bitbucket->authorizeOAuthInteractively($this->origin, $this->message));
|
$this->assertTrue($this->bitbucket->authorizeOAuthInteractively($this->origin, $this->message));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue