From 171b4f72ee5a84d2a67b99aca7df9406e68f60c1 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Thu, 19 Jun 2008 09:47:10 -0400 Subject: [PATCH] immediate mode for openid darcs-hash:20080619134710-84dde-6086a4ac7bbd72a251fe5ce6fe3156e3270ebd74.gz --- actions/finishaddopenid.php | 2 ++ actions/finishimmediate.php | 64 +++++++++++++++++++++++++++++++++++ actions/finishopenidlogin.php | 16 +++------ actions/logout.php | 3 ++ actions/openidlogin.php | 14 +++++--- index.php | 15 ++++++++ lib/openid.php | 52 +++++++++++++++++++++++++--- 7 files changed, 146 insertions(+), 20 deletions(-) create mode 100644 actions/finishimmediate.php diff --git a/actions/finishaddopenid.php b/actions/finishaddopenid.php index 237f0454f7..78aa67d89e 100644 --- a/actions/finishaddopenid.php +++ b/actions/finishaddopenid.php @@ -88,6 +88,8 @@ class FinishaddopenidAction extends Action { # success! $cur->query('COMMIT'); + + oid_set_last($display); common_redirect(common_local_url('openidsettings')); } diff --git a/actions/finishimmediate.php b/actions/finishimmediate.php new file mode 100644 index 0000000000..af55f166ef --- /dev/null +++ b/actions/finishimmediate.php @@ -0,0 +1,64 @@ +. + */ + +if (!defined('LACONICA')) { exit(1); } + +require_once(INSTALLDIR.'/lib/openid.php'); + +class FinishimmediateAction extends Action { + + function handle($args) { + parent::handle($args); + + $consumer = oid_consumer(); + + $response = $consumer->complete(common_local_url('finishimmediate')); + + if ($response->status == Auth_OpenID_SUCCESS) { + $display = $response->getDisplayIdentifier(); + $canonical = ($response->endpoint->canonicalID) ? + $response->endpoint->canonicalID : $response->getDisplayIdentifier(); + + $user = $this->get_user($canonical); + + if ($user) { + $this->update_user($user, $sreg); + common_set_user($user->nickname); + $this->go_backto(); + return; + } + } + + # Failure! Clear openid so we don't try it again + + oid_clear_last(); + $this->go_backto(); + return; + } + + function go_backto() { + common_ensure_session(); + $backto = $_SESSION['openid_immediate_backto']; + if (!$backto) { + # gar. Well, push them to the public page + $backto = common_local_url('public'); + } + common_redirect($backto); + } +} diff --git a/actions/finishopenidlogin.php b/actions/finishopenidlogin.php index 2b3616ffae..3a7f9f250b 100644 --- a/actions/finishopenidlogin.php +++ b/actions/finishopenidlogin.php @@ -104,9 +104,10 @@ class FinishopenidloginAction extends Action { $sreg = $sreg_resp->contents(); } - $user = $this->get_user($canonical); + $user = oid_get_user($canonical); if ($user) { + oid_set_last($display); $this->update_user($user, $sreg); common_set_user($user->nickname); $this->go_home($user->nickname); @@ -123,15 +124,6 @@ class FinishopenidloginAction extends Action { common_show_footer(); } - function get_user($canonical) { - $user = NULL; - $oid = User_openid::staticGet('canonical', $canonical); - if ($oid) { - $user = User::staticGet('id', $oid->user_id); - } - return $user; - } - function update_user($user, $sreg) { $profile = $user->getProfile(); @@ -210,7 +202,7 @@ class FinishopenidloginAction extends Action { # Possible race condition... let's be paranoid - $other = $this->get_user($canonical); + $other = oid_get_user($canonical); if ($other) { common_server_error(_t('Creating new account for OpenID that already has a user.')); @@ -272,6 +264,7 @@ class FinishopenidloginAction extends Action { $profile->delete(); } + oid_set_last($display); common_set_user($user->nickname); common_redirect(common_local_url('showstream', array('nickname' => $user->nickname))); } @@ -305,6 +298,7 @@ class FinishopenidloginAction extends Action { } $this->update_user($user, $sreg); + oid_set_last($display); common_set_user($user->nickname); $this->go_home($user->nickname); } diff --git a/actions/logout.php b/actions/logout.php index 4df69c3b32..9cdda52d84 100644 --- a/actions/logout.php +++ b/actions/logout.php @@ -19,6 +19,8 @@ if (!defined('LACONICA')) { exit(1); } +require_once(INSTALLDIR.'/lib/openid.php'); + class LogoutAction extends Action { function handle($args) { parent::handle($args); @@ -26,6 +28,7 @@ class LogoutAction extends Action { common_user_error(_t('Not logged in.')); } else { common_set_user(NULL); + oid_clear_last(); common_redirect(common_local_url('public')); } } diff --git a/actions/openidlogin.php b/actions/openidlogin.php index ecc4e6bff6..f00c171810 100644 --- a/actions/openidlogin.php +++ b/actions/openidlogin.php @@ -28,13 +28,15 @@ class OpenidloginAction extends Action { if (common_logged_in()) { common_user_error(_t('Already logged in.')); } else if ($_SERVER['REQUEST_METHOD'] == 'POST') { - $result = oid_authenticate($this->trimmed('openid_url'), + $openid_url = $this->trimmed('openid_url'); + $result = oid_authenticate($openid_url, 'finishopenidlogin'); if (is_string($result)) { # error message - $this->show_form($result); + $this->show_form($result, $openid_url); } } else { - $this->show_form(); + $openid_url = oid_get_last(); + $this->show_form(NULL, $openid_url); } } @@ -47,13 +49,15 @@ class OpenidloginAction extends Action { } } - function show_form($error=NULL) { + function show_form($error=NULL, $openid_url) { common_show_header(_t('OpenID Login'), NULL, $error, array($this, 'show_top')); $formaction = common_local_url('openidlogin'); common_element_start('form', array('method' => 'POST', 'id' => 'openidlogin', 'action' => $formaction)); - common_input('openid_url', _t('OpenID URL')); + common_input('openid_url', _t('OpenID URL'), + $openid_url, + _t('Your OpenID URL')); common_submit('submit', _t('Login')); common_element_end('form'); common_show_footer(); diff --git a/index.php b/index.php index 53fd1bfe66..c40eca7876 100644 --- a/index.php +++ b/index.php @@ -28,6 +28,21 @@ if (!$action) { common_redirect(common_local_url('public')); } +# Do an OpenID immediate request if they're not logged in +# and they have an OpenID cookie + +if (!common_logged_in() && + $_SERVER['REQUEST_METHOD'] == 'GET' && + $action != 'finishimmediate') +{ + require_once(INSTALLDIR.'/lib/openid.php'); + $openid_url = oid_get_last(); + if ($openid_url) { + oid_check_immediate($openid_url); + return; + } +} + $actionfile = INSTALLDIR."/actions/$action.php"; if (file_exists($actionfile)) { diff --git a/lib/openid.php b/lib/openid.php index 67f8edf7b3..6dbeebd2bd 100644 --- a/lib/openid.php +++ b/lib/openid.php @@ -26,6 +26,11 @@ require_once('Auth/OpenID/Consumer.php'); require_once('Auth/OpenID/SReg.php'); require_once('Auth/OpenID/MySQLStore.php'); +# About one year cookie expiry + +define('OPENID_COOKIE_EXPIRY', round(365.25 * 24 * 60 * 60)); +define('OPENID_COOKIE_KEY', 'lastusedopenid'); + function oid_store() { static $store = NULL; if (!$store) { @@ -43,6 +48,24 @@ function oid_consumer() { return $consumer; } +function oid_clear_last() { + if (oid_get_last()) { + oid_set_last(''); + } +} + +function oid_set_last($openid_url) { + global $config; + setcookie(OPENID_COOKIE_KEY, $openid_url, + time() + OPENID_COOKIE_EXPIRY, + '/' . $config['site']['path'] . '/', + $config['site']['server']); +} + +function oid_get_last() { + return $_COOKIE[OPENID_COOKIE_KEY]; +} + function oid_link_user($id, $canonical, $display) { $oid = new User_openid(); @@ -60,8 +83,28 @@ function oid_link_user($id, $canonical, $display) { return true; } -function oid_authenticate($openid_url, $returnto) { - +function oid_get_user($openid_url) { + $user = NULL; + $oid = User_openid::staticGet('canonical', $openid_url); + if ($oid) { + $user = User::staticGet('id', $oid->user_id); + } + return $user; +} + +function oid_check_immediate($openid_url, $backto=NULL) { + if (!$backto) { + $backto = $_SERVER['PHP_SELF']; + } + common_ensure_session(); + $_SESSION['openid_immediate_backto'] = $backto; + oid_authenticate($openid_url, + 'finishimmediate', + true); +} + +function oid_authenticate($openid_url, $returnto, $immediate=false) { + $consumer = oid_consumer(); if (!$consumer) { @@ -100,7 +143,8 @@ function oid_authenticate($openid_url, $returnto) { if ($auth_request->shouldSendRedirect()) { $redirect_url = $auth_request->redirectURL($trust_root, - $process_url); + $process_url, + $immediate); if (!$redirect_url) { } else if (Auth_OpenID::isFailure($redirect_url)) { return _t('Could not redirect to server: ') . $redirect_url->message; @@ -111,7 +155,7 @@ function oid_authenticate($openid_url, $returnto) { // Generate form markup and render it. $form_id = 'openid_message'; $form_html = $auth_request->formMarkup($trust_root, $process_url, - false, array('id' => $form_id)); + $immediate, array('id' => $form_id)); # XXX: This is cheap, but things choke if we don't escape ampersands # in the HTML attributes