diff options
-rw-r--r-- | actions/newmessage.php | 4 | ||||
-rw-r--r-- | actions/shownotice.php | 4 | ||||
-rw-r--r-- | classes/statusnet.ini | 10 | ||||
-rw-r--r-- | index.php | 2 | ||||
-rw-r--r-- | plugins/OpenID/OpenIDPlugin.php | 10 | ||||
-rw-r--r-- | plugins/OpenID/User_openid_trustroot.php | 29 | ||||
-rw-r--r-- | plugins/OpenID/openidserver.php | 98 | ||||
-rw-r--r-- | plugins/OpenID/openidtrust.php | 142 |
8 files changed, 274 insertions, 25 deletions
diff --git a/actions/newmessage.php b/actions/newmessage.php index a0b17fc18..eac4ab210 100644 --- a/actions/newmessage.php +++ b/actions/newmessage.php @@ -99,7 +99,9 @@ class NewmessageAction extends Action $user = common_current_user(); if (!$user) { - $this->clientError(_('Only logged-in users can send direct messages.'), 403); + /* Go log in, and then come back. */ + common_set_returnto($_SERVER['REQUEST_URI']); + common_redirect(common_local_url('login')); return false; } diff --git a/actions/shownotice.php b/actions/shownotice.php index 41408c23c..5d16fdad9 100644 --- a/actions/shownotice.php +++ b/actions/shownotice.php @@ -172,9 +172,9 @@ class ShownoticeAction extends OwnerDesignAction function title() { if (!empty($this->profile->fullname)) { - $base = $this->profile->fullname . ' (' . $this->user->nickname . ') '; + $base = $this->profile->fullname . ' (' . $this->profile->nickname . ') '; } else { - $base = $this->user->nickname; + $base = $this->profile->nickname; } return sprintf(_('%1$s\'s status on %2$s'), diff --git a/classes/statusnet.ini b/classes/statusnet.ini index 7931c7bcd..623790b10 100644 --- a/classes/statusnet.ini +++ b/classes/statusnet.ini @@ -537,6 +537,16 @@ modified = 384 canonical = K display = U +[user_openid_trustroot] +trustroot = 130 +user_id = 129 +created = 142 +modified = 384 + +[user_openid__keys] +trustroot = K +user_id = K + [user_role] user_id = 129 role = 130 @@ -143,7 +143,7 @@ function checkMirror($action_obj, $args) function isLoginAction($action) { - static $loginActions = array('login', 'recoverpassword', 'api', 'doc', 'register'); + static $loginActions = array('login', 'recoverpassword', 'api', 'doc', 'register', 'publicxrds'); $login = null; diff --git a/plugins/OpenID/OpenIDPlugin.php b/plugins/OpenID/OpenIDPlugin.php index 5ebee2cbe..2309eea9d 100644 --- a/plugins/OpenID/OpenIDPlugin.php +++ b/plugins/OpenID/OpenIDPlugin.php @@ -150,6 +150,7 @@ class OpenIDPlugin extends Plugin case 'PublicxrdsAction': case 'OpenidsettingsAction': case 'OpenidserverAction': + case 'OpenidtrustAction': require_once(INSTALLDIR.'/plugins/OpenID/' . strtolower(mb_substr($cls, 0, -6)) . '.php'); return false; case 'User_openid': @@ -179,6 +180,7 @@ class OpenIDPlugin extends Plugin { case 'openidlogin': case 'finishopenidlogin': + case 'openidserver': $login = true; return false; default: @@ -286,6 +288,14 @@ class OpenIDPlugin extends Plugin new ColumnDef('created', 'datetime', null, false), new ColumnDef('modified', 'timestamp'))); + $schema->ensureTable('user_openid_trustroot', + array(new ColumnDef('trustroot', 'varchar', + '255', false, 'PRI'), + new ColumnDef('user_id', 'integer', + null, false, 'PRI'), + new ColumnDef('created', 'datetime', + null, false), + new ColumnDef('modified', 'timestamp'))); return true; } } diff --git a/plugins/OpenID/User_openid_trustroot.php b/plugins/OpenID/User_openid_trustroot.php new file mode 100644 index 000000000..4654b72df --- /dev/null +++ b/plugins/OpenID/User_openid_trustroot.php @@ -0,0 +1,29 @@ +<?php +/** + * Table Definition for user_openid_trustroot + */ +require_once INSTALLDIR.'/classes/Memcached_DataObject.php'; + +class User_openid_trustroot extends Memcached_DataObject +{ + ###START_AUTOCODE + /* the code below is auto generated do not remove the above tag */ + + public $__table = 'user_openid_trustroot'; // table name + public $trustroot; // varchar(255) primary_key not_null + public $user_id; // int(4) primary_key not_null + public $created; // datetime() not_null + public $modified; // timestamp() not_null default_CURRENT_TIMESTAMP + + /* Static get */ + function staticGet($k,$v=null) + { return Memcached_DataObject::staticGet('User_openid_trustroot',$k,$v); } + + /* the code above is auto generated do not remove the tag below */ + ###END_AUTOCODE + + function &pkeyGet($kv) + { + return Memcached_DataObject::pkeyGet('User_openid_trustroot', $kv); + } +} diff --git a/plugins/OpenID/openidserver.php b/plugins/OpenID/openidserver.php index a6b18608d..dab97c93e 100644 --- a/plugins/OpenID/openidserver.php +++ b/plugins/OpenID/openidserver.php @@ -33,6 +33,7 @@ if (!defined('STATUSNET') && !defined('LACONICA')) { require_once INSTALLDIR.'/lib/action.php'; require_once INSTALLDIR.'/plugins/OpenID/openid.php'; +require_once(INSTALLDIR.'/plugins/OpenID/User_openid_trustroot.php'); /** * Settings for OpenID @@ -47,49 +48,104 @@ require_once INSTALLDIR.'/plugins/OpenID/openid.php'; */ class OpenidserverAction extends Action { + var $oserver; + + function prepare($args) + { + parent::prepare($args); + $this->oserver = oid_server(); + return true; + } function handle($args) { parent::handle($args); - $oserver = oid_server(); - $request = $oserver->decodeRequest(); + $request = $this->oserver->decodeRequest(); if (in_array($request->mode, array('checkid_immediate', 'checkid_setup'))) { - $cur = common_current_user(); - error_log("Request identity: " . $request->identity); - if(!$cur){ - /* Go log in, and then come back. */ - common_set_returnto($_SERVER['REQUEST_URI']); - common_redirect(common_local_url('login')); - return; - }else if(common_profile_url($cur->nickname) == $request->identity || $request->idSelect()){ - $response = &$request->answer(true, null, common_profile_url($cur->nickname)); + $user = common_current_user(); + if(!$user){ + if($request->immediate){ + //cannot prompt the user to login in immediate mode, so answer false + $response = $this->generateDenyResponse($request); + }else{ + /* Go log in, and then come back. */ + common_set_returnto($_SERVER['REQUEST_URI']); + common_redirect(common_local_url('login')); + return; + } + }else if(common_profile_url($user->nickname) == $request->identity || $request->idSelect()){ + $user_openid_trustroot = User_openid_trustroot::pkeyGet( + array('user_id'=>$user->id, 'trustroot'=>$request->trust_root)); + if(empty($user_openid_trustroot)){ + if($request->immediate){ + //cannot prompt the user to trust this trust root in immediate mode, so answer false + $response = $this->generateDenyResponse($request); + }else{ + common_ensure_session(); + $_SESSION['openid_trust_root'] = $request->trust_root; + $allowResponse = $this->generateAllowResponse($request, $user); + $this->oserver->encodeResponse($allowResponse); //sign the response + $denyResponse = $this->generateDenyResponse($request); + $this->oserver->encodeResponse($denyResponse); //sign the response + $_SESSION['openid_allow_url'] = $allowResponse->encodeToUrl(); + $_SESSION['openid_deny_url'] = $denyResponse->encodeToUrl(); + //ask the user to trust this trust root + common_redirect(common_local_url('openidtrust')); + return; + } + }else{ + //user has previously authorized this trust root + $response = $this->generateAllowResponse($request, $user); + //$response = $request->answer(true, null, common_profile_url($user->nickname)); + } } else if ($request->immediate) { - $response = &$request->answer(false); + $response = $this->generateDenyResponse($request); } else { //invalid $this->clientError(sprintf(_('You are not authorized to use the identity %s'),$request->identity),$code=403); } } else { - $response = &$oserver->handleRequest($request); + $response = $this->oserver->handleRequest($request); } if($response){ - $webresponse = $oserver->encodeResponse($response); - - if ($webresponse->code != AUTH_OPENID_HTTP_OK) { - header(sprintf("HTTP/1.1 %d ", $webresponse->code), - true, $webresponse->code); + $response = $this->oserver->encodeResponse($response); + if ($response->code != AUTH_OPENID_HTTP_OK) { + header(sprintf("HTTP/1.1 %d ", $response->code), + true, $response->code); } - if($webresponse->headers){ - foreach ($webresponse->headers as $k => $v) { + if($response->headers){ + foreach ($response->headers as $k => $v) { header("$k: $v"); } } - $this->raw($webresponse->body); + $this->raw($response->body); }else{ $this->clientError(_('Just an OpenID provider. Nothing to see here, move along...'),$code=500); } } + + function generateAllowResponse($request, $user){ + $response = $request->answer(true, null, common_profile_url($user->nickname)); + + $profile = $user->getProfile(); + $sreg_data = array( + 'fullname' => $profile->fullname, + 'nickname' => $user->nickname, + 'email' => $user->email, + 'language' => $user->language, + 'timezone' => $user->timezone); + $sreg_request = Auth_OpenID_SRegRequest::fromOpenIDRequest($request); + $sreg_response = Auth_OpenID_SRegResponse::extractResponse( + $sreg_request, $sreg_data); + $sreg_response->toMessage($response->fields); + return $response; + } + + function generateDenyResponse($request){ + $response = $request->answer(false); + return $response; + } } diff --git a/plugins/OpenID/openidtrust.php b/plugins/OpenID/openidtrust.php new file mode 100644 index 000000000..29c7bdc23 --- /dev/null +++ b/plugins/OpenID/openidtrust.php @@ -0,0 +1,142 @@ +<?php +/* + * StatusNet - the distributed open-source microblogging tool + * Copyright (C) 2008, 2009, StatusNet, Inc. + * + * 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/>. + */ + +if (!defined('STATUSNET') && !defined('LACONICA')) { exit(1); } + +require_once INSTALLDIR.'/plugins/OpenID/openid.php'; +require_once(INSTALLDIR.'/plugins/OpenID/User_openid_trustroot.php'); + +class OpenidtrustAction extends Action +{ + var $trust_root; + var $allowUrl; + var $denyUrl; + var $user; + + /** + * Is this a read-only action? + * + * @return boolean false + */ + + function isReadOnly($args) + { + return false; + } + + /** + * Title of the page + * + * @return string title of the page + */ + + function title() + { + return _('OpenID Identity Verification'); + } + + function prepare($args) + { + parent::prepare($args); + common_ensure_session(); + $this->user = common_current_user(); + if(empty($this->user)){ + /* Go log in, and then come back. */ + common_set_returnto($_SERVER['REQUEST_URI']); + common_redirect(common_local_url('login')); + return; + } + $this->trust_root = $_SESSION['openid_trust_root']; + $this->allowUrl = $_SESSION['openid_allow_url']; + $this->denyUrl = $_SESSION['openid_deny_url']; + if(empty($this->trust_root) || empty($this->allowUrl) || empty($this->denyUrl)){ + $this->clientError(_('This page should only be reached during OpenID processing, not directly.')); + return; + } + return true; + } + + function handle($args) + { + parent::handle($args); + if($_SERVER['REQUEST_METHOD'] == 'POST'){ + $this->handleSubmit(); + }else{ + $this->showPage(); + } + } + + function handleSubmit() + { + unset($_SESSION['openid_trust_root']); + unset($_SESSION['openid_allow_url']); + unset($_SESSION['openid_deny_url']); + if($this->arg('allow')) + { + //save to database + $user_openid_trustroot = new User_openid_trustroot(); + $user_openid_trustroot->user_id = $this->user->id; + $user_openid_trustroot->trustroot = $this->trust_root; + $user_openid_trustroot->created = DB_DataObject_Cast::dateTime(); + if (!$user_openid_trustroot->insert()) { + $err = PEAR::getStaticProperty('DB_DataObject','lastError'); + common_debug('DB error ' . $err->code . ': ' . $err->message, __FILE__); + } + common_redirect($this->allowUrl, $code=302); + }else{ + common_redirect($this->denyUrl, $code=302); + } + } + + /** + * Show page notice + * + * Display a notice for how to use the page, or the + * error if it exists. + * + * @return void + */ + + function showPageNotice() + { + $this->element('p',null,sprintf(_('%s has asked to verify your identity. Click Continue to verify your identity and login without creating a new password.'),$this->trust_root)); + } + + /** + * Core of the display code + * + * Shows the login form. + * + * @return void + */ + + function showContent() + { + $this->elementStart('form', array('method' => 'post', + 'id' => 'form_openidtrust', + 'class' => 'form_settings', + 'action' => common_local_url('openidtrust'))); + $this->elementStart('fieldset'); + $this->submit('allow', _('Continue')); + $this->submit('deny', _('Cancel')); + + $this->elementEnd('fieldset'); + $this->elementEnd('form'); + } +} |