Failed Conditions
Push — newinternal ( b66232...216d62 )
by Simon
16:33 queued 06:35
created

OAuthProtocolHelper   A

Complexity

Total Complexity 17

Size/Duplication

Total Lines 232
Duplicated Lines 3.88 %

Coupling/Cohesion

Components 1
Dependencies 4

Importance

Changes 0
Metric Value
dl 9
loc 232
rs 10
c 0
b 0
f 0
wmc 17
lcom 1
cbo 4

6 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 15 1
A getRequestToken() 0 32 4
A getAuthoriseUrl() 0 4 1
A callbackCompleted() 0 35 4
A getIdentityTicket() 0 32 3
A apiCall() 9 36 4

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

1
<?php
2
/******************************************************************************
3
 * Wikipedia Account Creation Assistance tool                                 *
4
 *                                                                            *
5
 * All code in this file is released into the public domain by the ACC        *
6
 * Development Team. Please see team.json for a list of contributors.         *
7
 ******************************************************************************/
8
9
namespace Waca\Helpers;
10
11
use Exception;
12
use JWT;
13
use OAuthConsumer;
14
use OAuthRequest;
15
use OAuthSignatureMethod_HMAC_SHA1;
16
use OAuthToken;
17
use stdClass;
18
use Waca\Exceptions\ApplicationLogicException;
19
use Waca\Exceptions\CurlException;
20
use Waca\Exceptions\OAuthException;
21
use Waca\Helpers\Interfaces\IOAuthProtocolHelper;
22
23
class OAuthProtocolHelper implements IOAuthProtocolHelper
24
{
25
    private $oauthConsumer;
26
    /**
27
     * @var string
28
     */
29
    private $oauthEndpoint;
30
    /**
31
     * @var string
32
     */
33
    private $consumerToken;
34
    /**
35
     * @var string
36
     */
37
    private $consumerSecret;
38
    /**
39
     * @var HttpHelper
40
     */
41
    private $httpHelper;
42
    /**
43
     * @var string
44
     */
45
    private $mediawikiWebServiceEndpoint;
46
47
    /**
48
     * OAuthHelper constructor.
49
     *
50
     * @param string     $oauthEndpoint
51
     * @param string     $consumerKey
52
     * @param string     $consumerSecret
53
     * @param HttpHelper $httpHelper
54
     * @param string     $mediawikiWebServiceEndpoint
55
     */
56
    public function __construct(
57
        $oauthEndpoint,
58
        $consumerKey,
59
        $consumerSecret,
60
        HttpHelper $httpHelper,
61
        $mediawikiWebServiceEndpoint
62
    ) {
63
        $this->oauthEndpoint = $oauthEndpoint;
64
        $this->consumerToken = $consumerKey;
65
        $this->consumerSecret = $consumerSecret;
66
        $this->httpHelper = $httpHelper;
67
68
        $this->oauthConsumer = new OAuthConsumer($this->consumerToken, $this->consumerSecret);
69
        $this->mediawikiWebServiceEndpoint = $mediawikiWebServiceEndpoint;
70
    }
71
72
    /**
73
     * @return stdClass
74
     *
75
     * @throws Exception
76
     * @throws CurlException
77
     */
78
    public function getRequestToken()
79
    {
80
        $endpoint = $this->oauthEndpoint . '/initiate&format=json&oauth_callback=oob';
81
82
        $parsedUrl = parse_url($endpoint);
83
        $urlParameters = array();
84
        parse_str($parsedUrl['query'], $urlParameters);
85
86
        $req_req = OAuthRequest::from_consumer_and_token($this->oauthConsumer, null, 'GET', $endpoint, $urlParameters);
87
        $hmac_method = new OAuthSignatureMethod_HMAC_SHA1();
88
        $req_req->sign_request($hmac_method, $this->oauthConsumer, null);
89
90
        $targetUrl = (string)$req_req;
91
92
        $data = $this->httpHelper->get($targetUrl, null);
93
94
        if ($data === false) {
95
            throw new CurlException('Curl error: ' . $this->httpHelper->getError());
96
        }
97
98
        $token = json_decode($data);
99
100
        if (!isset($token)) {
101
            throw new OAuthException('Unknown error encountered getting request token while decoding json data.');
102
        }
103
104
        if (isset($token->error)) {
105
            throw new OAuthException('Error encountered while getting request token: ' . $token->error);
106
        }
107
108
        return $token;
109
    }
110
111
    /**
112
     * @param string $requestToken
113
     *
114
     * @return string
115
     */
116
    public function getAuthoriseUrl($requestToken)
117
    {
118
        return "{$this->oauthEndpoint}/authorize&oauth_token={$requestToken}&oauth_consumer_key={$this->consumerToken}";
119
    }
120
121
    /**
122
     * @param string $oauthRequestToken
123
     * @param string $oauthRequestSecret
124
     * @param string $oauthVerifier
125
     *
126
     * @return stdClass
127
     * @throws CurlException
128
     * @throws Exception
129
     */
130
    public function callbackCompleted($oauthRequestToken, $oauthRequestSecret, $oauthVerifier)
131
    {
132
        $endpoint = $this->oauthEndpoint . '/token&format=json';
133
134
        $requestConsumer = new OAuthConsumer($oauthRequestToken, $oauthRequestSecret);
135
136
        $parsedUrl = parse_url($endpoint);
137
        parse_str($parsedUrl['query'], $urlParameters);
138
        $urlParameters['oauth_verifier'] = trim($oauthVerifier);
139
140
        $acc_req = OAuthRequest::from_consumer_and_token($this->oauthConsumer, $requestConsumer, 'GET', $endpoint,
141
            $urlParameters);
142
        $hmac_method = new OAuthSignatureMethod_HMAC_SHA1();
143
        $acc_req->sign_request($hmac_method, $this->oauthConsumer, $requestConsumer);
144
145
        $targetUrl = (string)$acc_req;
146
147
        $data = $this->httpHelper->get($targetUrl, null);
148
149
        if ($data === false) {
150
            throw new CurlException('Curl error: ' . $this->httpHelper->getError());
151
        }
152
153
        $token = json_decode($data);
154
155
        if (!isset($token)) {
156
            throw new OAuthException('Unknown error encountered getting access token while decoding json data.');
157
        }
158
159
        if (isset($token->error)) {
160
            throw new OAuthException('Error encountered while getting access token: ' . $token->error);
161
        }
162
163
        return $token;
164
    }
165
166
    /**
167
     * @param string $oauthAccessToken
168
     * @param string $oauthAccessSecret
169
     *
170
     * @return stdClass
171
     * @throws CurlException
172
     * @throws Exception
173
     */
174
    public function getIdentityTicket($oauthAccessToken, $oauthAccessSecret)
175
    {
176
        $endpoint = $this->oauthEndpoint . '/identify&format=json';
177
178
        $oauthToken = new OAuthToken($oauthAccessToken, $oauthAccessSecret);
179
180
        $parsedUrl = parse_url($endpoint);
181
        parse_str($parsedUrl['query'], $urlParameters);
182
183
        $acc_req = OAuthRequest::from_consumer_and_token($this->oauthConsumer, $oauthToken, 'GET', $endpoint,
184
            $urlParameters);
185
        $hmac_method = new OAuthSignatureMethod_HMAC_SHA1();
186
        $acc_req->sign_request($hmac_method, $this->oauthConsumer, $oauthToken);
187
188
        $targetUrl = (string)$acc_req;
189
190
        $data = $this->httpHelper->get($targetUrl, null);
191
192
        if ($data === false) {
193
            throw new CurlException('Curl error: ' . $this->httpHelper->getError());
194
        }
195
196
        $decodedData = json_decode($data);
197
198
        if (isset($decodedData->error)) {
199
            throw new OAuthException($decodedData->error);
200
        }
201
202
        $identity = JWT::decode($data, $this->consumerSecret);
203
204
        return $identity;
205
    }
206
207
    /**
208
     * @param array  $apiParams    array of parameters to send to the API
209
     * @param string $accessToken  user's access token
210
     * @param string $accessSecret user's secret
211
     * @param string $method       HTTP method
212
     *
213
     * @return stdClass
214
     * @throws ApplicationLogicException
215
     * @throws CurlException
216
     * @throws Exception
217
     */
218
    public function apiCall($apiParams, $accessToken, $accessSecret, $method = 'GET')
219
    {
220
        $userToken = new OAuthToken($accessToken, $accessSecret);
221
222
        $apiParams['format'] = 'json';
223
224
        $api_req = OAuthRequest::from_consumer_and_token(
225
            $this->oauthConsumer, // Consumer
226
            $userToken, // User Access Token
227
            $method, // HTTP Method
228
            $this->mediawikiWebServiceEndpoint, // Endpoint url
229
            $apiParams    // Extra signed parameters
230
        );
231
232
        $hmac_method = new OAuthSignatureMethod_HMAC_SHA1();
233
234
        $api_req->sign_request($hmac_method, $this->oauthConsumer, $userToken);
235
236
        $headers = array($api_req->to_header());
237
238 View Code Duplication
        if ($method == 'GET') {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
239
            $data = $this->httpHelper->get($this->mediawikiWebServiceEndpoint, $apiParams, $headers);
240
        }
241
        elseif ($method == 'POST') {
242
            $data = $this->httpHelper->post($this->mediawikiWebServiceEndpoint, $apiParams, $headers);
243
        }
244
        else {
245
            throw new ApplicationLogicException('Unsupported HTTP Method');
246
        }
247
248
        if ($data === false) {
249
            throw new CurlException('Curl error: ' . $this->httpHelper->getError());
250
        }
251
252
        return json_decode($data);
253
    }
254
}
255