225 lines
		
	
	
		
			6.8 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			225 lines
		
	
	
		
			6.8 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
| <?php
 | |
| /**
 | |
|  * StatusNet, the distributed open-source microblogging tool
 | |
|  *
 | |
|  * Class for doing OAuth authentication against Twitter
 | |
|  *
 | |
|  * PHP version 5
 | |
|  *
 | |
|  * LICENCE: This program is free software: you can redistribute it and/or modify
 | |
|  * it under the terms of the GNU Affero General Public License as published by
 | |
|  * the Free Software Foundation, either version 3 of the License, or
 | |
|  * (at your option) any later version.
 | |
|  *
 | |
|  * This program is distributed in the hope that it will be useful,
 | |
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | |
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | |
|  * GNU Affero General Public License for more details.
 | |
|  *
 | |
|  * You should have received a copy of the GNU Affero General Public License
 | |
|  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | |
|  *
 | |
|  * @category  TwitterauthorizationAction
 | |
|  * @package   StatusNet
 | |
|  * @author    Zach Copely <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/
 | |
|  */
 | |
| 
 | |
| if (!defined('STATUSNET') && !defined('LACONICA')) {
 | |
|     exit(1);
 | |
| }
 | |
| 
 | |
| require_once INSTALLDIR . '/plugins/TwitterBridge/twitter.php';
 | |
| 
 | |
| /**
 | |
|  * Class for doing OAuth authentication against Twitter
 | |
|  *
 | |
|  * Peforms the OAuth "dance" between StatusNet and Twitter -- requests a token,
 | |
|  * authorizes it, and exchanges it for an access token.  It also creates a link
 | |
|  * (Foreign_link) between the StatusNet user and Twitter user and stores the
 | |
|  * access token and secret in the link.
 | |
|  *
 | |
|  * @category Twitter
 | |
|  * @package  StatusNet
 | |
|  * @author   Zach Copley <zach@status.net>
 | |
|  * @license  http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
 | |
|  * @link     http://laconi.ca/
 | |
|  *
 | |
|  */
 | |
| class TwitterauthorizationAction extends Action
 | |
| {
 | |
|     /**
 | |
|      * Initialize class members. Looks for 'oauth_token' parameter.
 | |
|      *
 | |
|      * @param array $args misc. arguments
 | |
|      *
 | |
|      * @return boolean true
 | |
|      */
 | |
|     function prepare($args)
 | |
|     {
 | |
|         parent::prepare($args);
 | |
| 
 | |
|         $this->oauth_token = $this->arg('oauth_token');
 | |
| 
 | |
|         return true;
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Handler method
 | |
|      *
 | |
|      * @param array $args is ignored since it's now passed in in prepare()
 | |
|      *
 | |
|      * @return nothing
 | |
|      */
 | |
|     function handle($args)
 | |
|     {
 | |
|         parent::handle($args);
 | |
| 
 | |
|         if (!common_logged_in()) {
 | |
|             $this->clientError(_('Not logged in.'), 403);
 | |
|         }
 | |
| 
 | |
|         $user  = common_current_user();
 | |
|         $flink = Foreign_link::getByUserID($user->id, TWITTER_SERVICE);
 | |
| 
 | |
|         // If there's already a foreign link record, it means we already
 | |
|         // have an access token, and this is unecessary. So go back.
 | |
| 
 | |
|         if (isset($flink)) {
 | |
|             common_redirect(common_local_url('twittersettings'));
 | |
|         }
 | |
| 
 | |
|         // $this->oauth_token is only populated once Twitter authorizes our
 | |
|         // request token. If it's empty we're at the beginning of the auth
 | |
|         // process
 | |
| 
 | |
|         if (empty($this->oauth_token)) {
 | |
|             $this->authorizeRequestToken();
 | |
|         } else {
 | |
|             $this->saveAccessToken();
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Asks Twitter for a request token, and then redirects to Twitter
 | |
|      * to authorize it.
 | |
|      *
 | |
|      * @return nothing
 | |
|      */
 | |
|     function authorizeRequestToken()
 | |
|     {
 | |
|         try {
 | |
| 
 | |
|             // Get a new request token and authorize it
 | |
| 
 | |
|             $client  = new TwitterOAuthClient();
 | |
|             $req_tok =
 | |
|               $client->getRequestToken(TwitterOAuthClient::$requestTokenURL);
 | |
| 
 | |
|             // Sock the request token away in the session temporarily
 | |
| 
 | |
|             $_SESSION['twitter_request_token']        = $req_tok->key;
 | |
|             $_SESSION['twitter_request_token_secret'] = $req_tok->secret;
 | |
| 
 | |
|             $auth_link = $client->getAuthorizeLink($req_tok);
 | |
| 
 | |
|         } catch (TwitterOAuthClientException $e) {
 | |
|             $msg = sprintf('OAuth client cURL error - code: %1s, msg: %2s',
 | |
|                            $e->getCode(), $e->getMessage());
 | |
|             $this->serverError(_('Couldn\'t link your Twitter account.'));
 | |
|         }
 | |
| 
 | |
|         common_redirect($auth_link);
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Called when Twitter returns an authorized request token. Exchanges
 | |
|      * it for an access token and stores it.
 | |
|      *
 | |
|      * @return nothing
 | |
|      */
 | |
|     function saveAccessToken()
 | |
|     {
 | |
| 
 | |
|         // Check to make sure Twitter returned the same request
 | |
|         // token we sent them
 | |
| 
 | |
|         if ($_SESSION['twitter_request_token'] != $this->oauth_token) {
 | |
|             $this->serverError(_('Couldn\'t link your Twitter account.'));
 | |
|         }
 | |
| 
 | |
|         try {
 | |
| 
 | |
|             $client = new TwitterOAuthClient($_SESSION['twitter_request_token'],
 | |
|                 $_SESSION['twitter_request_token_secret']);
 | |
| 
 | |
|             // Exchange the request token for an access token
 | |
| 
 | |
|             $atok = $client->getAccessToken(TwitterOAuthClient::$accessTokenURL);
 | |
| 
 | |
|             // Test the access token and get the user's Twitter info
 | |
| 
 | |
|             $client       = new TwitterOAuthClient($atok->key, $atok->secret);
 | |
|             $twitter_user = $client->verifyCredentials();
 | |
| 
 | |
|         } catch (OAuthClientException $e) {
 | |
|             $msg = sprintf('OAuth client cURL error - code: %1$s, msg: %2$s',
 | |
|                            $e->getCode(), $e->getMessage());
 | |
|             $this->serverError(_('Couldn\'t link your Twitter account.'));
 | |
|         }
 | |
| 
 | |
|         // Save the access token and Twitter user info
 | |
| 
 | |
|         $this->saveForeignLink($atok, $twitter_user);
 | |
| 
 | |
|         // Clean up the the mess we made in the session
 | |
| 
 | |
|         unset($_SESSION['twitter_request_token']);
 | |
|         unset($_SESSION['twitter_request_token_secret']);
 | |
| 
 | |
|         common_redirect(common_local_url('twittersettings'));
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Saves a Foreign_link between Twitter user and local user,
 | |
|      * which includes the access token and secret.
 | |
|      *
 | |
|      * @param OAuthToken $access_token the access token to save
 | |
|      * @param mixed      $twitter_user twitter API user object
 | |
|      *
 | |
|      * @return nothing
 | |
|      */
 | |
|     function saveForeignLink($access_token, $twitter_user)
 | |
|     {
 | |
|         $user = common_current_user();
 | |
| 
 | |
|         $flink = new Foreign_link();
 | |
| 
 | |
|         $flink->user_id     = $user->id;
 | |
|         $flink->foreign_id  = $twitter_user->id;
 | |
|         $flink->service     = TWITTER_SERVICE;
 | |
| 
 | |
|         $creds = TwitterOAuthClient::packToken($access_token);
 | |
| 
 | |
|         $flink->credentials = $creds;
 | |
|         $flink->created     = common_sql_now();
 | |
| 
 | |
|         // Defaults: noticesync on, everything else off
 | |
| 
 | |
|         $flink->set_flags(true, false, false, false);
 | |
| 
 | |
|         $flink_id = $flink->insert();
 | |
| 
 | |
|         if (empty($flink_id)) {
 | |
|             common_log_db_error($flink, 'INSERT', __FILE__);
 | |
|                 $this->serverError(_('Couldn\'t link your Twitter account.'));
 | |
|         }
 | |
| 
 | |
|         save_twitter_user($twitter_user->id, $twitter_user->screen_name);
 | |
|     }
 | |
| 
 | |
| }
 | |
| 
 |