/coin/yahoo_api/oauth_helper.php

https://gitlab.com/joelopezcuenca/proyectocoin · PHP · 226 lines · 118 code · 32 blank · 76 comment · 29 complexity · 52f5425769037c54ab21e26e669c9fd4 MD5 · raw file

  1. <?php
  2. /**
  3. * Helper functions for OAuth
  4. */
  5. /**
  6. * Build a query parameter string according to OAuth Spec.
  7. * @param array $params an array of query parameters
  8. * @return string all the query parameters properly sorted and encoded
  9. * according to the OAuth spec, or an empty string if params is empty.
  10. * @link http://oauth.net/core/1.0/#rfc.section.9.1.1
  11. */
  12. function oauth_http_build_query($params, $excludeOauthParams=false)
  13. {
  14. $query_string = '';
  15. if (! empty($params)) {
  16. // rfc3986 encode both keys and values
  17. $keys = rfc3986_encode(array_keys($params));
  18. $values = rfc3986_encode(array_values($params));
  19. $params = array_combine($keys, $values);
  20. // Parameters are sorted by name, using lexicographical byte value ordering.
  21. // http://oauth.net/core/1.0/#rfc.section.9.1.1
  22. uksort($params, 'strcmp');
  23. // Turn params array into an array of "key=value" strings
  24. $kvpairs = array();
  25. foreach ($params as $k => $v) {
  26. if ($excludeOauthParams && substr($k, 0, 5) == 'oauth') {
  27. continue;
  28. }
  29. if (is_array($v)) {
  30. // If two or more parameters share the same name,
  31. // they are sorted by their value. OAuth Spec: 9.1.1 (1)
  32. natsort($v);
  33. foreach ($v as $value_for_same_key) {
  34. array_push($kvpairs, ($k . '=' . $value_for_same_key));
  35. }
  36. } else {
  37. // For each parameter, the name is separated from the corresponding
  38. // value by an '=' character (ASCII code 61). OAuth Spec: 9.1.1 (2)
  39. array_push($kvpairs, ($k . '=' . $v));
  40. }
  41. }
  42. // Each name-value pair is separated by an '&' character, ASCII code 38.
  43. // OAuth Spec: 9.1.1 (2)
  44. $query_string = implode('&', $kvpairs);
  45. }
  46. return $query_string;
  47. }
  48. /**
  49. * Parse a query string into an array.
  50. * @param string $query_string an OAuth query parameter string
  51. * @return array an array of query parameters
  52. * @link http://oauth.net/core/1.0/#rfc.section.9.1.1
  53. */
  54. function oauth_parse_str($query_string)
  55. {
  56. $query_array = array();
  57. if (isset($query_string)) {
  58. // Separate single string into an array of "key=value" strings
  59. $kvpairs = explode('&', $query_string);
  60. // Separate each "key=value" string into an array[key] = value
  61. foreach ($kvpairs as $pair) {
  62. list($k, $v) = explode('=', $pair, 2);
  63. // Handle the case where multiple values map to the same key
  64. // by pulling those values into an array themselves
  65. if (isset($query_array[$k])) {
  66. // If the existing value is a scalar, turn it into an array
  67. if (is_scalar($query_array[$k])) {
  68. $query_array[$k] = array($query_array[$k]);
  69. }
  70. array_push($query_array[$k], $v);
  71. } else {
  72. $query_array[$k] = $v;
  73. }
  74. }
  75. }
  76. return $query_array;
  77. }
  78. /**
  79. * Build an OAuth header for API calls
  80. * @param array $params an array of query parameters
  81. * @return string encoded for insertion into HTTP header of API call
  82. */
  83. function build_oauth_header($params, $realm='')
  84. {
  85. $header = 'Authorization: OAuth realm="' . $realm . '"';
  86. foreach ($params as $k => $v) {
  87. if (substr($k, 0, 5) == 'oauth') {
  88. $header .= ',' . rfc3986_encode($k) . '="' . rfc3986_encode($v) . '"';
  89. }
  90. }
  91. return $header;
  92. }
  93. /**
  94. * Compute an OAuth PLAINTEXT signature
  95. * @param string $consumer_secret
  96. * @param string $token_secret
  97. */
  98. function oauth_compute_plaintext_sig($consumer_secret, $token_secret)
  99. {
  100. return ($consumer_secret . '&' . $token_secret);
  101. }
  102. /**
  103. * Compute an OAuth HMAC-SHA1 signature
  104. * @param string $http_method GET, POST, etc.
  105. * @param string $url
  106. * @param array $params an array of query parameters for the request
  107. * @param string $consumer_secret
  108. * @param string $token_secret
  109. * @return string a base64_encoded hmac-sha1 signature
  110. * @see http://oauth.net/core/1.0/#rfc.section.A.5.1
  111. */
  112. function oauth_compute_hmac_sig($http_method, $url, $params, $consumer_secret, $token_secret)
  113. {
  114. global $debug;
  115. $base_string = signature_base_string($http_method, $url, $params);
  116. $signature_key = rfc3986_encode($consumer_secret) . '&' . rfc3986_encode($token_secret);
  117. $sig = base64_encode(hash_hmac('sha1', $base_string, $signature_key, true));
  118. if ($debug) {
  119. logit("oauth_compute_hmac_sig:DBG:sig:$sig");
  120. }
  121. return $sig;
  122. }
  123. /**
  124. * Make the URL conform to the format scheme://host/path
  125. * @param string $url
  126. * @return string the url in the form of scheme://host/path
  127. */
  128. function normalize_url($url)
  129. {
  130. $parts = parse_url($url);
  131. $scheme = $parts['scheme'];
  132. $host = $parts['host'];
  133. $port = $parts['port'];
  134. $path = $parts['path'];
  135. if (! $port) {
  136. $port = ($scheme == 'https') ? '443' : '80';
  137. }
  138. if (($scheme == 'https' && $port != '443')
  139. || ($scheme == 'http' && $port != '80')) {
  140. $host = "$host:$port";
  141. }
  142. return "$scheme://$host$path";
  143. }
  144. /**
  145. * Returns the normalized signature base string of this request
  146. * @param string $http_method
  147. * @param string $url
  148. * @param array $params
  149. * The base string is defined as the method, the url and the
  150. * parameters (normalized), each urlencoded and the concated with &.
  151. * @see http://oauth.net/core/1.0/#rfc.section.A.5.1
  152. */
  153. function signature_base_string($http_method, $url, $params)
  154. {
  155. // Decompose and pull query params out of the url
  156. $query_str = parse_url($url, PHP_URL_QUERY);
  157. if ($query_str) {
  158. $parsed_query = oauth_parse_str($query_str);
  159. // merge params from the url with params array from caller
  160. $params = array_merge($params, $parsed_query);
  161. }
  162. // Remove oauth_signature from params array if present
  163. if (isset($params['oauth_signature'])) {
  164. unset($params['oauth_signature']);
  165. }
  166. // Create the signature base string. Yes, the $params are double encoded.
  167. $base_string = rfc3986_encode(strtoupper($http_method)) . '&' .
  168. rfc3986_encode(normalize_url($url)) . '&' .
  169. rfc3986_encode(oauth_http_build_query($params));
  170. logit("signature_base_string:INFO:normalized_base_string:$base_string");
  171. return $base_string;
  172. }
  173. /**
  174. * Encode input per RFC 3986
  175. * @param string|array $raw_input
  176. * @return string|array properly rfc3986 encoded raw_input
  177. * If an array is passed in, rfc3896 encode all elements of the array.
  178. * @link http://oauth.net/core/1.0/#encoding_parameters
  179. */
  180. function rfc3986_encode($raw_input)
  181. {
  182. if (is_array($raw_input)) {
  183. return array_map('rfc3986_encode', $raw_input);
  184. } else if (is_scalar($raw_input)) {
  185. return str_replace('%7E', '~', rawurlencode($raw_input));
  186. } else {
  187. return '';
  188. }
  189. }
  190. function rfc3986_decode($raw_input)
  191. {
  192. return rawurldecode($raw_input);
  193. }
  194. ?>