Completed
Push — master ( ee7427...2774a1 )
by Дмитрий
13:08
created

AbstractProvider::getConsumerToken()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 0
cts 4
cp 0
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 0
crap 2
1
<?php
2
/**
3
 * SocialConnect project
4
 * @author: Patsura Dmitry https://github.com/ovr <[email protected]>
5
 */
6
7
namespace SocialConnect\OAuth1;
8
9
use SocialConnect\Common\Http\Client\ClientInterface;
10
use SocialConnect\OAuth1\Exception\UnknownAuthorization;
11
use SocialConnect\Provider\AbstractBaseProvider;
12
use SocialConnect\Provider\Consumer;
13
use SocialConnect\Provider\Exception\InvalidAccessToken;
14
use SocialConnect\Provider\Exception\InvalidResponse;
15
use SocialConnect\Common\Http\Client\Client;
16
use SocialConnect\OAuth1\Exception\InvalidRequestToken;
17
use SocialConnect\OAuth1\Signature\MethodHMACSHA1;
18
use SocialConnect\Provider\Session\SessionInterface;
19
20
abstract class AbstractProvider extends AbstractBaseProvider
21
{
22
    /**
23
     * @var string
24
     */
25
    protected $oauth1Version = '1.0a';
26
27
    /**
28
     * @var string
29
     */
30
    protected $requestTokenMethod = Client::POST;
31
32
    /**
33
     * @var Consumer
34
     */
35
    protected $consumer;
36
37
    /**
38
     * @var Token
39
     */
40
    protected $consumerToken;
41
42
    /**
43
     * @var array
44
     */
45
    protected $scope = [];
46
47
    /**
48
     * @param ClientInterface $httpClient
49
     * @param Consumer $consumer
50
     * @param array $parameters
51
     */
52
    public function __construct(ClientInterface $httpClient, SessionInterface $session, Consumer $consumer, array $parameters)
53
    {
54
        parent::__construct($httpClient, $session, $consumer, $parameters);
55
56
        $this->consumerToken = new Token('', '');
57
    }
58
59
    /**
60
     * @return string
61
     */
62
    abstract public function getAuthorizeUri();
63
64
    /**
65
     * @return string
66
     */
67
    abstract public function getRequestTokenUri();
68
69
    /**
70
     * @return string
71
     */
72
    abstract public function getRequestTokenAccessUri();
73
74
    /**
75
     * @return Token
76
     * @throws InvalidResponse
77
     */
78
    protected function requestAuthToken()
79
    {
80
        $parameters = [];
81
82
        /**
83
         * OAuth Core 1.0 Revision A: oauth_callback: An absolute URL to which the Service Provider will redirect
84
         * the User back when the Obtaining User Authorization step is completed.
85
         *
86
         * http://oauth.net/core/1.0a/#auth_step1
87
         */
88
        if ('1.0a' == $this->oauth1Version) {
89
            $parameters['oauth_callback'] = $this->getRedirectUrl();
90
        }
91
92
        $response = $this->oauthRequest(
93
            $this->getRequestTokenUri(),
94
            $this->requestTokenMethod,
95
            $parameters
96
        );
97
98
        if ($response->isSuccess()) {
99
            $token = $this->parseToken($response->getBody());
100
101
102
            $this->session->set('oauth1_request_token', $token);
103
104
            return $token;
105
        }
106
107
        throw new InvalidResponse('Provider response is not success');
108
    }
109
110
    /**
111
     * Parse Token from response's $body
112
     *
113
     * @param string|boolean $body
114
     * @return Token
115
     * @throws InvalidRequestToken
116
     * @throws InvalidResponse
117
     */
118
    public function parseToken($body)
119
    {
120
        if (empty($body)) {
121
            throw new InvalidResponse('Provider response with empty body');
122
        }
123
124
        parse_str($body, $token);
125
        if (!is_array($token) || !isset($token['oauth_token']) || !isset($token['oauth_token_secret'])) {
126
            throw new InvalidRequestToken;
127
        }
128
129
        return new Token($token['oauth_token'], $token['oauth_token_secret']);
130
    }
131
132
    /**
133
     * @param string $uri
134
     * @param string $method
135
     * @param array $parameters
136
     * @return \SocialConnect\Common\Http\Response
137
     */
138
    public function oauthRequest($uri, $method = Client::GET, $parameters = [], $headers = [])
139
    {
140
        $headers = array_merge([
141
            'Accept' => 'application/json'
142
        ], $headers);
143
144
        if ($method == Client::POST) {
145
            $headers['Content-Type'] = 'application/x-www-form-urlencoded';
146
        }
147
148
        $parameters = array_merge(
149
            [
150
                'oauth_version' => '1.0',
151
                'oauth_nonce' => md5(time() . mt_rand()),
152
                'oauth_timestamp' => time(),
153
                'oauth_consumer_key' => $this->consumer->getKey()
154
            ],
155
            $parameters
156
        );
157
158
        $request = new Request(
159
            $uri,
160
            $parameters,
161
            $method,
162
            $headers
163
        );
164
165
        $request->signRequest(
166
            new MethodHMACSHA1(),
167
            $this->consumer,
168
            $this->consumerToken
169
        );
170
171
        return $this->httpClient->fromRequest($request);
172
    }
173
174
    /**
175
     * @return string
176
     */
177
    public function makeAuthUrl()
178
    {
179
        $urlParameters = [
180
            'oauth_token' => $this->requestAuthToken()->getKey()
181
        ];
182
183
        return $this->getAuthorizeUri() . '?' . http_build_query($urlParameters, '', '&');
184
    }
185
186
    /**
187
     * @param array $parameters
188
     * @return AccessToken
189
     * @throws \SocialConnect\OAuth1\Exception\UnknownAuthorization
190
     */
191
    public function getAccessTokenByRequestParameters(array $parameters)
192
    {
193
        $token = $this->session->get('oauth1_request_token');
194
        if (!$token) {
195
            throw new UnknownAuthorization();
196
        }
197
198
        $this->session->delete('oauth1_request_token');
199
200
        return $this->getAccessToken($token, $parameters['oauth_verifier']);
201
    }
202
203
    /**
204
     * @param Token $token
205
     * @param $oauthVerifier
206
     * @return AccessToken
207
     * @throws InvalidResponse
208
     */
209
    public function getAccessToken(Token $token, $oauthVerifier)
210
    {
211
        $this->consumerToken = $token;
212
213
        $parameters = [
214
            'oauth_consumer_key' => $this->consumer->getKey(),
215
            'oauth_token' => $token->getKey(),
216
            'oauth_verifier' => $oauthVerifier
217
        ];
218
219
        $response = $this->oauthRequest(
220
            $this->getRequestTokenAccessUri(),
221
            $this->requestTokenMethod,
222
            $parameters
223
        );
224
225
        if ($response->getStatusCode() === 200) {
226
            return $this->parseAccessToken($response->getBody());
227
        }
228
229
        throw new InvalidResponse(
230
            'Unexpected response code',
231
            $response->getBody()
232
        );
233
    }
234
235
    /**
236
     * Parse AccessToken from response's $body
237
     *
238
     * @param string|boolean $body
239
     * @return AccessToken
240
     * @throws InvalidAccessToken
241
     * @throws InvalidResponse
242
     */
243
    public function parseAccessToken($body)
244
    {
245
        if (empty($body)) {
246
            throw new InvalidResponse('Provider response with empty body');
247
        }
248
249
        parse_str($body, $token);
250
        if (!is_array($token) || !isset($token['oauth_token']) || !isset($token['oauth_token_secret'])) {
251
            throw new InvalidAccessToken;
252
        }
253
254
        $accessToken = new AccessToken($token['oauth_token'], $token['oauth_token_secret']);
255
        if (isset($token['user_id'])) {
256
            $accessToken->setUserId($token['user_id']);
257
        }
258
259
        return $accessToken;
260
    }
261
262
    /**
263
     * @return array
264
     */
265
    public function getScope()
266
    {
267
        return $this->scope;
268
    }
269
270
    /**
271
     * @param array $scope
272
     */
273
    public function setScope(array $scope)
274
    {
275
        $this->scope = $scope;
276
    }
277
278
    /**
279
     * @param Token $token
280
     */
281
    public function setConsumerToken(Token $token)
282
    {
283
        $this->consumerToken = $token;
284
    }
285
286
    /**
287
     * @return \SocialConnect\OAuth1\Token
288
     */
289
    public function getConsumerToken()
290
    {
291
        return $this->consumerToken;
292
    }
293
}
294