|
Moodle
2.2.1
http://www.collinsharper.com
|
00001 <?php 00002 00003 // This file is part of Moodle - http://moodle.org/ 00004 // 00005 // Moodle is free software: you can redistribute it and/or modify 00006 // it under the terms of the GNU General Public License as published by 00007 // the Free Software Foundation, either version 3 of the License, or 00008 // (at your option) any later version. 00009 // 00010 // Moodle is distributed in the hope that it will be useful, 00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 // GNU General Public License for more details. 00014 // 00015 // You should have received a copy of the GNU General Public License 00016 // along with Moodle. If not, see <http://www.gnu.org/licenses/>. 00017 00042 class oauth_helper { 00044 protected $consumer_key; 00046 protected $consumer_secret; 00048 protected $api_root; 00050 protected $request_token_api; 00052 protected $authorize_url; 00053 protected $http_method; 00055 protected $access_token_api; 00057 protected $http; 00058 00068 function __construct($args) { 00069 if (!empty($args['api_root'])) { 00070 $this->api_root = $args['api_root']; 00071 } else { 00072 $this->api_root = ''; 00073 } 00074 $this->consumer_key = $args['oauth_consumer_key']; 00075 $this->consumer_secret = $args['oauth_consumer_secret']; 00076 00077 if (empty($args['request_token_api'])) { 00078 $this->request_token_api = $this->api_root . '/request_token'; 00079 } else { 00080 $this->request_token_api = $args['request_token_api']; 00081 } 00082 00083 if (empty($args['authorize_url'])) { 00084 $this->authorize_url = $this->api_root . '/authorize'; 00085 } else { 00086 $this->authorize_url = $args['authorize_url']; 00087 } 00088 00089 if (empty($args['access_token_api'])) { 00090 $this->access_token_api = $this->api_root . '/access_token'; 00091 } else { 00092 $this->access_token_api = $args['access_token_api']; 00093 } 00094 00095 if (!empty($args['oauth_callback'])) { 00096 $this->oauth_callback = new moodle_url($args['oauth_callback']); 00097 } 00098 if (!empty($args['access_token'])) { 00099 $this->access_token = $args['access_token']; 00100 } 00101 if (!empty($args['access_token_secret'])) { 00102 $this->access_token_secret = $args['access_token_secret']; 00103 } 00104 $this->http = new curl(array('debug'=>false)); 00105 } 00106 00120 function get_signable_parameters($params){ 00121 $sorted = $params; 00122 ksort($sorted); 00123 00124 $total = array(); 00125 foreach ($sorted as $k => $v) { 00126 if ($k == 'oauth_signature') { 00127 continue; 00128 } 00129 00130 $total[] = rawurlencode($k) . '=' . rawurlencode($v); 00131 } 00132 return implode('&', $total); 00133 } 00134 00142 public function sign($http_method, $url, $params, $secret) { 00143 $sig = array( 00144 strtoupper($http_method), 00145 preg_replace('/%7E/', '~', rawurlencode($url)), 00146 rawurlencode($this->get_signable_parameters($params)), 00147 ); 00148 00149 $base_string = implode('&', $sig); 00150 $sig = base64_encode(hash_hmac('sha1', $base_string, $secret, true)); 00151 return $sig; 00152 } 00153 00170 public function prepare_oauth_parameters($url, $params, $http_method = 'POST') { 00171 if (is_array($params)) { 00172 $oauth_params = $params; 00173 } else { 00174 $oauth_params = array(); 00175 } 00176 $oauth_params['oauth_version'] = '1.0'; 00177 $oauth_params['oauth_nonce'] = $this->get_nonce(); 00178 $oauth_params['oauth_timestamp'] = $this->get_timestamp(); 00179 $oauth_params['oauth_consumer_key'] = $this->consumer_key; 00180 if (!empty($this->oauth_callback)) { 00181 $oauth_params['oauth_callback'] = $this->oauth_callback->out(false); 00182 } 00183 $oauth_params['oauth_signature_method'] = 'HMAC-SHA1'; 00184 $oauth_params['oauth_signature'] = $this->sign($http_method, $url, $oauth_params, $this->sign_secret); 00185 return $oauth_params; 00186 } 00187 00188 public function setup_oauth_http_header($params) { 00189 00190 $total = array(); 00191 ksort($params); 00192 foreach ($params as $k => $v) { 00193 $total[] = rawurlencode($k) . '="' . rawurlencode($v).'"'; 00194 } 00195 $str = implode(', ', $total); 00196 $str = 'Authorization: OAuth '.$str; 00197 $this->http->setHeader('Expect:'); 00198 $this->http->setHeader($str); 00199 } 00200 00206 public function request_token() { 00207 $this->sign_secret = $this->consumer_secret.'&'; 00208 $params = $this->prepare_oauth_parameters($this->request_token_api, array(), 'GET'); 00209 $content = $this->http->get($this->request_token_api, $params); 00210 // Including: 00211 // oauth_token 00212 // oauth_token_secret 00213 $result = $this->parse_result($content); 00214 if (empty($result['oauth_token'])) { 00215 // failed 00216 var_dump($result); 00217 exit; 00218 } 00219 // build oauth authrize url 00220 if (!empty($this->oauth_callback)) { 00221 // url must be rawurlencode 00222 $result['authorize_url'] = $this->authorize_url . '?oauth_token='.$result['oauth_token'].'&oauth_callback='.rawurlencode($this->oauth_callback->out(false)); 00223 } else { 00224 // no callback 00225 $result['authorize_url'] = $this->authorize_url . '?oauth_token='.$result['oauth_token']; 00226 } 00227 return $result; 00228 } 00229 00235 public function set_access_token($token, $secret) { 00236 $this->access_token = $token; 00237 $this->access_token_secret = $secret; 00238 } 00239 00247 public function get_access_token($token, $secret, $verifier='') { 00248 $this->sign_secret = $this->consumer_secret.'&'.$secret; 00249 $params = $this->prepare_oauth_parameters($this->access_token_api, array('oauth_token'=>$token, 'oauth_verifier'=>$verifier), 'POST'); 00250 $this->setup_oauth_http_header($params); 00251 $content = $this->http->post($this->access_token_api, $params); 00252 $keys = $this->parse_result($content); 00253 $this->set_access_token($keys['oauth_token'], $keys['oauth_token_secret']); 00254 return $keys; 00255 } 00256 00264 public function request($method, $url, $params=array(), $token='', $secret='') { 00265 if (empty($token)) { 00266 $token = $this->access_token; 00267 } 00268 if (empty($secret)) { 00269 $secret = $this->access_token_secret; 00270 } 00271 // to access protected resource, sign_secret will alwasy be consumer_secret+token_secret 00272 $this->sign_secret = $this->consumer_secret.'&'.$secret; 00273 $oauth_params = $this->prepare_oauth_parameters($url, array('oauth_token'=>$token), $method); 00274 $this->setup_oauth_http_header($oauth_params); 00275 $content = call_user_func_array(array($this->http, strtolower($method)), array($url, $params)); 00276 return $content; 00277 } 00278 00282 public function get($url, $params=array(), $token='', $secret='') { 00283 return $this->request('GET', $url, $params, $token, $secret); 00284 } 00285 00289 public function post($url, $params=array(), $token='', $secret='') { 00290 return $this->request('POST', $url, $params, $token, $secret); 00291 } 00292 00298 public function parse_result($str) { 00299 if (empty($str)) { 00300 throw new moodle_exception('error'); 00301 } 00302 $parts = explode('&', $str); 00303 $result = array(); 00304 foreach ($parts as $part){ 00305 list($k, $v) = explode('=', $part, 2); 00306 $result[urldecode($k)] = urldecode($v); 00307 } 00308 if (empty($result)) { 00309 throw new moodle_exception('error'); 00310 } 00311 return $result; 00312 } 00313 00317 function set_nonce($str) { 00318 $this->nonce = $str; 00319 } 00323 function set_timestamp($time) { 00324 $this->timestamp = $time; 00325 } 00329 function get_timestamp() { 00330 if (!empty($this->timestamp)) { 00331 $timestamp = $this->timestamp; 00332 unset($this->timestamp); 00333 return $timestamp; 00334 } 00335 return time(); 00336 } 00340 function get_nonce() { 00341 if (!empty($this->nonce)) { 00342 $nonce = $this->nonce; 00343 unset($this->nonce); 00344 return $nonce; 00345 } 00346 $mt = microtime(); 00347 $rand = mt_rand(); 00348 00349 return md5($mt . $rand); 00350 } 00351 }