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