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') { |
|
|
|
|
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
|
|
|
|
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.