LTI Integration Library 4.10.3
PHP class library for building LTI integrations
 
Loading...
Searching...
No Matches
OAuthRequest.php
1<?php
2
3namespace ceLTIc\LTI\OAuth;
4
13{
14
20 protected $parameters;
21
27 protected $http_method;
28
34 protected $http_url;
35
36 // For debug purposes
37
44
50 public static $version = '1.0';
51
57 public static $POST_INPUT = 'php://input';
58
67 {
68 $parameters = ($parameters) ? $parameters : array();
69 $parameters = array_merge(OAuthUtil::parse_parameters(parse_url($http_url, PHP_URL_QUERY)), $parameters);
70 $this->parameters = $parameters;
71 $this->http_method = $http_method;
72 $this->http_url = $http_url;
73 }
74
84 public static function from_request($http_method = null, $http_url = null, $parameters = null)
85 {
86 if (!$http_url) {
87 if ((isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && ($_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https')) ||
88 (isset($_SERVER['HTTP_X_FORWARDED_SSL']) && ($_SERVER['HTTP_X_FORWARDED_SSL'] === 'on')) ||
89 (isset($_SERVER['HTTP_X_URL_SCHEME']) && ($_SERVER['HTTP_X_URL_SCHEME'] === 'https'))) {
90 $_SERVER['HTTPS'] = 'on';
91 $_SERVER['SERVER_PORT'] = 443;
92 } elseif (isset($_SERVER['HTTP_X_FORWARDED_PROTO'])) {
93 $_SERVER['HTTPS'] = 'off';
94 $_SERVER['SERVER_PORT'] = 80;
95 } elseif (!isset($_SERVER['HTTPS'])) {
96 $_SERVER['HTTPS'] = 'off';
97 }
98 if (!empty($_SERVER['HTTP_X_FORWARDED_HOST'])) {
99 $forwardedHosts = str_replace(' ', ',', trim($_SERVER['HTTP_X_FORWARDED_HOST'])); // Use first if multiple hosts listed
100 $hosts = explode(',', $forwardedHosts);
101 if (!empty($hosts[0])) {
102 $host = explode(':', $hosts[0], 2);
103 $_SERVER['SERVER_NAME'] = $host[0];
104 if (count($host) > 1) {
105 $_SERVER['SERVER_PORT'] = $host[1];
106 } elseif ($_SERVER['HTTPS'] === 'on') {
107 $_SERVER['SERVER_PORT'] = 443;
108 } else {
109 $_SERVER['SERVER_PORT'] = 80;
110 }
111 }
112 } elseif (!empty($_SERVER['HTTP_X_ORIGINAL_HOST'])) {
113 $_SERVER['SERVER_NAME'] = $_SERVER['HTTP_X_ORIGINAL_HOST'];
114 }
115 $scheme = ($_SERVER['HTTPS'] === 'on') ? 'https' : 'http';
116 $http_url = "{$scheme}://{$_SERVER['SERVER_NAME']}:{$_SERVER['SERVER_PORT']}{$_SERVER['REQUEST_URI']}";
117 }
118 $http_method = ($http_method) ? $http_method : $_SERVER['REQUEST_METHOD'];
119
120 // We weren't handed any parameters, so let's find the ones relevant to
121 // this request.
122 // If you run XML-RPC or similar you should use this to provide your own
123 // parsed parameter-list
124 if (!$parameters) {
125 // Find request headers
126 $request_headers = OAuthUtil::get_headers();
127
128 // Parse the query-string to find GET parameters
129 if (isset($_SERVER['QUERY_STRING'])) {
130 $parameters = OAuthUtil::parse_parameters($_SERVER['QUERY_STRING']);
131 } else {
132 $parameters = array();
133 }
134
135 if (($http_method === 'POST' && isset($request_headers['Content-Type']) && stristr($request_headers['Content-Type'],
136 'application/x-www-form-urlencoded')) || !empty($_POST)) {
137 // It's a POST request of the proper content-type, so parse POST
138 // parameters and add those overriding any duplicates from GET
139 $post_data = OAuthUtil::parse_parameters(file_get_contents(self::$POST_INPUT));
140 $parameters = array_merge_recursive($parameters, $post_data);
141 }
142
143 // We have a Authorization-header with OAuth data. Parse the header
144 // and add those overriding any duplicates from GET or POST
145 if (isset($request_headers['Authorization']) && substr($request_headers['Authorization'], 0, 6) == 'OAuth ') {
146 $header_parameters = OAuthUtil::split_header($request_headers['Authorization']);
147 $parameters = array_merge_recursive($parameters, $header_parameters);
148 }
149 }
150
152 }
153
165 public static function from_consumer_and_token($consumer, $token, $http_method, $http_url, $parameters = null)
166 {
167 $parameters = ($parameters) ? $parameters : array();
168 $defaults = array('oauth_version' => OAuthRequest::$version,
169 'oauth_nonce' => OAuthRequest::generate_nonce(),
170 'oauth_timestamp' => OAuthRequest::generate_timestamp(),
171 'oauth_consumer_key' => $consumer->key);
172 if ($token)
173 $defaults['oauth_token'] = $token->key;
174
175 $parameters = array_merge($defaults, $parameters);
176
178 }
179
187 public function set_parameter($name, $value, $allow_duplicates = true)
188 {
189 if ($allow_duplicates && isset($this->parameters[$name])) {
190 // We have already added parameter(s) with this name, so add to the list
191 if (is_scalar($this->parameters[$name])) {
192 // This is the first duplicate, so transform scalar (string)
193 // into an array so we can add the duplicates
194 $this->parameters[$name] = array($this->parameters[$name]);
195 }
196
197 $this->parameters[$name][] = $value;
198 } else {
199 $this->parameters[$name] = $value;
200 }
201 }
202
210 public function get_parameter($name)
211 {
212 return isset($this->parameters[$name]) ? $this->parameters[$name] : null;
213 }
214
220 public function get_parameters()
221 {
222 return $this->parameters;
223 }
224
230 public function unset_parameter($name)
231 {
232 unset($this->parameters[$name]);
233 }
234
240 public function get_signable_parameters()
241 {
242 // Grab all parameters
243 $params = $this->parameters;
244
245 // Remove oauth_signature if present
246 // Ref: Spec: 9.1.1 ("The oauth_signature parameter MUST be excluded.")
247 if (isset($params['oauth_signature'])) {
248 unset($params['oauth_signature']);
249 }
250
251 return OAuthUtil::build_http_query($params);
252 }
253
264 {
265 $parts = array(
269 );
270
271 $parts = OAuthUtil::urlencode_rfc3986($parts);
272
273 return implode('&', $parts);
274 }
275
282 {
283 return strtoupper($this->http_method);
284 }
285
291 public function get_normalized_http_url()
292 {
293 $parts = parse_url($this->http_url);
294
295 $scheme = (isset($parts['scheme'])) ? $parts['scheme'] : 'http';
296 $port = (isset($parts['port'])) ? $parts['port'] : (($scheme == 'https') ? '443' : '80');
297 $host = (isset($parts['host'])) ? strtolower($parts['host']) : '';
298 $path = (isset($parts['path'])) ? $parts['path'] : '';
299
300 if (($scheme == 'https' && $port != '443') || ($scheme == 'http' && $port != '80')) {
301 $host = "$host:$port";
302 }
303
304 return "$scheme://$host$path";
305 }
306
312 public function to_url()
313 {
314 $post_data = $this->to_postdata();
315 $out = $this->get_normalized_http_url();
316 if ($post_data) {
317 $out .= '?' . $post_data;
318 }
319
320 return $out;
321 }
322
328 public function to_postdata()
329 {
330 return OAuthUtil::build_http_query($this->parameters);
331 }
332
341 public function to_header($realm = null)
342 {
343 $first = true;
344 if ($realm) {
345 $out = 'Authorization: OAuth realm="' . OAuthUtil::urlencode_rfc3986($realm) . '"';
346 $first = false;
347 } else
348 $out = 'Authorization: OAuth';
349
350 $total = array();
351 foreach ($this->parameters as $k => $v) {
352 if (substr($k, 0, 5) != "oauth")
353 continue;
354 if (is_array($v)) {
355 throw new OAuthException('Arrays not supported in headers');
356 }
357 $out .= ($first) ? ' ' : ',';
358 $out .= OAuthUtil::urlencode_rfc3986($k) .
359 '="' .
361 '"';
362 $first = false;
363 }
364
365 return $out;
366 }
367
373 public function __toString()
374 {
375 return $this->to_url();
376 }
377
385 public function sign_request($signature_method, $consumer, $token)
386 {
387 $this->set_parameter(
388 "oauth_signature_method", $signature_method->get_name(), false
389 );
390 $signature = $this->build_signature($signature_method, $consumer, $token);
391 $this->set_parameter("oauth_signature", $signature, false);
392 }
393
403 public function build_signature($signature_method, $consumer, $token)
404 {
405 $signature = $signature_method->build_signature($this, $consumer, $token);
406 return $signature;
407 }
408
414 private static function generate_timestamp()
415 {
416 return time();
417 }
418
424 private static function generate_nonce()
425 {
426 $mt = microtime();
427 $rand = mt_rand();
428
429 return md5($mt . $rand); // md5s look nicer than numbers
430 }
431
432}
Class to represent an OAuth Exception.
Class to represent an OAuth request.
build_signature($signature_method, $consumer, $token)
Build the signature.
unset_parameter($name)
Delete a parameter.
__construct($http_method, $http_url, $parameters=null)
Class constructor.
get_signature_base_string()
Returns the base string of this request.
to_url()
Builds a url usable for a GET request.
get_signable_parameters()
The request parameters, sorted and concatenated into a normalized string.
get_normalized_http_method()
Just uppercases the http method.
to_postdata()
Builds the data one would send in a POST request.
static from_consumer_and_token($consumer, $token, $http_method, $http_url, $parameters=null)
Pretty much a helper function to set up the request.
$parameters
Request parameters.
__toString()
Convert object to a string.
get_parameters()
Get request parameters.
static from_request($http_method=null, $http_url=null, $parameters=null)
Attempt to build up a request from what was passed to the server.
sign_request($signature_method, $consumer, $token)
Sign the request.
get_normalized_http_url()
Parses the url and rebuilds it to be scheme://host/path.
to_header($realm=null)
Builds the Authorization: header.
set_parameter($name, $value, $allow_duplicates=true)
Set a parameter.
get_parameter($name)
Get a parameter.
static $POST_INPUT
Access to POST data.
static build_http_query($params)
Build HTTP query string.
static split_header($header, $only_allow_oauth_parameters=true)
Utility function for turning the Authorization: header into parameters, has to do some unescaping.
Definition OAuthUtil.php:62
static urlencode_rfc3986($input)
URL encode.
Definition OAuthUtil.php:22
static parse_parameters($input)
Parse parameters.
static get_headers()
Helper to try to sort out headers for people who aren't running apache.
Definition OAuthUtil.php:83