Compare commits

...

5 Commits

Author SHA1 Message Date
Vitaliy Filippov 40b0c7c3b7 Include more details in exceptions, add JSON Web Token implementation 2017-05-31 16:21:37 +03:00
Vitaliy Filippov 7b137a5d34 Add GenericProvider 2016-03-11 14:32:01 +03:00
Vitaliy Filippov b789b77c07 Simplify everything
* Remove useless wrapper code (IDPException, Entity\User, Grant\*, httpBuildQuery)
* Remove useless getUserUid(), getUserEmail(), getUserScreenName() methods that throw away remote-fetched data
* Do not depend on Guzzle, use just cURL instead
* Shorten namespace name and remove sub-namespaces
* Do not use Mockery in tests, use custom cURL mock instead (TESTS STILL PASS)
2015-04-19 00:29:09 +03:00
Ben Ramsey 7496e419e3 Merge pull request #257 from soundasleep/patch-1
Add link to third-party Coinbase OAuth2 provider
2015-04-09 07:42:57 -05:00
Jevon Wright a49c4c72e0 Add link to third-party Coinbase OAuth2 provider
Provided by https://github.com/openclerk/coinbase-oauth2
2015-04-09 18:40:52 +12:00
50 changed files with 1521 additions and 2083 deletions

View File

@ -7,15 +7,10 @@ php:
- 7.0
- hhvm
before_script:
- travis_retry composer self-update
- travis_retry composer install --no-interaction --prefer-source
script:
- mkdir -p build/logs
- ./vendor/bin/parallel-lint src test
- ./vendor/bin/phpunit --coverage-text
- ./vendor/bin/phpcs src --standard=psr2 -sp
after_script:
- php vendor/bin/coveralls

106
README.md
View File

@ -1,9 +1,8 @@
# OAuth 2.0 Client
This is a STANDALONE SIMPLIFIED fork of https://github.com/thephpleague/oauth2-client/
[![Build Status](https://travis-ci.org/thephpleague/oauth2-client.svg?branch=master)](https://travis-ci.org/thephpleague/oauth2-client)
[![Coverage Status](https://coveralls.io/repos/thephpleague/oauth2-client/badge.svg?branch=master)](https://coveralls.io/r/thephpleague/oauth2-client?branch=master)
[![Latest Stable Version](https://poser.pugx.org/league/oauth2-client/version.svg)](https://packagist.org/packages/league/oauth2-client)
[![Total Downloads](https://poser.pugx.org/league/oauth2-client/downloads.svg)](https://packagist.org/packages/league/oauth2-client)
cURL is used instead of Guzzle, some useless wrapper code is removed. Tests still pass.
# OAuth 2.0 Client
This package makes it stupidly simple to integrate your application with OAuth 2.0 identity providers.
@ -13,14 +12,6 @@ integration is an important feature of most web-apps these days. Many of these s
It will work with any OAuth 2.0 provider (be it an OAuth 2.0 Server for your own API or Facebook) and provides support
for popular systems out of the box. This package abstracts out some of the subtle but important differences between various providers, handles access tokens and refresh tokens, and allows you easy access to profile information on these other sites.
This package is compliant with [PSR-1][], [PSR-2][] and [PSR-4][]. If you notice compliance oversights, please send
a patch via pull request.
[PSR-1]: https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-1-basic-coding-standard.md
[PSR-2]: https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-2-coding-style-guide.md
[PSR-4]: https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-4-autoloader.md
## Requirements
The following versions of PHP are supported.
@ -36,45 +27,73 @@ The following versions of PHP are supported.
### Authorization Code Flow
```php
$provider = new League\OAuth2\Client\Provider\<ProviderName>([
$provider = new \OAuth2\<ProviderName>([
'clientId' => 'XXXXXXXX',
'clientSecret' => 'XXXXXXXX',
'redirectUri' => 'https://your-registered-redirect-uri/',
'scopes' => ['email', '...', '...'],
]);
if (!isset($_GET['code'])) {
// For example, with simplest GenericProvider and Keycloak
$provider = new \OAuth2\GenericProvider([
'clientId' => 'XXXXXXXX',
'clientSecret' => 'XXXXXXXX',
'urlAuthorize' => 'http://keycloak-server/auth/realms/example/protocol/openid-connect/auth',
'urlAccessToken' => 'http://keycloak-server/auth/realms/example/protocol/openid-connect/token',
'urlUserDetails' => 'http://keycloak-server/auth/realms/example/protocol/openid-connect/userinfo',
'scopes' => ['name', 'email'],
]);
$useJWT = false;
$jwksEndpointURL = '';
if (!isset($_GET['code']))
{
// If we don't have an authorization code then get one
$authUrl = $provider->getAuthorizationUrl();
$_SESSION['oauth2state'] = $provider->state;
header('Location: '.$authUrl);
exit;
// Check given state against previously stored one to mitigate CSRF attack
} elseif (empty($_GET['state']) || ($_GET['state'] !== $_SESSION['oauth2state'])) {
}
elseif (empty($_GET['state']) || ($_GET['state'] !== $_SESSION['oauth2state']))
{
// Check given state against previously stored one to mitigate CSRF attack
unset($_SESSION['oauth2state']);
exit('Invalid state');
} else {
}
else
{
// Try to get an access token (using the authorization code grant)
$token = $provider->getAccessToken('authorization_code', [
'code' => $_GET['code']
]);
// Optional: Now you have a token you can look up a users profile data
try {
try
{
if (!$useJWT)
{
// We got an access token, let's now get the user's details
$userDetails = $provider->getUserDetails($token);
}
else
{
// If your tokens are JWT (JSON Web Tokens) (Keycloak's ones are),
// you may decode and verify them instead of fetching user details from server
$keys = \OAuth2\JWT::extractKeys(json_decode(file_get_contents($jwksEndpointURL), true));
$userDetails = JWT::decode($token->accessToken, $keys);
// We got an access token, let's now get the user's details
$userDetails = $provider->getUserDetails($token);
// You may also just decode it without verifying
$userDetails = JWT::decode($token->accessToken, NULL);
}
// Use these details to create a new profile
printf('Hello %s!', $userDetails->firstName);
} catch (Exception $e) {
printf('Hello %s!', $userDetails['firstname']);
var_dump($userDetails);
}
catch (Exception $e)
{
// Failed to get user details
exit('Oh dear...');
}
@ -93,21 +112,20 @@ if (!isset($_GET['code'])) {
### Refreshing a Token
```php
$provider = new League\OAuth2\Client\Provider\<ProviderName>([
$provider = new \OAuth2\<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]);
$token = $provider->getAccessToken('refresh_token', ['refresh_token' => $refreshToken]);
```
### Built-In Providers
This package currently has built-in support for:
- Basic GenericProvider suitable for any OAuth2 server
- Eventbrite
- Facebook
- Github
@ -129,6 +147,7 @@ so please help them out with a pull request if you notice this.
- [Auth0](https://github.com/RiskioFr/oauth2-auth0)
- [Battle.net](https://packagist.org/packages/depotwarehouse/oauth2-bnet)
- [Coinbase](https://github.com/openclerk/coinbase-oauth2)
- [Dropbox](https://github.com/pixelfear/oauth2-dropbox)
- [FreeAgent](https://github.com/CloudManaged/oauth2-freeagent)
- [Google Nest](https://github.com/JC5/nest-oauth2-provider)
@ -146,14 +165,14 @@ so please help them out with a pull request if you notice this.
### Implementing your own provider
If you are working with an oauth2 service not supported out-of-the-box or by an existing package, it is quite simple to
implement your own. Simply extend `League\OAuth2\Client\Provider\AbstractProvider` and implement the required abstract
implement your own. Simply extend `\OAuth2\AbstractProvider` and implement the required abstract
methods:
```php
abstract public function urlAuthorize();
abstract public function urlAccessToken();
abstract public function urlUserDetails(\League\OAuth2\Client\Token\AccessToken $token);
abstract public function userDetails($response, \League\OAuth2\Client\Token\AccessToken $token);
abstract public function urlUserDetails(\OAuth2\AccessToken $token);
abstract public function userDetails($response, \OAuth2\AccessToken $token);
```
Each of these abstract methods contain a docblock defining their expectations and typical behaviour. Once you have
@ -172,18 +191,12 @@ provider you would add a property:
public $uidKey = 'accountId';
```
### Client Packages
Some developers use this library as a base for their own PHP API wrappers, and that seems like a really great idea. It might make it slightly tricky to integrate their provider with an existing generic "OAuth 2.0 All the Things" login system, but it does make working with them easier.
- [Sniply](https://github.com/younes0/sniply)
## Install
Via Composer
``` bash
$ composer require league/oauth2-client
$ composer require vitalif/oauth2-client
```
## Testing
@ -192,13 +205,9 @@ $ composer require league/oauth2-client
$ ./vendor/bin/phpunit
```
## Contributing
Please see [CONTRIBUTING](https://github.com/thephpleague/oauth2-client/blob/master/CONTRIBUTING.md) for details.
## Credits
- [Vitaliy Filippov](https://github.com/vitalif) - this simplified version
- [Alex Bilbie](https://github.com/alexbilbie)
- [Ben Corlett](https://github.com/bencorlett)
- [James Mills](https://github.com/jamesmills)
@ -206,7 +215,6 @@ Please see [CONTRIBUTING](https://github.com/thephpleague/oauth2-client/blob/mas
- [Tom Anderson](https://github.com/TomHAnderson)
- [All Contributors](https://github.com/thephpleague/oauth2-client/contributors)
## License
The MIT License (MIT). Please see [License File](https://github.com/thephpleague/oauth2-client/blob/master/LICENSE) for more information.
The MIT License (MIT). Please see [License File](https://github.com/vitalif/oauth2-client/blob/master/LICENSE) for more information.

View File

@ -1,17 +1,12 @@
{
"name": "league/oauth2-client",
"description": "OAuth 2.0 Client Library",
"name": "vitalif/oauth2-client",
"description": "OAuth 2.0 Client Library Simplified",
"license": "MIT",
"require": {
"php": ">=5.4.0",
"guzzle/guzzle": "~3.7"
"php": ">=5.4.0"
},
"require-dev": {
"phpunit/phpunit": "~4.0",
"mockery/mockery": "~0.9",
"squizlabs/php_codesniffer": "~2.0",
"satooshi/php-coveralls": "0.6.*",
"jakub-onderka/php-parallel-lint": "0.8.*"
"phpunit/phpunit": "~4.0"
},
"keywords": [
"oauth",
@ -33,17 +28,17 @@
],
"autoload": {
"psr-4": {
"League\\OAuth2\\Client\\": "src/"
"OAuth2\\": "src/"
}
},
"autoload-dev": {
"psr-4": {
"League\\OAuth2\\Client\\Test\\": "test/src/"
}
"OAuth2\\Test\\": "test/src/"
},
"files": ["test/CurlMock.php"]
},
"extra": {
"branch-alias": {
"dev-master": "0.10.x-dev"
}
}
}

308
src/AbstractProvider.php Normal file
View File

@ -0,0 +1,308 @@
<?php
namespace OAuth2;
interface ProviderInterface
{
public function urlAuthorize();
public function urlAccessToken();
public function urlUserDetails(AccessToken $token);
public function userDetails($response, AccessToken $token);
public function getScopes();
public function setScopes(array $scopes);
public function getAuthorizationUrl($options = []);
public function authorize($options = []);
public function getAccessToken($grant = 'authorization_code', $params = []);
public function getHeaders($token = null);
public function getUserDetails(AccessToken $token);
}
abstract class AbstractProvider implements ProviderInterface
{
public $clientId = '';
public $clientSecret = '';
public $redirectUri = '';
public $state;
public $name;
public $uidKey = 'uid';
public $scopes = [];
public $method = 'post';
public $scopeSeparator = ',';
public $responseType = 'json';
public $headers = [];
public $authorizationHeader;
protected $redirectHandler;
public function __construct($options = [])
{
foreach ($options as $option => $value)
{
if (property_exists($this, $option))
{
$this->{$option} = $value;
}
}
}
/**
* Get the URL that this provider uses to begin authorization.
*
* @return string
*/
abstract public function urlAuthorize();
/**
* Get the URL that this provider users to request an access token.
*
* @return string
*/
abstract public function urlAccessToken();
/**
* Get the URL that this provider uses to request user details.
*
* Since this URL is typically an authorized route, most providers will require you to pass the access_token as
* a parameter to the request. For example, the google url is:
*
* 'https://www.googleapis.com/oauth2/v1/userinfo?alt=json&access_token='.$token
*
* @param AccessToken $token
* @return string
*/
abstract public function urlUserDetails(AccessToken $token);
/**
* Given an object response from the server, process the user details into a format expected by the user
* of the client.
*
* @param object $response
* @param AccessToken $token
* @return mixed
*/
abstract public function userDetails($response, AccessToken $token);
public function getScopes()
{
return $this->scopes;
}
public function setScopes(array $scopes)
{
$this->scopes = $scopes;
}
public function getAuthorizationUrl($options = [])
{
$this->state = isset($options['state']) ? $options['state'] : md5(uniqid(rand(), true));
$params = [
'client_id' => $this->clientId,
'redirect_uri' => $this->redirectUri,
'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' => isset($options['approval_prompt']) ? $options['approval_prompt'] : 'auto',
];
return $this->urlAuthorize().'?'.http_build_query($params);
}
public function authorize($options = [])
{
$url = $this->getAuthorizationUrl($options);
if ($this->redirectHandler)
{
$handler = $this->redirectHandler;
return $handler($url);
}
header('Location: ' . $url);
exit;
}
/**
* @param string $grant: grant type, one of 'authorization_code' (default), 'client_credentials', 'refresh_token', 'password'
*/
public function getAccessToken($grant = 'authorization_code', $params = [])
{
if ($grant == 'password' && (empty($params['username']) || empty($params['password'])))
{
throw new \BadMethodCallException('Missing username or password');
}
elseif ($grant == 'authorization_code' && empty($params['code']))
{
throw new \BadMethodCallException('Missing authorization code');
}
elseif ($grant == 'refresh_token' && empty($params['refresh_token']))
{
throw new \BadMethodCallException('Missing refresh_token');
}
$requestParams = [
'client_id' => $this->clientId,
'client_secret' => $this->clientSecret,
'redirect_uri' => $this->redirectUri,
'grant_type' => $grant,
] + $params;
$curl = curl_init();
if (strtoupper($this->method) == 'POST')
{
curl_setopt_array($curl, [
CURLOPT_URL => ($url = $this->urlAccessToken()),
CURLOPT_POST => 1,
CURLOPT_HTTPHEADER => $this->getHeaders(),
CURLOPT_POSTFIELDS => http_build_query($requestParams),
CURLOPT_RETURNTRANSFER => true,
]);
}
else
{
// No providers included with this library use get but 3rd parties may
curl_setopt_array($curl, [
CURLOPT_URL => ($url = $this->urlAccessToken() . '?' . http_build_query($requestParams)),
CURLOPT_HTTPHEADER => $this->getHeaders(),
CURLOPT_RETURNTRANSFER => true,
]);
}
$response = curl_exec($curl);
$code = curl_getinfo($curl, CURLINFO_HTTP_CODE);
$errno = curl_errno($curl);
$error = curl_error($curl);
curl_close($curl);
switch ($this->responseType)
{
case 'json':
$result = json_decode($response, true);
if (JSON_ERROR_NONE !== json_last_error())
{
$result = [];
}
break;
case 'string':
$result = [];
parse_str($response, $result);
break;
}
if (isset($result['error']) && !empty($result['error']))
{
// OAuth 2.0 Draft 10 style
throw new \Exception($result['error']);
}
elseif (!$result)
{
// cURL?
throw new \Exception($url . ' returned: ' . ($code ? "HTTP $code, content: $response" : "cURL: $errno $error"));
}
$result = $this->prepareAccessTokenResult($result);
return new AccessToken($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".
*
* @param array $result
*/
protected function setResultUid(array &$result)
{
// If we're operating with the default uidKey there's nothing to do.
if ($this->uidKey === "uid")
{
return;
}
if (isset($result[$this->uidKey]))
{
// The AccessToken expects a "uid" to have the key "uid".
$result['uid'] = $result[$this->uidKey];
}
}
public function getUserDetails(AccessToken $token)
{
$response = $this->fetchUserDetails($token);
return $this->userDetails(json_decode($response), $token);
}
protected function fetchUserDetails(AccessToken $token)
{
$url = $this->urlUserDetails($token);
$headers = $this->getHeaders($token);
return $this->fetchProviderData($url, $headers);
}
protected function fetchProviderData($url, array $headers = [])
{
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => $url,
CURLOPT_HTTPHEADER => $headers,
CURLOPT_RETURNTRANSFER => true,
]);
$errno = curl_errno($curl);
$error = curl_error($curl);
$response = curl_exec($curl);
$status = curl_getinfo($curl, CURLINFO_HTTP_CODE);
curl_close($curl);
if ($status != 200)
{
throw new \Exception($url . ' returned: ' . ($status ? "HTTP $status, content: $response" : "cURL: $errno $error"));
}
return $response;
}
protected function getAuthorizationHeaders($token)
{
$headers = [];
if ($this->authorizationHeader)
{
$headers[] = 'Authorization: ' . $this->authorizationHeader . ' ' . $token;
}
return $headers;
}
public function getHeaders($token = null)
{
$headers = $this->headers;
if ($token)
{
$headers = array_merge($headers, $this->getAuthorizationHeaders($token));
}
return $headers;
}
public function setRedirectHandler(callable $handler)
{
$this->redirectHandler = $handler;
}
}

40
src/Token/AccessToken.php → src/AccessToken.php Executable file → Normal file
View File

@ -1,62 +1,50 @@
<?php
namespace League\OAuth2\Client\Token;
use InvalidArgumentException;
namespace OAuth2;
class AccessToken
{
/**
* @var string accessToken
*/
public $accessToken;
/**
* @var int expires
*/
public $expires;
/**
* @var string refreshToken
*/
public $refreshToken;
/**
* @var string uid
*/
public $uid;
/**
* Sets the token, expiry, etc values.
*
* @param array $options token options
* @param array $options token options
* @return void
*/
public function __construct(array $options = null)
{
if (! isset($options['access_token'])) {
if (!isset($options['access_token']))
{
throw new \InvalidArgumentException(
'Required option not passed: access_token'.PHP_EOL
.print_r($options, true)
'Required option not passed: access_token in '.print_r($options, true)
);
}
$this->accessToken = $options['access_token'];
if (!empty($options['uid'])) {
if (!empty($options['uid']))
{
$this->uid = $options['uid'];
}
if (!empty($options['refresh_token'])) {
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.
// Defer to 'expires' if it is provided instead.
if (!empty($options['expires_in'])) {
if (!empty($options['expires_in']))
{
$this->expires = time() + ((int) $options['expires_in']);
} elseif (!empty($options['expires'])) {
}
elseif (!empty($options['expires']))
{
// Some providers supply the seconds until expiration rather than
// the exact timestamp. Take a best guess at which we received.
$expires = $options['expires'];

View File

@ -1,117 +0,0 @@
<?php
namespace League\OAuth2\Client\Entity;
class User
{
protected $uid;
protected $nickname;
protected $name;
protected $firstName;
protected $lastName;
protected $email;
protected $location;
protected $description;
protected $imageUrl;
protected $urls;
protected $gender;
protected $locale;
public function __get($name)
{
if (!property_exists($this, $name)) {
throw new \OutOfRangeException(sprintf(
'%s does not contain a property by the name of "%s"',
__CLASS__,
$name
));
}
return $this->{$name};
}
public function __set($property, $value)
{
if (!property_exists($this, $property)) {
throw new \OutOfRangeException(sprintf(
'%s does not contain a property by the name of "%s"',
__CLASS__,
$property
));
}
$this->$property = $value;
return $this;
}
public function __isset($name)
{
return (property_exists($this, $name));
}
public function getArrayCopy()
{
return [
'uid' => $this->uid,
'nickname' => $this->nickname,
'name' => $this->name,
'firstName' => $this->firstName,
'lastName' => $this->lastName,
'email' => $this->email,
'location' => $this->location,
'description' => $this->description,
'imageUrl' => $this->imageUrl,
'urls' => $this->urls,
'gender' => $this->gender,
'locale' => $this->locale,
];
}
public function exchangeArray(array $data)
{
foreach ($data as $key => $value) {
$key = strtolower($key);
switch ($key) {
case 'uid':
$this->uid = $value;
break;
case 'nickname':
$this->nickname = $value;
break;
case 'name':
$this->name = $value;
break;
case 'firstname':
$this->firstName = $value;
break;
case 'lastname':
$this->lastName = $value;
break;
case 'email':
$this->email = $value;
break;
case 'location':
$this->location = $value;
break;
case 'description':
$this->description = $value;
break;
case 'imageurl':
$this->imageUrl = $value;
break;
case 'urls':
$this->urls = $value;
break;
case 'gender':
$this->gender = $value;
break;
case 'locale':
$this->locale = $value;
break;
}
}
return $this;
}
}

31
src/Eventbrite.php Normal file
View File

@ -0,0 +1,31 @@
<?php
namespace OAuth2;
class Eventbrite extends AbstractProvider
{
public $authorizationHeader = 'Bearer';
public function urlAuthorize()
{
return 'https://www.eventbrite.com/oauth/authorize';
}
public function urlAccessToken()
{
return 'https://www.eventbrite.com/oauth/token';
}
public function urlUserDetails(AccessToken $token)
{
return 'https://www.eventbrite.com/json/user_get';
}
public function userDetails($response, AccessToken $token)
{
return [
'uid' => $response->user->user_id,
'email' => $response->user->email,
];
}
}

View File

@ -1,64 +0,0 @@
<?php
namespace League\OAuth2\Client\Exception;
class IDPException extends \Exception
{
protected $result;
public function __construct($result)
{
$this->result = $result;
$code = isset($result['code']) ? $result['code'] : 0;
if (isset($result['error']) && $result['error'] !== '') {
// OAuth 2.0 Draft 10 style
$message = $result['error'];
} elseif (isset($result['message']) && $result['message'] !== '') {
// cURL style
$message = $result['message'];
} else {
$message = 'Unknown Error.';
}
parent::__construct($message, $code);
}
public function getResponseBody()
{
return $this->result;
}
public function getType()
{
$result = 'Exception';
if (isset($this->result['error'])) {
$message = $this->result['error'];
if (is_string($message)) {
// OAuth 2.0 Draft 10 style
$result = $message;
}
}
return $result;
}
/**
* To make debugging easier.
*
* @return string The string representation of the error.
*/
public function __toString()
{
$str = $this->getType().': ';
if ($this->code != 0) {
$str .= $this->code.': ';
}
return $str.$this->message;
}
}

View File

@ -1,8 +1,6 @@
<?php
namespace League\OAuth2\Client\Provider;
use League\OAuth2\Client\Entity\User;
namespace OAuth2;
class Facebook extends AbstractProvider
{
@ -38,7 +36,7 @@ class Facebook extends AbstractProvider
return 'https://graph.facebook.com/'.$this->graphApiVersion.'/oauth/access_token';
}
public function urlUserDetails(\League\OAuth2\Client\Token\AccessToken $token)
public function urlUserDetails(AccessToken $token)
{
$fields = implode(',', [
'id',
@ -57,10 +55,8 @@ class Facebook extends AbstractProvider
return 'https://graph.facebook.com/'.$this->graphApiVersion.'/me?fields='.$fields.'&access_token='.$token;
}
public function userDetails($response, \League\OAuth2\Client\Token\AccessToken $token)
public function userDetails($response, AccessToken $token)
{
$user = new User();
$email = (isset($response->email)) ? $response->email : null;
// The "hometown" field will only be returned if you ask for the `user_hometown` permission.
$location = (isset($response->hometown->name)) ? $response->hometown->name : null;
@ -69,7 +65,7 @@ class Facebook extends AbstractProvider
$gender = (isset($response->gender)) ? $response->gender : null;
$locale = (isset($response->locale)) ? $response->locale : null;
$user->exchangeArray([
return [
'uid' => $response->id,
'name' => $response->name,
'firstname' => $response->first_name,
@ -77,27 +73,10 @@ class Facebook extends AbstractProvider
'email' => $email,
'location' => $location,
'description' => $description,
'imageurl' => $imageUrl,
'image_url' => $imageUrl,
'gender' => $gender,
'locale' => $locale,
'urls' => [ 'Facebook' => $response->link ],
]);
return $user;
}
public function userUid($response, \League\OAuth2\Client\Token\AccessToken $token)
{
return $response->id;
}
public function userEmail($response, \League\OAuth2\Client\Token\AccessToken $token)
{
return isset($response->email) && $response->email ? $response->email : null;
}
public function userScreenName($response, \League\OAuth2\Client\Token\AccessToken $token)
{
return [$response->first_name, $response->last_name];
];
}
}

31
src/GenericProvider.php Normal file
View File

@ -0,0 +1,31 @@
<?php
namespace OAuth2;
class GenericProvider extends AbstractProvider
{
public $scopes = ['basic'];
public $responseType = 'json';
public $urlAuthorize, $urlAccessToken, $urlUserDetails;
public $authorizationHeader = 'Bearer';
public function urlAuthorize()
{
return $this->urlAuthorize;
}
public function urlAccessToken()
{
return $this->urlAccessToken;
}
public function urlUserDetails(AccessToken $token)
{
return str_replace('$token', $token, $this->urlUserDetails);
}
public function userDetails($response, AccessToken $token)
{
return $response;
}
}

View File

@ -1,9 +1,6 @@
<?php
namespace League\OAuth2\Client\Provider;
use League\OAuth2\Client\Entity\User;
use League\OAuth2\Client\Token\AccessToken;
namespace OAuth2;
class Github extends AbstractProvider
{
@ -27,7 +24,8 @@ class Github extends AbstractProvider
public function urlUserDetails(AccessToken $token)
{
if ($this->domain === 'https://github.com') {
if ($this->domain === 'https://github.com')
{
return $this->apiDomain.'/user';
}
return $this->domain.'/api/v3/user';
@ -35,7 +33,8 @@ class Github extends AbstractProvider
public function urlUserEmails(AccessToken $token)
{
if ($this->domain === 'https://github.com') {
if ($this->domain === 'https://github.com')
{
return $this->apiDomain.'/user/emails';
}
return $this->domain.'/api/v3/user/emails';
@ -43,12 +42,10 @@ class Github extends AbstractProvider
public function userDetails($response, AccessToken $token)
{
$user = new User();
$name = (isset($response->name)) ? $response->name : null;
$email = (isset($response->email)) ? $response->email : null;
$user->exchangeArray([
return [
'uid' => $response->id,
'nickname' => $response->login,
'name' => $name,
@ -56,36 +53,13 @@ class Github extends AbstractProvider
'urls' => [
'GitHub' => $this->domain.'/'.$response->login,
],
]);
return $user;
}
public function userUid($response, AccessToken $token)
{
return $response->id;
];
}
public function getUserEmails(AccessToken $token)
{
$response = $this->fetchUserEmails($token);
return $this->userEmails(json_decode($response), $token);
}
public function userEmail($response, AccessToken $token)
{
return isset($response->email) && $response->email ? $response->email : null;
}
public function userEmails($response, AccessToken $token)
{
return $response;
}
public function userScreenName($response, AccessToken $token)
{
return $response->name;
return json_decode($response);
}
protected function fetchUserEmails(AccessToken $token)

View File

@ -1,8 +1,6 @@
<?php
namespace League\OAuth2\Client\Provider;
use League\OAuth2\Client\Entity\User;
namespace OAuth2;
class Google extends AbstractProvider
{
@ -57,7 +55,7 @@ class Google extends AbstractProvider
return 'https://accounts.google.com/o/oauth2/token';
}
public function urlUserDetails(\League\OAuth2\Client\Token\AccessToken $token)
public function urlUserDetails(AccessToken $token)
{
return
'https://www.googleapis.com/plus/v1/people/me?'.
@ -65,58 +63,37 @@ class Google extends AbstractProvider
'emails%2Fvalue%2Cimage%2Furl&alt=json';
}
public function userDetails($response, \League\OAuth2\Client\Token\AccessToken $token)
public function userDetails($response, AccessToken $token)
{
$response = (array) $response;
$user = new User();
$imageUrl = (isset($response['image']) &&
$response['image']->url) ? $response['image']->url : null;
$email =
(isset($response['emails']) &&
count($response['emails']) &&
$response['emails'][0]->value)? $response['emails'][0]->value : null;
$email = (isset($response['emails']) && count($response['emails']) &&
$response['emails'][0]->value) ? $response['emails'][0]->value : null;
$user->exchangeArray([
return [
'uid' => $response['id'],
'name' => $response['displayName'],
'firstname' => $response['name']->givenName,
'lastName' => $response['name']->familyName,
'lastname' => $response['name']->familyName,
'email' => $email,
'imageUrl' => $imageUrl,
]);
return $user;
}
public function userUid($response, \League\OAuth2\Client\Token\AccessToken $token)
{
return $response->id;
}
public function userEmail($response, \League\OAuth2\Client\Token\AccessToken $token)
{
return ($response->emails &&
count($response->emails) &&
$response->emails[0]->value) ? $response->emails[0]->value : null;
}
public function userScreenName($response, \League\OAuth2\Client\Token\AccessToken $token)
{
return [$response->name->givenName, $response->name->familyName];
'image_url' => $imageUrl,
];
}
public function getAuthorizationUrl($options = array())
{
$url = parent::getAuthorizationUrl($options);
if (!empty($this->hostedDomain)) {
$url .= '&' . $this->httpBuildQuery(['hd' => $this->hostedDomain]);
if (!empty($this->hostedDomain))
{
$url .= '&' . http_build_query(['hd' => $this->hostedDomain]);
}
if (!empty($this->accessType)) {
$url .= '&' . $this->httpBuildQuery(['access_type'=> $this->accessType]);
if (!empty($this->accessType))
{
$url .= '&' . http_build_query(['access_type'=> $this->accessType]);
}
return $url;

View File

@ -1,27 +0,0 @@
<?php
namespace League\OAuth2\Client\Grant;
use League\OAuth2\Client\Token\AccessToken;
class AuthorizationCode implements GrantInterface
{
public function __toString()
{
return 'authorization_code';
}
public function prepRequestParams($defaultParams, $params)
{
if (! isset($params['code']) || empty($params['code'])) {
throw new \BadMethodCallException('Missing authorization code');
}
return array_merge($defaultParams, $params);
}
public function handleResponse($response = [])
{
return new AccessToken($response);
}
}

View File

@ -1,25 +0,0 @@
<?php
namespace League\OAuth2\Client\Grant;
use League\OAuth2\Client\Token\AccessToken;
class ClientCredentials implements GrantInterface
{
public function __toString()
{
return 'client_credentials';
}
public function prepRequestParams($defaultParams, $params)
{
$params['grant_type'] = 'client_credentials';
return array_merge($defaultParams, $params);
}
public function handleResponse($response = array())
{
return new AccessToken($response);
}
}

View File

@ -1,12 +0,0 @@
<?php
namespace League\OAuth2\Client\Grant;
interface GrantInterface
{
public function __toString();
public function handleResponse($response = []);
public function prepRequestParams($defaultParams, $params);
}

View File

@ -1,33 +0,0 @@
<?php
namespace League\OAuth2\Client\Grant;
use League\OAuth2\Client\Token\AccessToken;
class Password implements GrantInterface
{
public function __toString()
{
return 'password';
}
public function prepRequestParams($defaultParams, $params)
{
if (! isset($params['username']) || empty($params['username'])) {
throw new \BadMethodCallException('Missing username');
}
if (! isset($params['password']) || empty($params['password'])) {
throw new \BadMethodCallException('Missing password');
}
$params['grant_type'] = 'password';
return array_merge($defaultParams, $params);
}
public function handleResponse($response = array())
{
return new AccessToken($response);
}
}

View File

@ -1,29 +0,0 @@
<?php
namespace League\OAuth2\Client\Grant;
use League\OAuth2\Client\Token\AccessToken as AccessToken;
class RefreshToken implements GrantInterface
{
public function __toString()
{
return 'refresh_token';
}
public function prepRequestParams($defaultParams, $params)
{
if (! isset($params['refresh_token']) || empty($params['refresh_token'])) {
throw new \BadMethodCallException('Missing refresh_token');
}
$params['grant_type'] = 'refresh_token';
return array_merge($defaultParams, $params);
}
public function handleResponse($response = [])
{
return new AccessToken($response);
}
}

36
src/Instagram.php Normal file
View File

@ -0,0 +1,36 @@
<?php
namespace OAuth2;
class Instagram extends AbstractProvider
{
public $scopes = ['basic'];
public $responseType = 'json';
public function urlAuthorize()
{
return 'https://api.instagram.com/oauth/authorize';
}
public function urlAccessToken()
{
return 'https://api.instagram.com/oauth/access_token';
}
public function urlUserDetails(AccessToken $token)
{
return 'https://api.instagram.com/v1/users/self?access_token='.$token;
}
public function userDetails($response, AccessToken $token)
{
$description = (isset($response->data->bio)) ? $response->data->bio : null;
return [
'uid' => $response->data->id,
'nickname' => $response->data->username,
'name' => $response->data->full_name,
'description' => $description,
'image_url' => $response->data->profile_picture,
];
}
}

476
src/JWT.php Normal file
View File

@ -0,0 +1,476 @@
<?php
namespace OAuth2;
/**
* JSON Web Token implementation, based on this spec:
* http://tools.ietf.org/html/draft-ietf-oauth-json-web-token-06
*
* PHP version 5
*
* @category Authentication
* @package Authentication_JWT
* @author Neuman Vong <neuman@twilio.com>
* @author Anant Narayanan <anant@php.net>
* @author Vitaliy Filippov <vitalif@mail.ru>
* @license http://opensource.org/licenses/BSD-3-Clause 3-clause BSD
* @link https://github.com/firebase/php-jwt (forked from here)
*/
class JWT
{
/**
* When checking nbf, iat or expiration times,
* we want to provide some extra leeway time to
* account for clock skew.
*/
public static $leeway = 0;
/**
* Allow the current timestamp to be specified.
* Useful for fixing a value within unit testing.
*
* Will default to PHP time() value if null.
*/
public static $timestamp = null;
public static $supported_algs = array(
'HS256' => array('hash_hmac', 'SHA256'),
'HS512' => array('hash_hmac', 'SHA512'),
'HS384' => array('hash_hmac', 'SHA384'),
'RS256' => array('openssl', 'SHA256'),
);
/**
* Extract keys from JWKS response structure
* { keys: [ { kid, kty, alg, use, n, e }, ... ] }
*
* For example, from Keycloak's "certs" endpoint URL:
* http://your-keycloak-server.com/auth/realms/your-realm/protocol/openid-connect/certs
*/
public static function extractKeys(array $jwks)
{
if (!isset($jwks['keys']) || !is_array($jwks['keys']))
{
return NULL;
}
$keys = [];
foreach ($jwks['keys'] as $key)
{
if (!isset($key['kid']) || !isset($key['kty']))
{
continue;
}
if ($key['kty'] == 'RSA')
{
if (!isset($key['n']) || !isset($key['e']))
{
continue;
}
$keys[$key['kid']] = JWT_RSAPubKey::modexp2openssl($key['n'], $key['e']);
}
elseif ($key['kty'] == 'oct')
{
if (!isset($key['k']))
{
continue;
}
$keys[$key['kid']] = $key['k'];
}
}
return $keys;
}
/**
* Decodes a JWT string into a PHP object.
*
* @param string $jwt The JWT
* @param string|array|null $key The key, or map of keys.
* If the algorithm used is asymmetric, this is the public key
* If empty, no verification is performed
*
* @return object The JWT's payload as a PHP object
*
* @throws UnexpectedValueException Provided JWT was invalid
* @throws JWT_SignatureInvalidException Provided JWT was invalid because the signature verification failed
* @throws JWT_BeforeValidException Provided JWT is trying to be used before it's eligible as defined by 'nbf'
* @throws JWT_BeforeValidException Provided JWT is trying to be used before it's been created as defined by 'iat'
* @throws JWT_ExpiredException Provided JWT has since expired, as defined by the 'exp' claim
*
* @uses jsonDecode
* @uses urlsafeB64Decode
*/
public static function decode($jwt, $key)
{
$timestamp = is_null(static::$timestamp) ? time() : static::$timestamp;
$tks = explode('.', $jwt);
if (count($tks) != 3)
{
throw new \UnexpectedValueException('Wrong number of segments');
}
list($headb64, $bodyb64, $cryptob64) = $tks;
if (null === ($header = static::jsonDecode(static::urlsafeB64Decode($headb64))))
{
throw new \UnexpectedValueException('Invalid header encoding');
}
if (null === $payload = static::jsonDecode(static::urlsafeB64Decode($bodyb64)))
{
throw new \UnexpectedValueException('Invalid claims encoding');
}
$sig = static::urlsafeB64Decode($cryptob64);
if ($key)
{
if (empty($header['alg']))
{
throw new \UnexpectedValueException('Empty algorithm');
}
if (empty(static::$supported_algs[$header['alg']]))
{
throw new \UnexpectedValueException('Algorithm not supported');
}
if (is_array($key) || $key instanceof \ArrayAccess)
{
if (isset($header['kid']))
{
$key = $key[$header['kid']];
}
else
{
throw new \UnexpectedValueException('"kid" empty, unable to lookup correct key');
}
}
// Check the signature
if (!static::verify("$headb64.$bodyb64", $sig, $key, $header['alg']))
{
throw new JWT_SignatureInvalidException('Signature verification failed');
}
}
// Check if the nbf if it is defined. This is the time that the
// token can actually be used. If it's not yet that time, abort.
if (isset($payload['nbf']) && $payload['nbf'] > ($timestamp + static::$leeway))
{
throw new JWT_BeforeValidException(
'Cannot handle token prior to ' . date(DateTime::ISO8601, $payload['nbf'])
);
}
// Check that this token has been created before 'now'. This prevents
// using tokens that have been created for later use (and haven't
// correctly used the nbf claim).
if (isset($payload['iat']) && $payload['iat'] > ($timestamp + static::$leeway))
{
throw new JWT_BeforeValidException(
'Cannot handle token prior to ' . date(DateTime::ISO8601, $payload['iat'])
);
}
// Check if this token has expired.
if (isset($payload['exp']) && ($timestamp - static::$leeway) >= $payload['exp'])
{
throw new JWT_ExpiredException('Expired token');
}
return $payload;
}
/**
* Converts and signs a PHP object or array into a JWT string.
*
* @param object|array $payload PHP object or array
* @param string $key The secret key.
* If the algorithm used is asymmetric, this is the private key
* @param string $alg The signing algorithm.
* Supported algorithms are 'HS256', 'HS384', 'HS512' and 'RS256'
* @param mixed $keyId
* @param array $head An array with header elements to attach
*
* @return string A signed JWT
*
* @uses jsonEncode
* @uses urlsafeB64Encode
*/
public static function encode($payload, $key, $alg = 'HS256', $keyId = null, $head = null)
{
$header = array('typ' => 'JWT', 'alg' => $alg);
if ($keyId !== null)
{
$header['kid'] = $keyId;
}
if (isset($head) && is_array($head))
{
$header = array_merge($head, $header);
}
$segments = array();
$segments[] = static::urlsafeB64Encode(static::jsonEncode($header));
$segments[] = static::urlsafeB64Encode(static::jsonEncode($payload));
$signing_input = implode('.', $segments);
$signature = static::sign($signing_input, $key, $alg);
$segments[] = static::urlsafeB64Encode($signature);
return implode('.', $segments);
}
/**
* Sign a string with a given key and algorithm.
*
* @param string $msg The message to sign
* @param string|resource $key The secret key
* @param string $alg The signing algorithm.
* Supported algorithms are 'HS256', 'HS384', 'HS512' and 'RS256'
*
* @return string An encrypted message
*
* @throws DomainException Unsupported algorithm was specified
*/
public static function sign($msg, $key, $alg = 'HS256')
{
if (empty(static::$supported_algs[$alg]))
{
throw new \DomainException('Algorithm not supported');
}
list($function, $algorithm) = static::$supported_algs[$alg];
if ($function == 'hash_hmac')
{
return hash_hmac($algorithm, $msg, $key, true);
}
elseif ($function == 'openssl')
{
$signature = '';
$success = openssl_sign($msg, $signature, $key, $algorithm);
if (!$success)
throw new \DomainException("OpenSSL unable to sign data");
else
return $signature;
}
}
/**
* Verify a signature with the message, key and method. Not all methods
* are symmetric, so we must have a separate verify and sign method.
*
* @param string $msg The original message (header and body)
* @param string $signature The original signature
* @param string|resource $key For HS*, a string key works. for RS*, must be a resource of an openssl public key
* @param string $alg The algorithm
*
* @return bool
*
* @throws DomainException Invalid Algorithm or OpenSSL failure
*/
private static function verify($msg, $signature, $key, $alg)
{
if (empty(static::$supported_algs[$alg]))
{
throw new \DomainException('Algorithm not supported');
}
list($function, $algorithm) = static::$supported_algs[$alg];
if ($function == 'openssl')
{
$success = openssl_verify($msg, $signature, $key, $algorithm);
if (!$success)
throw new \DomainException("OpenSSL unable to verify data: " . openssl_error_string());
else
return $signature;
}
else /* if ($function == 'hash_hmac') */
{
$hash = hash_hmac($algorithm, $msg, $key, true);
if (function_exists('hash_equals'))
{
return hash_equals($signature, $hash);
}
$len = min(strlen($signature), strlen($hash));
$status = 0;
for ($i = 0; $i < $len; $i++)
$status |= (ord($signature[$i]) ^ ord($hash[$i]));
$status |= (strlen($signature) ^ strlen($hash));
return ($status === 0);
}
}
/**
* Decode a JSON string into a PHP object.
*
* @param string $input JSON string
*
* @return object Object representation of JSON string
*
* @throws DomainException Provided string was invalid JSON
*/
public static function jsonDecode($input)
{
if (version_compare(PHP_VERSION, '5.4.0', '>=') && !(defined('JSON_C_VERSION') && PHP_INT_SIZE > 4))
{
/** In PHP >=5.4.0, json_decode() accepts an options parameter, that allows you
* to specify that large ints (like Steam Transaction IDs) should be treated as
* strings, rather than the PHP default behaviour of converting them to floats.
*/
$obj = json_decode($input, true, 512, JSON_BIGINT_AS_STRING);
}
else
{
/** Not all servers will support that, however, so for older versions we must
* manually detect large ints in the JSON string and quote them (thus converting
*them to strings) before decoding, hence the preg_replace() call.
*/
$max_int_length = strlen((string) PHP_INT_MAX) - 1;
$json_without_bigints = preg_replace('/:\s*(-?\d{'.$max_int_length.',})/', ': "$1"', $input);
$obj = json_decode($json_without_bigints, true);
}
if (function_exists('json_last_error') && $errno = json_last_error())
{
static::handleJsonError($errno);
}
elseif ($obj === null && $input !== 'null')
{
throw new \DomainException('Null result with non-null input');
}
return $obj;
}
/**
* Encode a PHP object into a JSON string.
*
* @param object|array $input A PHP object or array
*
* @return string JSON representation of the PHP object or array
*
* @throws DomainException Provided object could not be encoded to valid JSON
*/
public static function jsonEncode($input)
{
$json = json_encode($input);
if (function_exists('json_last_error') && $errno = json_last_error())
{
static::handleJsonError($errno);
}
elseif ($json === 'null' && $input !== null)
{
throw new \DomainException('Null result with non-null input');
}
return $json;
}
/**
* Decode a string with URL-safe Base64.
*
* @param string $input A Base64 encoded string
*
* @return string A decoded string
*/
public static function urlsafeB64Decode($input)
{
$remainder = strlen($input) % 4;
if ($remainder)
{
$padlen = 4 - $remainder;
$input .= str_repeat('=', $padlen);
}
return base64_decode(strtr($input, '-_', '+/'));
}
/**
* Encode a string with URL-safe Base64.
*
* @param string $input The string you want encoded
*
* @return string The base64 encode of what you passed in
*/
public static function urlsafeB64Encode($input)
{
return str_replace('=', '', strtr(base64_encode($input), '+/', '-_'));
}
/**
* Helper method to create a JSON error.
*
* @param int $errno An error number from json_last_error()
*
* @return void
*/
private static function handleJsonError($errno)
{
$messages = array(
JSON_ERROR_DEPTH => 'Maximum stack depth exceeded',
JSON_ERROR_CTRL_CHAR => 'Unexpected control character found',
JSON_ERROR_SYNTAX => 'Syntax error, malformed JSON'
);
throw new \DomainException(
isset($messages[$errno])
? $messages[$errno]
: 'Unknown JSON error: ' . $errno
);
}
}
class JWT_BeforeValidException extends \UnexpectedValueException
{
}
class JWT_ExpiredException extends \UnexpectedValueException
{
}
class JWT_SignatureInvalidException extends \UnexpectedValueException
{
}
class JWT_RSAPubKey
{
protected static function asn1length($len)
{
if ($len < 0x80)
return chr($len);
elseif ($len < 0x100)
return chr(0x81) . chr($len);
elseif ($len < 0x10000)
return chr(0x82) . chr(0xFF & ($len >> 8)) . chr(0xFF & $len);
elseif ($len < 0x1000000)
return chr(0x83) . chr(0xFF & ($len >> 16)) . chr(0xFF & ($len >> 8)) . chr(0xFF & $len);
else
return chr(0x84) . chr(0xFF & ($len >> 24)) . chr(0xFF & ($len >> 16)) . chr(0xFF & ($len >> 8)) . chr(0xFF & $len);
}
protected static function asn1int($int)
{
$int = (ord($int{0}) > 0x7f ? "\x00" : "") . $int;
return "\x02" . self::asn1length(strlen($int)) . $int;
}
protected static function asn1seq($elem1, $elem2)
{
return "\x30" . self::asn1length(strlen($elem1) + strlen($elem2)) . $elem1 . $elem2;
}
protected static function asn1bitstring($elem)
{
$elem = "\x00" . $elem;
return "\x03" . self::asn1length(strlen($elem)) . $elem;
}
/**
* Convert modulus + exponent ('n', 'e' fields from JWK) to OpenSSL RSA public key format
*/
public static function modexp2openssl($mod, $exp)
{
$rsaid = hex2bin('300D06092A864886F70D0101010500');
$exp = base64_decode(str_replace([ '-', '_' ], [ '+', '/' ], $exp), true);
$mod = base64_decode(str_replace([ '-', '_' ], [ '+', '/' ], $mod), true);
if (!$mod || !$exp)
return '';
$pk = self::asn1seq($rsaid, self::asn1bitstring(self::asn1seq(self::asn1int($mod), self::asn1int($exp))));
$pk = base64_encode($pk);
$pk = preg_replace('/(.{64})/', "\$1\n", $pk);
$pk = "-----BEGIN PUBLIC KEY-----\n$pk\n-----END PUBLIC KEY-----\n";
return $pk;
}
}

View File

@ -1,9 +1,6 @@
<?php
namespace League\OAuth2\Client\Provider;
use League\OAuth2\Client\Entity\User;
use League\OAuth2\Client\Token\AccessToken;
namespace OAuth2;
class LinkedIn extends AbstractProvider
{
@ -33,14 +30,12 @@ class LinkedIn extends AbstractProvider
public function userDetails($response, AccessToken $token)
{
$user = new User();
$email = (isset($response->emailAddress)) ? $response->emailAddress : null;
$location = (isset($response->location->name)) ? $response->location->name : null;
$description = (isset($response->headline)) ? $response->headline : null;
$pictureUrl = (isset($response->pictureUrl)) ? $response->pictureUrl : null;
$user->exchangeArray([
return [
'uid' => $response->id,
'name' => $response->firstName.' '.$response->lastName,
'firstname' => $response->firstName,
@ -48,27 +43,8 @@ class LinkedIn extends AbstractProvider
'email' => $email,
'location' => $location,
'description' => $description,
'imageurl' => $pictureUrl,
'image_url' => $pictureUrl,
'urls' => $response->publicProfileUrl,
]);
return $user;
}
public function userUid($response, AccessToken $token)
{
return $response->id;
}
public function userEmail($response, AccessToken $token)
{
return isset($response->emailAddress) && $response->emailAddress
? $response->emailAddress
: null;
}
public function userScreenName($response, AccessToken $token)
{
return [$response->firstName, $response->lastName];
];
}
}

51
src/Microsoft.php Normal file
View File

@ -0,0 +1,51 @@
<?php
namespace OAuth2;
class Microsoft extends AbstractProvider
{
public $scopes = ['wl.basic', 'wl.emails'];
public $responseType = 'json';
public function urlAuthorize()
{
return 'https://login.live.com/oauth20_authorize.srf';
}
public function urlAccessToken()
{
return 'https://login.live.com/oauth20_token.srf';
}
public function urlUserDetails(AccessToken $token)
{
return 'https://apis.live.net/v5.0/me?access_token='.$token;
}
public function userDetails($response, AccessToken $token)
{
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => 'https://apis.live.net/v5.0/'.$response->id.'/picture',
CURLOPT_FOLLOWLOCATION => 0,
CURLOPT_HEADER => 1,
CURLOPT_RETURNTRANSFER => 1,
]);
$redir = curl_exec($curl);
curl_close($curl);
preg_match('/^Location: (.*)$/im', $redir, $m);
$imageUrl = $m ? $m[1] : false;
$email = (isset($response->emails->preferred)) ? $response->emails->preferred : null;
return [
'uid' => $response->id,
'name' => $response->name,
'firstname' => $response->first_name,
'lastname' => $response->last_name,
'email' => $email,
'image_url' => $imageUrl,
'urls' => $response->link.'/cid-'.$response->id,
];
}
}

View File

@ -1,382 +0,0 @@
<?php
namespace League\OAuth2\Client\Provider;
use Closure;
use Guzzle\Http\Exception\BadResponseException;
use Guzzle\Service\Client as GuzzleClient;
use League\OAuth2\Client\Exception\IDPException as IDPException;
use League\OAuth2\Client\Grant\GrantInterface;
use League\OAuth2\Client\Token\AccessToken as AccessToken;
abstract class AbstractProvider implements ProviderInterface
{
public $clientId = '';
public $clientSecret = '';
public $redirectUri = '';
public $state;
public $name;
public $uidKey = 'uid';
public $scopes = [];
public $method = 'post';
public $scopeSeparator = ',';
public $responseType = 'json';
public $headers = [];
public $authorizationHeader;
/**
* @var GuzzleClient
*/
protected $httpClient;
protected $redirectHandler;
/**
* @var int This represents: PHP_QUERY_RFC1738, which is the default value for php 5.4
* and the default encryption type for the http_build_query setup
*/
protected $httpBuildEncType = 1;
public function __construct($options = [])
{
foreach ($options as $option => $value) {
if (property_exists($this, $option)) {
$this->{$option} = $value;
}
}
$this->setHttpClient(new GuzzleClient());
}
public function setHttpClient(GuzzleClient $client)
{
$this->httpClient = $client;
return $this;
}
public function getHttpClient()
{
$client = clone $this->httpClient;
return $client;
}
/**
* Get the URL that this provider uses to begin authorization.
*
* @return string
*/
abstract public function urlAuthorize();
/**
* Get the URL that this provider users to request an access token.
*
* @return string
*/
abstract public function urlAccessToken();
/**
* Get the URL that this provider uses to request user details.
*
* Since this URL is typically an authorized route, most providers will require you to pass the access_token as
* a parameter to the request. For example, the google url is:
*
* 'https://www.googleapis.com/oauth2/v1/userinfo?alt=json&access_token='.$token
*
* @param AccessToken $token
* @return string
*/
abstract public function urlUserDetails(AccessToken $token);
/**
* Given an object response from the server, process the user details into a format expected by the user
* of the client.
*
* @param object $response
* @param AccessToken $token
* @return mixed
*/
abstract public function userDetails($response, AccessToken $token);
public function getScopes()
{
return $this->scopes;
}
public function setScopes(array $scopes)
{
$this->scopes = $scopes;
}
public function getAuthorizationUrl($options = [])
{
$this->state = isset($options['state']) ? $options['state'] : md5(uniqid(rand(), true));
$params = [
'client_id' => $this->clientId,
'redirect_uri' => $this->redirectUri,
'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' => isset($options['approval_prompt']) ? $options['approval_prompt'] : 'auto',
];
return $this->urlAuthorize().'?'.$this->httpBuildQuery($params, '', '&');
}
// @codeCoverageIgnoreStart
public function authorize($options = [])
{
$url = $this->getAuthorizationUrl($options);
if ($this->redirectHandler) {
$handler = $this->redirectHandler;
return $handler($url);
}
// @codeCoverageIgnoreStart
header('Location: ' . $url);
exit;
// @codeCoverageIgnoreEnd
}
public function getAccessToken($grant = 'authorization_code', $params = [])
{
if (is_string($grant)) {
// PascalCase the grant. E.g: 'authorization_code' becomes 'AuthorizationCode'
$className = str_replace(' ', '', ucwords(str_replace(['-', '_'], ' ', $grant)));
$grant = 'League\\OAuth2\\Client\\Grant\\'.$className;
if (! class_exists($grant)) {
throw new \InvalidArgumentException('Unknown grant "'.$grant.'"');
}
$grant = new $grant();
} elseif (! $grant instanceof GrantInterface) {
$message = get_class($grant).' is not an instance of League\OAuth2\Client\Grant\GrantInterface';
throw new \InvalidArgumentException($message);
}
$defaultParams = [
'client_id' => $this->clientId,
'client_secret' => $this->clientSecret,
'redirect_uri' => $this->redirectUri,
'grant_type' => $grant,
];
$requestParams = $grant->prepRequestParams($defaultParams, $params);
try {
switch (strtoupper($this->method)) {
case 'GET':
// @codeCoverageIgnoreStart
// No providers included with this library use get but 3rd parties may
$client = $this->getHttpClient();
$client->setBaseUrl($this->urlAccessToken() . '?' . $this->httpBuildQuery($requestParams, '', '&'));
$request = $client->get(null, $this->getHeaders(), $requestParams)->send();
$response = $request->getBody();
break;
// @codeCoverageIgnoreEnd
case 'POST':
$client = $this->getHttpClient();
$client->setBaseUrl($this->urlAccessToken());
$request = $client->post(null, $this->getHeaders(), $requestParams)->send();
$response = $request->getBody();
break;
// @codeCoverageIgnoreStart
default:
throw new \InvalidArgumentException('Neither GET nor POST is specified for request');
// @codeCoverageIgnoreEnd
}
} catch (BadResponseException $e) {
// @codeCoverageIgnoreStart
$response = $e->getResponse()->getBody();
// @codeCoverageIgnoreEnd
}
switch ($this->responseType) {
case 'json':
$result = json_decode($response, true);
if (JSON_ERROR_NONE !== json_last_error()) {
$result = [];
}
break;
case 'string':
parse_str($response, $result);
break;
}
if (isset($result['error']) && ! empty($result['error'])) {
// @codeCoverageIgnoreStart
throw new IDPException($result);
// @codeCoverageIgnoreEnd
}
$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".
*
* @param array $result
*/
protected function setResultUid(array &$result)
{
// If we're operating with the default uidKey there's nothing to do.
if ($this->uidKey === "uid") {
return;
}
if (isset($result[$this->uidKey])) {
// The AccessToken expects a "uid" to have the key "uid".
$result['uid'] = $result[$this->uidKey];
}
}
public function getUserDetails(AccessToken $token)
{
$response = $this->fetchUserDetails($token);
return $this->userDetails(json_decode($response), $token);
}
public function getUserUid(AccessToken $token)
{
$response = $this->fetchUserDetails($token, true);
return $this->userUid(json_decode($response), $token);
}
public function getUserEmail(AccessToken $token)
{
$response = $this->fetchUserDetails($token, true);
return $this->userEmail(json_decode($response), $token);
}
public function getUserScreenName(AccessToken $token)
{
$response = $this->fetchUserDetails($token, true);
return $this->userScreenName(json_decode($response), $token);
}
public function userUid($response, AccessToken $token)
{
return isset($response->id) && $response->id ? $response->id : null;
}
public function userEmail($response, AccessToken $token)
{
return isset($response->email) && $response->email ? $response->email : null;
}
public function userScreenName($response, AccessToken $token)
{
return isset($response->name) && $response->name ? $response->name : null;
}
/**
* Build HTTP the HTTP query, handling PHP version control options
*
* @param array $params
* @param integer $numeric_prefix
* @param string $arg_separator
* @param null|integer $enc_type
*
* @return string
* @codeCoverageIgnoreStart
*/
protected function httpBuildQuery($params, $numeric_prefix = 0, $arg_separator = '&', $enc_type = null)
{
if (version_compare(PHP_VERSION, '5.4.0', '>=') && !defined('HHVM_VERSION')) {
if ($enc_type === null) {
$enc_type = $this->httpBuildEncType;
}
$url = http_build_query($params, $numeric_prefix, $arg_separator, $enc_type);
} else {
$url = http_build_query($params, $numeric_prefix, $arg_separator);
}
return $url;
}
protected function fetchUserDetails(AccessToken $token)
{
$url = $this->urlUserDetails($token);
$headers = $this->getHeaders($token);
return $this->fetchProviderData($url, $headers);
}
protected function fetchProviderData($url, array $headers = [])
{
try {
$client = $this->getHttpClient();
$client->setBaseUrl($url);
if ($headers) {
$client->setDefaultOption('headers', $headers);
}
$request = $client->get()->send();
$response = $request->getBody();
} catch (BadResponseException $e) {
// @codeCoverageIgnoreStart
$raw_response = explode("\n", $e->getResponse());
throw new IDPException(end($raw_response));
// @codeCoverageIgnoreEnd
}
return $response;
}
protected function getAuthorizationHeaders($token)
{
$headers = [];
if ($this->authorizationHeader) {
$headers['Authorization'] = $this->authorizationHeader . ' ' . $token;
}
return $headers;
}
public function getHeaders($token = null)
{
$headers = $this->headers;
if ($token) {
$headers = array_merge($headers, $this->getAuthorizationHeaders($token));
}
return $headers;
}
public function setRedirectHandler(Closure $handler)
{
$this->redirectHandler = $handler;
}
}

View File

@ -1,51 +0,0 @@
<?php
namespace League\OAuth2\Client\Provider;
use League\OAuth2\Client\Entity\User;
class Eventbrite extends AbstractProvider
{
public $authorizationHeader = 'Bearer';
public function urlAuthorize()
{
return 'https://www.eventbrite.com/oauth/authorize';
}
public function urlAccessToken()
{
return 'https://www.eventbrite.com/oauth/token';
}
public function urlUserDetails(\League\OAuth2\Client\Token\AccessToken $token)
{
return 'https://www.eventbrite.com/json/user_get';
}
public function userDetails($response, \League\OAuth2\Client\Token\AccessToken $token)
{
$user = new User();
$user->exchangeArray([
'uid' => $response->user->user_id,
'email' => $response->user->email,
]);
return $user;
}
public function userUid($response, \League\OAuth2\Client\Token\AccessToken $token)
{
return $response->user->user_id;
}
public function userEmail($response, \League\OAuth2\Client\Token\AccessToken $token)
{
return isset($response->user->email) && $response->user->email ? $response->user->email : null;
}
public function userScreenName($response, \League\OAuth2\Client\Token\AccessToken $token)
{
return $response->user->user_id;
}
}

View File

@ -1,58 +0,0 @@
<?php
namespace League\OAuth2\Client\Provider;
use League\OAuth2\Client\Entity\User;
class Instagram extends AbstractProvider
{
public $scopes = ['basic'];
public $responseType = 'json';
public function urlAuthorize()
{
return 'https://api.instagram.com/oauth/authorize';
}
public function urlAccessToken()
{
return 'https://api.instagram.com/oauth/access_token';
}
public function urlUserDetails(\League\OAuth2\Client\Token\AccessToken $token)
{
return 'https://api.instagram.com/v1/users/self?access_token='.$token;
}
public function userDetails($response, \League\OAuth2\Client\Token\AccessToken $token)
{
$user = new User();
$description = (isset($response->data->bio)) ? $response->data->bio : null;
$user->exchangeArray([
'uid' => $response->data->id,
'nickname' => $response->data->username,
'name' => $response->data->full_name,
'description' => $description,
'imageUrl' => $response->data->profile_picture,
]);
return $user;
}
public function userUid($response, \League\OAuth2\Client\Token\AccessToken $token)
{
return $response->data->id;
}
public function userEmail($response, \League\OAuth2\Client\Token\AccessToken $token)
{
return;
}
public function userScreenName($response, \League\OAuth2\Client\Token\AccessToken $token)
{
return $response->data->full_name;
}
}

View File

@ -1,69 +0,0 @@
<?php
namespace League\OAuth2\Client\Provider;
use League\OAuth2\Client\Entity\User;
use League\OAuth2\Client\Token\AccessToken;
class Microsoft extends AbstractProvider
{
public $scopes = ['wl.basic', 'wl.emails'];
public $responseType = 'json';
public function urlAuthorize()
{
return 'https://login.live.com/oauth20_authorize.srf';
}
public function urlAccessToken()
{
return 'https://login.live.com/oauth20_token.srf';
}
public function urlUserDetails(AccessToken $token)
{
return 'https://apis.live.net/v5.0/me?access_token='.$token;
}
public function userDetails($response, AccessToken $token)
{
$client = $this->getHttpClient();
$client->setBaseUrl('https://apis.live.net/v5.0/'.$response->id.'/picture');
$request = $client->get()->send();
$info = $request->getInfo();
$imageUrl = $info['url'];
$user = new User();
$email = (isset($response->emails->preferred)) ? $response->emails->preferred : null;
$user->exchangeArray([
'uid' => $response->id,
'name' => $response->name,
'firstname' => $response->first_name,
'lastname' => $response->last_name,
'email' => $email,
'imageurl' => $imageUrl,
'urls' => $response->link.'/cid-'.$response->id,
]);
return $user;
}
public function userUid($response, AccessToken $token)
{
return $response->id;
}
public function userEmail($response, AccessToken $token)
{
return isset($response->emails->preferred) && $response->emails->preferred
? $response->emails->preferred
: null;
}
public function userScreenName($response, AccessToken $token)
{
return [$response->first_name, $response->last_name];
}
}

View File

@ -1,36 +0,0 @@
<?php
namespace League\OAuth2\Client\Provider;
use League\OAuth2\Client\Token\AccessToken as AccessToken;
interface ProviderInterface
{
public function urlAuthorize();
public function urlAccessToken();
public function urlUserDetails(AccessToken $token);
public function userDetails($response, AccessToken $token);
public function getScopes();
public function setScopes(array $scopes);
public function getAuthorizationUrl($options = []);
public function authorize($options = []);
public function getAccessToken($grant = 'authorization_code', $params = []);
public function getHeaders($token = null);
public function getUserDetails(AccessToken $token);
public function getUserUid(AccessToken $token);
public function getUserEmail(AccessToken $token);
public function getUserScreenName(AccessToken $token);
}

View File

@ -1,9 +1,6 @@
<?php
namespace League\OAuth2\Client\Provider;
use League\OAuth2\Client\Entity\User;
use League\OAuth2\Client\Token\AccessToken;
namespace OAuth2;
class Vkontakte extends AbstractProvider
{
@ -21,7 +18,8 @@ class Vkontakte extends AbstractProvider
public function urlUserDetails(AccessToken $token)
{
$fields = ['nickname',
$fields = [
'nickname',
'screen_name',
'sex',
'bdate',
@ -45,7 +43,8 @@ class Vkontakte extends AbstractProvider
'can_post',
'universities',
'schools',
'verified', ];
'verified'
];
return "https://api.vk.com/method/users.get?user_id={$token->uid}&fields="
.implode(",", $fields)."&access_token={$token}";
@ -55,13 +54,11 @@ class Vkontakte extends AbstractProvider
{
$response = $response->response[0];
$user = new User();
$email = (isset($response->email)) ? $response->email : null;
$location = (isset($response->country)) ? $response->country : null;
$description = (isset($response->status)) ? $response->status : null;
$user->exchangeArray([
return [
'uid' => $response->uid,
'nickname' => $response->nickname,
'name' => $response->screen_name,
@ -70,30 +67,7 @@ class Vkontakte extends AbstractProvider
'email' => $email,
'location' => $location,
'description' => $description,
'imageUrl' => $response->photo_200_orig,
]);
return $user;
}
public function userUid($response, AccessToken $token)
{
$response = $response->response[0];
return $response->uid;
}
public function userEmail($response, AccessToken $token)
{
$response = $response->response[0];
return isset($response->email) && $response->email ? $response->email : null;
}
public function userScreenName($response, AccessToken $token)
{
$response = $response->response[0];
return [$response->first_name, $response->last_name];
'image_url' => $response->photo_200_orig,
];
}
}

View File

@ -1,6 +1,6 @@
<?php
namespace LeagueTests\OAuth2\Client;
namespace OAuth2;
error_reporting(E_ALL | E_STRICT);
chdir(__DIR__);

63
test/CurlMock.php Normal file
View File

@ -0,0 +1,63 @@
<?php
namespace OAuth2;
class CurlMock
{
static $pending = [];
static function addPendingResponse($exec_ok, $status_line, $headers, $body)
{
self::$pending[] = [ $exec_ok, $status_line, $headers, $body ];
}
var $options = [];
var $response = [];
function __construct($response)
{
$this->response = $response;
}
}
function curl_init()
{
if (!CurlMock::$pending)
{
return false;
}
return new CurlMock(array_shift(CurlMock::$pending));
}
function curl_setopt_array($curl, $array)
{
$curl->options = $array + $curl->options;
}
function curl_exec($curl)
{
if (!$curl->response[0])
{
return false;
}
if (!empty($curl->options[CURLOPT_RETURNTRANSFER]))
{
if (!empty($curl->options[CURLOPT_HEADER]))
{
return trim($curl->response[2])."\n\n".$curl->response[3];
}
return $curl->response[3];
}
return true;
}
function curl_close($curl)
{
}
function curl_getinfo($curl, $opt)
{
if ($opt == CURLINFO_HTTP_CODE)
{
return intval($curl->response[1]);
}
return false;
}

View File

@ -0,0 +1,119 @@
<?php
namespace OAuth2\Test;
class AbstractProviderTest extends \PHPUnit_Framework_TestCase
{
/**
* @var AbstractProvider
*/
protected $provider;
protected function setUp()
{
$this->provider = new \OAuth2\Google([
'clientId' => 'mock_client_id',
'clientSecret' => 'mock_secret',
'redirectUri' => 'none',
]);
}
public function testAuthorizationUrlStateParam()
{
$this->assertContains('state=XXX', $this->provider->getAuthorizationUrl([
'state' => 'XXX'
]));
}
/**
* Tests https://github.com/thephpleague/oauth2-client/issues/134
*/
public function testConstructorSetsProperties()
{
$options = [
'clientId' => '1234',
'clientSecret' => '4567',
'redirectUri' => 'http://example.org/redirect',
'state' => 'foo',
'name' => 'bar',
'uidKey' => 'mynewuid',
'scopes' => ['a', 'b', 'c'],
'method' => 'get',
'scopeSeparator' => ';',
'responseType' => 'csv',
'headers' => ['Foo' => 'Bar'],
'authorizationHeader' => 'Bearer',
];
$mockProvider = new MockProvider($options);
foreach ($options as $key => $value)
{
$this->assertEquals($value, $mockProvider->{$key});
}
}
public function testSetRedirectHandler()
{
$this->testFunction = false;
$callback = function ($url) {
$this->testFunction = $url;
};
$this->provider->setRedirectHandler($callback);
$this->provider->authorize('http://test.url/');
$this->assertNotFalse($this->testFunction);
}
public function getHeadersTest()
{
$provider = $this->getMockForAbstractClass(
'\OAuth2\AbstractProvider',
[
[
'clientId' => 'mock_client_id',
'clientSecret' => 'mock_secret',
'redirectUri' => 'none',
]
]
);
/**
* @var $provider AbstractProvider
*/
$this->assertEquals([], $provider->getHeaders());
$this->assertEquals([], $provider->getHeaders('mock_token'));
$provider->authorizationHeader = 'Bearer';
$this->assertEquals(['Authorization: Bearer abc'], $provider->getHeaders('abc'));
$token = new \OAuth2\AccessToken(['access_token' => 'xyz', 'expires_in' => 3600]);
$this->assertEquals(['Authorization: Bearer xyz'], $provider->getHeaders($token));
}
}
class MockProvider extends \OAuth2\AbstractProvider
{
public function urlAuthorize()
{
return '';
}
public function urlAccessToken()
{
return '';
}
public function urlUserDetails(\OAuth2\AccessToken $token)
{
return '';
}
public function userDetails($response, \OAuth2\AccessToken $token)
{
return '';
}
}

View File

@ -1,6 +1,6 @@
<?php
namespace League\OAuth2\Client\Test\Token;
namespace OAuth2\Test;
class AccessTokenTest extends \PHPUnit_Framework_TestCase
{
@ -9,13 +9,13 @@ class AccessTokenTest extends \PHPUnit_Framework_TestCase
*/
public function testInvalidRefreshToken()
{
new \League\OAuth2\Client\Token\AccessToken(['invalid_access_token' => 'none']);
new \OAuth2\AccessToken(['invalid_access_token' => 'none']);
}
public function testExpiresInCorrection()
{
$options = array('access_token' => 'access_token', 'expires_in' => 100);
$token = new \League\OAuth2\Client\Token\AccessToken($options);
$token = new \OAuth2\AccessToken($options);
$this->assertNotNull($token->expires);
}
}

View File

@ -1,8 +1,6 @@
<?php
namespace League\OAuth2\Client\Test\Grant;
use Mockery as m;
namespace OAuth2\Test;
class AuthorizationCodeTest extends \PHPUnit_Framework_TestCase
{
@ -10,25 +8,13 @@ class AuthorizationCodeTest extends \PHPUnit_Framework_TestCase
protected function setUp()
{
$this->provider = new \League\OAuth2\Client\Provider\Google([
$this->provider = new \OAuth2\Google([
'clientId' => 'mock_client_id',
'clientSecret' => 'mock_secret',
'redirectUri' => 'none',
]);
}
public function tearDown()
{
m::close();
parent::tearDown();
}
public function testGetAccessToken()
{
$grant = new \League\OAuth2\Client\Grant\AuthorizationCode();
$this->assertEquals('authorization_code', (string) $grant);
}
/**
* @expectedException BadMethodCallException
*/

View File

@ -0,0 +1,25 @@
<?php
namespace OAuth2\Test;
class ClientCredentialsTest extends \PHPUnit_Framework_TestCase
{
protected $provider;
protected function setUp()
{
$this->provider = new \OAuth2\Google(array(
'clientId' => 'mock_client_id',
'clientSecret' => 'mock_secret',
'redirectUri' => 'none',
));
}
public function testGetAccessToken()
{
\OAuth2\CurlMock::addPendingResponse(true, "200 OK", '', '{"access_token": "mock_access_token", "expires": 3600, "refresh_token": "mock_refresh_token", "uid": 1}');
$token = $this->provider->getAccessToken('client_credentials');
$this->assertInstanceOf('\OAuth2\AccessToken', $token);
}
}

View File

@ -1,64 +0,0 @@
<?php
namespace League\OAuth2\Client\Test\Entity;
use League\OAuth2\Client\Entity\User;
class UserTest extends \PHPUnit_Framework_TestCase
{
private $user;
private $userArray;
public function setUp()
{
$this->user = new User();
$this->userArray = [
'uid' => 'mock_uid',
'nickname' => 'mock_nickname',
'name' => 'mock_name',
'firstName' => 'mock_firstName',
'lastName' => 'mock_lastName',
'email' => 'mock_email',
'location' => 'mock_location',
'description' => 'mock_description',
'imageUrl' => 'mock_imageUrl',
'urls' => 'mock_urls',
'gender' => 'mock_gender',
'locale' => 'mock_locale',
];
}
public function testExchangeArrayGetArrayCopy()
{
$this->user->exchangeArray($this->userArray);
$this->assertEquals($this->userArray, $this->user->getArrayCopy());
}
public function testMagicMethos()
{
$this->user->exchangeArray($this->userArray);
$this->user->name = 'mock_change_test';
$this->assertTrue(isset($this->user->name));
$this->assertEquals('mock_change_test', $this->user->name);
}
/**
* @expectedException \OutOfRangeException
*/
public function testInvalidMagicSet()
{
$this->user->invalidProp = 'mock';
}
/**
* @expectedException \OutOfRangeException
*/
public function testInvalidMagicGet()
{
$this->user->invalidProp;
}
}

View File

@ -1,8 +1,6 @@
<?php
namespace League\OAuth2\Client\Test\Provider;
use Mockery as m;
namespace OAuth2\Test;
class EventbriteTest extends \PHPUnit_Framework_TestCase
{
@ -10,19 +8,13 @@ class EventbriteTest extends \PHPUnit_Framework_TestCase
protected function setUp()
{
$this->provider = new \League\OAuth2\Client\Provider\Eventbrite([
$this->provider = new \OAuth2\Eventbrite([
'clientId' => 'mock_client_id',
'clientSecret' => 'mock_secret',
'redirectUri' => 'none',
]);
}
public function tearDown()
{
m::close();
parent::tearDown();
}
public function testAuthorizationUrl()
{
$url = $this->provider->getAuthorizationUrl();
@ -48,13 +40,7 @@ class EventbriteTest extends \PHPUnit_Framework_TestCase
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}');
$client = m::mock('Guzzle\Service\Client');
$client->shouldReceive('setBaseUrl')->times(1);
$client->shouldReceive('post->send')->times(1)->andReturn($response);
$this->provider->setHttpClient($client);
\OAuth2\CurlMock::addPendingResponse(true, "200 OK", '', '{"access_token": "mock_access_token", "expires": 3600, "refresh_token": "mock_refresh_token", "uid": 1}');
$token = $this->provider->getAccessToken('authorization_code', ['code' => 'mock_authorization_code']);
@ -72,25 +58,13 @@ class EventbriteTest extends \PHPUnit_Framework_TestCase
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}');
$getResponse = m::mock('Guzzle\Http\Message\Response');
$getResponse->shouldReceive('getBody')->times(4)->andReturn('{"user": {"user_id": 12345, "email": "mock_email"}}');
$client = m::mock('Guzzle\Service\Client');
$client->shouldReceive('setBaseUrl')->times(5);
$client->shouldReceive('post->send')->times(1)->andReturn($postResponse);
$client->shouldReceive('get->send')->times(4)->andReturn($getResponse);
$client->shouldReceive('setDefaultOption')->times(4);
$this->provider->setHttpClient($client);
\OAuth2\CurlMock::addPendingResponse(true, "200 OK", '', '{"access_token": "mock_access_token", "expires": 3600, "refresh_token": "mock_refresh_token", "uid": 1}');
\OAuth2\CurlMock::addPendingResponse(true, "200 OK", '', '{"user": {"user_id": 12345, "email": "mock_email"}}');
$token = $this->provider->getAccessToken('authorization_code', ['code' => 'mock_authorization_code']);
$user = $this->provider->getUserDetails($token);
$this->assertEquals(12345, $this->provider->getUserUid($token));
$this->assertEquals('mock_email', $this->provider->getUserEmail($token));
$this->assertEquals(12345, $this->provider->getUserScreenName($token));
$this->assertEquals('mock_email', $user->email);
$this->assertEquals(12345, $user['uid']);
$this->assertEquals('mock_email', $user['email']);
}
}

View File

@ -1,81 +0,0 @@
<?php
namespace League\OAuth2\Client\Test\Exception;
use League\OAuth2\Client\Exception\IDPException;
class IDPExceptionTest extends \PHPUnit_Framework_TestCase
{
public function testGetTypeErrorMessage()
{
$exception = new IDPException(array('error' => 'message'));
$this->assertEquals('message', $exception->getType());
}
public function testGetTypeMessage()
{
$exception = new IDPException(array('message' => 'message'));
$this->assertEquals('Exception', $exception->getType());
}
public function testGetTypeEmpty()
{
$exception = new IDPException([]);
$this->assertEquals('Exception', $exception->getType());
}
public function testAsString()
{
$exception = new IDPException(array('error' => 'message'));
$this->assertEquals('message: message', (string)$exception);
}
public function testAsStringWithCode()
{
$exception = new IDPException(array('error' => 'message', 'code' => 404));
$this->assertEquals('message: 404: message', (string)$exception);
}
public function testGetResponseBody()
{
$exception = new IDPException(array('error' => 'message', 'code' => 404));
$this->assertEquals(
[
'error' => 'message',
'code' => 404
],
$exception->getResponseBody()
);
}
public function testEmptyMessage()
{
$exception = new IDPException(array('error' => 'error_message', 'message' => ''));
$this->assertEquals('error_message', $exception->getMessage());
}
public function testNonEmptyErrorAndMessage()
{
$exception = new IDPException(array('error' => 'error_message', 'message' => 'message'));
$this->assertEquals('error_message', $exception->getMessage());
}
public function testEmptyError()
{
$exception = new IDPException(array('error' => '', 'message' => 'message'));
$this->assertEquals('message', $exception->getMessage());
}
public function testEmptyErrorAndMessage()
{
$exception = new IDPException(array('error' => '', 'message' => ''));
$this->assertEquals('Unknown Error.', $exception->getMessage());
}
}

View File

@ -1,31 +1,20 @@
<?php
namespace League\OAuth2\Client\Test\Provider;
use Mockery as m;
namespace OAuth2\Test;
class FacebookTest extends \PHPUnit_Framework_TestCase
{
/**
* @var \League\OAuth2\Client\Provider\Facebook
*/
protected $provider;
protected function setUp()
{
$this->provider = new \League\OAuth2\Client\Provider\Facebook([
$this->provider = new \OAuth2\Facebook([
'clientId' => 'mock_client_id',
'clientSecret' => 'mock_secret',
'redirectUri' => 'none',
]);
}
public function tearDown()
{
m::close();
parent::tearDown();
}
public function testAuthorizationUrl()
{
$url = $this->provider->getAuthorizationUrl();
@ -45,7 +34,7 @@ class FacebookTest extends \PHPUnit_Framework_TestCase
{
$url = $this->provider->urlAccessToken();
$uri = parse_url($url);
$graphVersion = \League\OAuth2\Client\Provider\Facebook::DEFAULT_GRAPH_VERSION;
$graphVersion = \OAuth2\Facebook::DEFAULT_GRAPH_VERSION;
$this->assertEquals('/'.$graphVersion.'/oauth/access_token', $uri['path']);
}
@ -53,10 +42,10 @@ class FacebookTest extends \PHPUnit_Framework_TestCase
public function testGraphApiVersionCanBeCustomized()
{
$graphVersion = 'v13.37';
$provider = new \League\OAuth2\Client\Provider\Facebook([
$provider = new \OAuth2\Facebook([
'graphApiVersion' => $graphVersion,
]);
$fooToken = new \League\OAuth2\Client\Token\AccessToken(['access_token' => 'foo_token']);
$fooToken = new \OAuth2\AccessToken(['access_token' => 'foo_token']);
$urlAuthorize = $provider->urlAuthorize();
$urlAccessToken = $provider->urlAccessToken();
@ -69,8 +58,8 @@ class FacebookTest extends \PHPUnit_Framework_TestCase
public function testGraphApiVersionWillFallbackToDefault()
{
$graphVersion = \League\OAuth2\Client\Provider\Facebook::DEFAULT_GRAPH_VERSION;
$fooToken = new \League\OAuth2\Client\Token\AccessToken(['access_token' => 'foo_token']);
$graphVersion = \OAuth2\Facebook::DEFAULT_GRAPH_VERSION;
$fooToken = new \OAuth2\AccessToken(['access_token' => 'foo_token']);
$urlAuthorize = $this->provider->urlAuthorize();
$urlAccessToken = $this->provider->urlAccessToken();
@ -83,13 +72,7 @@ class FacebookTest extends \PHPUnit_Framework_TestCase
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');
$client = m::mock('Guzzle\Service\Client');
$client->shouldReceive('setBaseUrl')->times(1);
$client->shouldReceive('post->send')->times(1)->andReturn($response);
$this->provider->setHttpClient($client);
\OAuth2\CurlMock::addPendingResponse(true, "200 OK", '', 'access_token=mock_access_token&expires=3600&refresh_token=mock_refresh_token&uid=1');
$token = $this->provider->getAccessToken('authorization_code', ['code' => 'mock_authorization_code']);
@ -107,25 +90,16 @@ class FacebookTest extends \PHPUnit_Framework_TestCase
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');
$getResponse = m::mock('Guzzle\Http\Message\Response');
$getResponse->shouldReceive('getBody')->andReturn('{"id": 12345, "name": "mock_name", "username": "mock_username", "first_name": "mock_first_name", "last_name": "mock_last_name", "email": "mock_email", "Location": "mock_home", "bio": "mock_description", "link": "mock_facebook_url"}');
$getResponse->shouldReceive('getInfo')->andReturn(['url' => 'mock_image_url']);
$client = m::mock('Guzzle\Service\Client');
$client->shouldReceive('setBaseUrl')->times(5);
$client->shouldReceive('post->send')->times(1)->andReturn($postResponse);
$client->shouldReceive('get->send')->andReturn($getResponse);
$this->provider->setHttpClient($client);
\OAuth2\CurlMock::addPendingResponse(true, "200 OK", '', 'access_token=mock_access_token&expires=3600&refresh_token=mock_refresh_token&uid=1');
\OAuth2\CurlMock::addPendingResponse(true, "200 OK", '', '{"id": 12345, "name": "mock_name", "username": "mock_username", "first_name": "mock_first_name", "last_name": "mock_last_name", "email": "mock_email", "Location": "mock_home", "bio": "mock_description", "link": "mock_facebook_url", "picture": {"data":{"url":"mock_image_url"}}}');
$token = $this->provider->getAccessToken('authorization_code', ['code' => 'mock_authorization_code']);
$user = $this->provider->getUserDetails($token);
$this->assertEquals(12345, $this->provider->getUserUid($token));
$this->assertEquals(['mock_first_name', 'mock_last_name'], $this->provider->getUserScreenName($token));
$this->assertEquals('mock_email', $this->provider->getUserEmail($token));
$this->assertEquals('mock_email', $user->email);
$this->assertEquals(12345, $user['uid']);
$this->assertEquals('mock_first_name', $user['firstname']);
$this->assertEquals('mock_last_name', $user['lastname']);
$this->assertEquals('mock_email', $user['email']);
$this->assertEquals('mock_image_url', $user['image_url']);
}
}

View File

@ -1,8 +1,6 @@
<?php
namespace League\OAuth2\Client\Test\Provider;
use Mockery as m;
namespace OAuth2\Test;
class GithubTest extends \PHPUnit_Framework_TestCase
{
@ -10,19 +8,13 @@ class GithubTest extends \PHPUnit_Framework_TestCase
protected function setUp()
{
$this->provider = new \League\OAuth2\Client\Provider\Github([
$this->provider = new \OAuth2\Github([
'clientId' => 'mock',
'clientSecret' => 'mock_secret',
'redirectUri' => 'none',
]);
}
public function tearDown()
{
m::close();
parent::tearDown();
}
public function testAuthorizationUrl()
{
$url = $this->provider->getAuthorizationUrl();
@ -48,13 +40,7 @@ class GithubTest extends \PHPUnit_Framework_TestCase
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');
$client = m::mock('Guzzle\Service\Client');
$client->shouldReceive('setBaseUrl')->times(1);
$client->shouldReceive('post->send')->times(1)->andReturn($response);
$this->provider->setHttpClient($client);
\OAuth2\CurlMock::addPendingResponse(true, "200 OK", '', 'access_token=mock_access_token&expires=3600&refresh_token=mock_refresh_token&uid=1');
$token = $this->provider->getAccessToken('authorization_code', ['code' => 'mock_authorization_code']);
@ -72,13 +58,8 @@ class GithubTest extends \PHPUnit_Framework_TestCase
*/
public function testGetAccessTokenWithInvalidJson()
{
$response = m::mock('Guzzle\Http\Message\Response');
$response->shouldReceive('getBody')->times(1)->andReturn('invalid');
\OAuth2\CurlMock::addPendingResponse(true, "200 OK", '', 'invalid');
$client = m::mock('Guzzle\Service\Client');
$client->shouldReceive('setBaseUrl')->times(1);
$client->shouldReceive('post->send')->times(1)->andReturn($response);
$this->provider->setHttpClient($client);
$this->provider->responseType = 'json';
$this->provider->getAccessToken('authorization_code', ['code' => 'mock_authorization_code']);
@ -88,13 +69,7 @@ class GithubTest extends \PHPUnit_Framework_TestCase
{
$this->provider->uidKey = 'otherKey';
$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 = m::mock('Guzzle\Service\Client');
$client->shouldReceive('setBaseUrl')->times(1);
$client->shouldReceive('post->send')->times(1)->andReturn($response);
$this->provider->setHttpClient($client);
\OAuth2\CurlMock::addPendingResponse(true, "200 OK", '', 'access_token=mock_access_token&expires=3600&refresh_token=mock_refresh_token&otherKey={1234}');
$token = $this->provider->getAccessToken('authorization_code', ['code' => 'mock_authorization_code']);
@ -113,37 +88,21 @@ class GithubTest extends \PHPUnit_Framework_TestCase
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');
$getResponse = m::mock('Guzzle\Http\Message\Response');
$getResponse->shouldReceive('getBody')->times(4)->andReturn('{"id": 12345, "login": "mock_login", "name": "mock_name", "email": "mock_email"}');
$client = m::mock('Guzzle\Service\Client');
$client->shouldReceive('setBaseUrl')->times(5);
$client->shouldReceive('setDefaultOption')->times(4);
$client->shouldReceive('post->send')->times(1)->andReturn($postResponse);
$client->shouldReceive('get->send')->times(4)->andReturn($getResponse);
$this->provider->setHttpClient($client);
\OAuth2\CurlMock::addPendingResponse(true, "200 OK", '', 'access_token=mock_access_token&expires=3600&refresh_token=mock_refresh_token&uid=1');
\OAuth2\CurlMock::addPendingResponse(true, "200 OK", '', '{"id": 12345, "login": "mock_login", "name": "mock_name", "email": "mock_email"}');
$token = $this->provider->getAccessToken('authorization_code', ['code' => 'mock_authorization_code']);
$user = $this->provider->getUserDetails($token);
$this->assertEquals(12345, $this->provider->getUserUid($token));
$this->assertEquals('mock_name', $this->provider->getUserScreenName($token));
$this->assertEquals('mock_name', $user->name);
$this->assertEquals('mock_email', $this->provider->getUserEmail($token));
$this->assertEquals(12345, $user['uid']);
$this->assertEquals('mock_name', $user['name']);
$this->assertEquals('mock_email', $user['email']);
}
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}');
\OAuth2\CurlMock::addPendingResponse(true, "200 OK", '', '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());
@ -156,13 +115,8 @@ class GithubTest extends \PHPUnit_Framework_TestCase
{
$this->provider->domain = 'https://github.company.com';
$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}');
\OAuth2\CurlMock::addPendingResponse(true, "200 OK", '', '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());
@ -173,21 +127,12 @@ class GithubTest extends \PHPUnit_Framework_TestCase
public function testUserEmails()
{
$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');
$getResponse = m::mock('Guzzle\Http\Message\Response');
$getResponse->shouldReceive('getBody')->times(1)->andReturn('[{"email":"mock_email_1","primary":false,"verified":true},{"email":"mock_email_2","primary":false,"verified":true},{"email":"mock_email_3","primary":true,"verified":true}]');
$client = m::mock('Guzzle\Service\Client');
$client->shouldReceive('setBaseUrl')->times(2);
$client->shouldReceive('setDefaultOption')->times(1);
$client->shouldReceive('post->send')->times(1)->andReturn($postResponse);
$client->shouldReceive('get->send')->times(1)->andReturn($getResponse);
$this->provider->setHttpClient($client);
\OAuth2\CurlMock::addPendingResponse(true, "200 OK", '', 'access_token=mock_access_token&expires=3600&refresh_token=mock_refresh_token&uid=1');
\OAuth2\CurlMock::addPendingResponse(true, "200 OK", '', '[{"email":"mock_email_1","primary":false,"verified":true},{"email":"mock_email_2","primary":false,"verified":true},{"email":"mock_email_3","primary":true,"verified":true}]');
$token = $this->provider->getAccessToken('authorization_code', ['code' => 'mock_authorization_code']);
$emails = $this->provider->getUserEmails($token);
$this->assertInternalType('array', $emails);
$this->assertCount(3, $emails);
$this->assertEquals('mock_email_3', $emails[2]->email);

View File

@ -1,8 +1,6 @@
<?php
namespace League\OAuth2\Client\Test\Provider;
use Mockery as m;
namespace OAuth2\Test;
class GoogleTest extends \PHPUnit_Framework_TestCase
{
@ -10,7 +8,7 @@ class GoogleTest extends \PHPUnit_Framework_TestCase
protected function setUp()
{
$this->provider = new \League\OAuth2\Client\Provider\Google([
$this->provider = new \OAuth2\Google([
'clientId' => 'mock_client_id',
'clientSecret' => 'mock_secret',
'redirectUri' => 'none',
@ -19,12 +17,6 @@ class GoogleTest extends \PHPUnit_Framework_TestCase
]);
}
public function tearDown()
{
m::close();
parent::tearDown();
}
public function testAuthorizationUrl()
{
$url = $this->provider->getAuthorizationUrl();
@ -52,13 +44,7 @@ class GoogleTest extends \PHPUnit_Framework_TestCase
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}');
$client = m::mock('Guzzle\Service\Client');
$client->shouldReceive('setBaseUrl')->times(1);
$client->shouldReceive('post->send')->times(1)->andReturn($response);
$this->provider->setHttpClient($client);
\OAuth2\CurlMock::addPendingResponse(true, "200 OK", '', '{"access_token": "mock_access_token", "expires": 3600, "refresh_token": "mock_refresh_token", "uid": 1}');
$token = $this->provider->getAccessToken('authorization_code', ['code' => 'mock_authorization_code']);
@ -76,26 +62,16 @@ class GoogleTest extends \PHPUnit_Framework_TestCase
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}');
$getResponse = m::mock('Guzzle\Http\Message\Response');
$getResponse->shouldReceive('getBody')->times(4)->andReturn('{"emails": [{"value": "mock_email"}],"id": "12345","displayName": "mock_name","name": {"familyName": "mock_last_name","givenName": "mock_first_name"},"image": {"url": "mock_image_url"}}');
$client = m::mock('Guzzle\Service\Client');
$client->shouldReceive('setBaseUrl')->times(5);
$client->shouldReceive('setDefaultOption')->times(4);
$client->shouldReceive('post->send')->times(1)->andReturn($postResponse);
$client->shouldReceive('get->send')->times(4)->andReturn($getResponse);
$this->provider->setHttpClient($client);
\OAuth2\CurlMock::addPendingResponse(true, "200 OK", '', '{"access_token": "mock_access_token", "expires": 3600, "refresh_token": "mock_refresh_token", "uid": 1}');
\OAuth2\CurlMock::addPendingResponse(true, "200 OK", '', '{"emails": [{"value": "mock_email"}],"id": "12345","displayName": "mock_name","name": {"familyName": "mock_last_name","givenName": "mock_first_name"},"image": {"url": "mock_image_url"}}');
$token = $this->provider->getAccessToken('authorization_code', ['code' => 'mock_authorization_code']);
$user = $this->provider->getUserDetails($token);
$this->assertEquals(12345, $this->provider->getUserUid($token));
$this->assertEquals(['mock_first_name', 'mock_last_name'], $this->provider->getUserScreenName($token));
$this->assertEquals('mock_email', $this->provider->getUserEmail($token));
$this->assertEquals('mock_email', $user->email);
$this->assertEquals(12345, $user['uid']);
$this->assertEquals('mock_first_name', $user['firstname']);
$this->assertEquals('mock_last_name', $user['lastname']);
$this->assertEquals('mock_email', $user['email']);
}
public function testGetHostedDomain()

View File

@ -1,42 +0,0 @@
<?php
namespace League\OAuth2\Client\Test\Grant;
use Mockery as m;
class ClientCredentialsTest extends \PHPUnit_Framework_TestCase
{
protected $provider;
protected function setUp()
{
$this->provider = new \League\OAuth2\Client\Provider\Google(array(
'clientId' => 'mock_client_id',
'clientSecret' => 'mock_secret',
'redirectUri' => 'none',
));
}
public function tearDown()
{
m::close();
parent::tearDown();
}
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}');
$client = m::mock('Guzzle\Service\Client');
$client->shouldReceive('setBaseUrl')->times(1);
$client->shouldReceive('post->send')->times(1)->andReturn($response);
$this->provider->setHttpClient($client);
$token = $this->provider->getAccessToken('client_credentials');
$this->assertInstanceOf('League\OAuth2\Client\Token\AccessToken', $token);
$grant = new \League\OAuth2\Client\Grant\ClientCredentials();
$this->assertEquals('client_credentials', (string) $grant);
}
}

View File

@ -1,64 +0,0 @@
<?php
namespace League\OAuth2\Client\Test\Grant;
use Mockery as m;
class RefreshTokenTest extends \PHPUnit_Framework_TestCase
{
protected $provider;
protected function setUp()
{
$this->provider = new \League\OAuth2\Client\Provider\Google([
'clientId' => 'mock_client_id',
'clientSecret' => 'mock_secret',
'redirectUri' => 'none',
]);
}
public function tearDown()
{
m::close();
parent::tearDown();
}
public function testGetAccessToken()
{
$response = m::mock('Guzzle\Http\Message\Response');
$response->shouldReceive('getBody')->times(2)->andReturn('{"access_token": "mock_access_token", "expires": 3600, "refresh_token": "mock_refresh_token", "uid": 1}');
$client = m::mock('Guzzle\Service\Client');
$client->shouldReceive('setBaseUrl')->times(2);
$client->shouldReceive('post->send')->times(2)->andReturn($response);
$this->provider->setHttpClient($client);
$token = $this->provider->getAccessToken('authorization_code', ['code' => 'mock_authorization_code']);
$this->assertInstanceOf('League\OAuth2\Client\Token\AccessToken', $token);
$grant = new \League\OAuth2\Client\Grant\RefreshToken();
$this->assertEquals('refresh_token', (string) $grant);
$newToken = $this->provider->getAccessToken($grant, ['refresh_token' => $token->refreshToken]);
$this->assertInstanceOf('League\OAuth2\Client\Token\AccessToken', $newToken);
}
/**
* @expectedException BadMethodCallException
*/
public function testInvalidRefreshToken()
{
$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}');
$client = m::mock('Guzzle\Service\Client');
$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']);
$grant = new \League\OAuth2\Client\Grant\RefreshToken();
$refreshToken = $this->provider->getAccessToken($grant, ['invalid_refresh_token' => $token->refreshToken]);
}
}

View File

@ -1,8 +1,6 @@
<?php
namespace League\OAuth2\Client\Test\Provider;
use Mockery as m;
namespace OAuth2\Test;
class InstagramTest extends \PHPUnit_Framework_TestCase
{
@ -10,19 +8,13 @@ class InstagramTest extends \PHPUnit_Framework_TestCase
protected function setUp()
{
$this->provider = new \League\OAuth2\Client\Provider\Instagram([
$this->provider = new \OAuth2\Instagram([
'clientId' => 'mock_client_id',
'clientSecret' => 'mock_secret',
'redirectUri' => 'none',
]);
}
public function tearDown()
{
m::close();
parent::tearDown();
}
public function testAuthorizationUrl()
{
$url = $this->provider->getAuthorizationUrl();
@ -48,18 +40,10 @@ class InstagramTest extends \PHPUnit_Framework_TestCase
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}');
$client = m::mock('Guzzle\Service\Client');
$client->shouldReceive('setBaseUrl')->times(1);
$client->shouldReceive('post->send')->times(1)->andReturn($response);
$this->provider->setHttpClient($client);
\OAuth2\CurlMock::addPendingResponse(true, "200 OK", '', '{"access_token": "mock_access_token", "expires": 3600, "refresh_token": "mock_refresh_token", "uid": 1}');
$token = $this->provider->getAccessToken('authorization_code', ['code' => 'mock_authorization_code']);
# print_r($token);die();
$this->assertEquals('mock_access_token', $token->accessToken);
$this->assertLessThanOrEqual(time() + 3600, $token->expires);
$this->assertGreaterThanOrEqual(time(), $token->expires);
@ -74,24 +58,14 @@ class InstagramTest extends \PHPUnit_Framework_TestCase
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}');
$getResponse = m::mock('Guzzle\Http\Message\Response');
$getResponse->shouldReceive('getBody')->times(4)->andReturn('{"data": {"id": "12345", "username": "mock_username", "full_name": "mock_full_name", "bio": "mock_bio", "profile_picture": "mock_profile_picture"}}');
$client = m::mock('Guzzle\Service\Client');
$client->shouldReceive('setBaseUrl')->times(5);
$client->shouldReceive('post->send')->times(1)->andReturn($postResponse);
$client->shouldReceive('get->send')->times(4)->andReturn($getResponse);
$this->provider->setHttpClient($client);
\OAuth2\CurlMock::addPendingResponse(true, "200 OK", '', '{"access_token": "mock_access_token", "expires": 3600, "refresh_token": "mock_refresh_token", "uid": 1}');
\OAuth2\CurlMock::addPendingResponse(true, "200 OK", '', '{"data": {"id": "12345", "username": "mock_username", "full_name": "mock_full_name", "bio": "mock_bio", "profile_picture": "mock_profile_picture"}}');
$token = $this->provider->getAccessToken('authorization_code', ['code' => 'mock_authorization_code']);
$user = $this->provider->getUserDetails($token);
$this->assertEquals(12345, $this->provider->getUserUid($token));
$this->assertEquals('mock_full_name', $this->provider->getUserScreenName($token));
$this->assertEquals(null, $this->provider->getUserEmail($token));
$this->assertEquals(null, $user->email);
$this->assertEquals(12345, $user['uid']);
$this->assertEquals('mock_full_name', $user['name']);
$this->assertEquals(true, !isset($user['email']));
}
}

72
test/src/LinkedInTest.php Normal file
View File

@ -0,0 +1,72 @@
<?php
namespace OAuth2\Test;
class LinkedInTest extends \PHPUnit_Framework_TestCase
{
protected $provider;
protected function setUp()
{
$this->provider = new \OAuth2\LinkedIn([
'clientId' => 'mock_client_id',
'clientSecret' => 'mock_secret',
'redirectUri' => 'none',
]);
}
public function testAuthorizationUrl()
{
$url = $this->provider->getAuthorizationUrl();
$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('response_type', $query);
$this->assertArrayHasKey('approval_prompt', $query);
$this->assertNotNull($this->provider->state);
}
public function testUrlAccessToken()
{
$url = $this->provider->urlAccessToken();
$uri = parse_url($url);
$this->assertEquals('/uas/oauth2/accessToken', $uri['path']);
}
public function testGetAccessToken()
{
\OAuth2\CurlMock::addPendingResponse(true, "200 OK", '', '{"access_token": "mock_access_token", "expires": 3600, "refresh_token": "mock_refresh_token", "uid": 1}');
$token = $this->provider->getAccessToken('authorization_code', ['code' => 'mock_authorization_code']);
$this->assertEquals('mock_access_token', $token->accessToken);
$this->assertLessThanOrEqual(time() + 3600, $token->expires);
$this->assertGreaterThanOrEqual(time(), $token->expires);
$this->assertEquals('mock_refresh_token', $token->refreshToken);
$this->assertEquals('1', $token->uid);
}
public function testScopes()
{
$this->assertEquals(['r_basicprofile r_emailaddress r_contactinfo'], $this->provider->getScopes());
}
public function testUserData()
{
\OAuth2\CurlMock::addPendingResponse(true, "200 OK", '', '{"access_token": "mock_access_token", "expires": 3600, "refresh_token": "mock_refresh_token", "uid": 1}');
\OAuth2\CurlMock::addPendingResponse(true, "200 OK", '', '{"id": 12345, "firstName": "mock_first_name", "lastName": "mock_last_name", "emailAddress": "mock_email", "location": { "name": "mock_location" }, "headline": "mock_headline", "pictureUrl": "mock_picture_url", "publicProfileUrl": "mock_profile_url"}');
$token = $this->provider->getAccessToken('authorization_code', ['code' => 'mock_authorization_code']);
$user = $this->provider->getUserDetails($token);
$this->assertEquals(12345, $user['uid']);
$this->assertEquals('mock_first_name', $user['firstname']);
$this->assertEquals('mock_last_name', $user['lastname']);
$this->assertEquals('mock_email', $user['email']);
}
}

View File

@ -1,8 +1,6 @@
<?php
namespace League\OAuth2\Client\Test\Provider;
use Mockery as m;
namespace OAuth2\Test;
class MicrosoftTest extends \PHPUnit_Framework_TestCase
{
@ -10,19 +8,13 @@ class MicrosoftTest extends \PHPUnit_Framework_TestCase
protected function setUp()
{
$this->provider = new \League\OAuth2\Client\Provider\Microsoft([
$this->provider = new \OAuth2\Microsoft([
'clientId' => 'mock_client_id',
'clientSecret' => 'mock_secret',
'redirectUri' => 'none',
]);
}
public function tearDown()
{
m::close();
parent::tearDown();
}
public function testAuthorizationUrl()
{
$url = $this->provider->getAuthorizationUrl();
@ -56,18 +48,10 @@ class MicrosoftTest extends \PHPUnit_Framework_TestCase
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}');
$client = m::mock('Guzzle\Service\Client');
$client->shouldReceive('setBaseUrl')->times(1);
$client->shouldReceive('post->send')->times(1)->andReturn($response);
$this->provider->setHttpClient($client);
\OAuth2\CurlMock::addPendingResponse(true, "200 OK", '', '{"access_token": "mock_access_token", "expires": 3600, "refresh_token": "mock_refresh_token", "uid": 1}');
$token = $this->provider->getAccessToken('authorization_code', ['code' => 'mock_authorization_code']);
# print_r($token);die();
$this->assertEquals('mock_access_token', $token->accessToken);
$this->assertLessThanOrEqual(time() + 3600, $token->expires);
$this->assertGreaterThanOrEqual(time(), $token->expires);
@ -82,27 +66,17 @@ class MicrosoftTest extends \PHPUnit_Framework_TestCase
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}');
$getResponse = m::mock('Guzzle\Http\Message\Response');
$getResponse->shouldReceive('getBody')->times(4)->andReturn('{"id": 12345, "name": "mock_name", "first_name": "mock_first_name", "last_name": "mock_last_name", "emails": {"preferred": "mock_email"}, "link": "mock_link"}');
$getResponse->shouldReceive('getInfo')->andReturn(array('url' => 'mock_image_url'));
$client = m::mock('Guzzle\Service\Client');
$client->shouldReceive('setBaseUrl')->times(6);
$client->shouldReceive('post->send')->times(1)->andReturn($postResponse);
$client->shouldReceive('get->send')->times(5)->andReturn($getResponse);
$this->provider->setHttpClient($client);
\OAuth2\CurlMock::addPendingResponse(true, "200 OK", '', '{"access_token": "mock_access_token", "expires": 3600, "refresh_token": "mock_refresh_token", "uid": 1}');
\OAuth2\CurlMock::addPendingResponse(true, "200 OK", '', '{"id": 12345, "name": "mock_name", "first_name": "mock_first_name", "last_name": "mock_last_name", "emails": {"preferred": "mock_email"}, "link": "mock_link"}');
\OAuth2\CurlMock::addPendingResponse(true, "302 Found", 'Location: mock_image_url', '');
$token = $this->provider->getAccessToken('authorization_code', ['code' => 'mock_authorization_code']);
$user = $this->provider->getUserDetails($token);
$this->assertEquals(12345, $this->provider->getUserUid($token));
$this->assertEquals(['mock_first_name', 'mock_last_name'], $this->provider->getUserScreenName($token));
$this->assertEquals('mock_email', $this->provider->getUserEmail($token));
$this->assertEquals('mock_email', $user->email);
$this->assertEquals('mock_image_url', $user->imageUrl);
$this->assertEquals(12345, $user['uid']);
$this->assertEquals('mock_first_name', $user['firstname']);
$this->assertEquals('mock_last_name', $user['lastname']);
$this->assertEquals('mock_email', $user['email']);
$this->assertEquals('mock_image_url', $user['image_url']);
}
}

View File

@ -1,8 +1,6 @@
<?php
namespace League\OAuth2\Client\Test\Grant;
use Mockery as m;
namespace OAuth2\Test;
class PasswordTest extends \PHPUnit_Framework_TestCase
{
@ -10,34 +8,19 @@ class PasswordTest extends \PHPUnit_Framework_TestCase
protected function setUp()
{
$this->provider = new \League\OAuth2\Client\Provider\Google(array(
$this->provider = new \OAuth2\Google(array(
'clientId' => 'mock_client_id',
'clientSecret' => 'mock_secret',
'redirectUri' => 'none',
));
}
public function tearDown()
{
m::close();
parent::tearDown();
}
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}');
$client = m::mock('Guzzle\Service\Client');
$client->shouldReceive('setBaseUrl')->times(1);
$client->shouldReceive('post->send')->times(1)->andReturn($response);
$this->provider->setHttpClient($client);
\OAuth2\CurlMock::addPendingResponse(true, "200 OK", '', '{"access_token": "mock_access_token", "expires": 3600, "refresh_token": "mock_refresh_token", "uid": 1}');
$token = $this->provider->getAccessToken('password', array('username' => 'mock_username', 'password' => 'mock_password'));
$this->assertInstanceOf('League\OAuth2\Client\Token\AccessToken', $token);
$grant = new \League\OAuth2\Client\Grant\Password();
$this->assertEquals('password', (string) $grant);
$this->assertInstanceOf('\OAuth2\AccessToken', $token);
}
/**

View File

@ -1,195 +0,0 @@
<?php
namespace League\OAuth2\Client\Test\Provider;
use League\OAuth2\Client\Provider\AbstractProvider;
use League\OAuth2\Client\Token\AccessToken;
use Mockery as m;
class AbstractProviderTest extends \PHPUnit_Framework_TestCase
{
/**
* @var AbstractProvider
*/
protected $provider;
protected function setUp()
{
$this->provider = new \League\OAuth2\Client\Provider\Google([
'clientId' => 'mock_client_id',
'clientSecret' => 'mock_secret',
'redirectUri' => 'none',
]);
}
public function tearDown()
{
m::close();
parent::tearDown();
}
/**
* @expectedException InvalidArgumentException
*/
public function testInvalidGrantString()
{
$this->provider->getAccessToken('invalid_grant', ['invalid_parameter' => 'none']);
}
/**
* @expectedException InvalidArgumentException
*/
public function testInvalidGrantObject()
{
$grant = new \StdClass();
$this->provider->getAccessToken($grant, ['invalid_parameter' => 'none']);
}
public function testAuthorizationUrlStateParam()
{
$this->assertContains('state=XXX', $this->provider->getAuthorizationUrl([
'state' => 'XXX'
]));
}
/**
* Tests https://github.com/thephpleague/oauth2-client/issues/134
*/
public function testConstructorSetsProperties()
{
$options = [
'clientId' => '1234',
'clientSecret' => '4567',
'redirectUri' => 'http://example.org/redirect',
'state' => 'foo',
'name' => 'bar',
'uidKey' => 'mynewuid',
'scopes' => ['a', 'b', 'c'],
'method' => 'get',
'scopeSeparator' => ';',
'responseType' => 'csv',
'headers' => ['Foo' => 'Bar'],
'authorizationHeader' => 'Bearer',
];
$mockProvider = new MockProvider($options);
foreach ($options as $key => $value) {
$this->assertEquals($value, $mockProvider->{$key});
}
}
public function testSetRedirectHandler()
{
$this->testFunction = false;
$callback = function ($url) {
$this->testFunction = $url;
};
$this->provider->setRedirectHandler($callback);
$this->provider->authorize('http://test.url/');
$this->assertNotFalse($this->testFunction);
}
/**
* @param $response
*
* @dataProvider userPropertyProvider
*/
public function testGetUserProperties($response, $name = null, $email = null, $id = null)
{
$token = new AccessToken(['access_token' => 'abc', 'expires_in' => 3600]);
$provider = $this->getMockForAbstractClass(
'\League\OAuth2\Client\Provider\AbstractProvider',
[
[
'clientId' => 'mock_client_id',
'clientSecret' => 'mock_secret',
'redirectUri' => 'none',
]
]
);
/**
* @var $provider AbstractProvider
*/
$this->assertEquals($name, $provider->userScreenName($response, $token));
$this->assertEquals($email, $provider->userEmail($response, $token));
$this->assertEquals($id, $provider->userUid($response, $token));
}
public function userPropertyProvider()
{
$response = new \stdClass();
$response->id = 1;
$response->email = 'test@example.com';
$response->name = 'test';
$response2 = new \stdClass();
$response2->id = null;
$response2->email = null;
$response2->name = null;
$response3 = new \stdClass();
return [
[$response, 'test', 'test@example.com', 1],
[$response2],
[$response3],
];
}
public function getHeadersTest()
{
$provider = $this->getMockForAbstractClass(
'\League\OAuth2\Client\Provider\AbstractProvider',
[
[
'clientId' => 'mock_client_id',
'clientSecret' => 'mock_secret',
'redirectUri' => 'none',
]
]
);
/**
* @var $provider AbstractProvider
*/
$this->assertEquals([], $provider->getHeaders());
$this->assertEquals([], $provider->getHeaders('mock_token'));
$provider->authorizationHeader = 'Bearer';
$this->assertEquals(['Authorization' => 'Bearer abc'], $provider->getHeaders('abc'));
$token = new AccessToken(['access_token' => 'xyz', 'expires_in' => 3600]);
$this->assertEquals(['Authorization' => 'Bearer xyz'], $provider->getHeaders($token));
}
}
class MockProvider extends \League\OAuth2\Client\Provider\AbstractProvider
{
public function urlAuthorize()
{
return '';
}
public function urlAccessToken()
{
return '';
}
public function urlUserDetails(\League\OAuth2\Client\Token\AccessToken $token)
{
return '';
}
public function userDetails($response, \League\OAuth2\Client\Token\AccessToken $token)
{
return '';
}
}

View File

@ -1,96 +0,0 @@
<?php
namespace League\OAuth2\Client\Test\Provider;
use Mockery as m;
class LinkedInTest extends \PHPUnit_Framework_TestCase
{
protected $provider;
protected function setUp()
{
$this->provider = new \League\OAuth2\Client\Provider\LinkedIn([
'clientId' => 'mock_client_id',
'clientSecret' => 'mock_secret',
'redirectUri' => 'none',
]);
}
public function tearDown()
{
m::close();
parent::tearDown();
}
public function testAuthorizationUrl()
{
$url = $this->provider->getAuthorizationUrl();
$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('response_type', $query);
$this->assertArrayHasKey('approval_prompt', $query);
$this->assertNotNull($this->provider->state);
}
public function testUrlAccessToken()
{
$url = $this->provider->urlAccessToken();
$uri = parse_url($url);
$this->assertEquals('/uas/oauth2/accessToken', $uri['path']);
}
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}');
$client = m::mock('Guzzle\Service\Client');
$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('mock_access_token', $token->accessToken);
$this->assertLessThanOrEqual(time() + 3600, $token->expires);
$this->assertGreaterThanOrEqual(time(), $token->expires);
$this->assertEquals('mock_refresh_token', $token->refreshToken);
$this->assertEquals('1', $token->uid);
}
public function testScopes()
{
$this->assertEquals(['r_basicprofile r_emailaddress r_contactinfo'], $this->provider->getScopes());
}
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}');
$getResponse = m::mock('Guzzle\Http\Message\Response');
$getResponse->shouldReceive('getBody')->times(4)->andReturn('{"id": 12345, "firstName": "mock_first_name", "lastName": "mock_last_name", "emailAddress": "mock_email", "location": { "name": "mock_location" }, "headline": "mock_headline", "pictureUrl": "mock_picture_url", "publicProfileUrl": "mock_profile_url"}');
$client = m::mock('Guzzle\Service\Client');
$client->shouldReceive('setBaseUrl')->times(5);
$client->shouldReceive('setDefaultOption')->times(4);
$client->shouldReceive('post->send')->times(1)->andReturn($postResponse);
$client->shouldReceive('get->send')->times(4)->andReturn($getResponse);
$this->provider->setHttpClient($client);
$token = $this->provider->getAccessToken('authorization_code', ['code' => 'mock_authorization_code']);
$user = $this->provider->getUserDetails($token);
$this->assertEquals(12345, $this->provider->getUserUid($token));
$this->assertEquals(['mock_first_name', 'mock_last_name'], $this->provider->getUserScreenName($token));
$this->assertEquals('mock_email', $this->provider->getUserEmail($token));
$this->assertEquals('mock_email', $user->email);
}
}

View File

@ -1,95 +0,0 @@
<?php
namespace League\OAuth2\Client\Test\Provider;
use Mockery as m;
class VkontakteTest extends \PHPUnit_Framework_TestCase
{
protected $provider;
protected function setUp()
{
$this->provider = new \League\OAuth2\Client\Provider\Vkontakte([
'clientId' => 'mock_client_id',
'clientSecret' => 'mock_secret',
'redirectUri' => 'none',
]);
}
public function tearDown()
{
m::close();
parent::tearDown();
}
public function testAuthorizationUrl()
{
$url = $this->provider->getAuthorizationUrl();
$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('response_type', $query);
$this->assertArrayHasKey('approval_prompt', $query);
$this->assertNotNull($this->provider->state);
}
public function testUrlAccessToken()
{
$url = $this->provider->urlAccessToken();
$uri = parse_url($url);
$this->assertEquals('/access_token', $uri['path']);
}
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}');
$client = m::mock('Guzzle\Service\Client');
$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('mock_access_token', $token->accessToken);
$this->assertLessThanOrEqual(time() + 3600, $token->expires);
$this->assertGreaterThanOrEqual(time(), $token->expires);
$this->assertEquals('mock_refresh_token', $token->refreshToken);
$this->assertEquals('1', $token->uid);
}
public function testScopes()
{
$this->assertEquals([], $this->provider->getScopes());
}
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}');
$getResponse = m::mock('Guzzle\Http\Message\Response');
$getResponse->shouldReceive('getBody')->times(4)->andReturn('{"response": [{"uid": 12345, "nickname": "mock_nickname", "screen_name": "mock_name", "first_name": "mock_first_name", "last_name": "mock_last_name", "email": "mock_email", "country": "UK", "status": "mock_status", "photo_200_orig": "mock_image_url"}]}');
$client = m::mock('Guzzle\Service\Client');
$client->shouldReceive('setBaseUrl')->times(5);
$client->shouldReceive('post->send')->times(1)->andReturn($postResponse);
$client->shouldReceive('get->send')->times(4)->andReturn($getResponse);
$this->provider->setHttpClient($client);
$token = $this->provider->getAccessToken('authorization_code', ['code' => 'mock_authorization_code']);
$user = $this->provider->getUserDetails($token);
$this->assertEquals(12345, $this->provider->getUserUid($token));
$this->assertEquals(['mock_first_name', 'mock_last_name'], $this->provider->getUserScreenName($token));
$this->assertEquals('mock_email', $this->provider->getUserEmail($token));
$this->assertEquals('mock_email', $user->email);
}
}

View File

@ -0,0 +1,41 @@
<?php
namespace OAuth2\Test;
class RefreshTokenTest extends \PHPUnit_Framework_TestCase
{
protected $provider;
protected function setUp()
{
$this->provider = new \OAuth2\Google([
'clientId' => 'mock_client_id',
'clientSecret' => 'mock_secret',
'redirectUri' => 'none',
]);
}
public function testGetAccessToken()
{
\OAuth2\CurlMock::addPendingResponse(true, "200 OK", '', '{"access_token": "mock_access_token", "expires": 3600, "refresh_token": "mock_refresh_token", "uid": 1}');
\OAuth2\CurlMock::addPendingResponse(true, "200 OK", '', '{"access_token": "mock_access_token", "expires": 3600, "refresh_token": "mock_refresh_token", "uid": 1}');
$token = $this->provider->getAccessToken('authorization_code', ['code' => 'mock_authorization_code']);
$this->assertInstanceOf('OAuth2\AccessToken', $token);
$newToken = $this->provider->getAccessToken('refresh_token', ['refresh_token' => $token->refreshToken]);
$this->assertInstanceOf('OAuth2\AccessToken', $newToken);
}
/**
* @expectedException BadMethodCallException
*/
public function testInvalidRefreshToken()
{
\OAuth2\CurlMock::addPendingResponse(true, "200 OK", '', '{"access_token": "mock_access_token", "expires": 3600, "refresh_token": "mock_refresh_token", "uid": 1}');
$token = $this->provider->getAccessToken('authorization_code', ['code' => 'mock_authorization_code']);
$refreshToken = $this->provider->getAccessToken('refresh_token', ['invalid_refresh_token' => $token->refreshToken]);
}
}

View File

@ -0,0 +1,73 @@
<?php
namespace OAuth2\Test;
class VkontakteTest extends \PHPUnit_Framework_TestCase
{
protected $provider;
protected function setUp()
{
$this->provider = new \OAuth2\Vkontakte([
'clientId' => 'mock_client_id',
'clientSecret' => 'mock_secret',
'redirectUri' => 'none',
]);
}
public function testAuthorizationUrl()
{
$url = $this->provider->getAuthorizationUrl();
$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('response_type', $query);
$this->assertArrayHasKey('approval_prompt', $query);
$this->assertNotNull($this->provider->state);
}
public function testUrlAccessToken()
{
$url = $this->provider->urlAccessToken();
$uri = parse_url($url);
$this->assertEquals('/access_token', $uri['path']);
}
public function testGetAccessToken()
{
\OAuth2\CurlMock::addPendingResponse(true, "200 OK", '', '{"access_token": "mock_access_token", "expires": 3600, "refresh_token": "mock_refresh_token", "uid": 1}');
$token = $this->provider->getAccessToken('authorization_code', ['code' => 'mock_authorization_code']);
$this->assertEquals('mock_access_token', $token->accessToken);
$this->assertLessThanOrEqual(time() + 3600, $token->expires);
$this->assertGreaterThanOrEqual(time(), $token->expires);
$this->assertEquals('mock_refresh_token', $token->refreshToken);
$this->assertEquals('1', $token->uid);
}
public function testScopes()
{
$this->assertEquals([], $this->provider->getScopes());
}
public function testUserData()
{
\OAuth2\CurlMock::addPendingResponse(true, "200 OK", '', '{"access_token": "mock_access_token", "expires": 3600, "refresh_token": "mock_refresh_token", "uid": 1}');
\OAuth2\CurlMock::addPendingResponse(true, "200 OK", '', '{"response": [{"uid": 12345, "nickname": "mock_nickname", "screen_name": "mock_name", "first_name": "mock_first_name", "last_name": "mock_last_name", "email": "mock_email", "country": "UK", "status": "mock_status", "photo_200_orig": "mock_image_url"}]}');
$token = $this->provider->getAccessToken('authorization_code', ['code' => 'mock_authorization_code']);
$user = $this->provider->getUserDetails($token);
$this->assertEquals(12345, $user['uid']);
$this->assertEquals('mock_first_name', $user['firstname']);
$this->assertEquals('mock_last_name', $user['lastname']);
$this->assertEquals('mock_email', $user['email']);
$this->assertEquals('mock_image_url', $user['image_url']);
}
}