AbstractProvider::getScope()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

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