From 3e7adbf8198d1bd5e0ad4e97ae5643d7dc8c61ab Mon Sep 17 00:00:00 2001 From: brettp Date: Sat, 12 Feb 2011 02:37:06 +0000 Subject: Twitter services now allows login with twitter properly for a single user. git-svn-id: http://code.elgg.org/elgg/trunk@8137 36083f99-b078-4883-b0ff-0f9b5a30f544 --- mod/twitterservice/start.php | 82 ++++++++++----- mod/twitterservice/twitterservice_lib.php | 167 ++++++++++++++++++------------ 2 files changed, 158 insertions(+), 91 deletions(-) diff --git a/mod/twitterservice/start.php b/mod/twitterservice/start.php index b5f4c2d21..ed5022359 100644 --- a/mod/twitterservice/start.php +++ b/mod/twitterservice/start.php @@ -2,22 +2,23 @@ /** * Elgg Twitter Service * This service plugin allows users to authenticate their Elgg account with Twitter. - * + * * @package TwitterService * @license http://www.gnu.org/licenses/old-licenses/gpl-2.0.html GNU Public License version 2 * @copyright Curverider Ltd 2008-2010 */ -register_elgg_event_handler('init', 'system', 'twitterservice_init'); +elgg_register_event_handler('init', 'system', 'twitterservice_init'); function twitterservice_init() { $notice_id = 'twitter_services_disable'; - + + // @todo there's a better way to do this with requires. if (!elgg_is_active_plugin('oauth_lib')) { // disable the plugin disable_plugin('twitterservice'); - + // alert the admin if (!elgg_admin_notice_exists($notice_id)) { elgg_add_admin_notice($notice_id, elgg_echo('twitterservice:requires_oauth')); @@ -25,37 +26,42 @@ function twitterservice_init() { } else { // cleanup notices elgg_delete_admin_notice($notice_id); - + // require libraries $base = elgg_get_plugins_path() . 'twitterservice'; require_once "$base/vendors/twitteroauth/twitterOAuth.php"; require_once "$base/twitterservice_lib.php"; - + // extend site views elgg_extend_view('metatags', 'twitterservice/metatags'); elgg_extend_view('css', 'twitterservice/css'); - + // sign on with twitter if (twitterservice_allow_sign_on_with_twitter()) { elgg_extend_view('login/extend', 'twitterservice/login'); } - + // register page handler register_page_handler('twitterservice', 'twitterservice_pagehandler'); - + // register Walled Garden public pages - register_plugin_hook('public_pages', 'walled_garden', 'twitterservice_public_pages'); - + elgg_register_plugin_hook_handler('public_pages', 'walled_garden', 'twitterservice_public_pages'); + // allow plugin authors to hook into this service - register_plugin_hook('tweet', 'twitter_service', 'twitterservice_tweet'); + elgg_register_plugin_hook_handler('tweet', 'twitter_service', 'twitterservice_tweet'); } } +/** + * Serves pages for twitter. + * + * @param array$page + */ function twitterservice_pagehandler($page) { if (!isset($page[0])) { forward(); } - + switch ($page[0]) { case 'authorize': twitterservice_authorize(); @@ -75,62 +81,84 @@ function twitterservice_pagehandler($page) { } } +/** + * Push a tweet to twitter. + * + * @param unknown_type $hook + * @param unknown_type $entity_type + * @param unknown_type $returnvalue + * @param unknown_type $params + */ function twitterservice_tweet($hook, $entity_type, $returnvalue, $params) { static $plugins; if (!$plugins) { - $plugins = trigger_plugin_hook('plugin_list', 'twitter_service', NULL, array()); + $plugins = elgg_trigger_plugin_hook('plugin_list', 'twitter_service', NULL, array()); } - + // ensure valid plugin if (!in_array($params['plugin'], $plugins)) { return NULL; } - + // check admin settings $consumer_key = elgg_get_plugin_setting('consumer_key', 'twitterservice'); $consumer_secret = elgg_get_plugin_setting('consumer_secret', 'twitterservice'); if (!($consumer_key && $consumer_secret)) { return NULL; } - + // check user settings $user_id = elgg_get_logged_in_user_guid(); - $access_key = get_plugin_usersetting('access_key', $user_id, 'twitterservice'); - $access_secret = get_plugin_usersetting('access_secret', $user_id, 'twitterservice'); + $access_key = elgg_get_plugin_user_setting('access_key', $user_id, 'twitterservice'); + $access_secret = elgg_get_plugin_user_setting('access_secret', $user_id, 'twitterservice'); if (!($access_key && $access_secret)) { return NULL; } - + // send tweet $api = new TwitterOAuth($consumer_key, $consumer_secret, $access_key, $access_secret); $response = $api->post('statuses/update', array('status' => $params['message'])); - + return TRUE; } -function twitterservice_fetch_tweets($user_id, $options=array()) { +/** + * Return tweets for a user. + * + * @param int $user_id The Elgg user GUID + * @param array $options + */ +function twitterservice_fetch_tweets($user_guid, $options=array()) { // check admin settings $consumer_key = elgg_get_plugin_setting('consumer_key', 'twitterservice'); $consumer_secret = elgg_get_plugin_setting('consumer_secret', 'twitterservice'); if (!($consumer_key && $consumer_secret)) { return FALSE; } - + // check user settings - $access_key = get_plugin_usersetting('access_key', $user_id, 'twitterservice'); - $access_secret = get_plugin_usersetting('access_secret', $user_id, 'twitterservice'); + $access_key = elgg_get_plugin_user_setting('access_key', $user_guid, 'twitterservice'); + $access_secret = elgg_get_plugin_user_setting('access_secret', $user_guid, 'twitterservice'); if (!($access_key && $access_secret)) { return FALSE; } - + // fetch tweets $api = new TwitterOAuth($consumer_key, $consumer_secret, $access_key, $access_secret); return $api->get('statuses/user_timeline', $options); } +/** + * Register as public pages for walled garden. + * + * @param unknown_type $hook + * @param unknown_type $type + * @param unknown_type $return_value + * @param unknown_type $params + */ function twitterservice_public_pages($hook, $type, $return_value, $params) { $return_value[] = 'pg/twitterservice/forward'; $return_value[] = 'pg/twitterservice/login'; - + return $return_value; } diff --git a/mod/twitterservice/twitterservice_lib.php b/mod/twitterservice/twitterservice_lib.php index 7e8004215..074c7d16c 100644 --- a/mod/twitterservice/twitterservice_lib.php +++ b/mod/twitterservice/twitterservice_lib.php @@ -17,53 +17,75 @@ function twitterservice_allow_sign_on_with_twitter() { if (!$consumer_key = elgg_get_plugin_setting('consumer_key', 'twitterservice')) { return FALSE; } - + if (!$consumer_secret = elgg_get_plugin_setting('consumer_secret', 'twitterservice')) { return FALSE; } - + return elgg_get_plugin_setting('sign_on', 'twitterservice') == 'yes'; } +/** + * Forwards + * + * @todo what is this? + */ function twitterservice_forward() { - // sanity check if (!twitterservice_allow_sign_on_with_twitter()) { forward(); } - + $callback = elgg_normalize_url("pg/twitterservice/login"); $request_link = twitterservice_get_authorize_url($callback); - + forward($request_link, 'twitterservice'); } +/** + * Log in a user with twitter. + */ function twitterservice_login() { - + // sanity check if (!twitterservice_allow_sign_on_with_twitter()) { forward(); } - + $token = twitterservice_get_access_token(get_input('oauth_verifier')); if (!isset($token['oauth_token']) or !isset($token['oauth_token_secret'])) { register_error(elgg_echo('twitterservice:login:error')); forward(); } - - // attempt to find user - $values = array( - 'plugin:settings:twitterservice:access_key' => $token['oauth_token'], - 'plugin:settings:twitterservice:access_secret' => $token['oauth_token_secret'], + + // attempt to find user and log them in. + // else, create a new user. + $options = array( + 'type' => 'user', + 'plugin_user_setting_name_value_pairs' => array( + 'access_key' => $token['oauth_token'], + 'access_secret' => $token['oauth_token_secret'], + ), + 'limit' => 0 ); - - if (!$users = get_entities_from_private_setting_multi($values, 'user', '', 0, '', 0)) { + + $users = elgg_get_entities_from_plugin_user_settings($options); + + if ($users) { + if (count($users) == 1 && login($users[0])) { + system_message(elgg_echo('twitterservice:login:success')); + } else { + system_message(elgg_echo('twitterservice:login:error')); + } + + forward(); + } else { // need Twitter account credentials $consumer_key = elgg_get_plugin_setting('consumer_key', 'twitterservice'); $consumer_secret = elgg_get_plugin_setting('consumer_secret', 'twitterservice'); $api = new TwitterOAuth($consumer_key, $consumer_secret, $token['oauth_token'], $token['oauth_token_secret']); $twitter = $api->get('account/verify_credentials'); - + // backward compatibility for stalled-development Twitter Login plugin $user = FALSE; if ($twitter_user = get_user_by_username($token['screen_name'])) { @@ -73,7 +95,7 @@ function twitterservice_login() { $forward = ''; } } - + // create new user if (!$user) { // check new registration allowed @@ -81,22 +103,22 @@ function twitterservice_login() { register_error(elgg_echo('registerdisabled')); forward(); } - + // trigger a hook for plugin authors to intercept - if (!trigger_plugin_hook('new_twitter_user', 'twitter_service', array('account' => $twitter), TRUE)) { + if (!elgg_trigger_plugin_hook('new_twitter_user', 'twitter_service', array('account' => $twitter), TRUE)) { // halt execution register_error(elgg_echo('twitterservice:login:error')); forward(); } - + // Elgg-ify Twitter credentials $username = "{$twitter->screen_name}_twitter"; $display_name = $twitter->name; $password = generate_random_cleartext_password(); - + // @hack Temporary, junk email account to allow user creation $email = "$username@elgg.com"; - + try { // create new account if (!$user_id = register_user($username, $password, $display_name, $email)) { @@ -107,50 +129,48 @@ function twitterservice_login() { register_error($r->getMessage()); forward(); } - + $user = new ElggUser($user_id); - + // @hack Remove temporary email and forward to user settings page // @todo Consider using a view to force valid email $site_name = elgg_get_site_entity()->name; system_message(elgg_echo('twitterservice:login:email', array($site_name))); $user->email = ''; $user->save(); - + $forward = "pg/settings/user/{$user->username}"; } - + // set twitter services tokens elgg_set_plugin_user_setting('twitter_name', $token['screen_name'], $user->guid); elgg_set_plugin_user_setting('access_key', $token['oauth_token'], $user->guid); elgg_set_plugin_user_setting('access_secret', $token['oauth_token_secret'], $user->guid); - + // pull in Twitter icon twitterservice_update_user_avatar($user, $twitter->profile_image_url); - + // login new user if (login($user)) { system_message(elgg_echo('twitterservice:login:success')); } else { system_message(elgg_echo('twitterservice:login:error')); } - + forward($forward, 'twitterservice'); - } elseif (count($users) == 1) { - if (login($users[0])) { - system_message(elgg_echo('twitterservice:login:success')); - } else { - system_message(elgg_echo('twitterservice:login:error')); - } - - forward(); } - + // register login error register_error(elgg_echo('twitterservice:login:error')); forward(); } +/** + * Pull in the latest avatar from twitter. + * + * @param unknown_type $user + * @param unknown_type $file_location + */ function twitterservice_update_user_avatar($user, $file_location) { $sizes = array( 'topbar' => array(16, 16, TRUE), @@ -160,7 +180,7 @@ function twitterservice_update_user_avatar($user, $file_location) { 'large' => array(200, 200, FALSE), 'master' => array(550, 550, FALSE), ); - + $filehandler = new ElggFile(); $filehandler->owner_guid = $user->getGUID(); foreach ($sizes as $size => $dimensions) { @@ -176,7 +196,7 @@ function twitterservice_update_user_avatar($user, $file_location) { $filehandler->write($image); $filehandler->close(); } - + return TRUE; } @@ -196,71 +216,90 @@ function twitterservice_authorize() { register_error(elgg_echo('twitterservice:authorize:error')); forward('pg/settings/plugins', 'twitterservice'); } - - // only one user per tokens - $values = array( - 'plugin:settings:twitterservice:access_key' => $token['oauth_token'], - 'plugin:settings:twitterservice:access_secret' => $token['oauth_token_secret'], + + // make sure no other users are registered to this twitter account. + $options = array( + 'type' => 'user', + 'plugin_user_setting_name_value_pairs' => array( + 'access_key' => $token['oauth_token'], + 'access_secret' => $token['oauth_token_secret'], + ), + 'limit' => 0 ); - - if ($users = get_entities_from_private_setting_multi($values, 'user', '', 0, '', 0)) { + + $users = elgg_get_entities_from_plugin_user_settings($options); + + if ($users) { foreach ($users as $user) { // revoke access - clear_plugin_usersetting('twitter_name', $user->getGUID()); - clear_plugin_usersetting('access_key', $user->getGUID()); - clear_plugin_usersetting('access_secret', $user->getGUID()); + elgg_unset_plugin_user_setting('twitter_name', $user->getGUID()); + elgg_unset_plugin_user_setting('access_key', $user->getGUID()); + elgg_unset_plugin_user_setting('access_secret', $user->getGUID()); } } - + // register user's access tokens elgg_set_plugin_user_setting('twitter_name', $token['screen_name']); elgg_set_plugin_user_setting('access_key', $token['oauth_token']); elgg_set_plugin_user_setting('access_secret', $token['oauth_token_secret']); - + system_message(elgg_echo('twitterservice:authorize:success')); forward('pg/settings/plugins', 'twitterservice'); } +/** + * Remove twitter access for the currently logged in user. + */ function twitterservice_revoke() { // unregister user's access tokens - clear_plugin_usersetting('twitter_name'); - clear_plugin_usersetting('access_key'); - clear_plugin_usersetting('access_secret'); - + elgg_unset_plugin_user_setting('twitter_name'); + elgg_unset_plugin_user_setting('access_key'); + elgg_unset_plugin_user_setting('access_secret'); + system_message(elgg_echo('twitterservice:revoke:success')); forward('pg/settings/plugins', 'twitterservice'); } -function twitterservice_get_authorize_url($callback=NULL) { +/** + * Returns the url to authorize a user. + * + * @param string $callback The callback URL? + */ +function twitterservice_get_authorize_url($callback = NULL) { global $SESSION; - + $consumer_key = elgg_get_plugin_setting('consumer_key', 'twitterservice'); $consumer_secret = elgg_get_plugin_setting('consumer_secret', 'twitterservice'); - + // request tokens from Twitter $twitter = new TwitterOAuth($consumer_key, $consumer_secret); $token = $twitter->getRequestToken($callback); - + // save token in session for use after authorization $SESSION['twitterservice'] = array( 'oauth_token' => $token['oauth_token'], 'oauth_token_secret' => $token['oauth_token_secret'], ); - + return $twitter->getAuthorizeURL($token['oauth_token']); } -function twitterservice_get_access_token($oauth_verifier=FALSE) { +/** + * Returns the access token to use in twitter calls. + * + * @param unknown_type $oauth_verifier + */ +function twitterservice_get_access_token($oauth_verifier = FALSE) { global $SESSION; - + $consumer_key = elgg_get_plugin_setting('consumer_key', 'twitterservice'); $consumer_secret = elgg_get_plugin_setting('consumer_secret', 'twitterservice'); - + // retrieve stored tokens $oauth_token = $SESSION['twitterservice']['oauth_token']; $oauth_token_secret = $SESSION['twitterservice']['oauth_token_secret']; $SESSION->offsetUnset('twitterservice'); - + // fetch an access token $api = new TwitterOAuth($consumer_key, $consumer_secret, $oauth_token, $oauth_token_secret); return $api->getAccessToken($oauth_verifier); -- cgit v1.2.3