]> git.mxchange.org Git - quix0rs-gnu-social.git/commitdiff
Make API auth handle OAuth requests w/access tokens
authorZach Copley <zach@status.net>
Tue, 12 Jan 2010 01:30:56 +0000 (17:30 -0800)
committerZach Copley <zach@status.net>
Thu, 14 Jan 2010 02:41:07 +0000 (02:41 +0000)
lib/apiauth.php

index 7102764cbaa753489430f072522db5cd37c3ccb1..3229ab19fda77008691e703e8fe4e8ba5f425694 100644 (file)
@@ -28,7 +28,7 @@
  * @author    Evan Prodromou <evan@status.net>
  * @author    mEDI <medi@milaro.net>
  * @author    Sarven Capadisli <csarven@status.net>
- * @author    Zach Copley <zach@status.net> 
+ * @author    Zach Copley <zach@status.net>
  * @copyright 2009 StatusNet, Inc.
  * @license   http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
  * @link      http://status.net/
@@ -39,6 +39,7 @@ if (!defined('STATUSNET')) {
 }
 
 require_once INSTALLDIR . '/lib/api.php';
+require_once INSTALLDIR . '/lib/apioauthstore.php';
 
 /**
  * Actions extending this class will require auth
@@ -52,6 +53,8 @@ require_once INSTALLDIR . '/lib/api.php';
 
 class ApiAuthAction extends ApiAction
 {
+    var $access_token;
+    var $oauth_access_type;
 
     /**
      * Take arguments for running, and output basic auth header if needed
@@ -67,12 +70,119 @@ class ApiAuthAction extends ApiAction
         parent::prepare($args);
 
         if ($this->requiresAuth()) {
-            $this->checkBasicAuthUser();
+
+           $this->consumer_key = $this->arg('oauth_consumer_key');
+           $this->access_token = $this->arg('oauth_token');
+
+           if (!empty($this->access_token)) {
+               $this->checkOAuthRequest();
+           } else {
+               $this->checkBasicAuthUser();
+           }
         }
 
         return true;
     }
 
+    function checkOAuthRequest()
+    {
+       common_debug("We have an OAuth request.");
+
+       $datastore   = new ApiStatusNetOAuthDataStore();
+       $server      = new OAuthServer($datastore);
+       $hmac_method = new OAuthSignatureMethod_HMAC_SHA1();
+
+       $server->add_signature_method($hmac_method);
+
+       $this->cleanRequest();
+
+       try {
+
+           $req  = OAuthRequest::from_request();
+           $server->verify_request($req);
+
+           common_debug("Good OAuth request!");
+
+           $app = Oauth_application::getByConsumerKey($this->consumer_key);
+
+           if (empty($app)) {
+
+               // this should really not happen
+               common_log(LOG_WARN,
+                          "Couldn't find the OAuth app for consumer key: $this->consumer_key");
+
+               throw new OAuthException('No application for that consumer key.');
+           }
+
+           $appUser = Oauth_application_user::staticGet('token',
+                                                        $this->access_token);
+
+           // XXX: check that app->id and appUser->application_id and consumer all
+           // match?
+
+           if (!empty($appUser)) {
+
+               // read or read-write
+               $this->oauth_access_type = $appUser->access_type;
+
+               // If access_type == 0 we have either a request token
+               // or a bad / revoked access token
+
+               if ($this->oauth_access_type != 0) {
+
+                   $this->auth_user = User::staticGet('id', $appUser->profile_id);
+
+                   $msg = "API OAuth authentication for user '%s' (id: %d) on behalf of " .
+                     "application '%s' (id: %d).";
+
+                   common_log(LOG_INFO, sprintf($msg,
+                                                $this->auth_user->nickname,
+                                                $this->auth_user->id,
+                                                $app->name,
+                                                $app->id));
+                   return true;
+               } else {
+                   throw new OAuthException('Bad access token.');
+               }
+           } else {
+
+               // also should not happen
+               throw new OAuthException('No user for that token.');
+           }
+
+       } catch (OAuthException $e) {
+           common_log(LOG_WARN, 'API OAuthException - ' . $e->getMessage());
+           common_debug(var_export($req, true));
+           $this->showOAuthError($e->getMessage());
+           exit();
+       }
+    }
+
+    function showOAuthError($msg)
+    {
+       header('HTTP/1.1 401 Unauthorized');
+       header('Content-Type: text/html; charset=utf-8');
+       print $msg . "\n";
+    }
+
+    function cleanRequest()
+    {
+       // kill evil effects of magical slashing
+
+       if(get_magic_quotes_gpc() == 1) {
+           $_POST = array_map('stripslashes', $_POST);
+           $_GET = array_map('stripslashes', $_GET);
+       }
+
+       // strip out the p param added in index.php
+
+       // XXX: should we strip anything else?  Or alternatively
+       // only allow a known list of params?
+
+       unset($_GET['p']);
+       unset($_POST['p']);
+    }
+
     /**
      * Does this API resource require authentication?
      *