diff --git a/README.md b/README.md index 56c8dbc..0a1430b 100644 --- a/README.md +++ b/README.md @@ -2,8 +2,15 @@ HtOauth\Server\ClientModule ====================== A Zend Framework 2 module which provides custom grant for [zfr-oauth2-server](https://github.com/zf-fr/zfr-oauth2-server) to authenticate users via third party applications like facebook, google etc. +[![Master Branch Build Status](https://api.travis-ci.org/hrevert/ht-oauth-server-client-module.png?branch=master)](http://travis-ci.org/hrevert/ht-oauth-server-client-module) +[![Latest Stable Version](https://poser.pugx.org/hrevert/ht-oauth-server-client-module/version.svg)](https://packagist.org/packages/hrevert/ht-oauth-server-client-module) +[![Latest Unstable Version](https://poser.pugx.org/hrevert/ht-oauth-server-client-module/v/unstable.svg)](//packagist.org/packages/hrevert/ht-oauth-server-client-module) [![Total Downloads](https://poser.pugx.org/hrevert/ht-oauth-server-client-module/downloads.svg)](https://packagist.org/packages/hrevert/ht-oauth-server-client-module) + +### What's with the name? +The module provides a grant for a oauth2 server and it is also a client for oauth2 servers of facebook, google etc. So, it is named as server as well as client. + ## Installation -* Add `"hrevert/ht-oauth-server-client-module": "dev-master"` to composer.json and run `php composer.phar update`. +* Add `"hrevert/ht-oauth-server-client-module": "0.1.*"` to composer.json and run `php composer.phar update`. * Enabled the following modules in `config/application.config.php`. ```php 'modules' => array( @@ -16,7 +23,7 @@ A Zend Framework 2 module which provides custom grant for [zfr-oauth2-server](ht ## Configuring the module #### Setting the User class -User class implements the ZfrOAuth2\Server\Entity\TokenOwnerInterface interface `Hrevert\OauthClient\Model\UserInterface`. Then, you need to modify the Doctrine mapping to associate this interface with your own user class. +User class must implement `Hrevert\OauthClient\Model\UserInterface`. Then, you need to modify the Doctrine mapping to associate this interface with your own user class. ```php return [ @@ -31,7 +38,7 @@ return [ ``` #### Provider configuration -You need to define the credentials like client id, client secret and other configuration. Read [this](https://github.com/hrevert/HtLeagueOauthClientModule/tree/0.0.1) for these configuration. +You need to define the credentials like client id, client secret and other configuration. Read [this](https://github.com/hrevert/HtLeagueOauthClientModule/tree/0.1.0) for these configuration. #### Adding grant types ```php @@ -57,7 +64,7 @@ To automatically create a new user, you need to specify a callable for creating return [ 'ht_oauth_service_client' => [ - 'create_user_callable' => function(\League\OAuth2\Client\Entity\User $userDetails) { + 'create_user_callable' => function(\HtLeagueOauthClientModule\Model\UserInterface $userDetails) { $user = ......; $userProvider = new \Hrevert\OauthClient\Entity\UserProvider(); @@ -74,3 +81,14 @@ return [ ] ]; ``` + +## How It Works +### Login with OAuth 2.0 +1. **Client:** Client sends a `POST` request to the server at */oauth/token* with oauth2 authorization code. +2. **Server:** Then *authorization code* is exchanged for *provider access token*. +3. **Server:** User information is retrived using the *provider access token* from **Step 2**. +4. **Server:** Look up the user by the unique *provider id*. If user already exists, grab +the existing user, otherwise create a new user account. +5. **Server:** Reply with a *new access token*. + + diff --git a/composer.json b/composer.json index 6bb2732..36319b0 100644 --- a/composer.json +++ b/composer.json @@ -9,11 +9,10 @@ "email": "info@hrevert.com" } ], - "minimum-stability" :"dev", "require": { "php": ">=5.4", "hrevert/ht-oauth-client-module": "0.0.*", - "hrevert/ht-league-oauth-client-module": "0.0.*", + "hrevert/ht-league-oauth-client-module": "0.1.*", "zendframework/zend-stdlib": "~2.2", "zfr/zfr-oauth2-server-module": "0.5.*" }, diff --git a/src/Grant/Oauth2Client.php b/src/Grant/Oauth2Client.php index 174d45a..8703348 100644 --- a/src/Grant/Oauth2Client.php +++ b/src/Grant/Oauth2Client.php @@ -21,6 +21,7 @@ use Hrevert\OauthClient\Entity\UserProvider; use Hrevert\OauthClient\Model\UserInterface; use Doctrine\Common\Persistence\ObjectManager; +use HtLeagueOauthClientModule\Model\Oauth2User; class Oauth2Client extends AbstractGrant implements AuthorizationServerAwareInterface { @@ -125,7 +126,7 @@ public function createTokenResponse(HttpRequest $request, Client $client = null, throw OAuth2Exception::invalidRequest(sprintf('Provider authorization code is invalid')); } - /** @var \League\OAuth2\Client\Entity\User */ + /** @var \League\OAuth2\Client\Provider\User */ $userDetails = $providerClient->getUserDetails($providerAccessToken); // access token is valid @@ -138,7 +139,7 @@ public function createTokenResponse(HttpRequest $request, Client $client = null, // by default, we expect the callable to return instance of "Hrevert\OauthClient\Model\UserProviderInterface" // because the developer may have extended the default implementation // Alternatively the callable may return user entity directly - $userProvider = $createUserCallable($userDetails); + $userProvider = $createUserCallable(new Oauth2User($userDetails)); if ($userProvider instanceof UserInterface) { $user = $userProvider; $userProvider = new UserProvider; diff --git a/tests/src/Grant/Oauth2ClientTest.php b/tests/src/Grant/Oauth2ClientTest.php index 02afa2e..3a6fe21 100644 --- a/tests/src/Grant/Oauth2ClientTest.php +++ b/tests/src/Grant/Oauth2ClientTest.php @@ -7,7 +7,7 @@ use DateTime; use ZfrOAuth2\Server\Entity\AccessToken; use Hrevert\OauthClient\Model\UserProviderInterface; -use League\OAuth2\Client\Entity\User as ProviderUser; +use League\OAuth2\Client\Provider\User as ProviderUser; use ZfrOAuth2\Server\Entity\Client; use ZfrOAuth2\Server\Entity\RefreshToken; use ZfrOAuth2\Server\Grant\RefreshTokenGrant; @@ -149,7 +149,7 @@ public function testGetExceptionWhenProviderAuthorizationCodeIsInvalid() ->with('facebook') ->will($this->returnValue($provider)); - $providerClient = $this->getMock('League\OAuth2\Client\Provider\ProviderInterface'); + $providerClient = $this->getMock('League\OAuth2\Client\Provider\IdentityProvider'); $providerClients->expects($this->once()) ->method('get') @@ -209,7 +209,7 @@ public function testCanCreateTokenResponse($hasRefreshGrant, UserProviderInterfa ->with('facebook') ->will($this->returnValue($provider)); - $providerClient = $this->getMock('League\OAuth2\Client\Provider\ProviderInterface'); + $providerClient = $this->getMock('League\OAuth2\Client\Provider\IdentityProvider'); $providerClients->expects($this->once()) ->method('get') @@ -238,7 +238,8 @@ public function testCanCreateTokenResponse($hasRefreshGrant, UserProviderInterfa if (!$userProvider) { $userProvider = $this->getMock('Hrevert\OauthClient\Model\UserProviderInterface'); - $createUserCallable = function() use ($userProvider) { + $createUserCallable = function($oauth2User) use ($userProvider) { + $this->assertInstanceOf('HtLeagueOauthClientModule\Model\Oauth2User', $oauth2User); return $userProvider; }; $options->expects($this->once()) @@ -307,7 +308,7 @@ private function getValidRefreshToken() $refreshToken->setToken('azerty_refresh'); $refreshToken->setScopes('read'); $validDate = new DateTime(); - $validDate->add(new DateInterval('P1D')); + $validDate->add(DateInterval::createFromDateString('3600 seconds')); $refreshToken->setExpiresAt($validDate);