From 0d25e02de79d66b0e937dad7504d3cb4159cb943 Mon Sep 17 00:00:00 2001 From: jeremykendall Date: Tue, 23 Dec 2014 14:33:55 -0600 Subject: [PATCH 1/5] Adds AbstractProvider::fetchProviderData(). New protected method is responsible for making the request to a provided URL, allowing for multiple API endpoints to be used within the same provider. AbstractProvider::fetchUserDetails() remains, but now only builds the user details URL and passes it to AbstractProvider::fetchProviderData(). --- src/Provider/AbstractProvider.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/Provider/AbstractProvider.php b/src/Provider/AbstractProvider.php index 3ca4aa8..6eab5a3 100644 --- a/src/Provider/AbstractProvider.php +++ b/src/Provider/AbstractProvider.php @@ -311,6 +311,11 @@ abstract class AbstractProvider implements ProviderInterface { $url = $this->urlUserDetails($token); + return $this->fetchProviderData($url); + } + + protected function fetchProviderData($url) + { try { $client = $this->getHttpClient(); $client->setBaseUrl($url); @@ -331,6 +336,7 @@ abstract class AbstractProvider implements ProviderInterface return $response; } + public function setRedirectHandler(Closure $handler) { $this->redirectHandler = $handler; From 8c0ae57065ae6da5c7d00217f948b269615fa75b Mon Sep 17 00:00:00 2001 From: jeremykendall Date: Tue, 23 Dec 2014 14:37:03 -0600 Subject: [PATCH 2/5] Adds methods that fetch a Github user's email addresses. --- src/Provider/Github.php | 24 ++++++++++++++++++++++++ test/src/Provider/GithubTest.php | 22 ++++++++++++++++++++++ 2 files changed, 46 insertions(+) diff --git a/src/Provider/Github.php b/src/Provider/Github.php index 009c5d8..5631ab8 100644 --- a/src/Provider/Github.php +++ b/src/Provider/Github.php @@ -28,6 +28,11 @@ class Github extends AbstractProvider return $this->domain.'/api/v3/user?access_token='.$token; } + public function urlUserEmails(\League\OAuth2\Client\Token\AccessToken $token) + { + return 'https://api.github.com/user/emails?access_token='.$token; + } + public function userDetails($response, \League\OAuth2\Client\Token\AccessToken $token) { $user = new User(); @@ -53,13 +58,32 @@ class Github extends AbstractProvider return $response->id; } + public function getUserEmails(\League\OAuth2\Client\Token\AccessToken $token) + { + $response = $this->fetchUserEmails($token); + + return $this->userEmails(json_decode($response), $token); + } + public function userEmail($response, \League\OAuth2\Client\Token\AccessToken $token) { return isset($response->email) && $response->email ? $response->email : null; } + public function userEmails($response, \League\OAuth2\Client\Token\AccessToken $token) + { + return $response; + } + public function userScreenName($response, \League\OAuth2\Client\Token\AccessToken $token) { return $response->name; } + + protected function fetchUserEmails(\League\OAuth2\Client\Token\AccessToken $token) + { + $url = $this->urlUserEmails($token); + + return $this->fetchProviderData($url); + } } diff --git a/test/src/Provider/GithubTest.php b/test/src/Provider/GithubTest.php index 4ca85f9..1e6c0e2 100644 --- a/test/src/Provider/GithubTest.php +++ b/test/src/Provider/GithubTest.php @@ -132,4 +132,26 @@ class GithubTest extends \PHPUnit_Framework_TestCase $this->assertEquals($this->provider->domain.'/login/oauth/access_token', $this->provider->urlAccessToken()); $this->assertEquals($this->provider->domain.'/api/v3/user?access_token=mock_access_token', $this->provider->urlUserDetails($token)); } + + 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('post->send')->times(1)->andReturn($postResponse); + $client->shouldReceive('get->send')->times(1)->andReturn($getResponse); + $this->provider->setHttpClient($client); + + $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); + $this->assertTrue($emails[2]->primary); + } } From f3d6724d6c03631708ba26f5176ebe4f3ef0b733 Mon Sep 17 00:00:00 2001 From: jeremykendall Date: Mon, 29 Dec 2014 04:18:12 -0600 Subject: [PATCH 3/5] Updates string comparison to use identical operator --- src/Provider/Github.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Provider/Github.php b/src/Provider/Github.php index 5631ab8..50124da 100644 --- a/src/Provider/Github.php +++ b/src/Provider/Github.php @@ -22,7 +22,7 @@ class Github extends AbstractProvider public function urlUserDetails(\League\OAuth2\Client\Token\AccessToken $token) { - if ($this->domain == 'https://github.com') { + if ($this->domain === 'https://github.com') { return $this->domain.'/user?access_token='.$token; } return $this->domain.'/api/v3/user?access_token='.$token; From 831f329e1c8ecd7a9ea283c72dac37ca530b7f0f Mon Sep 17 00:00:00 2001 From: jeremykendall Date: Mon, 29 Dec 2014 04:18:33 -0600 Subject: [PATCH 4/5] Updates urlEmailEquals for use with Github Enterprise See #188. --- src/Provider/Github.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/Provider/Github.php b/src/Provider/Github.php index 50124da..b78727b 100644 --- a/src/Provider/Github.php +++ b/src/Provider/Github.php @@ -30,7 +30,10 @@ class Github extends AbstractProvider public function urlUserEmails(\League\OAuth2\Client\Token\AccessToken $token) { - return 'https://api.github.com/user/emails?access_token='.$token; + if ($this->domain === 'https://github.com') { + return $this->domain.'/user/emails?access_token='.$token; + } + return $this->domain.'/api/v3/user/emails?access_token='.$token; } public function userDetails($response, \League\OAuth2\Client\Token\AccessToken $token) From 63d4bc6d941a98cae0c347947dd9e53def5de8a4 Mon Sep 17 00:00:00 2001 From: jeremykendall Date: Mon, 29 Dec 2014 04:19:32 -0600 Subject: [PATCH 5/5] Adds emails endpoint to GithubTest::testGithubEnterpriseDomainUrls --- test/src/Provider/GithubTest.php | 1 + 1 file changed, 1 insertion(+) diff --git a/test/src/Provider/GithubTest.php b/test/src/Provider/GithubTest.php index 1e6c0e2..c0843ca 100644 --- a/test/src/Provider/GithubTest.php +++ b/test/src/Provider/GithubTest.php @@ -131,6 +131,7 @@ class GithubTest extends \PHPUnit_Framework_TestCase $this->assertEquals($this->provider->domain.'/login/oauth/authorize', $this->provider->urlAuthorize()); $this->assertEquals($this->provider->domain.'/login/oauth/access_token', $this->provider->urlAccessToken()); $this->assertEquals($this->provider->domain.'/api/v3/user?access_token=mock_access_token', $this->provider->urlUserDetails($token)); + $this->assertEquals($this->provider->domain.'/api/v3/user/emails?access_token=mock_access_token', $this->provider->urlUserEmails($token)); } public function testUserEmails()