Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 3.11.x will end 14 Nov 2022 (12 months plus 6 months extension).
  • Bug fixes for security issues in 3.11.x will end 13 Nov 2023 (18 months plus 12 months extension).
  • PHP version: minimum PHP 7.3.0 Note: minimum PHP version has increased since Moodle 3.10. PHP 7.4.x is supported too.

Differences Between: [Versions 310 and 311] [Versions 39 and 311]

   1  <?php
   2  
   3  require_once ("OAuth.php");
   4  require_once ("TrivialOAuthDataStore.php");
   5  
   6  function getLastOAuthBodyBaseString() {
   7      global $LastOAuthBodyBaseString;
   8      return $LastOAuthBodyBaseString;
   9  }
  10  
  11  function handleOAuthBodyPOST($oauth_consumer_key, $oauth_consumer_secret)
  12  {
  13      $request_headers = OAuthUtil::get_headers();
  14      // print_r($request_headers);
  15  
  16      // Must reject application/x-www-form-urlencoded
  17      if ($request_headers['Content-type'] == 'application/x-www-form-urlencoded' ) {
  18          throw new Exception("OAuth request body signing must not use application/x-www-form-urlencoded");
  19      }
  20  
  21      if (@substr($request_headers['Authorization'], 0, 6) == "OAuth ") {
  22          $header_parameters = OAuthUtil::split_header($request_headers['Authorization']);
  23  
  24          // echo("HEADER PARMS=\n");
  25          // print_r($header_parameters);
  26          $oauth_body_hash = $header_parameters['oauth_body_hash'];
  27          // echo("OBH=".$oauth_body_hash."\n");
  28      }
  29  
  30      if ( ! isset($oauth_body_hash)  ) {
  31          throw new Exception("OAuth request body signing requires oauth_body_hash body");
  32      }
  33  
  34      // Verify the message signature
  35      $store = new TrivialOAuthDataStore();
  36      $store->add_consumer($oauth_consumer_key, $oauth_consumer_secret);
  37  
  38      $server = new OAuthServer($store);
  39  
  40      $method = new OAuthSignatureMethod_HMAC_SHA1();
  41      $server->add_signature_method($method);
  42      $request = OAuthRequest::from_request();
  43  
  44      global $LastOAuthBodyBaseString;
  45      $LastOAuthBodyBaseString = $request->get_signature_base_string();
  46      // echo($LastOAuthBodyBaseString."\n");
  47  
  48      try {
  49          $server->verify_request($request);
  50      } catch (Exception $e) {
  51          $message = $e->getMessage();
  52          throw new Exception("OAuth signature failed: " . $message);
  53      }
  54  
  55      $postdata = file_get_contents('php://input');
  56      // echo($postdata);
  57  
  58      $hash = base64_encode(sha1($postdata, TRUE));
  59  
  60      if ( $hash != $oauth_body_hash ) {
  61          throw new Exception("OAuth oauth_body_hash mismatch");
  62      }
  63  
  64      return $postdata;
  65  }
  66  
  67  function sendOAuthBodyPOST($method, $endpoint, $oauth_consumer_key, $oauth_consumer_secret, $content_type, $body)
  68  {
  69      global $CFG;
  70  
  71      require_once($CFG->dirroot . '/lib/filelib.php');
  72  
  73      $hash = base64_encode(sha1($body, TRUE));
  74  
  75      $parms = array('oauth_body_hash' => $hash);
  76  
  77      $test_token = '';
  78      $hmac_method = new OAuthSignatureMethod_HMAC_SHA1();
  79      $test_consumer = new OAuthConsumer($oauth_consumer_key, $oauth_consumer_secret, NULL);
  80  
  81      $acc_req = OAuthRequest::from_consumer_and_token($test_consumer, $test_token, $method, $endpoint, $parms);
  82      $acc_req->sign_request($hmac_method, $test_consumer, $test_token);
  83  
  84      // Pass this back up "out of band" for debugging
  85      global $LastOAuthBodyBaseString;
  86      $LastOAuthBodyBaseString = $acc_req->get_signature_base_string();
  87      // echo($LastOAuthBodyBaseString."\m");
  88  
  89      $headers = array();
  90      $headers[] = $acc_req->to_header();
  91      $headers[] = "Content-type: " . $content_type;
  92  
  93      $curl = new curl();
  94      $curl->setHeader($headers);
  95      $response =  $curl->post($endpoint, $body);
  96  
  97      return $response;
  98  }
  99  
 100  function sendOAuthParamsPOST($method, $endpoint, $oauth_consumer_key, $oauth_consumer_secret, $content_type, $params)
 101  {
 102  
 103      if (is_array($params)) {
 104          $body = http_build_query($params, '', '&');
 105      } else {
 106          $body = $params;
 107      }
 108  
 109      $hash = base64_encode(sha1($body, TRUE));
 110  
 111      $parms = $params;
 112      $parms['oauth_body_hash'] = $hash;
 113  
 114      $test_token = '';
 115      $hmac_method = new OAuthSignatureMethod_HMAC_SHA1();
 116      $test_consumer = new OAuthConsumer($oauth_consumer_key, $oauth_consumer_secret, NULL);
 117  
 118      $acc_req = OAuthRequest::from_consumer_and_token($test_consumer, $test_token, $method, $endpoint, $parms);
 119      $acc_req->sign_request($hmac_method, $test_consumer, $test_token);
 120  
 121      // Pass this back up "out of band" for debugging
 122      global $LastOAuthBodyBaseString;
 123      $LastOAuthBodyBaseString = $acc_req->get_signature_base_string();
 124      // echo($LastOAuthBodyBaseString."\m");
 125  
 126      $header = $acc_req->to_header();
 127      $header = $header . "\r\nContent-type: " . $content_type . "\r\n";
 128  
 129      $params = array('http' => array(
 130          'method' => 'POST',
 131          'content' => $body,
 132      'header' => $header
 133          ));
 134      $ctx = stream_context_create($params);
 135      $fp = @fopen($endpoint, 'rb', false, $ctx);
 136      if (!$fp) {
 137          $message = "(No error message provided.)";
 138          if ($error = error_get_last()) {
 139              $message = $error["message"];
 140          }
 141          throw new \Exception("Problem with $endpoint, $message");
 142      }
 143      $response = @stream_get_contents($fp);
 144      if ($response === false) {
 145          $message = "(No error message provided.)";
 146          if ($error = error_get_last()) {
 147              $message = $error["message"];
 148          }
 149          throw new \Exception("Problem reading data from $endpoint, $message");
 150      }
 151      return $response;
 152  }
 153  
 154  ?>