/atk4-addons/misc/lib/Controller/OAuth.php
PHP | 309 lines | 278 code | 12 blank | 19 comment | 25 complexity | 5c353a5f0b847c41456291e61bde0d41 MD5 | raw file
Possible License(s): AGPL-3.0
- <?php
- class Controller_OAuth extends AbstractController {
- protected $ch; //curl handler
- protected $sign_method = "RSA-SHA1"; // also supported are: PLAINTEXT and HMAC-SHA1
- protected $certfile; // required for RSA-SHA1
- protected $consumer_key; // required for all types
- protected $request_token_baseurl; // url for retreiving request token
- protected $access_token_baseurl; // url for exchanging tokens
- protected $authorize_token_baseurl; // url for token authorization
- protected $callback_url; // callback url
- protected $error_callback_url; // error calback url
- protected $type='abstract'; // redefine in childs
- function init(){
- parent::init();
- // $this->setCallbackURL($this->api->getDestinationURL(null,
- // array('oauth'=>$this->name)));
- // Default URL :)
- }
- function check(){
- /* This function will perform calls to getAuthToken() etc
- */
- $this->setCallbackUrl(
- $this->api->getDestinationURL(null,array(
- 'auth'=>$this->name,'callback'=>1))
- );
- $this->setSignatureInfo();
- if(($_GET['auth']==$this->name && $_GET["callback"]) || !$_GET["auth"]){
- return $this->getAuthToken();
- }
- }
- function isLoggedIn(){
- if ($token = $this->recall("oauth-access-token")){
- return true;
- } else {
- return false;
- }
- }
- function setSignatureInfo(){
- /* redefine per actual implementation */
- /* by default assumes MHAC-SHA1 */
- $this->setConsumerKey($this->api->getConfig('oauth/'.$this->type.'/consumer/key'));
- $this->setConsumerSecret($this->api->getConfig('oauth/'.$this->type.'/consumer/secret'));
- $this->setSignMethod("HMAC-SHA1");
- }
- function logout(){
- $this->resetAuthToken();
- }
- function resetAuthToken(){
- $this->forget("oauth-access-token");
- $this->forget("oauth-request-token");
- }
- function getAuthToken($full = true){
- if ($oauth_token = $_GET["oauth_token"]){
- $oauth_verifier = $_GET["oauth_verifier"];
- try {
- $this->obtainAccessToken($oauth_token, $oauth_verifier);
- $this->api->redirect($this->callback_url);
- } catch (Exception $e){
- $this->callback_error_url->setArguments(array("error_msg" => $e->getMessage()));
- $this->api->redirect($this->callback_error_url);
- }
- exit;
- }
- if ($token = $this->recall("oauth-access-token")){
- if ($full){
- return $token;
- } else {
- return $token["oauth_token"];
- }
- } else {
- $this->obtainRequestToken();
- $this->authorizeToken();
- }
- }
- function getAuthTokenSecret(){
- if (isset($this->use_request_token)){
- $oauth = $this->recall("oauth-request-token");
- } else {
- $oauth = $this->recall("oauth-access-token");
- }
- return $oauth["oauth_token_secret"];
- }
- function getRequestTokenSecret(){
- $oauth = $this->recall("oauth-request-token");
- return $oauth["oauth_token_secret"];
- }
- function setAuthToken($oauth_token, $oauth_token_secret = null){
- $this->memorize("oauth-access-token",
- array(
- "oauth_token" => $auth_token,
- "auth_token_secret" => $oauth_token_secret
- )
- );
- }
- function setSignMethod($method){
- /* supported: RSA-SHA1, PLAINTEXT */
- $this->sign_method = $method;
- }
- function signRequest($method, $baseurl, array $parameters){
- /*
- * $method = GET | POST
- * $baseurl = "https://www.google.com/accounts/OAuth...";
- * $parameters = "extra parameters"
- */
- if (method_exists($this, $sign_method = "signRequest" . preg_replace("/[^a-zA-Z0-9]+/", "", $this->sign_method))){
- return $this->$sign_method($method, $baseurl, $parameters);
- }
- }
- function signRequestPLAINTEXT($method, $baseurl, array $parameters){
- return $this->consumer_secret . "&" . $this->getAuthTokenSecret();
- }
- function signRequestHMACSHA1($method, $baseurl, array $parameters){
- $data = $this->createSignatureBase($method, $baseurl, $parameters);
- $sign = hash_hmac("sha1", $data, $raw=$this->consumer_secret . "&" . $this->getAuthTokenSecret(), true);
- return base64_encode($sign);
- }
- function signRequestRSASHA1($method, $baseurl, array $parameters){
- $fp = @fopen($this->certfile, "r");
- if (!$fp){
- throw new Exception("Could not read certificate file");
- }
- $private = fread($fp, 8192);
- fclose($fp);
- $data = $this->createSignatureBase($method, $baseurl, $parameters);
- $keyid = openssl_get_privatekey($private);
- openssl_sign($data, $signature, $keyid);
- openssl_free_key($keyid);
- return base64_encode($signature);
- }
- function encodeStr($str){
- return preg_replace("/\%7E/", "~", urlencode($str));
- }
- function createSignatureBase($method, $baseurl, array $parameters){
- $data = $method.'&';
- $data .= $this->encodeStr($baseurl).'&';
- $oauth = '';
- ksort($parameters);
- foreach($parameters as $key => $value){
- $oauth .= "&{$key}={$value}";
- }
- $data .= urlencode(substr($oauth, 1));
- return $data;
- }
- function buildAuthArray($baseurl, $extra = array(), $method = 'GET'){
- /*
- * All $extra params should be urlencoded!
- */
- $auth = array();
- $baseurl = preg_replace("/\?.*$/", "", $baseurl);
- $auth['oauth_consumer_key'] = $this->consumer_key;
- $auth['oauth_signature_method'] = $this->sign_method;
- $auth['oauth_timestamp'] = time();
- $auth['oauth_nonce'] = md5(uniqid(rand(), true));
- $auth['oauth_version'] = '1.0';
- $auth = array_merge($auth, is_array($extra)?$extra:array());
- $auth['oauth_signature'] = $this->signRequest($method, $baseurl, $auth);
- $auth['oauth_signature'] = urlencode($auth['oauth_signature']);
- return $auth;
- }
- function setCallbackURL($callback_url, $callback_error_url=null){
- if($callback_url instanceof URL){
- $callback_url->useAbsoluteURL();
- if(!$callback_error_url){
- $callback_error_url=clone $callback_url;
- $callback_error_url
- ->setArguments(array('error'=>1));
- }
-
- }
- if(!$callback_error_url){
- throw new BaseException
- ('Specify error_url or use URL class');
- }
- $this->callback_url=$callback_url;
- $this->callback_error_url=$callback_error_url;
- }
- function setConsumerKey($consumer_key){
- $this->consumer_key = $consumer_key;
- }
- function setConsumerSecret($consumer_secret){
- $this->consumer_secret = $consumer_secret;
- }
- function setCertFile($certfile){
- $this->certfile = $certfile;
- }
- function useRequestToken(){
- /* this is needed when exchanging tokens and using HMAC-RSA signature method */
- $this->use_request_token = true;
- }
- function obtainAccessToken($oauth_token, $oauth_verifier = null){
- $params = array("oauth_token" => urlencode($oauth_token));
- if ($oauth_verifier){
- $params["oauth_verifier"] = urlencode($oauth_verifier);
- }
- $this->useRequestToken();
- $response = $this->performRequest($this->access_token_baseurl, $params);
- $response = explode("&", $response);
- $data = array();
- foreach ($response as $row){
- $row = explode("=", $row);
- $data[$row[0]] = $row[1];
- }
- if (isset($data["oauth_token_secret"])){
- $this->memorize("oauth-access-token", $data);
- } else {
- throw new Exception("Could not fetch access token");
- }
- return $data;
- }
- function authorizeToken(){
- $token_data = $this->recall("oauth-request-token", array());
- if ($token_data){
- $u=$this->add('URL')
- ->setBaseURL($this->authorize_token_baseurl)
- ->setArguments(array(
- 'oauth_token'=>$token_data['oauth_token'],
- 'oauth_callback'=>$this->callback_url
- ));
- $this->api->redirect($u);
- }
- }
- function obtainRequestToken($extra = array()){
- $extra["oauth_callback"] = urlencode($this->callback_url->getURL());
- $response = $this->performRequest($this->request_token_baseurl, $extra);
- $response = explode("&", $response);
- $data = array();
- foreach ($response as $row){
- $row = explode("=", $row);
- $data[$row[0]] = $row[1];
- }
- $this->preProcessRequestToken($data);
- $this->memorize("oauth-request-token", $data);
- return $data;
- }
- function preProcessRequestToken(&$data){
- $data["oauth_token"] = urldecode($data["oauth_token"]);
- }
- function performRequest($url, $extra = array()){
- $this->curlInit($url);
- $auth = $this->buildAuthArray($url, $extra);
- $this->setCurlAuthHeader($auth);
- $response = $this->executeCurl();
- return $response;
- }
- function performPostRequest($url, $extra_header = array(), $extra_auth = array(), $post = array()){
- $this->curlInit($url, "POST");
- $auth = $this->buildAuthArray($url, $extra_auth, "POST");
- $this->setCurlAuthHeader($auth, $extra_header);
- $this->curlSetPost($post);
- $response = $this->executeCurl();
- return $response;
- }
- function createAuthHeader($auth){
- $str = array();
- foreach($auth as $k => $v){
- $str[] = "{$k}=\"{$v}\"";
- }
- $str = implode(", ", $str);
- return $str;
- }
- /* curl methods */
- function curlInit($url, $method = "GET"){
- $this->ch=curl_init();
- curl_setopt($this->ch, CURLOPT_URL, $url);
- curl_setopt($this->ch, CURLOPT_VERBOSE, true);
- //curl_setopt($this->ch, CURLOPT_STDERR, fopen("curlerr.log", "a"));
- curl_setopt($this->ch, CURLOPT_RETURNTRANSFER, 1);
- curl_setopt($this->ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC ) ;
- curl_setopt($this->ch, CURLOPT_SSLVERSION,3);
- curl_setopt($this->ch, CURLOPT_SSL_VERIFYPEER, FALSE);
- curl_setopt($this->ch, CURLOPT_SSL_VERIFYHOST, 2);
- curl_setopt($this->ch, CURLOPT_RETURNTRANSFER, true);
- if ($method == "POST"){
- curl_setopt($this->ch, CURLOPT_POST, 1);
- }
- return $this;
- }
- function curlSetPost($data){
- curl_setopt($this->ch, CURLOPT_POSTFIELDS, $data);
- }
- function setCurlAuthHeader($auth, $extra = null){
- $auth_header = $this->createAuthHeader($auth);
- curl_setopt($this->ch, CURLOPT_HTTPHEADER, $t = array_merge(array("Authorization: OAuth {$auth_header}"),
- is_array($extra)?$extra:array()));
- return $this;
- }
- function executeCurl(){
- $response = curl_exec($this->ch);
- $st = curl_getinfo($this->ch, CURLINFO_HTTP_CODE);
- if ($st < 200 || $st >= 300){
- $this->last_error = $response;
- throw new Exception("Could not process request ($st)" . $response, $st);
- }
- return $response;
- }
- function render(){
-
- }
- }