1<?php
2/**
3 * Delicious service.
4 *
5 * @author  Pedro Amorim <contact@pamorim.fr>
6 * @license http://www.opensource.org/licenses/mit-license.html  MIT License
7 * @link    https://github.com/SciDevs/delicious-api/blob/master/api/oauth.md
8 */
9
10namespace OAuth\OAuth2\Service;
11
12use OAuth\OAuth2\Token\StdOAuth2Token;
13use OAuth\Common\Http\Exception\TokenResponseException;
14use OAuth\Common\Http\Uri\Uri;
15use OAuth\Common\Consumer\CredentialsInterface;
16use OAuth\Common\Http\Client\ClientInterface;
17use OAuth\Common\Storage\TokenStorageInterface;
18use OAuth\Common\Http\Uri\UriInterface;
19
20/**
21 * Delicious service.
22 *
23 * @author  Pedro Amorim <contact@pamorim.fr>
24 * @license http://www.opensource.org/licenses/mit-license.html  MIT License
25 * @link    https://github.com/SciDevs/delicious-api/blob/master/api/oauth.md
26 */
27class Delicious extends AbstractService
28{
29    public function __construct(
30        CredentialsInterface $credentials,
31        ClientInterface $httpClient,
32        TokenStorageInterface $storage,
33        $scopes = array(),
34        UriInterface $baseApiUri = null
35    ) {
36        parent::__construct(
37            $credentials,
38            $httpClient,
39            $storage,
40            $scopes,
41            $baseApiUri,
42            true
43        );
44
45        if (null === $baseApiUri) {
46            $this->baseApiUri = new Uri('https://api.del.icio.us/v1/');
47        }
48    }
49
50    /**
51     * {@inheritdoc}
52     */
53    public function getAuthorizationEndpoint()
54    {
55        return new Uri('https://delicious.com/auth/authorize');
56
57    }
58
59    /**
60     * {@inheritdoc}
61     */
62    public function getAccessTokenEndpoint()
63    {
64        return new Uri('https://avosapi.delicious.com/api/v1/oauth/token');
65    }
66
67    /**
68     * {@inheritdoc}
69     */
70    protected function getAuthorizationMethod()
71    {
72        return static::AUTHORIZATION_METHOD_HEADER_BEARER;
73    }
74
75    /**
76     * {@inheritdoc}
77     */
78    protected function parseAccessTokenResponse($responseBody)
79    {
80        $data = json_decode($responseBody, true);
81
82        if (null === $data || !is_array($data)) {
83            throw new TokenResponseException('Unable to parse response.');
84        } elseif (isset($data['error'])) {
85            throw new TokenResponseException(
86                'Error in retrieving token: "' . $data['error'] . '"'
87            );
88        }
89
90        $token = new StdOAuth2Token();
91        $token->setAccessToken($data['access_token']);
92
93        if (isset($data['expires_in'])) {
94            $token->setLifetime($data['expires_in']);
95            unset($data['expires_in']);
96        }
97        if (isset($data['refresh_token'])) {
98            $token->setRefreshToken($data['refresh_token']);
99            unset($data['refresh_token']);
100        }
101
102        unset($data['access_token']);
103
104        $token->setExtraParams($data);
105
106        return $token;
107    }
108
109
110    // Special, delicious didn't respect the oauth2 RFC and need a grant_type='code'
111    /**
112     * {@inheritdoc}
113     */
114    public function requestAccessToken($code, $state = null)
115    {
116        if (null !== $state) {
117            $this->validateAuthorizationState($state);
118        }
119
120        $bodyParams = array(
121            'code'          => $code,
122            'client_id'     => $this->credentials->getConsumerId(),
123            'client_secret' => $this->credentials->getConsumerSecret(),
124            'redirect_uri'  => $this->credentials->getCallbackUrl(),
125            'grant_type'    => 'code',
126        );
127
128        $responseBody = $this->httpClient->retrieveResponse(
129            $this->getAccessTokenEndpoint(),
130            $bodyParams,
131            $this->getExtraOAuthHeaders()
132        );
133
134        $token = $this->parseAccessTokenResponse($responseBody);
135        $this->storage->storeAccessToken($this->service(), $token);
136
137        return $token;
138    }
139}
140