Skip to content

Commit

Permalink
Merge 6d27826 into f559ca1
Browse files Browse the repository at this point in the history
  • Loading branch information
TomHAnderson committed May 5, 2014
2 parents f559ca1 + 6d27826 commit 477e6e8
Show file tree
Hide file tree
Showing 20 changed files with 101 additions and 83 deletions.
28 changes: 12 additions & 16 deletions README.md
Expand Up @@ -41,22 +41,18 @@ damages our ability to make this package the best it can be, especially as we pr
If you would like to support other providers, please make them available as a Composer package, then link to them
below.

These providers allow integration with other providers not supported by `oauth2-client`. They may require an older version
These providers allow integration with other providers not included with `oauth2-client`. They may require an older version
so please help them out with a pull request if you notice this.

- _Insert providers here_
- [box.com](https://github.com/StukiOrg/BoxOAuth2Client-PHP)
- add more providers

## Install
##Installation with Composer

Via Composer

``` json
{
"require": {
"league/oauth2-client": "~0.3"
}
}
```sh
$ php composer.phar require league/oauth2-client:~0.3
```
For composer documentation, please refer to [getcomposer.org](http://getcomposer.org/).

## Requirements

Expand Down Expand Up @@ -86,15 +82,15 @@ 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']
'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'],
'grant_type' => 'authorization_code'
]);

// Optional: Now you have a token you can look up a users profile data
Expand All @@ -104,7 +100,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) {

Expand Down
2 changes: 2 additions & 0 deletions src/Entity/User.php
Expand Up @@ -70,6 +70,8 @@ public function exchangeArray(array $data)
$key = strtolower($key);
switch ($key) {
case 'uid':
case 'user_id':
case 'x_mailru_vid':
$this->uid = $value;
break;
case 'nickname':
Expand Down
21 changes: 18 additions & 3 deletions src/Provider/AbstractProvider.php
Expand Up @@ -38,6 +38,18 @@ abstract class AbstractProvider
*/
protected $httpBuildEncType = 1;

/**
* Does the Provider support and/or require a state when an access_token is requested?
*
* @var boolean requireState
*/
protected $requireState = false;

public function getRequireState()
{
return $this->requireState;
}

public function __construct($options = array())
{
foreach ($options as $option => $value) {
Expand Down Expand Up @@ -83,17 +95,20 @@ public function setScopes(array $scopes)

public function getAuthorizationUrl($options = array())
{
$state = md5(uniqid(rand(), true));

$params = array(
'client_id' => $this->clientId,
'redirect_uri' => $this->redirectUri,
'state' => $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'
);

if ($this->requireState and !isset($options['state'])) {
throw new \Exception('state is a required parameter for this Provider');
} elseif ($this->requireState) {
$params['state'] = $options['state'];
}

return $this->urlAuthorize() . '?' . $this->httpBuildQuery($params, '', '&');
}

Expand Down
1 change: 1 addition & 0 deletions src/Provider/Eventbrite.php
Expand Up @@ -6,6 +6,7 @@

class Eventbrite extends AbstractProvider
{
protected $requireState = false;

public function __construct($options)
{
Expand Down
1 change: 1 addition & 0 deletions src/Provider/Facebook.php
Expand Up @@ -8,6 +8,7 @@ class Facebook extends AbstractProvider
{
public $scopes = array('offline_access', 'email', 'read_stream');
public $responseType = 'string';
protected $requireState = true;

public function urlAuthorize()
{
Expand Down
1 change: 1 addition & 0 deletions src/Provider/Github.php
Expand Up @@ -7,6 +7,7 @@
class Github extends AbstractProvider
{
public $responseType = 'string';
protected $requireState = false;

public function urlAuthorize()
{
Expand Down
1 change: 1 addition & 0 deletions src/Provider/Google.php
Expand Up @@ -7,6 +7,7 @@
class Google extends AbstractProvider
{
public $scopeSeparator = ' ';
protected $requireState = true;

public $scopes = array(
'https://www.googleapis.com/auth/userinfo.profile',
Expand Down
1 change: 1 addition & 0 deletions src/Provider/Instagram.php
Expand Up @@ -8,6 +8,7 @@ class Instagram extends AbstractProvider
{
public $scopes = array('basic');
public $responseType = 'json';
protected $requireState = false;

public function urlAuthorize()
{
Expand Down
1 change: 1 addition & 0 deletions src/Provider/LinkedIn.php
Expand Up @@ -9,6 +9,7 @@ class LinkedIn extends AbstractProvider
{
public $scopes = array('r_basicprofile r_emailaddress r_contactinfo');
public $responseType = 'json';
protected $requireState = true;
public $fields = array(
'id', 'email-address', 'first-name', 'last-name', 'headline',
'location', 'industry', 'picture-url', 'public-profile-url'
Expand Down
1 change: 1 addition & 0 deletions src/Provider/Microsoft.php
Expand Up @@ -9,6 +9,7 @@ class Microsoft extends AbstractProvider
{
public $scopes = array('wl.basic', 'wl.emails');
public $responseType = 'json';
protected $requireState = false;

public function urlAuthorize()
{
Expand Down
15 changes: 6 additions & 9 deletions src/Provider/Vkontakte.php
Expand Up @@ -9,6 +9,7 @@ class Vkontakte extends AbstractProvider
{
public $scopes = array();
public $responseType = 'json';
protected $requireState = true;

public function urlAuthorize()
{
Expand Down Expand Up @@ -63,7 +64,7 @@ public function userDetails($response, AccessToken $token)
$description = (isset($response->status)) ? $response->status : null;

$user->exchangeArray(array(
'uid' => $response->uid,
'uid' => $response->user_id,
'nickname' => $response->nickname,
'name' => $response->screen_name,
'firstname' => $response->first_name,
Expand All @@ -79,22 +80,18 @@ public function userDetails($response, AccessToken $token)

public function userUid($response, AccessToken $token)
{
$response = $response->response[0];

return $response->uid;
return $this->userDetails($response, $token)->uid;
}

public function userEmail($response, AccessToken $token)
{
$response = $response->response[0];

return isset($response->email) && $response->email ? $response->email : null;
return $this->userDetails($response, $token)->email;
}

public function userScreenName($response, AccessToken $token)
{
$response = $response->response[0];
$user = $this->userDetails($response, $token);

return array($response->first_name, $response->last_name);
return array($user->firstName, $user->lastName);
}
}
42 changes: 28 additions & 14 deletions src/Token/AccessToken.php
Expand Up @@ -12,7 +12,12 @@ class AccessToken
public $accessToken;

/**
* @var int expires
* @var int expires_in
*/
public $expires_in;

/**
* @var int expires
*/
public $expires;

Expand Down Expand Up @@ -43,23 +48,32 @@ public function __construct(array $options = null)

$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'];

// 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'];
// Find uid
if (isset($options['uid'])) {
$this->uid = $options['uid'];
} elseif (isset($options['user_id'])) {
// Vkontakte uses user_id instead of uid
$this->uid = $options['user_id'];
} elseif (isset($options['x_mailru_vid'])) {
// Mailru uses x_mailru_vid instead of uid
$this->uid = $options['x_mailru_vid'];
}

// We need to know when the token expires, add num. seconds to current time
isset($options['expires_in']) and $this->expires = time() + ((int) $options['expires_in']);
// The OAuth2 spec works in expires_in values and
// not expiratory dates (as previously coded)
if (isset($options['expires_in'])) {
$this->expires_in = $options['expires_in'];
} elseif (isset($options['expires'])) {
// Facebook uses expires instead of expires_in
$this->expires_in = $options['expires'];
}

// Facebook is just being a spec ignoring jerk
isset($options['expires']) and $this->expires = time() + ((int) $options['expires']);
$this->expires = time() + $this->expires_in;

// Grab a refresh token so we can update access tokens when they expires
isset($options['refresh_token']) and $this->refreshToken = $options['refresh_token'];
if (isset($options['refresh_token'])) {
$this->refreshToken = $options['refresh_token'];
}
}

/**
Expand Down
8 changes: 3 additions & 5 deletions test/src/Provider/EventbriteTest.php
Expand Up @@ -25,7 +25,6 @@ public function testAuthorizationUrl()

$this->assertArrayHasKey('client_id', $query);
$this->assertArrayHasKey('redirect_uri', $query);
$this->assertArrayHasKey('state', $query);
$this->assertArrayHasKey('scope', $query);
$this->assertArrayHasKey('response_type', $query);
$this->assertArrayHasKey('approval_prompt', $query);
Expand All @@ -42,7 +41,7 @@ public function testUrlAccessToken()
public function testGetAccessToken()
{
$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", "uid": 1}');
$response->shouldReceive('getBody')->times(1)->andReturn('{"access_token": "mock_access_token", "expires_in": 3600, "refresh_token": "mock_refresh_token", "uid": 1}');

$client = m::mock('Guzzle\Service\Client');
$client->shouldReceive('setBaseUrl')->times(1);
Expand All @@ -52,8 +51,7 @@ public function testGetAccessToken()
$token = $this->provider->getAccessToken('authorization_code', array('code' => 'mock_authorization_code'));

$this->assertEquals('mock_access_token', $token->accessToken);
$this->assertLessThanOrEqual(time() + 3600, $token->expires);
$this->assertGreaterThanOrEqual(time(), $token->expires);
$this->assertEquals(3600, $token->expires_in);
$this->assertEquals('mock_refresh_token', $token->refreshToken);
$this->assertEquals('1', $token->uid);
}
Expand All @@ -66,7 +64,7 @@ public function testScopes()
public function testUserData()
{
$postResponse = m::mock('Guzzle\Http\Message\Response');
$postResponse->shouldReceive('getBody')->times(1)->andReturn('{"access_token": "mock_access_token", "expires": 3600, "refresh_token": "mock_refresh_token", "uid": 1}');
$postResponse->shouldReceive('getBody')->times(1)->andReturn('{"access_token": "mock_access_token", "expires_in": 3600, "refresh_token": "mock_refresh_token", "uid": 1}');

$getResponse = m::mock('Guzzle\Http\Message\Response');
$getResponse->shouldReceive('getBody')->times(1)->andReturn('{"user": {"user_id": 12345, "email": "mock_email"}}');
Expand Down
7 changes: 3 additions & 4 deletions test/src/Provider/FacebookTest.php
Expand Up @@ -19,14 +19,14 @@ protected function setUp()

public function testAuthorizationUrl()
{
$url = $this->provider->getAuthorizationUrl();
$url = $this->provider->getAuthorizationUrl(array('state' => 'mock_state'));
$uri = parse_url($url);
parse_str($uri['query'], $query);

$this->assertArrayHasKey('client_id', $query);
$this->assertArrayHasKey('redirect_uri', $query);
$this->assertArrayHasKey('state', $query);
$this->assertArrayHasKey('scope', $query);
$this->assertArrayHasKey('state', $query);
$this->assertArrayHasKey('response_type', $query);
$this->assertArrayHasKey('approval_prompt', $query);
}
Expand Down Expand Up @@ -54,8 +54,7 @@ public function testGetAccessToken()
# print_r($token);die();

$this->assertEquals('mock_access_token', $token->accessToken);
$this->assertLessThanOrEqual(time() + 3600, $token->expires);
$this->assertGreaterThanOrEqual(time(), $token->expires);
$this->assertEquals(3600, $token->expires_in);
$this->assertEquals('mock_refresh_token', $token->refreshToken);
$this->assertEquals('1', $token->uid);
}
Expand Down
8 changes: 3 additions & 5 deletions test/src/Provider/GithubTest.php
Expand Up @@ -25,7 +25,6 @@ public function testAuthorizationUrl()

$this->assertArrayHasKey('client_id', $query);
$this->assertArrayHasKey('redirect_uri', $query);
$this->assertArrayHasKey('state', $query);
$this->assertArrayHasKey('scope', $query);
$this->assertArrayHasKey('response_type', $query);
$this->assertArrayHasKey('approval_prompt', $query);
Expand All @@ -42,7 +41,7 @@ public function testUrlAccessToken()
public function testGetAccessToken()
{
$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&uid=1');
$response->shouldReceive('getBody')->times(1)->andReturn('access_token=mock_access_token&expires_in=3600&refresh_token=mock_refresh_token&uid=1');

$client = m::mock('Guzzle\Service\Client');
$client->shouldReceive('setBaseUrl')->times(1);
Expand All @@ -52,8 +51,7 @@ public function testGetAccessToken()
$token = $this->provider->getAccessToken('authorization_code', array('code' => 'mock_authorization_code'));

$this->assertEquals('mock_access_token', $token->accessToken);
$this->assertLessThanOrEqual(time() + 3600, $token->expires);
$this->assertGreaterThanOrEqual(time(), $token->expires);
$this->assertEquals(3600, $token->expires_in);
$this->assertEquals('mock_refresh_token', $token->refreshToken);
$this->assertEquals('1', $token->uid);
}
Expand All @@ -67,7 +65,7 @@ public function testScopes()
public function testUserData()
{
$postResponse = m::mock('Guzzle\Http\Message\Response');
$postResponse->shouldReceive('getBody')->times(1)->andReturn('access_token=mock_access_token&expires=3600&refresh_token=mock_refresh_token&uid=1');
$postResponse->shouldReceive('getBody')->times(1)->andReturn('access_token=mock_access_token&expires_in=3600&refresh_token=mock_refresh_token&uid=1');

$getResponse = m::mock('Guzzle\Http\Message\Response');
$getResponse->shouldReceive('getBody')->times(1)->andReturn('{"id": 12345, "login": "mock_login", "name": "mock_name", "email": "mock_email"}');
Expand Down

0 comments on commit 477e6e8

Please sign in to comment.