Merge branch 'master' into 1.0
Conflicts: README.md src/Provider/Facebook.php src/Provider/Vkontakte.php test/src/Provider/FacebookTest.php1.0
commit
5e500e44c6
47
README.md
47
README.md
|
@ -35,12 +35,12 @@ The following versions of PHP are supported.
|
||||||
### Authorization Code Flow
|
### Authorization Code Flow
|
||||||
|
|
||||||
```php
|
```php
|
||||||
$provider = new League\OAuth2\Client\Provider\<ProviderName>(array(
|
$provider = new League\OAuth2\Client\Provider\<ProviderName>([
|
||||||
'clientId' => 'XXXXXXXX',
|
'clientId' => 'XXXXXXXX',
|
||||||
'clientSecret' => 'XXXXXXXX',
|
'clientSecret' => 'XXXXXXXX',
|
||||||
'redirectUri' => 'https://your-registered-redirect-uri/',
|
'redirectUri' => 'https://your-registered-redirect-uri/',
|
||||||
'scopes' => array('email', '...', '...'),
|
'scopes' => ['email', '...', '...'],
|
||||||
));
|
]);
|
||||||
|
|
||||||
if (!isset($_GET['code'])) {
|
if (!isset($_GET['code'])) {
|
||||||
|
|
||||||
|
@ -58,15 +58,9 @@ if (!isset($_GET['code'])) {
|
||||||
|
|
||||||
} else {
|
} 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', [
|
$token = $provider->getAccessToken('authorization_code', [
|
||||||
'code' => $_GET['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'
|
|
||||||
]);
|
]);
|
||||||
|
|
||||||
// Optional: Now you have a token you can look up a users profile data
|
// 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);
|
$userDetails = $provider->getUserDetails($token);
|
||||||
|
|
||||||
// Use these details to create a new profile
|
// Use these details to create a new profile
|
||||||
printf('Hello %s!', $userDetails->firstName);
|
printf('Hello %s!', $userDetails->firstName);
|
||||||
|
|
||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
|
|
||||||
|
@ -98,11 +92,11 @@ if (!isset($_GET['code'])) {
|
||||||
### Refreshing a Token
|
### Refreshing a Token
|
||||||
|
|
||||||
```php
|
```php
|
||||||
$provider = new League\OAuth2\Client\Provider\<ProviderName>(array(
|
$provider = new League\OAuth2\Client\Provider\<ProviderName>([
|
||||||
'clientId' => 'XXXXXXXX',
|
'clientId' => 'XXXXXXXX',
|
||||||
'clientSecret' => 'XXXXXXXX',
|
'clientSecret' => 'XXXXXXXX',
|
||||||
'redirectUri' => 'https://your-registered-redirect-uri/'
|
'redirectUri' => 'https://your-registered-redirect-uri/',
|
||||||
));
|
]);
|
||||||
|
|
||||||
$grant = new \League\OAuth2\Client\Grant\RefreshToken();
|
$grant = new \League\OAuth2\Client\Grant\RefreshToken();
|
||||||
$token = $provider->getAccessToken($grant, ['refresh_token' => $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.
|
so please help them out with a pull request if you notice this.
|
||||||
|
|
||||||
- [Battle.net](https://packagist.org/packages/depotwarehouse/oauth2-bnet)
|
- [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)
|
- [Mail.ru](https://packagist.org/packages/aego/oauth2-mailru)
|
||||||
- [Meetup](https://github.com/howlowck/meetup-oauth2-provider)
|
- [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)
|
- [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
|
### Implementing your own provider
|
||||||
|
|
||||||
|
|
|
@ -41,7 +41,7 @@
|
||||||
},
|
},
|
||||||
"extra": {
|
"extra": {
|
||||||
"branch-alias": {
|
"branch-alias": {
|
||||||
"dev-master": "0.7.x-dev"
|
"dev-master": "0.8.x-dev"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -128,7 +128,7 @@ abstract class AbstractProvider implements ProviderInterface
|
||||||
'state' => $this->state,
|
'state' => $this->state,
|
||||||
'scope' => is_array($this->scopes) ? implode($this->scopeSeparator, $this->scopes) : $this->scopes,
|
'scope' => is_array($this->scopes) ? implode($this->scopeSeparator, $this->scopes) : $this->scopes,
|
||||||
'response_type' => isset($options['response_type']) ? $options['response_type'] : 'code',
|
'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, '', '&');
|
return $this->urlAuthorize().'?'.$this->httpBuildQuery($params, '', '&');
|
||||||
|
@ -199,8 +199,7 @@ abstract class AbstractProvider implements ProviderInterface
|
||||||
}
|
}
|
||||||
} catch (BadResponseException $e) {
|
} catch (BadResponseException $e) {
|
||||||
// @codeCoverageIgnoreStart
|
// @codeCoverageIgnoreStart
|
||||||
$raw_response = explode("\n", $e->getResponse());
|
$response = $e->getResponse()->getBody();
|
||||||
$response = end($raw_response);
|
|
||||||
// @codeCoverageIgnoreEnd
|
// @codeCoverageIgnoreEnd
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -220,11 +219,24 @@ abstract class AbstractProvider implements ProviderInterface
|
||||||
// @codeCoverageIgnoreEnd
|
// @codeCoverageIgnoreEnd
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->setResultUid($result);
|
$result = $this->prepareAccessTokenResult($result);
|
||||||
|
|
||||||
return $grant->handleResponse($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".
|
* Sets any result keys we've received matching our provider-defined uidKey to the key "uid".
|
||||||
*
|
*
|
||||||
|
|
|
@ -10,6 +10,8 @@ class Github extends AbstractProvider
|
||||||
|
|
||||||
public $domain = 'https://github.com';
|
public $domain = 'https://github.com';
|
||||||
|
|
||||||
|
public $apiDomain = 'https://api.github.com';
|
||||||
|
|
||||||
public function urlAuthorize()
|
public function urlAuthorize()
|
||||||
{
|
{
|
||||||
return $this->domain.'/login/oauth/authorize';
|
return $this->domain.'/login/oauth/authorize';
|
||||||
|
@ -23,7 +25,7 @@ class Github extends AbstractProvider
|
||||||
public function urlUserDetails(\League\OAuth2\Client\Token\AccessToken $token)
|
public function urlUserDetails(\League\OAuth2\Client\Token\AccessToken $token)
|
||||||
{
|
{
|
||||||
if ($this->domain === 'https://github.com') {
|
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;
|
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)
|
public function urlUserEmails(\League\OAuth2\Client\Token\AccessToken $token)
|
||||||
{
|
{
|
||||||
if ($this->domain === 'https://github.com') {
|
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;
|
return $this->domain.'/api/v3/user/emails?access_token='.$token;
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,6 +29,22 @@ class Google extends AbstractProvider
|
||||||
return $this->hostedDomain;
|
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()
|
public function urlAuthorize()
|
||||||
{
|
{
|
||||||
return 'https://accounts.google.com/o/oauth2/auth';
|
return 'https://accounts.google.com/o/oauth2/auth';
|
||||||
|
@ -43,7 +59,7 @@ class Google extends AbstractProvider
|
||||||
{
|
{
|
||||||
return
|
return
|
||||||
'https://www.googleapis.com/plus/v1/people/me?'.
|
'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;
|
'emails%2Fvalue%2Cimage%2Furl&alt=json&access_token='.$token;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -97,6 +113,10 @@ class Google extends AbstractProvider
|
||||||
$url .= '&' . $this->httpBuildQuery(['hd' => $this->hostedDomain]);
|
$url .= '&' . $this->httpBuildQuery(['hd' => $this->hostedDomain]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!empty($this->accessType)) {
|
||||||
|
$url .= '&' . $this->httpBuildQuery(['access_type'=> $this->accessType]);
|
||||||
|
}
|
||||||
|
|
||||||
return $url;
|
return $url;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,17 +43,13 @@ class AccessToken
|
||||||
|
|
||||||
$this->accessToken = $options['access_token'];
|
$this->accessToken = $options['access_token'];
|
||||||
|
|
||||||
// Some providers (not many) give the uid here, so lets take it
|
if (!empty($options['uid'])) {
|
||||||
isset($options['uid']) and $this->uid = $options['uid'];
|
$this->uid = $options['uid'];
|
||||||
|
}
|
||||||
|
|
||||||
// Vkontakte uses user_id instead of uid
|
if (!empty($options['refresh_token'])) {
|
||||||
isset($options['user_id']) and $this->uid = $options['user_id'];
|
$this->refreshToken = $options['refresh_token'];
|
||||||
|
}
|
||||||
// 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'];
|
|
||||||
|
|
||||||
// We need to know when the token expires. Show preference to
|
// We need to know when the token expires. Show preference to
|
||||||
// 'expires_in' since it is defined in RFC6749 Section 5.1.
|
// 'expires_in' since it is defined in RFC6749 Section 5.1.
|
||||||
|
@ -67,9 +63,6 @@ class AccessToken
|
||||||
$expiresInFuture = $expires > time();
|
$expiresInFuture = $expires > time();
|
||||||
$this->expires = $expiresInFuture ? $expires : time() + ((int) $expires);
|
$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'];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace League\OAuth2\Client\Test\Token;
|
namespace League\OAuth2\Client\Test\Entity;
|
||||||
|
|
||||||
use League\OAuth2\Client\Entity\User;
|
use League\OAuth2\Client\Entity\User;
|
||||||
|
|
||||||
|
|
|
@ -112,6 +112,23 @@ class GithubTest extends \PHPUnit_Framework_TestCase
|
||||||
$this->assertEquals('mock_email', $this->provider->getUserEmail($token));
|
$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()
|
public function testGithubEnterpriseDomainUrls()
|
||||||
{
|
{
|
||||||
$this->provider->domain = 'https://github.company.com';
|
$this->provider->domain = 'https://github.company.com';
|
||||||
|
|
|
@ -15,6 +15,7 @@ class GoogleTest extends \PHPUnit_Framework_TestCase
|
||||||
'clientSecret' => 'mock_secret',
|
'clientSecret' => 'mock_secret',
|
||||||
'redirectUri' => 'none',
|
'redirectUri' => 'none',
|
||||||
'hostedDomain' => 'mock_domain',
|
'hostedDomain' => 'mock_domain',
|
||||||
|
'accessType' => 'mock_access_type'
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,6 +38,7 @@ class GoogleTest extends \PHPUnit_Framework_TestCase
|
||||||
$this->assertArrayHasKey('response_type', $query);
|
$this->assertArrayHasKey('response_type', $query);
|
||||||
$this->assertArrayHasKey('approval_prompt', $query);
|
$this->assertArrayHasKey('approval_prompt', $query);
|
||||||
$this->assertArrayHasKey('hd', $query);
|
$this->assertArrayHasKey('hd', $query);
|
||||||
|
$this->assertArrayHasKey('access_type', $query);
|
||||||
$this->assertNotNull($this->provider->state);
|
$this->assertNotNull($this->provider->state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -105,4 +107,15 @@ class GoogleTest extends \PHPUnit_Framework_TestCase
|
||||||
$this->provider->setHostedDomain('changed_domain');
|
$this->provider->setHostedDomain('changed_domain');
|
||||||
$this->assertEquals('changed_domain', $this->provider->hostedDomain);
|
$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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue