Skip to content

Commit

Permalink
Merge pull request #429 from PedroAmorim/pinterest
Browse files Browse the repository at this point in the history
Add service Pinterest.
  • Loading branch information
elliotchance committed Oct 7, 2015
2 parents 848e4e0 + 5494db9 commit a48f63c
Show file tree
Hide file tree
Showing 5 changed files with 368 additions and 0 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ Included service implementations
- Netatmo
- Parrot Flower Power
- PayPal
- Pinterest
- Pocket
- Reddit
- RunKeeper
Expand Down
4 changes: 4 additions & 0 deletions examples/init.example.php
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,10 @@
'key' => '',
'secret' => '',
),
'pinterest' => array(
'key' => '',
'secret' => '',
),
'pocket' => array(
'key' => '',
),
Expand Down
51 changes: 51 additions & 0 deletions examples/pinterest.php
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>";
}
117 changes: 117 additions & 0 deletions src/OAuth/OAuth2/Service/Pinterest.php
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;
}
}
195 changes: 195 additions & 0 deletions tests/Unit/OAuth2/Service/PinterestTest.php
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'));
}
}

0 comments on commit a48f63c

Please sign in to comment.