Merge branch 'master' into 1.0

Conflicts:
	README.md
	src/Provider/Facebook.php
	src/Provider/Vkontakte.php
	test/src/Provider/FacebookTest.php
1.0
Ben Ramsey 2015-02-24 10:41:43 -06:00
commit 5e500e44c6
9 changed files with 102 additions and 46 deletions

View File

@ -35,12 +35,12 @@ The following versions of PHP are supported.
### Authorization Code Flow
```php
$provider = new League\OAuth2\Client\Provider\<ProviderName>(array(
'clientId' => 'XXXXXXXX',
'clientSecret' => 'XXXXXXXX',
'redirectUri' => 'https://your-registered-redirect-uri/',
'scopes' => array('email', '...', '...'),
));
$provider = new League\OAuth2\Client\Provider\<ProviderName>([
'clientId' => 'XXXXXXXX',
'clientSecret' => 'XXXXXXXX',
'redirectUri' => 'https://your-registered-redirect-uri/',
'scopes' => ['email', '...', '...'],
]);
if (!isset($_GET['code'])) {
@ -58,15 +58,9 @@ if (!isset($_GET['code'])) {
} else {
// Try to get an access token (using the authorization code grant)
// Try to get an access token (using the authorization code grant)
$token = $provider->getAccessToken('authorization_code', [
'code' => $_GET['code']
]);
// If you are using Eventbrite you will need to add the grant_type parameter (see below)
$token = $provider->getAccessToken('authorization_code', [
'code' => $_GET['code'],
'grant_type' => 'authorization_code'
'code' => $_GET['code']
]);
// Optional: Now you have a token you can look up a users profile data
@ -76,7 +70,7 @@ if (!isset($_GET['code'])) {
$userDetails = $provider->getUserDetails($token);
// Use these details to create a new profile
printf('Hello %s!', $userDetails->firstName);
printf('Hello %s!', $userDetails->firstName);
} catch (Exception $e) {
@ -98,11 +92,11 @@ if (!isset($_GET['code'])) {
### Refreshing a Token
```php
$provider = new League\OAuth2\Client\Provider\<ProviderName>(array(
'clientId' => 'XXXXXXXX',
'clientSecret' => 'XXXXXXXX',
'redirectUri' => 'https://your-registered-redirect-uri/'
));
$provider = new League\OAuth2\Client\Provider\<ProviderName>([
'clientId' => 'XXXXXXXX',
'clientSecret' => 'XXXXXXXX',
'redirectUri' => 'https://your-registered-redirect-uri/',
]);
$grant = new \League\OAuth2\Client\Grant\RefreshToken();
$token = $provider->getAccessToken($grant, ['refresh_token' => $refreshToken]);
@ -132,13 +126,18 @@ These providers allow integration with other providers not supported by `oauth2-
so please help them out with a pull request if you notice this.
- [Battle.net](https://packagist.org/packages/depotwarehouse/oauth2-bnet)
- [Dropbox](https://github.com/pixelfear/oauth2-dropbox)
- [Facebook](https://packagist.org/packages/league/oauth2-facebook)
- [FreeAgent](https://github.com/CloudManaged/oauth2-freeagent)
- [Google Nest](https://github.com/JC5/nest-oauth2-provider)
- [Mail.ru](https://packagist.org/packages/aego/oauth2-mailru)
- [Meetup](https://github.com/howlowck/meetup-oauth2-provider)
- [Odnoklassniki](https://packagist.org/packages/aego/oauth2-odnoklassniki)
- [Yandex](https://packagist.org/packages/aego/oauth2-yandex)
- [Vkontakte](https://packagist.org/packages/j4k/oauth2-vkontakte)
- [Naver](https://packagist.org/packages/deminoth/oauth2-naver)
- [Facebook](https://packagist.org/packages/league/oauth2-facebook)
- [Odnoklassniki](https://packagist.org/packages/aego/oauth2-odnoklassniki)
- [Square](https://packagist.org/packages/wheniwork/oauth2-square)
- [Twitch.tv](https://github.com/tpavlek/oauth2-twitch)
- [Vkontakte](https://packagist.org/packages/j4k/oauth2-vkontakte)
- [Yandex](https://packagist.org/packages/aego/oauth2-yandex)
### Implementing your own provider

View File

@ -41,7 +41,7 @@
},
"extra": {
"branch-alias": {
"dev-master": "0.7.x-dev"
"dev-master": "0.8.x-dev"
}
}
}

View File

@ -128,7 +128,7 @@ abstract class AbstractProvider implements ProviderInterface
'state' => $this->state,
'scope' => is_array($this->scopes) ? implode($this->scopeSeparator, $this->scopes) : $this->scopes,
'response_type' => isset($options['response_type']) ? $options['response_type'] : 'code',
'approval_prompt' => 'auto',
'approval_prompt' => isset($options['approval_prompt']) ? $options['approval_prompt'] : 'auto',
];
return $this->urlAuthorize().'?'.$this->httpBuildQuery($params, '', '&');
@ -199,8 +199,7 @@ abstract class AbstractProvider implements ProviderInterface
}
} catch (BadResponseException $e) {
// @codeCoverageIgnoreStart
$raw_response = explode("\n", $e->getResponse());
$response = end($raw_response);
$response = $e->getResponse()->getBody();
// @codeCoverageIgnoreEnd
}
@ -220,11 +219,24 @@ abstract class AbstractProvider implements ProviderInterface
// @codeCoverageIgnoreEnd
}
$this->setResultUid($result);
$result = $this->prepareAccessTokenResult($result);
return $grant->handleResponse($result);
}
/**
* Prepare the access token response for the grant. Custom mapping of
* expirations, etc should be done here.
*
* @param array $result
* @return array
*/
protected function prepareAccessTokenResult(array $result)
{
$this->setResultUid($result);
return $result;
}
/**
* Sets any result keys we've received matching our provider-defined uidKey to the key "uid".
*

View File

@ -10,6 +10,8 @@ class Github extends AbstractProvider
public $domain = 'https://github.com';
public $apiDomain = 'https://api.github.com';
public function urlAuthorize()
{
return $this->domain.'/login/oauth/authorize';
@ -23,7 +25,7 @@ class Github extends AbstractProvider
public function urlUserDetails(\League\OAuth2\Client\Token\AccessToken $token)
{
if ($this->domain === 'https://github.com') {
return $this->domain.'/user?access_token='.$token;
return $this->apiDomain.'/user?access_token='.$token;
}
return $this->domain.'/api/v3/user?access_token='.$token;
}
@ -31,7 +33,7 @@ class Github extends AbstractProvider
public function urlUserEmails(\League\OAuth2\Client\Token\AccessToken $token)
{
if ($this->domain === 'https://github.com') {
return $this->domain.'/user/emails?access_token='.$token;
return $this->apiDomain.'/user/emails?access_token='.$token;
}
return $this->domain.'/api/v3/user/emails?access_token='.$token;
}

View File

@ -29,6 +29,22 @@ class Google extends AbstractProvider
return $this->hostedDomain;
}
/**
* @var string If set, this will be sent to google as the "access_type" parameter.
* @link https://developers.google.com/accounts/docs/OAuth2WebServer#offline
*/
public $accessType = '';
public function setAccessType($accessType)
{
$this->accessType = $accessType;
}
public function getAccessType()
{
return $this->accessType;
}
public function urlAuthorize()
{
return 'https://accounts.google.com/o/oauth2/auth';
@ -43,7 +59,7 @@ class Google extends AbstractProvider
{
return
'https://www.googleapis.com/plus/v1/people/me?'.
'fields=name(familyName%2CgivenName)%2CdisplayName%2C'.
'fields=id%2Cname(familyName%2CgivenName)%2CdisplayName%2C'.
'emails%2Fvalue%2Cimage%2Furl&alt=json&access_token='.$token;
}
@ -97,6 +113,10 @@ class Google extends AbstractProvider
$url .= '&' . $this->httpBuildQuery(['hd' => $this->hostedDomain]);
}
if (!empty($this->accessType)) {
$url .= '&' . $this->httpBuildQuery(['access_type'=> $this->accessType]);
}
return $url;
}
}

View File

@ -43,17 +43,13 @@ class AccessToken
$this->accessToken = $options['access_token'];
// Some providers (not many) give the uid here, so lets take it
isset($options['uid']) and $this->uid = $options['uid'];
if (!empty($options['uid'])) {
$this->uid = $options['uid'];
}
// Vkontakte uses user_id instead of uid
isset($options['user_id']) and $this->uid = $options['user_id'];
// Mailru uses x_mailru_vid instead of uid
isset($options['x_mailru_vid']) and $this->uid = $options['x_mailru_vid'];
//Battle.net uses accountId instead of uid
isset($options['accountId']) and $this->uid = $options['accountId'];
if (!empty($options['refresh_token'])) {
$this->refreshToken = $options['refresh_token'];
}
// We need to know when the token expires. Show preference to
// 'expires_in' since it is defined in RFC6749 Section 5.1.
@ -67,9 +63,6 @@ class AccessToken
$expiresInFuture = $expires > time();
$this->expires = $expiresInFuture ? $expires : time() + ((int) $expires);
}
// Grab a refresh token so we can update access tokens when they expires
isset($options['refresh_token']) and $this->refreshToken = $options['refresh_token'];
}
/**

View File

@ -1,6 +1,6 @@
<?php
namespace League\OAuth2\Client\Test\Token;
namespace League\OAuth2\Client\Test\Entity;
use League\OAuth2\Client\Entity\User;

View File

@ -112,6 +112,23 @@ class GithubTest extends \PHPUnit_Framework_TestCase
$this->assertEquals('mock_email', $this->provider->getUserEmail($token));
}
public function testGithubDomainUrls()
{
$client = m::mock('Guzzle\Service\Client');
$response = m::mock('Guzzle\Http\Message\Response');
$response->shouldReceive('getBody')->times(1)->andReturn('access_token=mock_access_token&expires=3600&refresh_token=mock_refresh_token&otherKey={1234}');
$client->shouldReceive('setBaseUrl')->times(1);
$client->shouldReceive('post->send')->times(1)->andReturn($response);
$this->provider->setHttpClient($client);
$token = $this->provider->getAccessToken('authorization_code', ['code' => 'mock_authorization_code']);
$this->assertEquals($this->provider->domain.'/login/oauth/authorize', $this->provider->urlAuthorize());
$this->assertEquals($this->provider->domain.'/login/oauth/access_token', $this->provider->urlAccessToken());
$this->assertEquals($this->provider->apiDomain.'/user?access_token=mock_access_token', $this->provider->urlUserDetails($token));
$this->assertEquals($this->provider->apiDomain.'/user/emails?access_token=mock_access_token', $this->provider->urlUserEmails($token));
}
public function testGithubEnterpriseDomainUrls()
{
$this->provider->domain = 'https://github.company.com';

View File

@ -15,6 +15,7 @@ class GoogleTest extends \PHPUnit_Framework_TestCase
'clientSecret' => 'mock_secret',
'redirectUri' => 'none',
'hostedDomain' => 'mock_domain',
'accessType' => 'mock_access_type'
]);
}
@ -37,6 +38,7 @@ class GoogleTest extends \PHPUnit_Framework_TestCase
$this->assertArrayHasKey('response_type', $query);
$this->assertArrayHasKey('approval_prompt', $query);
$this->assertArrayHasKey('hd', $query);
$this->assertArrayHasKey('access_type', $query);
$this->assertNotNull($this->provider->state);
}
@ -105,4 +107,15 @@ class GoogleTest extends \PHPUnit_Framework_TestCase
$this->provider->setHostedDomain('changed_domain');
$this->assertEquals('changed_domain', $this->provider->hostedDomain);
}
public function testGetAccessType()
{
$this->assertEquals('mock_access_type', $this->provider->getAccessType());
}
public function testSetAccessType()
{
$this->provider->setAccessType('changed_access_type');
$this->assertEquals('changed_access_type', $this->provider->accessType);
}
}