PageRenderTime 25ms CodeModel.GetById 19ms RepoModel.GetById 1ms app.codeStats 0ms

/lib/PayPal/Auth/Oauth/OAuthRequest.php

https://gitlab.com/CORP-RESELLER/sdk-core-php
PHP | 323 lines | 223 code | 42 blank | 58 comment | 44 complexity | d80570f5bc826a50d44b7bf8fa3537a7 MD5 | raw file
  1. <?php
  2. namespace PayPal\Auth\Oauth;
  3. use PayPal\Exception\OAuthException;
  4. class OAuthRequest
  5. {
  6. public $parameters;
  7. protected $http_method;
  8. protected $http_url;
  9. // for debug purposes
  10. public $base_string;
  11. public static $version = '1.0';
  12. public static $POST_INPUT = 'php://input';
  13. function __construct($http_method, $http_url, $parameters = null)
  14. {
  15. $parameters = ($parameters) ? $parameters : array();
  16. $parameters = array_merge(OAuthUtil::parse_parameters(parse_url($http_url, PHP_URL_QUERY)), $parameters);
  17. $this->parameters = $parameters;
  18. $this->http_method = $http_method;
  19. $this->http_url = $http_url;
  20. }
  21. /**
  22. * attempt to build up a request from what was passed to the server
  23. */
  24. public static function from_request($http_method = null, $http_url = null, $parameters = null)
  25. {
  26. $scheme = (!isset($_SERVER['HTTPS']) || $_SERVER['HTTPS'] != "on")
  27. ? 'http'
  28. : 'https';
  29. $http_url = ($http_url) ? $http_url : $scheme .
  30. '://' . $_SERVER['HTTP_HOST'] .
  31. ':' .
  32. $_SERVER['SERVER_PORT'] .
  33. $_SERVER['REQUEST_URI'];
  34. $http_method = ($http_method) ? $http_method : $_SERVER['REQUEST_METHOD'];
  35. // We weren't handed any parameters, so let's find the ones relevant to
  36. // this request.
  37. // If you run XML-RPC or similar you should use this to provide your own
  38. // parsed parameter-list
  39. if (!$parameters) {
  40. // Find request headers
  41. $request_headers = OAuthUtil::get_headers();
  42. // Parse the query-string to find GET parameters
  43. $parameters = OAuthUtil::parse_parameters($_SERVER['QUERY_STRING']);
  44. // It's a POST request of the proper content-type, so parse POST
  45. // parameters and add those overriding any duplicates from GET
  46. if ($http_method == "POST"
  47. && isset($request_headers['Content-Type'])
  48. && strstr($request_headers['Content-Type'],
  49. 'application/x-www-form-urlencoded')
  50. ) {
  51. $post_data = OAuthUtil::parse_parameters(
  52. file_get_contents(self::$POST_INPUT)
  53. );
  54. $parameters = array_merge($parameters, $post_data);
  55. }
  56. // We have a Authorization-header with OAuth data. Parse the header
  57. // and add those overriding any duplicates from GET or POST
  58. if (isset($request_headers['Authorization']) && substr($request_headers['Authorization'], 0,
  59. 6) == 'OAuth '
  60. ) {
  61. $header_parameters = OAuthUtil::split_header(
  62. $request_headers['Authorization']
  63. );
  64. $parameters = array_merge($parameters, $header_parameters);
  65. }
  66. }
  67. return new OAuthRequest($http_method, $http_url, $parameters);
  68. }
  69. /**
  70. * pretty much a helper function to set up the request
  71. */
  72. public static function from_consumer_and_token($consumer, $token, $http_method, $http_url, $parameters = null)
  73. {
  74. $parameters = ($parameters) ? $parameters : array();
  75. $defaults = array(
  76. "oauth_version" => OAuthRequest::$version,
  77. // "oauth_nonce" => OAuthRequest::generate_nonce(),
  78. "oauth_timestamp" => OAuthRequest::generate_timestamp(),
  79. "oauth_consumer_key" => $consumer->key
  80. );
  81. if ($token) {
  82. $defaults['oauth_token'] = $token->key;
  83. }
  84. $parameters = array_merge($defaults, $parameters);
  85. ksort($parameters);
  86. return new OAuthRequest($http_method, $http_url, $parameters);
  87. }
  88. public function set_parameter($name, $value, $allow_duplicates = true)
  89. {
  90. if ($allow_duplicates && isset($this->parameters[$name])) {
  91. // We have already added parameter(s) with this name, so add to the list
  92. if (is_scalar($this->parameters[$name])) {
  93. // This is the first duplicate, so transform scalar (string)
  94. // into an array so we can add the duplicates
  95. $this->parameters[$name] = array($this->parameters[$name]);
  96. }
  97. $this->parameters[$name][] = $value;
  98. } else {
  99. $this->parameters[$name] = $value;
  100. }
  101. }
  102. public function get_parameter($name)
  103. {
  104. return isset($this->parameters[$name]) ? $this->parameters[$name] : null;
  105. }
  106. public function get_parameters()
  107. {
  108. return $this->parameters;
  109. }
  110. public function unset_parameter($name)
  111. {
  112. unset($this->parameters[$name]);
  113. }
  114. /**
  115. * The request parameters, sorted and concatenated into a normalized string.
  116. * @return string
  117. */
  118. public function get_signable_parameters()
  119. {
  120. // Grab all parameters
  121. $params = $this->parameters;
  122. ksort($params);
  123. // Remove oauth_signature if present
  124. // Ref: Spec: 9.1.1 ("The oauth_signature parameter MUST be excluded.")
  125. if (isset($params['oauth_signature'])) {
  126. unset($params['oauth_signature']);
  127. }
  128. foreach ($params as $key => $value) {
  129. $res[] = $key . "=" . $value;
  130. }
  131. return implode('&', $res);
  132. //return OAuthUtil::build_http_query($params);
  133. }
  134. /**
  135. * Returns the base string of this request
  136. *
  137. * The base string defined as the method, the url
  138. * and the parameters (normalized), each urlencoded
  139. * and the concated with &.
  140. */
  141. public function get_signature_base_string()
  142. {
  143. $parts = array(
  144. $this->get_normalized_http_method(),
  145. $this->get_normalized_http_url(),
  146. $this->get_signable_parameters()
  147. );
  148. $parts = OAuthUtil::urlencode_rfc3986($parts);
  149. return implode('&', $parts);
  150. }
  151. /**
  152. * just uppercases the http method
  153. */
  154. public function get_normalized_http_method()
  155. {
  156. return strtoupper($this->http_method);
  157. }
  158. /**
  159. * parses the url and rebuilds it to be
  160. * scheme://host/path
  161. */
  162. public function get_normalized_http_url()
  163. {
  164. $parts = parse_url($this->http_url);
  165. $scheme = (isset($parts['scheme'])) ? $parts['scheme'] : 'http';
  166. $port = (isset($parts['port'])) ? $parts['port'] : (($scheme == 'https') ? '443' : '80');
  167. $host = (isset($parts['host'])) ? $parts['host'] : '';
  168. $path = (isset($parts['path'])) ? $parts['path'] : '';
  169. if (($scheme == 'https' && $port != '443')
  170. || ($scheme == 'http' && $port != '80')
  171. ) {
  172. $host = "$host:$port";
  173. }
  174. return "$scheme://$host$path";
  175. }
  176. /**
  177. * builds a url usable for a GET request
  178. */
  179. public function to_url()
  180. {
  181. $post_data = $this->to_postdata();
  182. $out = $this->get_normalized_http_url();
  183. if ($post_data) {
  184. $out .= '?' . $post_data;
  185. }
  186. return $out;
  187. }
  188. /**
  189. * builds the data one would send in a POST request
  190. */
  191. public function to_postdata()
  192. {
  193. return OAuthUtil::build_http_query($this->parameters);
  194. }
  195. /**
  196. * builds the Authorization: header
  197. */
  198. public function to_header($realm = null)
  199. {
  200. $first = true;
  201. if ($realm) {
  202. $out = 'Authorization: OAuth realm="' . OAuthUtil::urlencode_rfc3986($realm) . '"';
  203. $first = false;
  204. } else {
  205. $out = 'Authorization: OAuth';
  206. }
  207. $total = array();
  208. foreach ($this->parameters as $k => $v) {
  209. if (substr($k, 0, 5) != "oauth") {
  210. continue;
  211. }
  212. if (is_array($v)) {
  213. throw new OAuthException('Arrays not supported in headers');
  214. }
  215. $out .= ($first) ? ' ' : ',';
  216. $out .= OAuthUtil::urlencode_rfc3986($k) .
  217. '="' .
  218. OAuthUtil::urlencode_rfc3986($v) .
  219. '"';
  220. $first = false;
  221. }
  222. return $out;
  223. }
  224. public function __toString()
  225. {
  226. return $this->to_url();
  227. }
  228. public function sign_request($signature_method, $consumer, $token)
  229. {
  230. $empty = false;
  231. $msg = array();
  232. if ($token->key == null) {
  233. $msg[] = 'Token key';
  234. }
  235. if ($token->secret == null) {
  236. $msg[] = 'Token secret';
  237. }
  238. if ($consumer->key == null) {
  239. $msg[] = 'Consumer key';
  240. }
  241. if ($consumer->secret == null) {
  242. $msg[] = 'Consumer secret';
  243. }
  244. if ($this->http_url == null) {
  245. $msg[] = 'Endpoint';
  246. }
  247. if ($this->http_method == null) {
  248. $msg[] = 'HTTP method';
  249. }
  250. if (count($msg)) {
  251. throw new OAuthException('Enter valid ' . implode(',', $msg));
  252. }
  253. $this->set_parameter(
  254. "oauth_signature_method",
  255. $signature_method->get_name(),
  256. false);
  257. $signature = $this->build_signature($signature_method, $consumer, $token);
  258. $this->set_parameter("oauth_signature", $signature, false);
  259. }
  260. public function build_signature($signature_method, $consumer, $token)
  261. {
  262. $signature = $signature_method->build_signature($this, $consumer, $token);
  263. return $signature;
  264. }
  265. /**
  266. * util function: current timestamp
  267. */
  268. private static function generate_timestamp()
  269. {
  270. return time();
  271. }
  272. /**
  273. * util function: current nonce
  274. */
  275. private static function generate_nonce()
  276. {
  277. $mt = microtime();
  278. $rand = mt_rand();
  279. return md5($mt . $rand); // md5s look nicer than numbers
  280. }
  281. }