/framework/Oauth/lib/Horde/Oauth/Request.php

https://github.com/sgtcarneiro/horde · PHP · 198 lines · 111 code · 25 blank · 62 comment · 18 complexity · 92060055c35defb7e595171acd3e79fe MD5 · raw file

  1. <?php
  2. /**
  3. * Copyright 2008-2011 The Horde Project (http://www.horde.org/)
  4. *
  5. * @author Chuck Hagenbuch <chuck@horde.org>
  6. * @license http://opensource.org/licenses/bsd-license.php BSD
  7. * @category Horde
  8. * @package Oauth
  9. */
  10. /**
  11. * OAuth request class
  12. *
  13. * @author Chuck Hagenbuch <chuck@horde.org>
  14. * @license http://opensource.org/licenses/bsd-license.php BSD
  15. * @category Horde
  16. * @package Oauth
  17. */
  18. class Horde_Oauth_Request
  19. {
  20. const VERSION = '1.0';
  21. protected $_params = array();
  22. protected $_url;
  23. protected $_method;
  24. function __construct($url, $params = array(), $method = 'POST')
  25. {
  26. if (!isset($params['oauth_version'])) {
  27. $params['oauth_version'] = self::VERSION;
  28. }
  29. if (!isset($params['oauth_nonce'])) {
  30. $params['oauth_nonce'] = self::_generateNonce();
  31. }
  32. if (!isset($params['oauth_timestamp'])) {
  33. $params['oauth_timestamp'] = time();
  34. }
  35. $this->_params = $params;
  36. $this->_url = $url;
  37. $this->_method = $method;
  38. }
  39. /**
  40. * Sign this request in accordance with OAuth
  41. *
  42. * @param $signatureMethod
  43. * @param $consumer
  44. * @param $token
  45. * @return unknown_type
  46. */
  47. public function sign($signatureMethod, $consumer, $token = null)
  48. {
  49. if (empty($this->_params['oauth_consumer_key'])) {
  50. $this->_params['oauth_consumer_key'] = $consumer->key;
  51. }
  52. if (empty($this->_params['oauth_token']) && !empty($token)) {
  53. $this->_params['oauth_token'] = $token->key;
  54. }
  55. $this->_params['oauth_signature_method'] = $signatureMethod->getName();
  56. $this->_params['oauth_signature'] = $signatureMethod->sign($this, $consumer, $token);
  57. return $this->_getNormalizedUrl() . '?' . $this->buildHttpQuery();
  58. }
  59. /**
  60. * Returns the signable string of this request
  61. *
  62. * The base string is defined as the method, the url and the parameters
  63. * (normalized), each urlencoded and concatenated with &.
  64. */
  65. public function getSignatureBaseString()
  66. {
  67. $parts = array(
  68. $this->_getNormalizedHttpMethod(),
  69. $this->_getNormalizedUrl(),
  70. $this->_getSignableParameters()
  71. );
  72. return implode('&', array_map(array('Horde_Oauth_Utils', 'urlencodeRfc3986'), $parts));
  73. }
  74. /**
  75. * Get a query string suitable for use in a URL or as POST data.
  76. */
  77. public function buildHttpQuery()
  78. {
  79. $parts = array();
  80. foreach ($this->_params as $k => $v) {
  81. $parts[] = Horde_Oauth_Utils::urlencodeRfc3986($k) . '=' . Horde_Oauth_Utils::urlencodeRfc3986($v);
  82. }
  83. return implode('&', $parts);
  84. }
  85. /**
  86. */
  87. public function buildAuthorizationHeader($realm = '')
  88. {
  89. $header = '';
  90. foreach ($this->_params as $k => $v) {
  91. if (strpos($k, 'oauth_') !== false) {
  92. $header .= Horde_Oauth_Utils::urlencodeRfc3986($k) . '="' . Horde_Oauth_Utils::urlencodeRfc3986($v) . '",';
  93. }
  94. }
  95. if (!empty($realm)) {
  96. $header .= 'realm="' . Horde_Oauth_Utils::urlencodeRfc3986($realm) . '"';
  97. }
  98. return 'OAuth ' . $header;
  99. }
  100. /**
  101. * Generate a nonce.
  102. */
  103. protected static function _generateNonce()
  104. {
  105. $mt = microtime();
  106. $rand = mt_rand();
  107. return hash('md5', microtime() . mt_rand());
  108. }
  109. /**
  110. * Returns the normalized parameters of the request
  111. *
  112. * This will be all parameters except oauth_signature, sorted first by key,
  113. * and if there are duplicate keys, then by value.
  114. *
  115. * The returned string will be all the key=value pairs concatenated by &.
  116. *
  117. * @return string
  118. */
  119. protected function _getSignableParameters()
  120. {
  121. // Grab all parameters
  122. $params = $this->_params;
  123. // Remove oauth_signature if present
  124. if (isset($params['oauth_signature'])) {
  125. unset($params['oauth_signature']);
  126. }
  127. // Urlencode both keys and values
  128. $keys = array_map(array('Horde_Oauth_Utils', 'urlencodeRfc3986'), array_keys($params));
  129. $values = array_map(array('Horde_Oauth_Utils', 'urlencodeRfc3986'), array_values($params));
  130. $params = array_combine($keys, $values);
  131. // Sort by keys (natsort)
  132. uksort($params, 'strnatcmp');
  133. // Generate key=value pairs
  134. $pairs = array();
  135. foreach ($params as $key => $value) {
  136. if (is_array($value)) {
  137. // If the value is an array, it's because there are multiple values
  138. // with the same key. Sort them, then add all the pairs.
  139. natsort($value);
  140. foreach ($value as $v2) {
  141. $pairs[] = $key . '=' . $v2;
  142. }
  143. } else {
  144. $pairs[] = $key . '=' . $value;
  145. }
  146. }
  147. // Return the pairs, concatenated with &
  148. return implode('&', $pairs);
  149. }
  150. /**
  151. * Uppercases the HTTP method
  152. */
  153. protected function _getNormalizedHttpMethod()
  154. {
  155. return strtoupper($this->_method);
  156. }
  157. /**
  158. * Parse the url and rebuilds it to be scheme://host/path
  159. */
  160. protected function _getNormalizedUrl()
  161. {
  162. $parts = parse_url($this->_url);
  163. $port = !empty($parts['port']) ? $parts['port'] : '80';
  164. $scheme = $parts['scheme'];
  165. $host = $parts['host'];
  166. $path = !empty($parts['path']) ? $parts['path'] : '';
  167. if (($scheme == 'https' && $port != '443') ||
  168. ($scheme == 'http' && $port != '80')) {
  169. $host = "$host:$port";
  170. }
  171. return "$scheme://$host$path";
  172. }
  173. }