-
Notifications
You must be signed in to change notification settings - Fork 452
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #429 from PedroAmorim/pinterest
Add service Pinterest.
- Loading branch information
Showing
5 changed files
with
368 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
<?php | ||
|
||
/** | ||
* Example of retrieving an authentication token of the Pinterest service | ||
* | ||
* @author Pedro Amorim <[email protected]> | ||
* @license http://www.opensource.org/licenses/mit-license.html MIT License | ||
* @link https://developers.pinterest.com/docs/api/overview/ | ||
*/ | ||
|
||
use OAuth\OAuth2\Service\Pinterest; | ||
use OAuth\Common\Storage\Session; | ||
use OAuth\Common\Consumer\Credentials; | ||
use OAuth\Common\Http\Client\CurlClient; | ||
|
||
/** | ||
* Bootstrap the example | ||
*/ | ||
require_once __DIR__ . '/bootstrap.php'; | ||
|
||
// Session storage | ||
$storage = new Session(); | ||
|
||
// Setup the credentials for the requests | ||
$credentials = new Credentials( | ||
$servicesCredentials['pinterest']['key'], | ||
$servicesCredentials['pinterest']['secret'], | ||
preg_replace('$http://$', 'https://', $currentUri->getAbsoluteUri()) // Pinterest require Https callback's url | ||
); | ||
$serviceFactory->setHttpClient(new CurlClient); | ||
// Instantiate the Pinterest service using the credentials, http client and storage mechanism for the token | ||
/** @var $pinterestService Pinterest */ | ||
$pinterestService = $serviceFactory->createService('pinterest', $credentials, $storage, [Pinterest::SCOPE_READ_PUBLIC]); | ||
|
||
if (!empty($_GET['code'])) { | ||
// retrieve the CSRF state parameter | ||
$state = isset($_GET['state']) ? $_GET['state'] : null; | ||
// This was a callback request from pinterest, get the token | ||
$token = $pinterestService->requestAccessToken($_GET['code'], $state); | ||
// Show some of the resultant data | ||
$result = json_decode($pinterestService->request('v1/me/'), true); | ||
echo 'Hello ' . ucfirst($result['data']['first_name']) | ||
. ' ' . strtoupper($result['data']['last_name']) | ||
. ' your Pinterst Id is ' . $result['data']['id']; | ||
} elseif (!empty($_GET['go']) && $_GET['go'] === 'go') { | ||
$url = $pinterestService->getAuthorizationUri(); | ||
header('Location: ' . $url); | ||
} else { | ||
$url = $currentUri->getRelativeUri() . '?go=go'; | ||
echo "<a href='$url'>Login with Pinterest!</a>"; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,117 @@ | ||
<?php | ||
/** | ||
* Pinterest service. | ||
* | ||
* @author Pedro Amorim <[email protected]> | ||
* @license http://www.opensource.org/licenses/mit-license.html MIT License | ||
* @link https://developers.pinterest.com/docs/api/overview/ | ||
*/ | ||
|
||
namespace OAuth\OAuth2\Service; | ||
|
||
use OAuth\OAuth2\Token\StdOAuth2Token; | ||
use OAuth\Common\Http\Exception\TokenResponseException; | ||
use OAuth\Common\Http\Uri\Uri; | ||
use OAuth\Common\Consumer\CredentialsInterface; | ||
use OAuth\Common\Http\Client\ClientInterface; | ||
use OAuth\Common\Storage\TokenStorageInterface; | ||
use OAuth\Common\Http\Uri\UriInterface; | ||
|
||
/** | ||
* Pinterest service. | ||
* | ||
* @author Pedro Amorim <[email protected]> | ||
* @license http://www.opensource.org/licenses/mit-license.html MIT License | ||
* @link https://developers.pinterest.com/docs/api/overview/ | ||
*/ | ||
class Pinterest extends AbstractService | ||
{ | ||
/** | ||
* Defined scopes - More scopes are listed here: | ||
* https://developers.pinterest.com/docs/api/overview/ | ||
*/ | ||
const SCOPE_READ_PUBLIC = 'read_public'; // read a user’s Pins, boards and likes | ||
const SCOPE_WRITE_PUBLIC = 'write_public'; // write Pins, boards, likes | ||
const SCOPE_READ_RELATIONSHIPS = 'read_relationships'; // read a user’s follows (boards, users, interests) | ||
const SCOPE_WRITE_RELATIONSHIPS = 'write_relationships'; // follow boards, users and interests | ||
|
||
public function __construct( | ||
CredentialsInterface $credentials, | ||
ClientInterface $httpClient, | ||
TokenStorageInterface $storage, | ||
$scopes = array(), | ||
UriInterface $baseApiUri = null | ||
) { | ||
parent::__construct( | ||
$credentials, | ||
$httpClient, | ||
$storage, | ||
$scopes, | ||
$baseApiUri, | ||
true | ||
); | ||
|
||
if (null === $baseApiUri) { | ||
$this->baseApiUri = new Uri('https://api.pinterest.com/'); | ||
} | ||
} | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function getAuthorizationEndpoint() | ||
{ | ||
return new Uri('https://api.pinterest.com/oauth/'); | ||
} | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function getAccessTokenEndpoint() | ||
{ | ||
return new Uri('https://api.pinterest.com/v1/oauth/token'); | ||
} | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
protected function getAuthorizationMethod() | ||
{ | ||
return static::AUTHORIZATION_METHOD_HEADER_BEARER; | ||
} | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
protected function parseAccessTokenResponse($responseBody) | ||
{ | ||
$data = json_decode($responseBody, true); | ||
|
||
if (null === $data || !is_array($data)) { | ||
throw new TokenResponseException('Unable to parse response.'); | ||
} elseif (isset($data['error'])) { | ||
throw new TokenResponseException( | ||
'Error in retrieving token: "' . $data['error'] . '"' | ||
); | ||
} | ||
|
||
$token = new StdOAuth2Token(); | ||
$token->setAccessToken($data['access_token']); | ||
|
||
if (isset($data['expires_in'])) { | ||
$token->setLifeTime($data['expires_in']); | ||
unset($data['expires_in']); | ||
} | ||
// I hope one day Pinterest add a refresh token :) | ||
if (isset($data['refresh_token'])) { | ||
$token->setRefreshToken($data['refresh_token']); | ||
unset($data['refresh_token']); | ||
} | ||
|
||
unset($data['access_token']); | ||
|
||
$token->setExtraParams($data); | ||
|
||
return $token; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,195 @@ | ||
<?php | ||
|
||
namespace OAuthTest\Unit\OAuth2\Service; | ||
|
||
use OAuth\OAuth2\Service\Pinterest; | ||
use OAuth\Common\Token\TokenInterface; | ||
|
||
class PinterestTest extends \PHPUnit_Framework_TestCase | ||
{ | ||
/** | ||
* @covers OAuth\OAuth2\Service\Pinterest::__construct | ||
*/ | ||
public function testConstructCorrectInterfaceWithoutCustomUri() | ||
{ | ||
$service = new Pinterest( | ||
$this->getMock('\\OAuth\\Common\\Consumer\\CredentialsInterface'), | ||
$this->getMock('\\OAuth\\Common\\Http\\Client\\ClientInterface'), | ||
$this->getMock('\\OAuth\\Common\\Storage\\TokenStorageInterface') | ||
); | ||
|
||
$this->assertInstanceOf('\\OAuth\\OAuth2\\Service\\ServiceInterface', $service); | ||
} | ||
|
||
/** | ||
* @covers OAuth\OAuth2\Service\Pinterest::__construct | ||
*/ | ||
public function testConstructCorrectInstanceWithoutCustomUri() | ||
{ | ||
$service = new Pinterest( | ||
$this->getMock('\\OAuth\\Common\\Consumer\\CredentialsInterface'), | ||
$this->getMock('\\OAuth\\Common\\Http\\Client\\ClientInterface'), | ||
$this->getMock('\\OAuth\\Common\\Storage\\TokenStorageInterface') | ||
); | ||
|
||
$this->assertInstanceOf('\\OAuth\\OAuth2\\Service\\AbstractService', $service); | ||
} | ||
|
||
/** | ||
* @covers OAuth\OAuth2\Service\Pinterest::__construct | ||
*/ | ||
public function testConstructCorrectInstanceWithCustomUri() | ||
{ | ||
$service = new Pinterest( | ||
$this->getMock('\\OAuth\\Common\\Consumer\\CredentialsInterface'), | ||
$this->getMock('\\OAuth\\Common\\Http\\Client\\ClientInterface'), | ||
$this->getMock('\\OAuth\\Common\\Storage\\TokenStorageInterface'), | ||
array(), | ||
$this->getMock('\\OAuth\\Common\\Http\\Uri\\UriInterface') | ||
); | ||
|
||
$this->assertInstanceOf('\\OAuth\\OAuth2\\Service\\AbstractService', $service); | ||
} | ||
|
||
/** | ||
* @covers OAuth\OAuth2\Service\Pinterest::__construct | ||
* @covers OAuth\OAuth2\Service\Pinterest::getAuthorizationEndpoint | ||
*/ | ||
public function testGetAuthorizationEndpoint() | ||
{ | ||
$service = new Pinterest( | ||
$this->getMock('\\OAuth\\Common\\Consumer\\CredentialsInterface'), | ||
$this->getMock('\\OAuth\\Common\\Http\\Client\\ClientInterface'), | ||
$this->getMock('\\OAuth\\Common\\Storage\\TokenStorageInterface') | ||
); | ||
|
||
$this->assertSame( | ||
'https://api.pinterest.com/oauth/', | ||
$service->getAuthorizationEndpoint()->getAbsoluteUri() | ||
); | ||
} | ||
|
||
/** | ||
* @covers OAuth\OAuth2\Service\Pinterest::__construct | ||
* @covers OAuth\OAuth2\Service\Pinterest::getAccessTokenEndpoint | ||
*/ | ||
public function testGetAccessTokenEndpoint() | ||
{ | ||
$service = new Pinterest( | ||
$this->getMock('\\OAuth\\Common\\Consumer\\CredentialsInterface'), | ||
$this->getMock('\\OAuth\\Common\\Http\\Client\\ClientInterface'), | ||
$this->getMock('\\OAuth\\Common\\Storage\\TokenStorageInterface') | ||
); | ||
|
||
$this->assertSame( | ||
'https://api.pinterest.com/v1/oauth/token', | ||
$service->getAccessTokenEndpoint()->getAbsoluteUri() | ||
); | ||
} | ||
|
||
/** | ||
* @covers OAuth\OAuth2\Service\Box::__construct | ||
* @covers OAuth\OAuth2\Service\Box::getAuthorizationMethod | ||
*/ | ||
public function testGetAuthorizationMethod() | ||
{ | ||
$client = $this->getMock('\\OAuth\\Common\\Http\\Client\\ClientInterface'); | ||
$client->expects($this->once())->method('retrieveResponse')->will($this->returnArgument(2)); | ||
|
||
$token = $this->getMock('\\OAuth\\OAuth2\\Token\\TokenInterface'); | ||
$token->expects($this->once())->method('getEndOfLife')->will($this->returnValue(TokenInterface::EOL_NEVER_EXPIRES)); | ||
$token->expects($this->once())->method('getAccessToken')->will($this->returnValue('foo')); | ||
|
||
$storage = $this->getMock('\\OAuth\\Common\\Storage\\TokenStorageInterface'); | ||
$storage->expects($this->once())->method('retrieveAccessToken')->will($this->returnValue($token)); | ||
|
||
$service = new Pinterest( | ||
$this->getMock('\\OAuth\\Common\\Consumer\\CredentialsInterface'), | ||
$client, | ||
$storage | ||
); | ||
|
||
$headers = $service->request('https://pieterhordijk.com/my/awesome/path'); | ||
|
||
$this->assertTrue(array_key_exists('Authorization', $headers)); | ||
$this->assertTrue(in_array('Bearer foo', $headers, true)); | ||
} | ||
|
||
/** | ||
* @covers OAuth\OAuth2\Service\Pinterest::__construct | ||
* @covers OAuth\OAuth2\Service\Pinterest::parseAccessTokenResponse | ||
*/ | ||
public function testParseAccessTokenResponseThrowsExceptionOnNulledResponse() | ||
{ | ||
$client = $this->getMock('\\OAuth\\Common\\Http\\Client\\ClientInterface'); | ||
$client->expects($this->once())->method('retrieveResponse')->will($this->returnValue(null)); | ||
|
||
$service = new Pinterest( | ||
$this->getMock('\\OAuth\\Common\\Consumer\\CredentialsInterface'), | ||
$client, | ||
$this->getMock('\\OAuth\\Common\\Storage\\TokenStorageInterface') | ||
); | ||
|
||
$this->setExpectedException('\\OAuth\\Common\\Http\\Exception\\TokenResponseException'); | ||
|
||
$service->requestAccessToken('foo'); | ||
} | ||
|
||
/** | ||
* @covers OAuth\OAuth2\Service\Pinterest::__construct | ||
* @covers OAuth\OAuth2\Service\Pinterest::parseAccessTokenResponse | ||
*/ | ||
public function testParseAccessTokenResponseThrowsExceptionOnErrorDescription() | ||
{ | ||
$client = $this->getMock('\\OAuth\\Common\\Http\\Client\\ClientInterface'); | ||
$client->expects($this->once())->method('retrieveResponse')->will($this->returnValue('error_description=some_error')); | ||
|
||
$service = new Pinterest( | ||
$this->getMock('\\OAuth\\Common\\Consumer\\CredentialsInterface'), | ||
$client, | ||
$this->getMock('\\OAuth\\Common\\Storage\\TokenStorageInterface') | ||
); | ||
|
||
$this->setExpectedException('\\OAuth\\Common\\Http\\Exception\\TokenResponseException'); | ||
|
||
$service->requestAccessToken('foo'); | ||
} | ||
|
||
/** | ||
* @covers OAuth\OAuth2\Service\Pinterest::__construct | ||
* @covers OAuth\OAuth2\Service\Pinterest::parseAccessTokenResponse | ||
*/ | ||
public function testParseAccessTokenResponseThrowsExceptionOnError() | ||
{ | ||
$client = $this->getMock('\\OAuth\\Common\\Http\\Client\\ClientInterface'); | ||
$client->expects($this->once())->method('retrieveResponse')->will($this->returnValue('error=some_error')); | ||
|
||
$service = new Pinterest( | ||
$this->getMock('\\OAuth\\Common\\Consumer\\CredentialsInterface'), | ||
$client, | ||
$this->getMock('\\OAuth\\Common\\Storage\\TokenStorageInterface') | ||
); | ||
|
||
$this->setExpectedException('\\OAuth\\Common\\Http\\Exception\\TokenResponseException'); | ||
|
||
$service->requestAccessToken('foo'); | ||
} | ||
|
||
/** | ||
* @covers OAuth\OAuth2\Service\Pinterest::__construct | ||
* @covers OAuth\OAuth2\Service\Pinterest::parseAccessTokenResponse | ||
*/ | ||
public function testParseAccessTokenResponseValid() | ||
{ | ||
$client = $this->getMock('\\OAuth\\Common\\Http\\Client\\ClientInterface'); | ||
$client->expects($this->once())->method('retrieveResponse')->will($this->returnValue('{"access_token":"foo","expires_in":"bar"}')); | ||
|
||
$service = new Pinterest( | ||
$this->getMock('\\OAuth\\Common\\Consumer\\CredentialsInterface'), | ||
$client, | ||
$this->getMock('\\OAuth\\Common\\Storage\\TokenStorageInterface') | ||
); | ||
|
||
$this->assertInstanceOf('\\OAuth\\OAuth2\\Token\\StdOAuth2Token', $service->requestAccessToken('foo')); | ||
} | ||
} |