PluginProbe
WP Database Backup – Unlimited Database & Files Backup by Backup for WP / 2.1.1
WP Database Backup – Unlimited Database & Files Backup by Backup for WP v2.1.1
7.13 7.12 trunk 1.1 2.1.1 5.9 6.0 6.1 6.10 6.11 6.12 6.12.1 6.2 6.3 6.4 6.5 6.5.1 6.6 6.7 6.8 6.9 7.0 7.0.1 7.1 7.10 All 34 releases
wp-database-backup / includes / admin / Destination / Dropbox / OAuthSimple.php

OAuthSimple.php in WP Database Backup – Unlimited Database & Files Backup by Backup for WP 2.1.1, at includes/admin/Destination/Dropbox/OAuthSimple.php

526 lines 14.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * OAuthSimple - A simpler version of OAuth
4
5 */
6
7 class OAuthSimple {
8 private $_secrets;
9 private $_default_signature_method;
10 private $_action;
11 private $_nonce_chars;
12
13 /**
14 * Constructor
15 *
16 * @access public
17 * @param api_key (String) The API Key (sometimes referred to as the consumer key) This value is usually supplied by the site you wish to use.
18 * @param shared_secret (String) The shared secret. This value is also usually provided by the site you wish to use.
19 * @return OAuthSimple (Object)
20 */
21 function __construct ($APIKey = "", $sharedSecret=""){
22
23 if (!empty($APIKey))
24 {
25 $this->_secrets['consumer_key'] = $APIKey;
26 }
27
28 if (!empty($sharedSecret))
29 {
30 $this->_secrets['shared_secret'] = $sharedSecret;
31 }
32
33 $this->_default_signature_method = "HMAC-SHA1";
34 $this->_action = "GET";
35 $this->_nonce_chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
36
37 return $this;
38 }
39
40 /**
41 * Reset the parameters and URL
42 *
43 * @access public
44 * @return OAuthSimple (Object)
45 */
46 public function reset() {
47 $this->_parameters = Array();
48 $this->path = NULL;
49 $this->sbs = NULL;
50
51 return $this;
52 }
53
54 /**
55 * Set the parameters either from a hash or a string
56 *
57 * @access public
58 * @param(string, object) List of parameters for the call, this can either be a URI string (e.g. "foo=bar&gorp=banana" or an object/hash)
59 * @return OAuthSimple (Object)
60 */
61 public function setParameters ($parameters=Array()) {
62
63 if (is_string($parameters))
64 {
65 $parameters = $this->_parseParameterString($parameters);
66 }
67 if (empty($this->_parameters))
68 {
69 $this->_parameters = $parameters;
70 }
71 else if (!empty($parameters))
72 {
73 $this->_parameters = array_merge($this->_parameters,$parameters);
74 }
75 if (empty($this->_parameters['oauth_nonce']))
76 {
77 $this->_getNonce();
78 }
79 if (empty($this->_parameters['oauth_timestamp']))
80 {
81 $this->_getTimeStamp();
82 }
83 if (empty($this->_parameters['oauth_consumer_key']))
84 {
85 $this->_getApiKey();
86 }
87 if (empty($this->_parameters['oauth_token']))
88 {
89 $this->_getAccessToken();
90 }
91 if (empty($this->_parameters['oauth_signature_method']))
92 {
93 $this->setSignatureMethod();
94 }
95 if (empty($this->_parameters['oauth_version']))
96 {
97 $this->_parameters['oauth_version']="1.0";
98 }
99
100 return $this;
101 }
102
103 /**
104 * Convenience method for setParameters
105 *
106 * @access public
107 * @see setParameters
108 */
109 public function setQueryString ($parameters)
110 {
111 return $this->setParameters($parameters);
112 }
113
114 /**
115 * Set the target URL (does not include the parameters)
116 *
117 * @param path (String) the fully qualified URI (excluding query arguments) (e.g "http://example.org/foo")
118 * @return OAuthSimple (Object)
119 */
120 public function setURL ($path)
121 {
122 if (empty($path))
123 {
124 throw new OAuthSimpleException('No path specified for OAuthSimple.setURL');
125 }
126 $this->_path=$path;
127
128 return $this;
129 }
130
131 /**
132 * Convenience method for setURL
133 *
134 * @param path (String)
135 * @see setURL
136 */
137 public function setPath ($path)
138 {
139 return $this->_path=$path;
140 }
141
142 /**
143 * Set the "action" for the url, (e.g. GET,POST, DELETE, etc.)
144 *
145 * @param action (String) HTTP Action word.
146 * @return OAuthSimple (Object)
147 */
148 public function setAction ($action)
149 {
150 if (empty($action))
151 {
152 $action = 'GET';
153 }
154 $action = strtoupper($action);
155 if (preg_match('/[^A-Z]/',$action))
156 {
157 throw new OAuthSimpleException('Invalid action specified for OAuthSimple.setAction');
158 }
159 $this->_action = $action;
160
161 return $this;
162 }
163
164 /**
165 * Set the signatures (as well as validate the ones you have)
166 *
167 * @param signatures (object) object/hash of the token/signature pairs {api_key:, shared_secret:, oauth_token: oauth_secret:}
168 * @return OAuthSimple (Object)
169 */
170 public function signatures ($signatures)
171 {
172 if (!empty($signatures) && !is_array($signatures))
173 {
174 throw new OAuthSimpleException('Must pass dictionary array to OAuthSimple.signatures');
175 }
176 if (!empty($signatures))
177 {
178 if (empty($this->_secrets))
179 {
180 $this->_secrets=Array();
181 }
182 $this->_secrets=array_merge($this->_secrets,$signatures);
183 }
184 if (isset($this->_secrets['api_key']))
185 {
186 $this->_secrets['consumer_key'] = $this->_secrets['api_key'];
187 }
188 if (isset($this->_secrets['access_token']))
189 {
190 $this->_secrets['oauth_token'] = $this->_secrets['access_token'];
191 }
192 if (isset($this->_secrets['access_secret']))
193 {
194 $this->_secrets['oauth_secret'] = $this->_secrets['access_secret'];
195 }
196 if (isset($this->_secrets['access_token_secret']))
197 {
198 $this->_secrets['oauth_secret'] = $this->_secrets['access_token_secret'];
199 }
200 if (empty($this->_secrets['consumer_key']))
201 {
202 throw new OAuthSimpleException('Missing required consumer_key in OAuthSimple.signatures');
203 }
204 if (empty($this->_secrets['shared_secret']))
205 {
206 throw new OAuthSimpleException('Missing requires shared_secret in OAuthSimple.signatures');
207 }
208 if (!empty($this->_secrets['oauth_token']) && empty($this->_secrets['oauth_secret']))
209 {
210 throw new OAuthSimpleException('Missing oauth_secret for supplied oauth_token in OAuthSimple.signatures');
211 }
212
213 return $this;
214 }
215
216 public function setTokensAndSecrets($signatures)
217 {
218 return $this->signatures($signatures);
219 }
220
221 /**
222 * Set the signature method (currently only Plaintext or SHA-MAC1)
223 *
224 * @param method (String) Method of signing the transaction (only PLAINTEXT and SHA-MAC1 allowed for now)
225 * @return OAuthSimple (Object)
226 */
227 public function setSignatureMethod ($method="")
228 {
229 if (empty($method))
230 {
231 $method = $this->_default_signature_method;
232 }
233 $method = strtoupper($method);
234 switch($method)
235 {
236 case 'PLAINTEXT':
237 case 'HMAC-SHA1':
238 $this->_parameters['oauth_signature_method']=$method;
239 break;
240 default:
241 throw new OAuthSimpleException ("Unknown signing method $method specified for OAuthSimple.setSignatureMethod");
242 break;
243 }
244
245 return $this;
246 }
247
248 /** sign the request
249 *
250 * note: all arguments are optional, provided you've set them using the
251 * other helper functions.
252 *
253 * @param args (Array) hash of arguments for the call {action, path, parameters (array), method, signatures (array)} all arguments are optional.
254 * @return (Array) signed values
255 */
256 public function sign($args=array())
257 {
258 if (!empty($args['action']))
259 {
260 $this->setAction($args['action']);
261 }
262 if (!empty($args['path']))
263 {
264 $this->setPath($args['path']);
265 }
266 if (!empty($args['method']))
267 {
268 $this->setSignatureMethod($args['method']);
269 }
270 if (!empty($args['signatures']))
271 {
272 $this->signatures($args['signatures']);
273 }
274 if (empty($args['parameters']))
275 {
276 $args['parameters']=array();
277 }
278 $this->setParameters($args['parameters']);
279 $normParams = $this->_normalizedParameters();
280 $this->_parameters['oauth_signature'] = $this->_generateSignature($normParams);
281
282 return Array (
283 'parameters' => $this->_parameters,
284 'signature' => self::_oauthEscape($this->_parameters['oauth_signature']),
285 'signed_url' => $this->_path . '?' . $this->_normalizedParameters(),
286 'header' => $this->getHeaderString(),
287 'sbs'=> $this->sbs
288 );
289 }
290
291 /**
292 * Return a formatted "header" string
293 *
294 * NOTE: This doesn't set the "Authorization: " prefix, which is required.
295 * It's not set because various set header functions prefer different
296 * ways to do that.
297 *
298 * @param args (Array)
299 * @return $result (String)
300 */
301 public function getHeaderString ($args=array())
302 {
303 if (empty($this->_parameters['oauth_signature']))
304 {
305 $this->sign($args);
306 }
307 $result = 'OAuth ';
308
309 foreach ($this->_parameters as $pName => $pValue)
310 {
311 if (strpos($pName,'oauth_') !== 0 || $pName == 'oauth_token_secret2')
312 {
313 continue;
314 }
315 if (is_array($pValue))
316 {
317 foreach ($pValue as $val)
318 {
319 $result .= $pName .'="' . self::_oauthEscape($val) . '", ';
320 }
321 }
322 else
323 {
324 $result .= $pName . '="' . self::_oauthEscape($pValue) . '", ';
325 }
326 }
327
328 return preg_replace('/, $/','',$result);
329 }
330
331 private function _parseParameterString ($paramString)
332 {
333 $elements = explode('&',$paramString);
334 $result = array();
335 foreach ($elements as $element)
336 {
337 list ($key,$token) = explode('=',$element);
338 if ($token)
339 {
340 $token = urldecode($token);
341 }
342 if (!empty($result[$key]))
343 {
344 if (!is_array($result[$key]))
345 {
346 $result[$key] = array($result[$key],$token);
347 }
348 else
349 {
350 array_push($result[$key],$token);
351 }
352 }
353 else
354 $result[$key]=$token;
355 }
356 return $result;
357 }
358
359
360 private static function _oauthEscape($string)
361 {
362 if ($string === 0) { return 0; }
363 if ($string == '0') { return '0'; }
364 if (strlen($string) == 0) { return ''; }
365 if (is_array($string)) {
366 throw new OAuthSimpleException('Array passed to _oauthEscape');
367 }
368 $string = rawurlencode($string);
369
370 $string = str_replace('+','%20',$string);
371 $string = str_replace('!','%21',$string);
372 $string = str_replace('*','%2A',$string);
373 $string = str_replace('\'','%27',$string);
374 $string = str_replace('(','%28',$string);
375 $string = str_replace(')','%29',$string);
376
377 return $string;
378 }
379
380 private function _getNonce($length=5)
381 {
382 $result = '';
383 $cLength = strlen($this->_nonce_chars);
384 for ($i=0; $i < $length; $i++)
385 {
386 $rnum = rand(0,$cLength);
387 $result .= substr($this->_nonce_chars,$rnum,1);
388 }
389 $result = md5($result);
390 $this->_parameters['oauth_nonce'] = $result;
391
392 return $result;
393 }
394
395 private function _getApiKey()
396 {
397 if (empty($this->_secrets['consumer_key']))
398 {
399 throw new OAuthSimpleException('No consumer_key set for OAuthSimple');
400 }
401 $this->_parameters['oauth_consumer_key']=$this->_secrets['consumer_key'];
402
403 return $this->_parameters['oauth_consumer_key'];
404 }
405
406 private function _getAccessToken()
407 {
408 if (!isset($this->_secrets['oauth_secret']))
409 {
410 return '';
411 }
412 if (!isset($this->_secrets['oauth_token']))
413 {
414 throw new OAuthSimpleException('No access token (oauth_token) set for OAuthSimple.');
415 }
416 $this->_parameters['oauth_token'] = $this->_secrets['oauth_token'];
417
418 return $this->_parameters['oauth_token'];
419 }
420
421 private function _getTimeStamp()
422 {
423 return $this->_parameters['oauth_timestamp'] = time();
424 }
425
426 private function _normalizedParameters()
427 {
428 $normalized_keys = array();
429 $return_array = array();
430
431 foreach ( $this->_parameters as $paramName=>$paramValue) {
432 if (!preg_match('/\w+_secret/',$paramName) OR (strpos($paramValue, '@') !== 0 && !file_exists(substr($paramValue, 1))) )
433 {
434 if (is_array($paramValue))
435 {
436 $normalized_keys[self::_oauthEscape($paramName)] = array();
437 foreach($paramValue as $item)
438 {
439 array_push($normalized_keys[self::_oauthEscape($paramName)], self::_oauthEscape($item));
440 }
441 }
442 else
443 {
444 $normalized_keys[self::_oauthEscape($paramName)] = self::_oauthEscape($paramValue);
445 }
446 }
447 }
448
449 ksort($normalized_keys);
450
451 foreach($normalized_keys as $key=>$val)
452 {
453 if (is_array($val))
454 {
455 sort($val);
456 foreach($val as $element)
457 {
458 array_push($return_array, $key . "=" . $element);
459 }
460 }
461 else
462 {
463 array_push($return_array, $key .'='. $val);
464 }
465
466 }
467
468 return join("&", $return_array);
469 }
470
471
472 private function _generateSignature ()
473 {
474 $secretKey = '';
475 if(isset($this->_secrets['shared_secret']))
476 {
477 $secretKey = self::_oauthEscape($this->_secrets['shared_secret']);
478 }
479
480 $secretKey .= '&';
481 if(isset($this->_secrets['oauth_secret']))
482 {
483 $secretKey .= self::_oauthEscape($this->_secrets['oauth_secret']);
484 }
485
486 switch($this->_parameters['oauth_signature_method'])
487 {
488 case 'PLAINTEXT':
489 return urlencode($secretKey);;
490 case 'HMAC-SHA1':
491 $this->sbs = self::_oauthEscape($this->_action).'&'.self::_oauthEscape($this->_path).'&'.self::_oauthEscape($this->_normalizedParameters());
492
493 return base64_encode(hash_hmac('sha1',$this->sbs,$secretKey,TRUE));
494 default:
495 throw new OAuthSimpleException('Unknown signature method for OAuthSimple');
496 break;
497 }
498 }
499 }
500
501 class OAuthSimpleException extends Exception {
502
503 public function __construct($err, $isDebug = FALSE)
504 {
505 self::log_error($err);
506 if ($isDebug)
507 {
508 self::display_error($err, TRUE);
509 }
510 }
511
512 public static function log_error($err)
513 {
514 error_log($err, 0);
515 }
516
517 public static function display_error($err, $kill = FALSE)
518 {
519 print_r($err);
520 if ($kill === FALSE)
521 {
522 die();
523 }
524 }
525 }
526