PageRenderTime 26ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 0ms

/wp-offload-dospaces/vendor/Aws2/guzzle/guzzle/src/Guzzle/Plugin/Oauth/OauthPlugin.php

https://bitbucket.org/yerdna/wp-dospaces
PHP | 241 lines | 126 code | 2 blank | 113 comment | 9 complexity | 2ec95c1a5618a017ac9b801357a7a91d MD5 | raw file
Possible License(s): Apache-2.0
  1. <?php
  2. namespace DeliciousBrains\WP_Offload_S3\Aws2\Guzzle\Plugin\Oauth;
  3. use DeliciousBrains\WP_Offload_S3\Aws2\Guzzle\Common\Event;
  4. use DeliciousBrains\WP_Offload_S3\Aws2\Guzzle\Common\Collection;
  5. use DeliciousBrains\WP_Offload_S3\Aws2\Guzzle\Http\Message\RequestInterface;
  6. use DeliciousBrains\WP_Offload_S3\Aws2\Guzzle\Http\Message\EntityEnclosingRequestInterface;
  7. use DeliciousBrains\WP_Offload_S3\Aws2\Guzzle\Http\QueryString;
  8. use DeliciousBrains\WP_Offload_S3\Aws2\Guzzle\Http\Url;
  9. use DeliciousBrains\WP_Offload_S3\Aws2\Symfony\Component\EventDispatcher\EventSubscriberInterface;
  10. /**
  11. * OAuth signing plugin
  12. * @link http://oauth.net/core/1.0/#rfc.section.9.1.1
  13. */
  14. class OauthPlugin implements \DeliciousBrains\WP_Offload_S3\Aws2\Symfony\Component\EventDispatcher\EventSubscriberInterface
  15. {
  16. /**
  17. * Consumer request method constants. See http://oauth.net/core/1.0/#consumer_req_param
  18. */
  19. const REQUEST_METHOD_HEADER = 'header';
  20. const REQUEST_METHOD_QUERY = 'query';
  21. /** @var Collection Configuration settings */
  22. protected $config;
  23. /**
  24. * Create a new OAuth 1.0 plugin
  25. *
  26. * @param array $config Configuration array containing these parameters:
  27. * - string 'request_method' Consumer request method. Use the class constants.
  28. * - string 'callback' OAuth callback
  29. * - string 'consumer_key' Consumer key
  30. * - string 'consumer_secret' Consumer secret
  31. * - string 'token' Token
  32. * - string 'token_secret' Token secret
  33. * - string 'verifier' OAuth verifier.
  34. * - string 'version' OAuth version. Defaults to 1.0
  35. * - string 'signature_method' Custom signature method
  36. * - bool 'disable_post_params' Set to true to prevent POST parameters from being signed
  37. * - array|Closure 'signature_callback' Custom signature callback that accepts a string to sign and a signing key
  38. */
  39. public function __construct($config)
  40. {
  41. $this->config = \DeliciousBrains\WP_Offload_S3\Aws2\Guzzle\Common\Collection::fromConfig($config, array('version' => '1.0', 'request_method' => self::REQUEST_METHOD_HEADER, 'consumer_key' => 'anonymous', 'consumer_secret' => 'anonymous', 'signature_method' => 'HMAC-SHA1', 'signature_callback' => function ($stringToSign, $key) {
  42. return hash_hmac('sha1', $stringToSign, $key, true);
  43. }), array('signature_method', 'signature_callback', 'version', 'consumer_key', 'consumer_secret'));
  44. }
  45. public static function getSubscribedEvents()
  46. {
  47. return array('request.before_send' => array('onRequestBeforeSend', -1000));
  48. }
  49. /**
  50. * Request before-send event handler
  51. *
  52. * @param Event $event Event received
  53. * @return array
  54. * @throws \InvalidArgumentException
  55. */
  56. public function onRequestBeforeSend(\DeliciousBrains\WP_Offload_S3\Aws2\Guzzle\Common\Event $event)
  57. {
  58. $timestamp = $this->getTimestamp($event);
  59. $request = $event['request'];
  60. $nonce = $this->generateNonce($request);
  61. $authorizationParams = $this->getOauthParams($timestamp, $nonce);
  62. $authorizationParams['oauth_signature'] = $this->getSignature($request, $timestamp, $nonce);
  63. switch ($this->config['request_method']) {
  64. case self::REQUEST_METHOD_HEADER:
  65. $request->setHeader('Authorization', $this->buildAuthorizationHeader($authorizationParams));
  66. break;
  67. case self::REQUEST_METHOD_QUERY:
  68. foreach ($authorizationParams as $key => $value) {
  69. $request->getQuery()->set($key, $value);
  70. }
  71. break;
  72. default:
  73. throw new \InvalidArgumentException(sprintf('Invalid consumer method "%s"', $this->config['request_method']));
  74. }
  75. return $authorizationParams;
  76. }
  77. /**
  78. * Builds the Authorization header for a request
  79. *
  80. * @param array $authorizationParams Associative array of authorization parameters
  81. *
  82. * @return string
  83. */
  84. private function buildAuthorizationHeader($authorizationParams)
  85. {
  86. $authorizationString = 'OAuth ';
  87. foreach ($authorizationParams as $key => $val) {
  88. if ($val) {
  89. $authorizationString .= $key . '="' . urlencode($val) . '", ';
  90. }
  91. }
  92. return substr($authorizationString, 0, -2);
  93. }
  94. /**
  95. * Calculate signature for request
  96. *
  97. * @param RequestInterface $request Request to generate a signature for
  98. * @param integer $timestamp Timestamp to use for nonce
  99. * @param string $nonce
  100. *
  101. * @return string
  102. */
  103. public function getSignature(\DeliciousBrains\WP_Offload_S3\Aws2\Guzzle\Http\Message\RequestInterface $request, $timestamp, $nonce)
  104. {
  105. $string = $this->getStringToSign($request, $timestamp, $nonce);
  106. $key = urlencode($this->config['consumer_secret']) . '&' . urlencode($this->config['token_secret']);
  107. return base64_encode(call_user_func($this->config['signature_callback'], $string, $key));
  108. }
  109. /**
  110. * Calculate string to sign
  111. *
  112. * @param RequestInterface $request Request to generate a signature for
  113. * @param int $timestamp Timestamp to use for nonce
  114. * @param string $nonce
  115. *
  116. * @return string
  117. */
  118. public function getStringToSign(\DeliciousBrains\WP_Offload_S3\Aws2\Guzzle\Http\Message\RequestInterface $request, $timestamp, $nonce)
  119. {
  120. $params = $this->getParamsToSign($request, $timestamp, $nonce);
  121. // Convert booleans to strings.
  122. $params = $this->prepareParameters($params);
  123. // Build signing string from combined params
  124. $parameterString = clone $request->getQuery();
  125. $parameterString->replace($params);
  126. $url = \DeliciousBrains\WP_Offload_S3\Aws2\Guzzle\Http\Url::factory($request->getUrl())->setQuery('')->setFragment(null);
  127. return strtoupper($request->getMethod()) . '&' . rawurlencode($url) . '&' . rawurlencode((string) $parameterString);
  128. }
  129. /**
  130. * Get the oauth parameters as named by the oauth spec
  131. *
  132. * @param $timestamp
  133. * @param $nonce
  134. * @return Collection
  135. */
  136. protected function getOauthParams($timestamp, $nonce)
  137. {
  138. $params = new \DeliciousBrains\WP_Offload_S3\Aws2\Guzzle\Common\Collection(array('oauth_consumer_key' => $this->config['consumer_key'], 'oauth_nonce' => $nonce, 'oauth_signature_method' => $this->config['signature_method'], 'oauth_timestamp' => $timestamp));
  139. // Optional parameters should not be set if they have not been set in the config as
  140. // the parameter may be considered invalid by the Oauth service.
  141. $optionalParams = array('callback' => 'oauth_callback', 'token' => 'oauth_token', 'verifier' => 'oauth_verifier', 'version' => 'oauth_version');
  142. foreach ($optionalParams as $optionName => $oauthName) {
  143. if (isset($this->config[$optionName]) == true) {
  144. $params[$oauthName] = $this->config[$optionName];
  145. }
  146. }
  147. return $params;
  148. }
  149. /**
  150. * Get all of the parameters required to sign a request including:
  151. * * The oauth params
  152. * * The request GET params
  153. * * The params passed in the POST body (with a content-type of application/x-www-form-urlencoded)
  154. *
  155. * @param RequestInterface $request Request to generate a signature for
  156. * @param integer $timestamp Timestamp to use for nonce
  157. * @param string $nonce
  158. *
  159. * @return array
  160. */
  161. public function getParamsToSign(\DeliciousBrains\WP_Offload_S3\Aws2\Guzzle\Http\Message\RequestInterface $request, $timestamp, $nonce)
  162. {
  163. $params = $this->getOauthParams($timestamp, $nonce);
  164. // Add query string parameters
  165. $params->merge($request->getQuery());
  166. // Add POST fields to signing string if required
  167. if ($this->shouldPostFieldsBeSigned($request)) {
  168. $params->merge($request->getPostFields());
  169. }
  170. // Sort params
  171. $params = $params->toArray();
  172. uksort($params, 'strcmp');
  173. return $params;
  174. }
  175. /**
  176. * Decide whether the post fields should be added to the base string that Oauth signs.
  177. * This implementation is correct. Non-conformant APIs may require that this method be
  178. * overwritten e.g. the Flickr API incorrectly adds the post fields when the Content-Type
  179. * is 'application/x-www-form-urlencoded'
  180. *
  181. * @param $request
  182. * @return bool Whether the post fields should be signed or not
  183. */
  184. public function shouldPostFieldsBeSigned($request)
  185. {
  186. if (!$this->config->get('disable_post_params') && $request instanceof EntityEnclosingRequestInterface && false !== strpos($request->getHeader('Content-Type'), 'application/x-www-form-urlencoded')) {
  187. return true;
  188. }
  189. return false;
  190. }
  191. /**
  192. * Returns a Nonce Based on the unique id and URL. This will allow for multiple requests in parallel with the same
  193. * exact timestamp to use separate nonce's.
  194. *
  195. * @param RequestInterface $request Request to generate a nonce for
  196. *
  197. * @return string
  198. */
  199. public function generateNonce(\DeliciousBrains\WP_Offload_S3\Aws2\Guzzle\Http\Message\RequestInterface $request)
  200. {
  201. return sha1(uniqid('', true) . $request->getUrl());
  202. }
  203. /**
  204. * Gets timestamp from event or create new timestamp
  205. *
  206. * @param Event $event Event containing contextual information
  207. *
  208. * @return int
  209. */
  210. public function getTimestamp(\DeliciousBrains\WP_Offload_S3\Aws2\Guzzle\Common\Event $event)
  211. {
  212. return $event['timestamp'] ?: time();
  213. }
  214. /**
  215. * Convert booleans to strings, removed unset parameters, and sorts the array
  216. *
  217. * @param array $data Data array
  218. *
  219. * @return array
  220. */
  221. protected function prepareParameters($data)
  222. {
  223. ksort($data);
  224. foreach ($data as $key => &$value) {
  225. switch (gettype($value)) {
  226. case 'NULL':
  227. unset($data[$key]);
  228. break;
  229. case 'array':
  230. $data[$key] = self::prepareParameters($value);
  231. break;
  232. case 'boolean':
  233. $data[$key] = $value ? 'true' : 'false';
  234. break;
  235. }
  236. }
  237. return $data;
  238. }
  239. }