See Release Notes
Long Term Support Release
Differences Between: [Versions 401 and 402] [Versions 401 and 403]
1 <?php 2 3 namespace IMSGlobal\LTI\OAuth; 4 5 /** 6 * Class to represent an %OAuth Server 7 * 8 * @copyright Andy Smith 9 * @version 2008-08-04 10 * @license https://opensource.org/licenses/MIT The MIT License 11 */ 12 class OAuthServer { 13 14 protected $timestamp_threshold = 300; // in seconds, five minutes 15 protected $version = '1.0'; // hi blaine 16 protected $signature_methods = array(); 17 18 protected $data_store; 19 20 function __construct($data_store) { 21 $this->data_store = $data_store; 22 } 23 24 public function add_signature_method($signature_method) { 25 $this->signature_methods[$signature_method->get_name()] = $signature_method; 26 } 27 28 // high level functions 29 30 /** 31 * process a request_token request 32 * returns the request token on success 33 */ 34 public function fetch_request_token(&$request) { 35 36 $this->get_version($request); 37 38 $consumer = $this->get_consumer($request); 39 40 // no token required for the initial token request 41 $token = NULL; 42 43 $this->check_signature($request, $consumer, $token); 44 45 // Rev A change 46 $callback = $request->get_parameter('oauth_callback'); 47 $new_token = $this->data_store->new_request_token($consumer, $callback); 48 49 return $new_token; 50 51 } 52 53 /** 54 * process an access_token request 55 * returns the access token on success 56 */ 57 public function fetch_access_token(&$request) { 58 59 $this->get_version($request); 60 61 $consumer = $this->get_consumer($request); 62 63 // requires authorized request token 64 $token = $this->get_token($request, $consumer, "request"); 65 66 $this->check_signature($request, $consumer, $token); 67 68 // Rev A change 69 $verifier = $request->get_parameter('oauth_verifier'); 70 $new_token = $this->data_store->new_access_token($token, $consumer, $verifier); 71 72 return $new_token; 73 74 } 75 76 /** 77 * verify an api call, checks all the parameters 78 */ 79 public function verify_request(&$request) { 80 81 $this->get_version($request); 82 $consumer = $this->get_consumer($request); 83 $token = $this->get_token($request, $consumer, "access"); 84 $this->check_signature($request, $consumer, $token); 85 86 return array($consumer, $token); 87 88 } 89 90 // Internals from here 91 /** 92 * version 1 93 */ 94 private function get_version(&$request) { 95 96 $version = $request->get_parameter("oauth_version"); 97 if (!$version) { 98 // Service Providers MUST assume the protocol version to be 1.0 if this parameter is not present. 99 // Chapter 7.0 ("Accessing Protected Ressources") 100 $version = '1.0'; 101 } 102 if ($version !== $this->version) { 103 throw new OAuthException("OAuth version '$version' not supported"); 104 } 105 106 return $version; 107 108 } 109 110 /** 111 * figure out the signature with some defaults 112 */ 113 private function get_signature_method($request) { 114 115 $signature_method = $request instanceof OAuthRequest 116 ? $request->get_parameter('oauth_signature_method') : NULL; 117 118 if (!$signature_method) { 119 // According to chapter 7 ("Accessing Protected Ressources") the signature-method 120 // parameter is required, and we can't just fallback to PLAINTEXT 121 throw new OAuthException('No signature method parameter. This parameter is required'); 122 } 123 124 if (!in_array($signature_method, 125 array_keys($this->signature_methods))) { 126 throw new OAuthException( 127 "Signature method '$signature_method' not supported " . 128 'try one of the following: ' . 129 implode(', ', array_keys($this->signature_methods)) 130 ); 131 } 132 133 return $this->signature_methods[$signature_method]; 134 135 } 136 137 /** 138 * try to find the consumer for the provided request's consumer key 139 */ 140 private function get_consumer($request) { 141 142 $consumer_key = $request instanceof OAuthRequest 143 ? $request->get_parameter('oauth_consumer_key') : NULL; 144 145 if (!$consumer_key) { 146 throw new OAuthException('Invalid consumer key'); 147 } 148 149 $consumer = $this->data_store->lookup_consumer($consumer_key); 150 if (!$consumer) { 151 throw new OAuthException('Invalid consumer'); 152 } 153 154 return $consumer; 155 156 } 157 158 /** 159 * try to find the token for the provided request's token key 160 */ 161 private function get_token($request, $consumer, $token_type="access") { 162 163 $token_field = $request instanceof OAuthRequest 164 ? $request->get_parameter('oauth_token') : NULL; 165 166 $token = $this->data_store->lookup_token($consumer, $token_type, $token_field); 167 if (!$token) { 168 throw new OAuthException("Invalid $token_type token: $token_field"); 169 } 170 171 return $token; 172 173 } 174 175 /** 176 * all-in-one function to check the signature on a request 177 * should guess the signature method appropriately 178 */ 179 private function check_signature($request, $consumer, $token) { 180 181 // this should probably be in a different method 182 $timestamp = $request instanceof OAuthRequest 183 ? $request->get_parameter('oauth_timestamp') 184 : NULL; 185 $nonce = $request instanceof OAuthRequest 186 ? $request->get_parameter('oauth_nonce') 187 : NULL; 188 189 $this->check_timestamp($timestamp); 190 $this->check_nonce($consumer, $token, $nonce, $timestamp); 191 192 $signature_method = $this->get_signature_method($request); 193 194 $signature = $request->get_parameter('oauth_signature'); 195 $valid_sig = $signature_method->check_signature($request, $consumer, $token, $signature); 196 197 if (!$valid_sig) { 198 throw new OAuthException('Invalid signature'); 199 } 200 } 201 202 /** 203 * check that the timestamp is new enough 204 */ 205 private function check_timestamp($timestamp) { 206 if(!$timestamp) 207 throw new OAuthException('Missing timestamp parameter. The parameter is required'); 208 209 // verify that timestamp is recentish 210 $now = time(); 211 if (abs($now - $timestamp) > $this->timestamp_threshold) { 212 throw new OAuthException("Expired timestamp, yours $timestamp, ours $now"); 213 } 214 215 } 216 217 /** 218 * check that the nonce is not repeated 219 */ 220 private function check_nonce($consumer, $token, $nonce, $timestamp) { 221 222 if(!$nonce) 223 throw new OAuthException('Missing nonce parameter. The parameter is required'); 224 225 // verify that the nonce is uniqueish 226 $found = $this->data_store->lookup_nonce($consumer, $token, $nonce, $timestamp); 227 if ($found) { 228 throw new OAuthException("Nonce already used: $nonce"); 229 } 230 231 } 232 233 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body