Upgrade Twitter bridge to use OAuth 1.0a. It's more secure, and allows

us to automatically send in a callback url instead of having to manually
configure one for each StatusNet instance.
This commit is contained in:
Zach Copley 2010-02-16 06:12:08 +00:00
parent e8275aa60a
commit c201baffbf
3 changed files with 98 additions and 28 deletions

View File

@ -90,20 +90,47 @@ class OAuthClient
/** /**
* Gets a request token from the given url * Gets a request token from the given url
* *
* @param string $url OAuth endpoint for grabbing request tokens * @param string $url OAuth endpoint for grabbing request tokens
* @param string $callback authorized request token callback
* *
* @return OAuthToken $token the request token * @return OAuthToken $token the request token
*/ */
function getRequestToken($url) function getRequestToken($url, $callback = null)
{ {
$response = $this->oAuthGet($url); $params = null;
if (!is_null($callback)) {
$params['oauth_callback'] = $callback;
}
$response = $this->oAuthGet($url, $params);
$arr = array(); $arr = array();
parse_str($response, $arr); parse_str($response, $arr);
if (isset($arr['oauth_token']) && isset($arr['oauth_token_secret'])) {
$token = new OAuthToken($arr['oauth_token'], @$arr['oauth_token_secret']); $token = $arr['oauth_token'];
$secret = $arr['oauth_token_secret'];
$confirm = $arr['oauth_callback_confirmed'];
if (isset($token) && isset($secret)) {
$token = new OAuthToken($token, $secret);
if (isset($confirm)) {
if ($confirm == 'true') {
common_debug('Twitter bridge - callback confirmed.');
return $token;
} else {
throw new OAuthClientException(
'Callback was not confirmed by Twitter.'
);
}
}
return $token; return $token;
} else { } else {
throw new OAuthClientException(); throw new OAuthClientException(
'Could not get a request token from Twitter.'
);
} }
} }
@ -113,49 +140,64 @@ class OAuthClient
* *
* @param string $url endpoint for authorizing request tokens * @param string $url endpoint for authorizing request tokens
* @param OAuthToken $request_token the request token to be authorized * @param OAuthToken $request_token the request token to be authorized
* @param string $oauth_callback optional callback url
* *
* @return string $authorize_url the url to redirect to * @return string $authorize_url the url to redirect to
*/ */
function getAuthorizeLink($url, $request_token, $oauth_callback = null) function getAuthorizeLink($url, $request_token)
{ {
$authorize_url = $url . '?oauth_token=' . $authorize_url = $url . '?oauth_token=' .
$request_token->key; $request_token->key;
if (isset($oauth_callback)) {
$authorize_url .= '&oauth_callback=' . urlencode($oauth_callback);
}
return $authorize_url; return $authorize_url;
} }
/** /**
* Fetches an access token * Fetches an access token
* *
* @param string $url OAuth endpoint for exchanging authorized request tokens * @param string $url OAuth endpoint for exchanging authorized request tokens
* for access tokens * for access tokens
* @param string $verifier 1.0a verifier
* *
* @return OAuthToken $token the access token * @return OAuthToken $token the access token
*/ */
function getAccessToken($url) function getAccessToken($url, $verifier = null)
{ {
$response = $this->oAuthPost($url); $params = array();
parse_str($response);
$token = new OAuthToken($oauth_token, $oauth_token_secret); if (!is_null($verifier)) {
return $token; $params['oauth_verifier'] = $verifier;
}
$response = $this->oAuthPost($url, $params);
$arr = array();
parse_str($response, $arr);
$token = $arr['oauth_token'];
$secret = $arr['oauth_token_secret'];
if (isset($token) && isset($secret)) {
$token = new OAuthToken($token, $secret);
return $token;
} else {
throw new OAuthClientException(
'Could not get a access token from Twitter.'
);
}
} }
/** /**
* Use HTTP GET to make a signed OAuth request * Use HTTP GET to make a signed OAuth requesta
* *
* @param string $url OAuth endpoint * @param string $url OAuth request token endpoint
* @param array $params additional parameters
* *
* @return mixed the request * @return mixed the request
*/ */
function oAuthGet($url) function oAuthGet($url, $params = null)
{ {
$request = OAuthRequest::from_consumer_and_token($this->consumer, $request = OAuthRequest::from_consumer_and_token($this->consumer,
$this->token, 'GET', $url, null); $this->token, 'GET', $url, $params);
$request->sign_request($this->sha1_method, $request->sign_request($this->sha1_method,
$this->consumer, $this->token); $this->consumer, $this->token);

View File

@ -56,6 +56,7 @@ class TwitterauthorizationAction extends Action
var $tw_fields = null; var $tw_fields = null;
var $access_token = null; var $access_token = null;
var $signin = null; var $signin = null;
var $verifier = null;
/** /**
* Initialize class members. Looks for 'oauth_token' parameter. * Initialize class members. Looks for 'oauth_token' parameter.
@ -70,6 +71,7 @@ class TwitterauthorizationAction extends Action
$this->signin = $this->boolean('signin'); $this->signin = $this->boolean('signin');
$this->oauth_token = $this->arg('oauth_token'); $this->oauth_token = $this->arg('oauth_token');
$this->verifier = $this->arg('oauth_verifier');
return true; return true;
} }
@ -160,8 +162,7 @@ class TwitterauthorizationAction extends Action
// Get a new request token and authorize it // Get a new request token and authorize it
$client = new TwitterOAuthClient(); $client = new TwitterOAuthClient();
$req_tok = $req_tok = $client->getRequestToken();
$client->getRequestToken(TwitterOAuthClient::$requestTokenURL);
// Sock the request token away in the session temporarily // Sock the request token away in the session temporarily
@ -171,7 +172,7 @@ class TwitterauthorizationAction extends Action
$auth_link = $client->getAuthorizeLink($req_tok, $this->signin); $auth_link = $client->getAuthorizeLink($req_tok, $this->signin);
} catch (OAuthClientException $e) { } catch (OAuthClientException $e) {
$msg = sprintf('OAuth client cURL error - code: %1s, msg: %2s', $msg = sprintf('OAuth client error - code: %1s, msg: %2s',
$e->getCode(), $e->getMessage()); $e->getCode(), $e->getMessage());
$this->serverError(_m('Couldn\'t link your Twitter account.')); $this->serverError(_m('Couldn\'t link your Twitter account.'));
} }
@ -187,7 +188,6 @@ class TwitterauthorizationAction extends Action
*/ */
function saveAccessToken() function saveAccessToken()
{ {
// Check to make sure Twitter returned the same request // Check to make sure Twitter returned the same request
// token we sent them // token we sent them
@ -204,7 +204,7 @@ class TwitterauthorizationAction extends Action
// Exchange the request token for an access token // Exchange the request token for an access token
$atok = $client->getAccessToken(TwitterOAuthClient::$accessTokenURL); $atok = $client->getAccessToken($this->verifier);
// Test the access token and get the user's Twitter info // Test the access token and get the user's Twitter info

View File

@ -91,6 +91,19 @@ class TwitterOAuthClient extends OAuthClient
} }
} }
/**
* Gets a request token from Twitter
*
* @return OAuthToken $token the request token
*/
function getRequestToken()
{
return parent::getRequestToken(
self::$requestTokenURL,
common_local_url('twitterauthorization')
);
}
/** /**
* Builds a link to Twitter's endpoint for authorizing a request token * Builds a link to Twitter's endpoint for authorizing a request token
* *
@ -107,6 +120,21 @@ class TwitterOAuthClient extends OAuthClient
common_local_url('twitterauthorization')); common_local_url('twitterauthorization'));
} }
/**
* Fetches an access token from Twitter
*
* @param string $verifier 1.0a verifier
*
* @return OAuthToken $token the access token
*/
function getAccessToken($verifier = null)
{
return parent::getAccessToken(
self::$accessTokenURL,
$verifier
);
}
/** /**
* Calls Twitter's /account/verify_credentials API method * Calls Twitter's /account/verify_credentials API method
* *