Skip to content

Commit cf3770e

Browse files
committed
Merge pull request #433 from PedroAmorim/deezer
Add service Deezer
2 parents 92f3ee6 + 237ae54 commit cf3770e

File tree

5 files changed

+353
-0
lines changed

5 files changed

+353
-0
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ Included service implementations
6666
- Buffer
6767
- Dailymotion
6868
- Delicious
69+
- Deezer
6970
- DeviantArt
7071
- Dropbox
7172
- Eve Online

examples/deezer.php

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
<?php
2+
3+
/**
4+
* Example of retrieving an authentication token of the Deezer service
5+
*
6+
* @author Pedro Amorim <[email protected]>
7+
* @license http://www.opensource.org/licenses/mit-license.html MIT License
8+
* @link http://developers.deezer.com/api/
9+
*/
10+
11+
use OAuth\OAuth2\Service\Deezer;
12+
use OAuth\Common\Storage\Session;
13+
use OAuth\Common\Consumer\Credentials;
14+
use OAuth\Common\Http\Client\CurlClient;
15+
16+
/**
17+
* Bootstrap the example
18+
*/
19+
require_once __DIR__ . '/bootstrap.php';
20+
21+
// Session storage
22+
$storage = new Session();
23+
24+
// Setup the credentials for the requests
25+
$credentials = new Credentials(
26+
$servicesCredentials['deezer']['key'],
27+
$servicesCredentials['deezer']['secret'],
28+
$currentUri->getAbsoluteUri() // Deezer require Https callback's url
29+
);
30+
$serviceFactory->setHttpClient(new CurlClient);
31+
// Instantiate the Deezer service using the credentials, http client and storage mechanism for the token
32+
/** @var $deezerService Deezer */
33+
$deezerService = $serviceFactory->createService('deezer', $credentials, $storage, [Deezer::SCOPE_BASIC_ACCESS, Deezer::SCOPE_OFFLINE_ACCESS, Deezer::SCOPE_EMAIL, Deezer::SCOPE_DELETE_LIBRARY]);
34+
35+
if (!empty($_GET['code'])) {
36+
// retrieve the CSRF state parameter
37+
$state = isset($_GET['state']) ? $_GET['state'] : null;
38+
// This was a callback request from deezer, get the token
39+
$token = $deezerService->requestAccessToken($_GET['code'], $state);
40+
// Show some of the resultant data
41+
$result = json_decode($deezerService->request('user/me'), true);
42+
echo 'Hello ' . ucfirst($result['name'])
43+
. ' your Deezer Id is ' . $result['id'];
44+
echo '<br><img src="'.$result['picture_medium'].'">';
45+
46+
} elseif (!empty($_GET['go']) && $_GET['go'] === 'go') {
47+
$url = $deezerService->getAuthorizationUri();
48+
header('Location: ' . $url);
49+
} else {
50+
$url = $currentUri->getRelativeUri() . '?go=go';
51+
echo "<a href='$url'>Login with Deezer!</a>";
52+
}

examples/init.example.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,10 @@
4747
'key' => '',
4848
'secret' => '',
4949
),
50+
'deezer' => array(
51+
'key' => '',
52+
'secret' => '',
53+
),
5054
'deviantart' => array(
5155
'key' => '',
5256
'secret' => '',
Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
<?php
2+
/**
3+
* Deezer service.
4+
*
5+
* @author Pedro Amorim <[email protected]>
6+
* @license http://www.opensource.org/licenses/mit-license.html MIT License
7+
* @link http://developers.deezer.com/api/
8+
*/
9+
10+
namespace OAuth\OAuth2\Service;
11+
12+
use OAuth\OAuth2\Token\StdOAuth2Token;
13+
use OAuth\Common\Http\Exception\TokenResponseException;
14+
use OAuth\Common\Http\Uri\Uri;
15+
use OAuth\Common\Consumer\CredentialsInterface;
16+
use OAuth\Common\Http\Client\ClientInterface;
17+
use OAuth\Common\Storage\TokenStorageInterface;
18+
use OAuth\Common\Http\Uri\UriInterface;
19+
20+
/**
21+
* Deezer service.
22+
*
23+
* @author Pedro Amorim <[email protected]>
24+
* @license http://www.opensource.org/licenses/mit-license.html MIT License
25+
* @link http://developers.deezer.com/api/
26+
*/
27+
class Deezer extends AbstractService
28+
{
29+
/**
30+
* Defined scopes
31+
* http://developers.deezer.com/api/permissions
32+
*/
33+
const SCOPE_BASIC_ACCESS = 'basic_access'; // Access users basic information
34+
const SCOPE_EMAIL = 'email'; // Get the user's email
35+
const SCOPE_OFFLINE_ACCESS = 'offline_access'; // Access user data any time
36+
const SCOPE_MANAGE_LIBRARY = 'manage_library'; // Manage users' library
37+
const SCOPE_MANAGE_COMMUNITY = 'manage_community'; // Manage users' friends
38+
const SCOPE_DELETE_LIBRARY = 'delete_library'; // Delete library items
39+
const SCOPE_LISTENING_HISTORY = 'listening_history'; // Access the user's listening history
40+
41+
public function __construct(
42+
CredentialsInterface $credentials,
43+
ClientInterface $httpClient,
44+
TokenStorageInterface $storage,
45+
$scopes = array(),
46+
UriInterface $baseApiUri = null
47+
) {
48+
parent::__construct(
49+
$credentials,
50+
$httpClient,
51+
$storage,
52+
$scopes,
53+
$baseApiUri,
54+
true
55+
);
56+
57+
if (null === $baseApiUri) {
58+
$this->baseApiUri = new Uri('https://api.deezer.com/');
59+
}
60+
}
61+
62+
/**
63+
* {@inheritdoc}
64+
*/
65+
public function getAuthorizationEndpoint()
66+
{
67+
return new Uri('https://connect.deezer.com/oauth/auth.php');
68+
}
69+
70+
/**
71+
* {@inheritdoc}
72+
*/
73+
public function getAccessTokenEndpoint()
74+
{
75+
return new Uri('https://connect.deezer.com/oauth/access_token.php');
76+
}
77+
78+
/**
79+
* {@inheritdoc}
80+
*/
81+
protected function getAuthorizationMethod()
82+
{
83+
return static::AUTHORIZATION_METHOD_QUERY_STRING;
84+
}
85+
86+
/**
87+
* {@inheritdoc}
88+
*/
89+
protected function parseAccessTokenResponse($responseBody)
90+
{
91+
parse_str($responseBody, $data);
92+
if (null === $data || !is_array($data) || empty($data)) {
93+
throw new TokenResponseException('Unable to parse response.');
94+
} elseif (isset($data['error'])) {
95+
throw new TokenResponseException(
96+
'Error in retrieving token: "' . $data['error'] . '"'
97+
);
98+
} elseif (isset($data['error_reason'])) {
99+
throw new TokenResponseException(
100+
'Error in retrieving token: "' . $data['error_reason'] . '"'
101+
);
102+
}
103+
104+
$token = new StdOAuth2Token();
105+
$token->setAccessToken($data['access_token']);
106+
$token->setLifeTime($data['expires']);
107+
108+
// I hope one day Deezer add a refresh token :)
109+
if (isset($data['refresh_token'])) {
110+
$token->setRefreshToken($data['refresh_token']);
111+
unset($data['refresh_token']);
112+
}
113+
114+
unset($data['access_token']);
115+
unset($data['expires']);
116+
117+
$token->setExtraParams($data);
118+
119+
return $token;
120+
}
121+
}
Lines changed: 175 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,175 @@
1+
<?php
2+
3+
namespace OAuthTest\Unit\OAuth2\Service;
4+
5+
use OAuth\OAuth2\Service\Deezer;
6+
use OAuth\Common\Token\TokenInterface;
7+
8+
class DeezerTest extends \PHPUnit_Framework_TestCase
9+
{
10+
/**
11+
* @covers OAuth\OAuth2\Service\Deezer::__construct
12+
*/
13+
public function testConstructCorrectInterfaceWithoutCustomUri()
14+
{
15+
$service = new Deezer(
16+
$this->getMock('\\OAuth\\Common\\Consumer\\CredentialsInterface'),
17+
$this->getMock('\\OAuth\\Common\\Http\\Client\\ClientInterface'),
18+
$this->getMock('\\OAuth\\Common\\Storage\\TokenStorageInterface')
19+
);
20+
21+
$this->assertInstanceOf('\\OAuth\\OAuth2\\Service\\ServiceInterface', $service);
22+
}
23+
24+
/**
25+
* @covers OAuth\OAuth2\Service\Deezer::__construct
26+
*/
27+
public function testConstructCorrectInstanceWithoutCustomUri()
28+
{
29+
$service = new Deezer(
30+
$this->getMock('\\OAuth\\Common\\Consumer\\CredentialsInterface'),
31+
$this->getMock('\\OAuth\\Common\\Http\\Client\\ClientInterface'),
32+
$this->getMock('\\OAuth\\Common\\Storage\\TokenStorageInterface')
33+
);
34+
35+
$this->assertInstanceOf('\\OAuth\\OAuth2\\Service\\AbstractService', $service);
36+
}
37+
38+
/**
39+
* @covers OAuth\OAuth2\Service\Deezer::__construct
40+
*/
41+
public function testConstructCorrectInstanceWithCustomUri()
42+
{
43+
$service = new Deezer(
44+
$this->getMock('\\OAuth\\Common\\Consumer\\CredentialsInterface'),
45+
$this->getMock('\\OAuth\\Common\\Http\\Client\\ClientInterface'),
46+
$this->getMock('\\OAuth\\Common\\Storage\\TokenStorageInterface'),
47+
array(),
48+
$this->getMock('\\OAuth\\Common\\Http\\Uri\\UriInterface')
49+
);
50+
51+
$this->assertInstanceOf('\\OAuth\\OAuth2\\Service\\AbstractService', $service);
52+
}
53+
54+
/**
55+
* @covers OAuth\OAuth2\Service\Deezer::__construct
56+
* @covers OAuth\OAuth2\Service\Deezer::getAuthorizationEndpoint
57+
*/
58+
public function testGetAuthorizationEndpoint()
59+
{
60+
$service = new Deezer(
61+
$this->getMock('\\OAuth\\Common\\Consumer\\CredentialsInterface'),
62+
$this->getMock('\\OAuth\\Common\\Http\\Client\\ClientInterface'),
63+
$this->getMock('\\OAuth\\Common\\Storage\\TokenStorageInterface')
64+
);
65+
66+
$this->assertSame(
67+
'https://connect.deezer.com/oauth/auth.php',
68+
$service->getAuthorizationEndpoint()->getAbsoluteUri()
69+
);
70+
}
71+
72+
/**
73+
* @covers OAuth\OAuth2\Service\Deezer::__construct
74+
* @covers OAuth\OAuth2\Service\Deezer::getAccessTokenEndpoint
75+
*/
76+
public function testGetAccessTokenEndpoint()
77+
{
78+
$service = new Deezer(
79+
$this->getMock('\\OAuth\\Common\\Consumer\\CredentialsInterface'),
80+
$this->getMock('\\OAuth\\Common\\Http\\Client\\ClientInterface'),
81+
$this->getMock('\\OAuth\\Common\\Storage\\TokenStorageInterface')
82+
);
83+
84+
$this->assertSame(
85+
'https://connect.deezer.com/oauth/access_token.php',
86+
$service->getAccessTokenEndpoint()->getAbsoluteUri()
87+
);
88+
}
89+
90+
/**
91+
* @covers OAuth\OAuth2\Service\Deezer::__construct
92+
* @covers OAuth\OAuth2\Service\Deezer::getAuthorizationMethod
93+
*/
94+
public function testGetAuthorizationMethod()
95+
{
96+
$client = $this->getMock('\\OAuth\\Common\\Http\\Client\\ClientInterface');
97+
$client->expects($this->once())->method('retrieveResponse')->will($this->returnArgument(0));
98+
99+
$token = $this->getMock('\\OAuth\\OAuth2\\Token\\TokenInterface');
100+
$token->expects($this->once())->method('getEndOfLife')->will($this->returnValue(TokenInterface::EOL_NEVER_EXPIRES));
101+
$token->expects($this->once())->method('getAccessToken')->will($this->returnValue('foo'));
102+
103+
$storage = $this->getMock('\\OAuth\\Common\\Storage\\TokenStorageInterface');
104+
$storage->expects($this->once())->method('retrieveAccessToken')->will($this->returnValue($token));
105+
106+
$service = new Deezer(
107+
$this->getMock('\\OAuth\\Common\\Consumer\\CredentialsInterface'),
108+
$client,
109+
$storage
110+
);
111+
112+
$uri = $service->request('https://pieterhordijk.com/my/awesome/path');
113+
$absoluteUri = parse_url($uri->getAbsoluteUri());
114+
115+
$this->assertSame('access_token=foo', $absoluteUri['query']);
116+
}
117+
118+
/**
119+
* @covers OAuth\OAuth2\Service\Deezer::__construct
120+
* @covers OAuth\OAuth2\Service\Deezer::parseAccessTokenResponse
121+
*/
122+
public function testParseAccessTokenResponseThrowsExceptionOnNulledResponse()
123+
{
124+
$client = $this->getMock('\\OAuth\\Common\\Http\\Client\\ClientInterface');
125+
$client->expects($this->once())->method('retrieveResponse')->will($this->returnValue(null));
126+
127+
$service = new Deezer(
128+
$this->getMock('\\OAuth\\Common\\Consumer\\CredentialsInterface'),
129+
$client,
130+
$this->getMock('\\OAuth\\Common\\Storage\\TokenStorageInterface')
131+
);
132+
133+
$this->setExpectedException('\\OAuth\\Common\\Http\\Exception\\TokenResponseException');
134+
135+
$service->requestAccessToken('foo');
136+
}
137+
138+
/**
139+
* @covers OAuth\OAuth2\Service\Deezer::__construct
140+
* @covers OAuth\OAuth2\Service\Deezer::parseAccessTokenResponse
141+
*/
142+
public function testParseAccessTokenResponseThrowsExceptionOnError()
143+
{
144+
$client = $this->getMock('\\OAuth\\Common\\Http\\Client\\ClientInterface');
145+
$client->expects($this->once())->method('retrieveResponse')->will($this->returnValue('error_reason=user_denied'));
146+
147+
$service = new Deezer(
148+
$this->getMock('\\OAuth\\Common\\Consumer\\CredentialsInterface'),
149+
$client,
150+
$this->getMock('\\OAuth\\Common\\Storage\\TokenStorageInterface')
151+
);
152+
153+
$this->setExpectedException('\\OAuth\\Common\\Http\\Exception\\TokenResponseException');
154+
155+
$service->requestAccessToken('foo');
156+
}
157+
158+
/**
159+
* @covers OAuth\OAuth2\Service\Deezer::__construct
160+
* @covers OAuth\OAuth2\Service\Deezer::parseAccessTokenResponse
161+
*/
162+
public function testParseAccessTokenResponseValid()
163+
{
164+
$client = $this->getMock('\\OAuth\\Common\\Http\\Client\\ClientInterface');
165+
$client->expects($this->once())->method('retrieveResponse')->will($this->returnValue('access_token=foo&expires=bar'));
166+
167+
$service = new Deezer(
168+
$this->getMock('\\OAuth\\Common\\Consumer\\CredentialsInterface'),
169+
$client,
170+
$this->getMock('\\OAuth\\Common\\Storage\\TokenStorageInterface')
171+
);
172+
173+
$this->assertInstanceOf('\\OAuth\\OAuth2\\Token\\StdOAuth2Token', $service->requestAccessToken('foo'));
174+
}
175+
}

0 commit comments

Comments
 (0)