From 3c921f38de55922b1de3a331826e01cb876898a2 Mon Sep 17 00:00:00 2001 From: Zach Copley Date: Wed, 10 Nov 2010 01:18:06 +0000 Subject: [PATCH] Add an action to handle deauthorization callbacks from Facebook --- plugins/FacebookSSO/FacebookSSOPlugin.php | 6 +- .../actions/facebookdeauthorize.php | 214 ++++++++++++++++++ plugins/FacebookSSO/lib/facebookclient.php | 28 ++- 3 files changed, 235 insertions(+), 13 deletions(-) create mode 100644 plugins/FacebookSSO/actions/facebookdeauthorize.php diff --git a/plugins/FacebookSSO/FacebookSSOPlugin.php b/plugins/FacebookSSO/FacebookSSOPlugin.php index 32b6a29106..19d61211d8 100644 --- a/plugins/FacebookSSO/FacebookSSOPlugin.php +++ b/plugins/FacebookSSO/FacebookSSOPlugin.php @@ -94,6 +94,7 @@ class FacebookSSOPlugin extends Plugin case 'FacebookfinishloginAction': case 'FacebookadminpanelAction': case 'FacebooksettingsAction': + case 'FacebookdeauthorizeAction': include_once $dir . '/actions/' . strtolower(mb_substr($cls, 0, -6)) . '.php'; return false; case 'Facebookclient': @@ -149,11 +150,14 @@ class FacebookSSOPlugin extends Plugin 'main/facebookfinishlogin', array('action' => 'facebookfinishlogin') ); - $m->connect( 'settings/facebook', array('action' => 'facebooksettings') ); + $m->connect( + 'facebook/deauthorize', + array('action' => 'facebookdeauthorize') + ); } diff --git a/plugins/FacebookSSO/actions/facebookdeauthorize.php b/plugins/FacebookSSO/actions/facebookdeauthorize.php new file mode 100644 index 0000000000..fb4afa13bc --- /dev/null +++ b/plugins/FacebookSSO/actions/facebookdeauthorize.php @@ -0,0 +1,214 @@ +. + * + * @category Plugin + * @package StatusNet + * @author Zach Copley + * @copyright 2010 StatusNet, Inc. + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0 + * @link http://status.net/ + */ + +if (!defined('STATUSNET')) { + exit(1); +} + +/* + * Action class for handling deauthorize callbacks from Facebook. If the user + * doesn't have a password let her know she'll need to contact the site + * admin to get back into her account (if possible). + */ +class FacebookdeauthorizeAction extends Action +{ + private $facebook; + + /** + * For initializing members of the class. + * + * @param array $args misc. arguments + * + * @return boolean true + */ + function prepare($args) + { + $this->facebook = Facebookclient::getFacebook(); + + return true; + } + + /** + * Handler method + * + * @param array $args is ignored since it's now passed in in prepare() + */ + function handle($args) + { + parent::handle($args); + + $data = $this->facebook->getSignedRequest(); + + if (isset($data['user_id'])) { + + $fbuid = $data['user_id']; + + $flink = Foreign_link::getByForeignID($fbuid, FACEBOOK_SERVICE); + $user = $flink->getUser(); + + // Remove the link to Facebook + $result = $flink->delete(); + + if (!$result) { + common_log_db_error($flink, 'DELETE', __FILE__); + common_log( + LOG_WARNING, + sprintf( + 'Unable to delete Facebook foreign link ' + . 'for %s (%d), fbuid %s', + $user->nickname, + $user->id, + $fbuid + ), + __FILE__ + ); + return; + } + + common_log( + LOG_INFO, + sprintf( + 'Facebook callback: %s (%d), fbuid %s has deauthorized ' + . 'the Facebook application.', + $user->nickname, + $user->id, + $fbuid + ), + __FILE__ + ); + + // Warn the user about being locked out of their account + // if we can. + if (empty($user->password) && !empty($user->email)) { + $this->emailWarn($user); + } else { + common_log( + LOG_WARNING, + sprintf( + '%s (%d), fbuid $s has deauthorized his/her Facebook ' + . 'connection but hasn\'t set a password so s/he ' + . 'is locked out.', + $user->nickname, + $user->id, + $fbuid + ), + __FILE__ + ); + } + + } else { + if (!empty($data)) { + common_log( + LOG_WARNING, + sprintf( + 'Facebook called the deauthorize callback ' + . ' but didn\'t provide a user ID.' + ), + __FILE__ + ); + } else { + // It probably wasn't Facebook that hit this action, + // so redirect to the login page + common_redirect(common_local_url('login'), 303); + } + } + } + + /* + * Send the user an email warning that their account has been + * disconnected and he/she has no way to login and must contact + * the site administrator for help. + * + * @param User $user the deauthorizing user + * + */ + function emailWarn($user) + { + $profile = $user->getProfile(); + + $siteName = common_config('site', 'name'); + $siteEmail = common_config('site', 'email'); + + if (empty($siteEmail)) { + common_log( + LOG_WARNING, + "No site email address configured. Please set one." + ); + } + + common_switch_locale($user->language); + + $subject = _m('Contact the %s administrator to retrieve your account'); + + $msg = <<nickname, + $siteName, + $siteEmail + ); + + common_switch_locale(); + + if (mail_to_user($user, $subject, $body)) { + common_log( + LOG_INFO, + sprintf( + 'Sent account lockout warning to %s (%d)', + $user->nickname, + $user->id + ), + __FILE__ + ); + } else { + common_log( + LOG_WARNING, + sprintf( + 'Unable to send account lockout warning to %s (%d)', + $user->nickname, + $user->id + ), + __FILE__ + ); + } + } + +} \ No newline at end of file diff --git a/plugins/FacebookSSO/lib/facebookclient.php b/plugins/FacebookSSO/lib/facebookclient.php index 6753243ed0..cf00b55e3a 100644 --- a/plugins/FacebookSSO/lib/facebookclient.php +++ b/plugins/FacebookSSO/lib/facebookclient.php @@ -673,25 +673,29 @@ class Facebookclient */ function mailFacebookDisconnect() { - $profile = $user->getProfile(); + $profile = $this->user->getProfile(); $siteName = common_config('site', 'name'); - common_switch_locale($user->language); + common_switch_locale($this->user->language); - $subject = sprintf( - _m('Your Facebook connection has been removed'), - $siteName - ); + $subject = _m('Your Facebook connection has been removed'); $msg = <<