mirror of
https://github.com/elyby/league-oauth2-ely.git
synced 2024-11-26 16:52:03 +05:30
Initial commit
This commit is contained in:
commit
0d37392bbe
5
.gitignore
vendored
Normal file
5
.gitignore
vendored
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
/build
|
||||||
|
/vendor
|
||||||
|
composer.phar
|
||||||
|
composer.lock
|
||||||
|
.DS_Store
|
15
.travis.yml
Normal file
15
.travis.yml
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
language: php
|
||||||
|
|
||||||
|
php:
|
||||||
|
- 5.5
|
||||||
|
- 5.6
|
||||||
|
- 7.0
|
||||||
|
- hhvm
|
||||||
|
|
||||||
|
before_script:
|
||||||
|
- travis_retry composer self-update
|
||||||
|
- travis_retry composer install --no-interaction --prefer-source --dev
|
||||||
|
- travis_retry phpenv rehash
|
||||||
|
|
||||||
|
script:
|
||||||
|
- ./vendor/bin/phpunit --coverage-text --coverage-clover=coverage.clover
|
7
CHANGELOG.md
Normal file
7
CHANGELOG.md
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
# Changelog
|
||||||
|
All Notable changes to `oauth2-ely` will be documented in this file
|
||||||
|
|
||||||
|
## 1.0.0 - 2016-11-25
|
||||||
|
|
||||||
|
### Added
|
||||||
|
- Initial release
|
39
CONTRIBUTING.md
Normal file
39
CONTRIBUTING.md
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
# Contributing
|
||||||
|
|
||||||
|
Contributions are **welcome** and will be fully **credited**.
|
||||||
|
|
||||||
|
We accept contributions via Pull Requests on [Github](https://github.com/elyby/league-oauth2-ely).
|
||||||
|
|
||||||
|
## Pull Requests
|
||||||
|
|
||||||
|
- **[PSR-2 Coding Standard](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-2-coding-style-guide.md)** - The easiest way to apply the conventions is to install [PHP Code Sniffer](http://pear.php.net/package/PHP_CodeSniffer).
|
||||||
|
|
||||||
|
- **Add tests!** - Your patch won't be accepted if it doesn't have tests.
|
||||||
|
|
||||||
|
- **Document any change in behaviour** - Make sure the README and any other relevant documentation are kept up-to-date.
|
||||||
|
|
||||||
|
- **Consider our release cycle** - We try to follow SemVer. Randomly breaking public APIs is not an option.
|
||||||
|
|
||||||
|
- **Create topic branches** - Don't ask us to pull from your master branch.
|
||||||
|
|
||||||
|
- **One pull request per feature** - If you want to do more than one thing, send multiple pull requests.
|
||||||
|
|
||||||
|
- **Send coherent history** - Make sure each individual commit in your pull request is meaningful. If you had to make multiple intermediate commits while developing, please squash them before submitting.
|
||||||
|
|
||||||
|
- **Ensure tests pass!** - Please run the tests (see below) before submitting your pull request, and make sure they pass. We won't accept a patch until all tests pass.
|
||||||
|
|
||||||
|
- **Ensure no coding standards violations** - Please run PHP Code Sniffer using the PSR-2 standard (see below) before submitting your pull request. A violation will cause the build to fail, so please make sure there are no violations. We can't accept a patch if the build fails.
|
||||||
|
|
||||||
|
## Running Tests
|
||||||
|
|
||||||
|
``` bash
|
||||||
|
$ ./vendor/bin/phpunit
|
||||||
|
```
|
||||||
|
|
||||||
|
## Running PHP Code Sniffer
|
||||||
|
|
||||||
|
``` bash
|
||||||
|
$ ./vendor/bin/phpcs src --standard=psr2 -sp
|
||||||
|
```
|
||||||
|
|
||||||
|
**Happy coding**!
|
21
LICENSE.md
Normal file
21
LICENSE.md
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2016 Ely.by <team@ely.by>
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
145
README.md
Normal file
145
README.md
Normal file
@ -0,0 +1,145 @@
|
|||||||
|
# Ely.by Provider for OAuth 2.0 Client
|
||||||
|
|
||||||
|
This package provides Ely.by OAuth 2.0 support for the PHP League's
|
||||||
|
[OAuth 2.0 Client](https://github.com/thephpleague/oauth2-client).
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
To install, use composer:
|
||||||
|
|
||||||
|
```
|
||||||
|
composer require ely/oauth2-client
|
||||||
|
```
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
Usage is the same as The League's OAuth client, using `\Ely\OAuth2\Client\Provider` as the provider. You can find
|
||||||
|
more information in [League repository README](https://github.com/thephpleague/oauth2-client#authorization-code-grant).
|
||||||
|
|
||||||
|
You can get your own `clientId` and `clientSecret` at [Ely.by Account OAuth2 registration page](#).
|
||||||
|
|
||||||
|
```php
|
||||||
|
<?php
|
||||||
|
$provider = new \Ely\OAuth2\Client\Provider([
|
||||||
|
'clientId' => '{elyby-client-id}',
|
||||||
|
'clientSecret' => '{elyby-client-secret}',
|
||||||
|
'redirectUri' => 'http://example.com/callback-uri',
|
||||||
|
]);
|
||||||
|
```
|
||||||
|
|
||||||
|
We suggest to put this provider object into service locator for access it at any time or mock for testing.
|
||||||
|
In code below we think, that `$provider` contains our provider object.
|
||||||
|
|
||||||
|
### Authorization Code Flow
|
||||||
|
|
||||||
|
First of all, you must generate redirect user to route, which will set state session value and redirect user to Ely.by
|
||||||
|
authorization page. This can be done by such code, placed into controller:
|
||||||
|
|
||||||
|
```php
|
||||||
|
<?php
|
||||||
|
$authUrl = $provider->getAuthorizationUrl();
|
||||||
|
$_SESSION['oauth2state'] = $provider->getState();
|
||||||
|
header('Location: ' . $authUrl);
|
||||||
|
exit();
|
||||||
|
```
|
||||||
|
|
||||||
|
Note, that `getAuthorizationUrl()` takes as argument array of overriding parameters. For example, if you want request
|
||||||
|
additional scopes and change app description, then you must pass `scope` and `description` keys with needed values:
|
||||||
|
|
||||||
|
```php
|
||||||
|
<?php
|
||||||
|
$authUrl = $provider->getAuthorizationUrl([
|
||||||
|
'scope' => ['account_info', 'account_email'],
|
||||||
|
'description' => 'My super application!',
|
||||||
|
]);
|
||||||
|
```
|
||||||
|
|
||||||
|
After user finish authentication and authorization on Ely.by Account site, he will be redirected back, on `redirectUri`,
|
||||||
|
that you specified in Provider configuration. Inside redirectUri handler you must check for errors and state matches.
|
||||||
|
If all checks passed normal, then try to exchange received `auth_code` to `access_token`. This can be done by code
|
||||||
|
like below:
|
||||||
|
|
||||||
|
```php
|
||||||
|
<?php
|
||||||
|
if (isset($_GET['error'])) {
|
||||||
|
echo 'Oh no! The error ' . $_GET['error'] . ' with message ' . $_GET['message'];
|
||||||
|
} elseif (!isset($_GET['state']) || $_GET['state'] !== $_SESSION['oauth2state']) {
|
||||||
|
unset($_SESSION['oauth2state']);
|
||||||
|
echo 'Invalid state value.';
|
||||||
|
} else {
|
||||||
|
// Try to get an access token (using the authorization code grant)
|
||||||
|
$token = $provider->getAccessToken(new \League\OAuth2\Client\Grant\AuthorizationCode(), [
|
||||||
|
'code' => $_GET['code'],
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Optional: Now you have a token you can look up a users account data
|
||||||
|
try {
|
||||||
|
// We got an access token, let's now get the user's details
|
||||||
|
$account = $provider->getResourceOwner($token);
|
||||||
|
|
||||||
|
// Use these details to create a new profile
|
||||||
|
printf('Hello %s!', $account->getUsername());
|
||||||
|
} catch (\Ely\OAuth2\Client\Exception\IdentityProviderException $e) {
|
||||||
|
// Failed to get user details
|
||||||
|
echo 'Cannot get user account identity. The error is ' . $e->getMessage();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Use this to interact with an API on the users behalf
|
||||||
|
echo $token->getToken();
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Refreshing a Token
|
||||||
|
|
||||||
|
Refresh tokens are only provided to applications which request offline access. You can specify offline access by
|
||||||
|
setting the `scope` option on authorization url generating:
|
||||||
|
|
||||||
|
```php
|
||||||
|
<?php
|
||||||
|
$authUrl = $provider->getAuthorizationUrl([
|
||||||
|
'scope' => ['account_info', 'account_email', 'offline_access'],
|
||||||
|
]);
|
||||||
|
```
|
||||||
|
|
||||||
|
It is important to note that the refresh token is only returned on the first request after this it will be null.
|
||||||
|
You should securely store the refresh token when it is returned:
|
||||||
|
|
||||||
|
```php
|
||||||
|
<?php
|
||||||
|
$token = $provider->getAccessToken('authorization_code', [
|
||||||
|
'code' => $code
|
||||||
|
]);
|
||||||
|
|
||||||
|
// persist the token in a database
|
||||||
|
$refreshToken = $token->getRefreshToken();
|
||||||
|
```
|
||||||
|
|
||||||
|
Now you have everything you need to refresh an access token using a refresh token:
|
||||||
|
|
||||||
|
```php
|
||||||
|
<?php
|
||||||
|
$token = $provider->getAccessToken(new League\OAuth2\Client\Grant\RefreshToken(), [
|
||||||
|
'refresh_token' => $refreshToken,
|
||||||
|
]);
|
||||||
|
```
|
||||||
|
|
||||||
|
## Testing
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ ./vendor/bin/phpunit
|
||||||
|
```
|
||||||
|
|
||||||
|
## Contributing
|
||||||
|
|
||||||
|
Please see [CONTRIBUTING](CONTRIBUTING.md) for details.
|
||||||
|
|
||||||
|
## Credits
|
||||||
|
|
||||||
|
This package was designed and developed within the [Ely.by](http://ely.by) project team. We also thank all the
|
||||||
|
[contributors](link-contributors) for their help.
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
The MIT License (MIT). Please see [License File](LICENSE.md) for more information.
|
||||||
|
|
||||||
|
[link-contributors]: ../../contributors
|
35
composer.json
Normal file
35
composer.json
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
{
|
||||||
|
"name": "ely/oauth2-client",
|
||||||
|
"description": "Ely.by provider for league/oauth2-client",
|
||||||
|
"license": "MIT",
|
||||||
|
"keywords": ["authorization", "authentication", "client", "league", "oauth", "oauth2", "ely", "elyby"],
|
||||||
|
"homepage": "https://github.com/elyby/league-oauth2-ely",
|
||||||
|
"type": "library",
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Ely.by team",
|
||||||
|
"email": "team@ely.by"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "ErickSkrauch",
|
||||||
|
"email": "erickskrauch@ely.by"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"require": {
|
||||||
|
"league/oauth2-client": "^1.0"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"phpunit/phpunit": "^5.0",
|
||||||
|
"mockery/mockery": "~0.9"
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Ely\\OAuth2\\Client\\": "src/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"autoload-dev": {
|
||||||
|
"psr-4": {
|
||||||
|
"Ely\\OAuth2\\Client\\Test\\": "tests/src/"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
37
phpunit.xml
Normal file
37
phpunit.xml
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<phpunit backupGlobals="false"
|
||||||
|
backupStaticAttributes="false"
|
||||||
|
bootstrap="vendor/autoload.php"
|
||||||
|
colors="true"
|
||||||
|
convertErrorsToExceptions="true"
|
||||||
|
convertNoticesToExceptions="true"
|
||||||
|
convertWarningsToExceptions="true"
|
||||||
|
processIsolation="false"
|
||||||
|
stopOnFailure="false"
|
||||||
|
syntaxCheck="false"
|
||||||
|
>
|
||||||
|
<logging>
|
||||||
|
<log type="coverage-html"
|
||||||
|
target="./build/coverage/html"
|
||||||
|
charset="UTF-8"
|
||||||
|
highlight="false"
|
||||||
|
lowUpperBound="35"
|
||||||
|
highLowerBound="70"/>
|
||||||
|
<log type="coverage-clover"
|
||||||
|
target="./build/coverage/log/coverage.xml"/>
|
||||||
|
</logging>
|
||||||
|
<testsuites>
|
||||||
|
<testsuite name="Package Test Suite">
|
||||||
|
<directory suffix=".php">./tests/</directory>
|
||||||
|
</testsuite>
|
||||||
|
</testsuites>
|
||||||
|
<filter>
|
||||||
|
<whitelist>
|
||||||
|
<directory suffix=".php">./</directory>
|
||||||
|
<exclude>
|
||||||
|
<directory suffix=".php">./vendor</directory>
|
||||||
|
<directory suffix=".php">./tests</directory>
|
||||||
|
</exclude>
|
||||||
|
</whitelist>
|
||||||
|
</filter>
|
||||||
|
</phpunit>
|
9
src/Exception/IdentityProviderException.php
Normal file
9
src/Exception/IdentityProviderException.php
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<?php
|
||||||
|
namespace Ely\OAuth2\Client\Exception;
|
||||||
|
|
||||||
|
use League\OAuth2\Client\Provider\Exception\IdentityProviderException as LeagueIdentityProviderException;
|
||||||
|
|
||||||
|
class IdentityProviderException extends LeagueIdentityProviderException
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
89
src/Provider.php
Normal file
89
src/Provider.php
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
<?php
|
||||||
|
namespace Ely\OAuth2\Client;
|
||||||
|
|
||||||
|
use Ely\OAuth2\Client\Exception\IdentityProviderException;
|
||||||
|
use League\OAuth2\Client\Provider\AbstractProvider;
|
||||||
|
use League\OAuth2\Client\Token\AccessToken;
|
||||||
|
use League\OAuth2\Client\Tool\BearerAuthorizationTrait;
|
||||||
|
use Psr\Http\Message\ResponseInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @method ResourceOwner getResourceOwner(AccessToken $token)
|
||||||
|
*/
|
||||||
|
class Provider extends AbstractProvider
|
||||||
|
{
|
||||||
|
use BearerAuthorizationTrait;
|
||||||
|
|
||||||
|
const REDIRECT_URI_STATIC_PAGE = 'static_page';
|
||||||
|
const REDIRECT_URI_STATIC_PAGE_WITH_CODE = 'static_page_with_code';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
*/
|
||||||
|
public function getBaseAuthorizationUrl()
|
||||||
|
{
|
||||||
|
return 'https://account.ely.by/oauth2/v1/' . $this->clientId;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
*/
|
||||||
|
public function getBaseAccessTokenUrl(array $params)
|
||||||
|
{
|
||||||
|
return 'https://account.ely.by/api/oauth2/v1/token';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
*/
|
||||||
|
public function getResourceOwnerDetailsUrl(AccessToken $token)
|
||||||
|
{
|
||||||
|
return 'https://account.ely.by/api/account/v1/info';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
*/
|
||||||
|
protected function getAuthorizationParameters(array $options)
|
||||||
|
{
|
||||||
|
$params = parent::getAuthorizationParameters($options);
|
||||||
|
// client_id applied to base url
|
||||||
|
// approval_prompt not supported
|
||||||
|
unset($params['client_id'], $params['approval_prompt']);
|
||||||
|
|
||||||
|
return $params;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
*/
|
||||||
|
protected function getDefaultScopes()
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'account_info',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
*/
|
||||||
|
protected function checkResponse(ResponseInterface $response, $data)
|
||||||
|
{
|
||||||
|
$statusCode = $response->getStatusCode();
|
||||||
|
if ($statusCode !== 200 || isset($data['message'])) {
|
||||||
|
throw new IdentityProviderException($data['message'] ?: $response->getReasonPhrase(), $statusCode, $response);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate a user object from a successful user details request.
|
||||||
|
*
|
||||||
|
* @param array $response
|
||||||
|
* @param AccessToken $token
|
||||||
|
* @return ResourceOwner
|
||||||
|
*/
|
||||||
|
protected function createResourceOwner(array $response, AccessToken $token)
|
||||||
|
{
|
||||||
|
return new ResourceOwner($response);
|
||||||
|
}
|
||||||
|
}
|
120
src/ResourceOwner.php
Normal file
120
src/ResourceOwner.php
Normal file
@ -0,0 +1,120 @@
|
|||||||
|
<?php
|
||||||
|
namespace Ely\OAuth2\Client;
|
||||||
|
|
||||||
|
use DateTime;
|
||||||
|
use League\OAuth2\Client\Provider\ResourceOwnerInterface;
|
||||||
|
|
||||||
|
class ResourceOwner implements ResourceOwnerInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Raw response
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected $response;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates new resource owner.
|
||||||
|
*
|
||||||
|
* @param array $response
|
||||||
|
*/
|
||||||
|
public function __construct(array $response = [])
|
||||||
|
{
|
||||||
|
$this->response = $response;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get resource owner id
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getId()
|
||||||
|
{
|
||||||
|
return $this->response['id'];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get resource owner UUID
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getUuid()
|
||||||
|
{
|
||||||
|
return $this->response['uuid'];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get resource owner current username
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getUsername()
|
||||||
|
{
|
||||||
|
return $this->response['username'];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get resource owner confirmed E-mail. If you do not have permission 'account_email',
|
||||||
|
* then you will get null
|
||||||
|
*
|
||||||
|
* @return string|null
|
||||||
|
*/
|
||||||
|
public function getEmail()
|
||||||
|
{
|
||||||
|
return isset($this->response['email']) ? $this->response['email'] : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get resource owner registration date.
|
||||||
|
*
|
||||||
|
* @return DateTime
|
||||||
|
*/
|
||||||
|
public function getRegisteredAt()
|
||||||
|
{
|
||||||
|
return new DateTime('@' . $this->response['registeredAt']);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Link to resource owner Ely.by profile
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getProfileLink()
|
||||||
|
{
|
||||||
|
return $this->response['profileLink'];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get resource owner preferred language, that he used on Ely.by
|
||||||
|
* Language codes correspond to ISO 639-1 standard
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getPreferredLanguage()
|
||||||
|
{
|
||||||
|
return $this->response['preferredLanguage'];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get resource owner current skin url.
|
||||||
|
* Remember that this is not a direct link to skin file.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getSkinUrl()
|
||||||
|
{
|
||||||
|
return "http://skinsystem.ely.by/skins/{$this->getUsername()}.png";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return all of the owner details available as an array.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function toArray()
|
||||||
|
{
|
||||||
|
return array_merge($this->response, [
|
||||||
|
'skinUrl' => $this->getSkinUrl(),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
161
tests/ProviderTest.php
Normal file
161
tests/ProviderTest.php
Normal file
@ -0,0 +1,161 @@
|
|||||||
|
<?php
|
||||||
|
namespace Ely\OAuth2\Client\Test;
|
||||||
|
|
||||||
|
use Ely\OAuth2\Client\Provider;
|
||||||
|
use Ely\OAuth2\Client\ResourceOwner;
|
||||||
|
use GuzzleHttp\ClientInterface;
|
||||||
|
use League\OAuth2\Client\Token\AccessToken;
|
||||||
|
use Mockery as m;
|
||||||
|
use Psr\Http\Message\ResponseInterface;
|
||||||
|
|
||||||
|
class ProviderTest extends \PHPUnit_Framework_TestCase
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var Provider
|
||||||
|
*/
|
||||||
|
protected $provider;
|
||||||
|
|
||||||
|
protected function setUp()
|
||||||
|
{
|
||||||
|
$this->provider = new Provider([
|
||||||
|
'clientId' => 'mock_client_id',
|
||||||
|
'clientSecret' => 'mock_secret',
|
||||||
|
'redirectUri' => 'none',
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function tearDown()
|
||||||
|
{
|
||||||
|
m::close();
|
||||||
|
parent::tearDown();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testGetResourceOwnerDetailsUrl()
|
||||||
|
{
|
||||||
|
$url = $this->provider->getResourceOwnerDetailsUrl(new AccessToken(['access_token' => 'mock_token']));
|
||||||
|
$uri = parse_url($url);
|
||||||
|
$this->assertEquals('/api/account/v1/info', $uri['path']);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testGetAuthorizationUrl()
|
||||||
|
{
|
||||||
|
$url = $this->provider->getAuthorizationUrl();
|
||||||
|
$uri = parse_url($url);
|
||||||
|
parse_str($uri['query'], $query);
|
||||||
|
|
||||||
|
$this->assertEquals('/oauth2/v1/mock_client_id', $uri['path']);
|
||||||
|
$this->assertArrayNotHasKey('client_id', $query);
|
||||||
|
$this->assertArrayHasKey('redirect_uri', $query);
|
||||||
|
$this->assertArrayHasKey('state', $query);
|
||||||
|
$this->assertArrayHasKey('scope', $query);
|
||||||
|
$this->assertArrayHasKey('response_type', $query);
|
||||||
|
$this->assertArrayNotHasKey('approval_prompt', $query);
|
||||||
|
$this->assertNotNull($this->provider->getState());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testScopes()
|
||||||
|
{
|
||||||
|
$options = ['scope' => ['minecraft_server_session', 'account_info']];
|
||||||
|
|
||||||
|
$url = $this->provider->getAuthorizationUrl($options);
|
||||||
|
|
||||||
|
$this->assertContains(urlencode(implode(',', $options['scope'])), $url);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testGetBaseAccessTokenUrl()
|
||||||
|
{
|
||||||
|
$params = [];
|
||||||
|
|
||||||
|
$url = $this->provider->getBaseAccessTokenUrl($params);
|
||||||
|
$uri = parse_url($url);
|
||||||
|
|
||||||
|
$this->assertEquals('/api/oauth2/v1/token', $uri['path']);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testGetAccessToken()
|
||||||
|
{
|
||||||
|
/** @var m\Mock|ResponseInterface $response */
|
||||||
|
$response = m::mock(ResponseInterface::class);
|
||||||
|
$response->shouldReceive('getBody')->andReturn($this->getAccessTokenResponse());
|
||||||
|
$response->shouldReceive('getHeader')->andReturn(['content-type' => 'json']);
|
||||||
|
$response->shouldReceive('getStatusCode')->andReturn(200);
|
||||||
|
|
||||||
|
/** @var m\Mock|ClientInterface $client */
|
||||||
|
$client = m::mock(ClientInterface::class);
|
||||||
|
$client->shouldReceive('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->getToken());
|
||||||
|
$this->assertNotNull($token->getExpires());
|
||||||
|
$this->assertNull($token->getRefreshToken());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @expectedException \Ely\OAuth2\Client\Exception\IdentityProviderException
|
||||||
|
* @expectedExceptionMessageRegExp /Exception message .+/
|
||||||
|
*/
|
||||||
|
public function testExceptionThrownWhenErrorObjectReceived()
|
||||||
|
{
|
||||||
|
$name = 'Error ' . uniqid();
|
||||||
|
$message = 'Exception message ' . uniqid();
|
||||||
|
$status = rand(400, 600);
|
||||||
|
/** @var m\Mock|ResponseInterface $postResponse */
|
||||||
|
$postResponse = m::mock(ResponseInterface::class);
|
||||||
|
$postResponse->shouldReceive('getBody')->andReturn(json_encode([
|
||||||
|
'name' => $name,
|
||||||
|
'message' => $message,
|
||||||
|
'status' => $status,
|
||||||
|
'code' => 0,
|
||||||
|
]));
|
||||||
|
$postResponse->shouldReceive('getHeader')->andReturn(['content-type' => 'json']);
|
||||||
|
$postResponse->shouldReceive('getStatusCode')->andReturn($status);
|
||||||
|
|
||||||
|
/** @var m\Mock|ClientInterface $client */
|
||||||
|
$client = m::mock(ClientInterface::class);
|
||||||
|
$client->shouldReceive('send')
|
||||||
|
->times(1)
|
||||||
|
->andReturn($postResponse);
|
||||||
|
$this->provider->setHttpClient($client);
|
||||||
|
$this->provider->getAccessToken('authorization_code', ['code' => 'mock_authorization_code']);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testGetResourceOwner()
|
||||||
|
{
|
||||||
|
/** @var m\Mock|ResponseInterface $postResponse */
|
||||||
|
$postResponse = m::mock(ResponseInterface::class);
|
||||||
|
$postResponse->shouldReceive('getBody')->andReturn($this->getAccessTokenResponse());
|
||||||
|
$postResponse->shouldReceive('getHeader')->andReturn(['content-type' => 'json']);
|
||||||
|
$postResponse->shouldReceive('getStatusCode')->andReturn(200);
|
||||||
|
|
||||||
|
/** @var m\Mock|ResponseInterface $userResponse */
|
||||||
|
$userResponse = m::mock(ResponseInterface::class);
|
||||||
|
$userResponse->shouldReceive('getBody')->andReturn(
|
||||||
|
file_get_contents(__DIR__ . '/data/identity-info-response.json')
|
||||||
|
);
|
||||||
|
$userResponse->shouldReceive('getHeader')->andReturn(['content-type' => 'json']);
|
||||||
|
$userResponse->shouldReceive('getStatusCode')->andReturn(200);
|
||||||
|
|
||||||
|
/** @var m\Mock|ClientInterface $client */
|
||||||
|
$client = m::mock(ClientInterface::class);
|
||||||
|
$client->shouldReceive('send')
|
||||||
|
->times(2)
|
||||||
|
->andReturn($postResponse, $userResponse);
|
||||||
|
$this->provider->setHttpClient($client);
|
||||||
|
|
||||||
|
$token = $this->provider->getAccessToken('authorization_code', ['code' => 'mock_authorization_code']);
|
||||||
|
$user = $this->provider->getResourceOwner($token);
|
||||||
|
|
||||||
|
$this->assertInstanceOf(ResourceOwner::class, $user);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getAccessTokenResponse()
|
||||||
|
{
|
||||||
|
return json_encode([
|
||||||
|
'access_token' => 'mock_access_token',
|
||||||
|
'token_type' => 'bearer',
|
||||||
|
'expires_in' => 3600,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
84
tests/ResourceOwnerTest.php
Normal file
84
tests/ResourceOwnerTest.php
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
<?php
|
||||||
|
namespace Ely\OAuth2\Client\Test;
|
||||||
|
|
||||||
|
use Ely\OAuth2\Client\ResourceOwner;
|
||||||
|
|
||||||
|
class ResourceOwnerTest extends \PHPUnit_Framework_TestCase
|
||||||
|
{
|
||||||
|
public function testGetId()
|
||||||
|
{
|
||||||
|
$this->assertEquals(1, $this->createModel()->getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testGetUuid()
|
||||||
|
{
|
||||||
|
$this->assertEquals('ffc8fdc9-5824-509e-8a57-c99b940fb996', $this->createModel()->getUuid());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testGetUsername()
|
||||||
|
{
|
||||||
|
$this->assertEquals('ErickSkrauch', $this->createModel()->getUsername());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testGetEmail()
|
||||||
|
{
|
||||||
|
$this->assertEquals('erickskrauch@ely.by', $this->createModel()->getEmail());
|
||||||
|
$this->assertNull($this->createModelWithoutEmail()->getEmail());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testGetRegisteredAt()
|
||||||
|
{
|
||||||
|
$registeredAt = $this->createModel()->getRegisteredAt();
|
||||||
|
$this->assertInstanceOf(\DateTime::class, $registeredAt);
|
||||||
|
$this->assertEquals(1470566470, $registeredAt->getTimestamp());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testGetProfileLink()
|
||||||
|
{
|
||||||
|
$this->assertEquals('http://ely.by/u1', $this->createModel()->getProfileLink());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testGetPreferredLanguage()
|
||||||
|
{
|
||||||
|
$this->assertEquals('be', $this->createModel()->getPreferredLanguage());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testGetSkinUrl()
|
||||||
|
{
|
||||||
|
$this->assertEquals('http://skinsystem.ely.by/skins/ErickSkrauch.png', $this->createModel()->getSkinUrl());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testToArray()
|
||||||
|
{
|
||||||
|
$array = $this->createModel()->toArray();
|
||||||
|
$this->assertTrue(is_array($array));
|
||||||
|
$this->assertEquals(1, $array['id']);
|
||||||
|
$this->assertEquals('ffc8fdc9-5824-509e-8a57-c99b940fb996', $array['uuid']);
|
||||||
|
$this->assertEquals('ErickSkrauch', $array['username']);
|
||||||
|
$this->assertEquals('erickskrauch@ely.by', $array['email']);
|
||||||
|
$this->assertEquals(1470566470, $array['registeredAt']);
|
||||||
|
$this->assertEquals('http://ely.by/u1', $array['profileLink']);
|
||||||
|
$this->assertEquals('http://skinsystem.ely.by/skins/ErickSkrauch.png', $array['skinUrl']);
|
||||||
|
|
||||||
|
$array = $this->createModelWithoutEmail()->toArray();
|
||||||
|
$this->assertArrayNotHasKey('email', $array);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function createModelWithoutEmail()
|
||||||
|
{
|
||||||
|
$params = $this->getAllResponseParams();
|
||||||
|
unset($params['email']);
|
||||||
|
|
||||||
|
return new ResourceOwner($params);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function createModel()
|
||||||
|
{
|
||||||
|
return new ResourceOwner($this->getAllResponseParams());
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getAllResponseParams()
|
||||||
|
{
|
||||||
|
return json_decode(file_get_contents(__DIR__ . '/data/identity-info-response.json'), true);
|
||||||
|
}
|
||||||
|
}
|
9
tests/data/identity-info-response.json
Normal file
9
tests/data/identity-info-response.json
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"id": 1,
|
||||||
|
"uuid": "ffc8fdc9-5824-509e-8a57-c99b940fb996",
|
||||||
|
"username": "ErickSkrauch",
|
||||||
|
"registeredAt": 1470566470,
|
||||||
|
"profileLink": "http:\/\/ely.by\/u1",
|
||||||
|
"preferredLanguage": "be",
|
||||||
|
"email": "erickskrauch@ely.by"
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user