Improves the OpenID support in plat/al:
authorVincent Zanotti <vincent.zanotti@m4x.org>
Thu, 4 Jun 2009 00:03:41 +0000 (02:03 +0200)
committerVincent Zanotti <vincent.zanotti@m4x.org>
Thu, 4 Jun 2009 19:13:46 +0000 (21:13 +0200)
 * fixes a few security issues (including an XSRF vulnerability);
 * simplifies the authorization logic (now using the one advised by Auth::OpenID);
 * stops using the session to store OpenID requests (everything is passed in the URL);
 * simplifies the design of the trust page, and allows users to disable SReg.

Signed-off-by: Vincent Zanotti <vincent.zanotti@m4x.org>
Makefile
modules/openid.php
modules/openid/openid.inc.php
modules/platal.php
templates/openid/idp_xrds.tpl
templates/openid/openid.tpl
templates/openid/trust.tpl
templates/openid/user_xrds.tpl

index 232aa1f..ba24d7e 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -115,20 +115,20 @@ get-wiki:
 openid: get-openid spool/openid/store
 
 # There is no obvious way to automatically use the latest version
+OPENID_VERSION = 2.1.3
 get-openid:
        @if ! test -d include/Auth; then                                  \
-           wget http://openidenabled.com/files/php-openid/packages/php-openid-2.1.2.tar.bz2; \
-           tar -xjf php-openid-2.1.2.tar.bz2;                            \
-           mv php-openid-2.1.2/Auth include/;                            \
-           rm php-openid-2.1.2.tar.bz2;                                  \
-           rm -r php-openid-2.1.2;                                       \
+           wget http://openidenabled.com/files/php-openid/packages/php-openid-$(OPENID_VERSION).tar.bz2; \
+           tar -xjf php-openid-$(OPENID_VERSION).tar.bz2;                \
+           mv php-openid-$(OPENID_VERSION)/Auth include/;                \
+           rm php-openid-$(OPENID_VERSION).tar.bz2;                      \
+           rm -r php-openid-$(OPENID_VERSION);                           \
        fi
 
 spool/openid/store:
        mkdir -p $@
        chmod o+w $@
 
-
 ##
 ## banana
 ##
index 15c0af0..5b4eaff 100644 (file)
@@ -61,144 +61,147 @@ class OpenidModule extends PLModule
     function handlers()
     {
         return array(
-            'openid'                => $this->make_hook('openid',        AUTH_PUBLIC),
-            'openid/trust'          => $this->make_hook('trust',         AUTH_COOKIE),
-            'openid/trusted'        => $this->make_hook('trusted',       AUTH_MDP),
-            'admin/openid/trusted'  => $this->make_hook('admin_trusted', AUTH_MDP),
-            'openid/idp_xrds'       => $this->make_hook('idp_xrds',      AUTH_PUBLIC),
-            'openid/user_xrds'      => $this->make_hook('user_xrds',     AUTH_PUBLIC),
-            'openid/melix'          => $this->make_hook('melix',         AUTH_PUBLIC),
+            'openid'                => $this->make_hook('openid', AUTH_PUBLIC),
+            'openid/melix'          => $this->make_hook('melix', AUTH_PUBLIC),
+            'openid/xrds'           => $this->make_hook('xrds', AUTH_PUBLIC),
+            'openid/trust'          => $this->make_hook('trust', AUTH_MDP),
+            'openid/trusted'        => $this->make_hook('trusted', AUTH_MDP),
+            'admin/openid/trusted'  => $this->make_hook('admin_trusted', AUTH_MDP, 'admin'),
         );
     }
 
-    function handler_openid(&$page, $x = null)
+    function handler_openid(&$page, $login = null)
     {
         $this->load('openid.inc.php');
+        $requested_user = User::getSilent($login);
+        $server = new OpenId();
 
         // Spec §4.1.2: if "openid.mode" is absent, we SHOULD assume that
-        // the request is not an OpenId message
-        if (!array_key_exists('openid_mode', $_REQUEST)) {
-            return $this->render_discovery_page($page, get_user($x));
+        // the request is not an OpenId message.
+        if (!$server->IsOpenIdRequest()) {
+            if ($requested_user) {
+                $server->RenderDiscoveryPage($page, $requested_user);
+                return;
+            } else {
+                pl_redirect('Xorg/OpenId');
+            }
+            exit;
         }
 
-        // Now, deal with the OpenId message
-        $server = init_openid_server();
-        $request = $server->decodeRequest();
-
-        // In modes 'checkid_immediate' and 'checkid_setup', the request
-        // needs some logic and can not be automatically answered by the server
-
-        // Immediate mode
-        if ($request->mode == 'checkid_immediate') {
+        // Initializes the OpenId environment from the request.
+        $server->Initialize();
+
+        // In modes 'checkid_immediate' and 'checkid_setup', we need to check
+        // by ourselves that we want to allow the user to be authenticated.
+        // Otherwise it can simply be forwarded to the Server object.
+        if ($server->IsAuthorizationRequest()) {
+            $authorized = S::logged() &&
+                $server->IsUserAuthorized(S::user()) &&
+                $server->IsEndpointTrusted(S::user());
+
+            if ($authorized) {
+                // TODO(vzanotti): SReg requests are currently not honored if
+                // the website is already trusted. We may want to redirect SReg
+                // requests to /openid/trust, to allow the user to choose.
+                $server->AnswerRequest(true);
+            } else if ($server->IsImmediateRequest()) {
+                $server->AnswerRequest(false);
+            } else {
+                // The user is currently not authorized to get her authorization
+                // request approved. Two possibilities:
+                //  * the endpoint is not yet trusted => redirect to openid/trust
+                //  * the user is not logged in => log in the user.
+                //
+                // The second case requires a special handling when the request
+                // was POSTed, as our current log in mechanism does not preserve
+                // POST arguments.
+                $openid_args = $server->GetQueryStringForRequest();
+                if (S::logged()) {
+                    pl_redirect('openid/trust', $openid_args);
+                } else if (count($_POST)) {
+                    pl_redirect('openid', $openid_args);
+                } else {
+                    return PL_DO_AUTH;
+                }
+            }
+        } else {
+            $server->HandleRequest();
+        }
 
-            // We deny immediate requests, unless:
-            //   - the user identifier is known by the RP
-            //   - the user is logged in
-            //   - the user identifier matches the user logged in
-            //   - the user has whitelisted the site
-            $answer = !$request->idSelect()
-                      && S::logged()
-                      && $request->identity == S::user()->login()
-                      && is_trusted_site(S::user(), $request->trust_root);
-            $response =& $request->answer($answer);
+        // All requests should have been answered at this point. The best here
+        // is to get the user back to a safe page.
+        pl_redirect('');
+    }
 
-        // Setup mode
-        } else if ($request->mode == 'checkid_setup') {
+    function handler_melix(&$page, $login = null)
+    {
+        $this->load('openid.inc.php');
 
-            // We redirect to a page where the user will authenticate
-            // and confirm the use of his/her OpenId
-            $request_id = uniqid('openid-');
-            S::set($request_id, serialize($request));
-            $query = 'request_id=' . urlencode($request_id);
-            pl_redirect('openid/trust', $query);
-            return;
+        global $globals;
+        $melix = ($login ? $login . '@' . $globals->mail->alias_dom : null);
 
-        // Other requests can be automatically handled by the server
+        if ($melix && ($requested_user = User::getSilent($melix))) {
+            $server = new OpenId();
+            $server->RenderDiscoveryPage($page, $requested_user);
         } else {
-            $response =& $server->handleRequest($request);
+            pl_redirect('Xorg/OpenId');
         }
-
-        $webresponse =& $server->encodeResponse($response);
-        $this->render_openid_response($webresponse);
     }
 
-    function handler_trust(&$page, $x = null)
+    function handler_xrds(&$page, $login = null)
     {
         $this->load('openid.inc.php');
+        $requested_user = User::getSilent($login);
+        $server = new OpenId();
 
-        // Recover request in session
-        $request_id = $_GET['request_id'];
-        if (is_null($request_id) || !isset($_SESSION[$request_id])) {
-            // There is no authentication information, something went wrong
-            pl_redirect('/');
-            return;
+        if (!$login) {
+            $server->RenderMainXrdsPage($page);
+        } else if ($requested_user) {
+            $server->RenderUserXrdsPage($page, $requested_user);
+        } else {
+            return PL_NOT_FOUND;
         }
+    }
 
-        require_once 'Auth/OpenID/Server.php';
-        $request = unserialize($_SESSION[$request_id]);
-
-        $server = init_openid_server();
+    function handler_trust(&$page)
+    {
+        $this->load('openid.inc.php');
+        $server = new OpenId();
         $user = S::user();
-        $identity = null;
-        $claimed_id = null;
 
-        // Set the identity to the user currently logged in
-        // if an OP Identifier was initially used
-        if ($request->identity == Auth_OpenID_IDENTIFIER_SELECT) {
-            $identity = $user->hruid;
-            $claimed_id = get_user_openid_url($user);
-        // Check that the identity matches the user currently logged in
-        // if an User Identifier was initially used
-        } else if ($request->identity != $user->hruid) {
-            $response =& $request->answer(false);
-            $webresponse =& $server->encodeResponse($response);
-            $this->render_openid_response($webresponse);
-            return;
+        // Initializes the OpenId environment from the request.
+        if (!$server->Initialize() || !$server->IsAuthorizationRequest()) {
+            $page->kill("Ta requête OpenID a échoué, merci de réessayer.");
         }
 
-        // Prepare Simple Registration response fields
-        require_once 'Auth/OpenID/SReg.php';
-        $sreg_request = Auth_OpenID_SRegRequest::fromOpenIDRequest($request);
-        $sreg_response = Auth_OpenID_SRegResponse::extractResponse($sreg_request, get_sreg_data($user));
+        // Prepares the SREG data, if any is required.
+        $sreg_response = $server->GetSRegDataForRequest($user);
 
-        $whitelisted = is_trusted_site($user, $request->trust_root);
-
-        // Ask the user for confirmation
-        $from_trust_page = $_SERVER['REQUEST_METHOD'] == 'POST'
-                           && (isset($_POST['openid_trust']) || isset($_POST['openid_cancel']));
-        if (!$whitelisted && !$from_trust_page) {
+        // Asks the user about her trust level of the current request, if not
+        // done yet.
+        if (!Post::has('trust_accept') && !Post::has('trust_cancel')) {
             $page->changeTpl('openid/trust.tpl');
-            $page->assign('relying_party', $request->trust_root);
-            $page->assign_by_ref('sreg_data', $sreg_response->data);
-            $query = 'request_id=' . urlencode($request_id);
-            $page->assign('query', $query);
-            return;
-        }
-
-        // If this point is reached, the user has just validated the form on the 'trust' page
+            $page->assign('openid_query', $server->GetQueryStringForRequest());
+            $page->assign('relying_party', $server->GetEndpoint());
+            $page->assign('sreg_data', $sreg_response->contents());
 
-        // Remove the request from session since an answer will be sent
-        S::kill($request_id);
-
-        // Add 'always trusted' sites to whitelist
-        if (isset($_POST['openid_trust']) && @$_POST['openid_always']) {
-            add_trusted_site($user, $request->trust_root);
+            return;
         }
 
-        // Answer to the Relying Party
-        if ($whitelisted || isset($_POST['openid_trust'])) {
-            $response =& $request->answer(true, null, $identity, $claimed_id);
-
-            // Add the simple registration response values to the OpenID
-            // response message.
-            $sreg_response->toMessage($response->fields);
-
-        } else { // !$whitelisted && isset($_POST['openid_cancel'])
-            $response =& $request->answer(false);
+        // Interprets the form results, and updates the user whitelist.
+        S::assert_xsrf_token();
+        $trusted = $server->UpdateEndpointTrust(
+            $user,
+            Post::b('trust_accept') && !Post::b('trust_cancel'),
+            Post::b('trust_always'));
+
+        // Finally answers the request.
+        if ($server->IsUserAuthorized($user) && $trusted) {
+            $server->AnswerRequest(
+                true, $user, Post::b('trust_sreg') ? $sreg_response : null);
+        } else {
+            $server->AnswerRequest(false);
         }
-
-        $webresponse =& $server->encodeResponse($response);
-        $this->render_openid_response($webresponse);
     }
 
     function handler_trusted(&$page, $action = 'list', $id = null)
@@ -224,91 +227,6 @@ class OpenidModule extends PLModule
         $page->assign('readonly', true);
         $table_editor->apply($page, $action, $id);
     }
-
-    function handler_idp_xrds(&$page)
-    {
-        $this->load('openid.inc.php');
-        header('Content-type: application/xrds+xml');
-        $page->changeTpl('openid/idp_xrds.tpl', NO_SKIN);
-        $page->assign('type2', Auth_OpenID_TYPE_2_0_IDP);
-        $page->assign('sreg', Auth_OpenID_SREG_URI);
-        $page->assign('provider', get_openid_url());
-    }
-
-    function handler_user_xrds(&$page, $x = null)
-    {
-        $this->load('openid.inc.php');
-
-        $user = get_user($x);
-        if (is_null($user)) {
-            return PL_NOT_FOUND;
-        }
-
-        header('Content-type: application/xrds+xml');
-        $page->changeTpl('openid/user_xrds.tpl', NO_SKIN);
-        $page->assign('type2', Auth_OpenID_TYPE_2_0);
-        $page->assign('type1', Auth_OpenID_TYPE_1_1);
-        $page->assign('sreg', Auth_OpenID_SREG_URI);
-        $page->assign('provider', get_openid_url());
-        $page->assign('local_id', $user->hruid);
-    }
-
-    function handler_melix(&$page, $x = null)
-    {
-        $this->load('openid.inc.php');
-        $user = get_user_by_alias($x);
-
-        // This will redirect to the canonic URL, which was not used
-        // if this hook was triggered
-        return $this->render_discovery_page(&$page, $user);
-    }
-
-    //--------------------------------------------------------------------//
-
-    function render_discovery_page(&$page, $user)
-    {
-
-        // Show the documentation if this is not the OpenId page of an user
-        if (is_null($user)) {
-            pl_redirect('Xorg/OpenId');
-        }
-
-        // Redirect to the canonic URL if we are using an alias
-        // There might be a risk of redirection loop here
-        // if $_SERVER was not exactly what we expect
-        $current_url = 'http' . (empty($_SERVER['HTTPS']) ? '' : 's') . '://'
-                       . $_SERVER['SERVER_NAME'] . $_SERVER['REQUEST_URI'];
-        $canonic_url = get_user_openid_url($user);
-        if ($current_url != $canonic_url) {
-            http_redirect($canonic_url);
-        }
-
-        // Include X-XRDS-Location response-header for Yadis discovery
-        header('X-XRDS-Location: ' . get_user_xrds_url($user));
-
-        $page->changeTpl('openid/openid.tpl');
-        $page->setTitle($user->fullName());
-        // Set the <link> tags for HTML-Based Discovery
-        $page->addLink('openid.server openid2.provider', get_openid_url());
-        $page->addLink('openid.delegate openid2.local_id', $user->hruid);
-        $page->assign_by_ref('user', $user);
-
-        return;
-    }
-
-    function render_openid_response($webresponse)
-    {
-        if ($webresponse->code != AUTH_OPENID_HTTP_OK) {
-            header(sprintf("HTTP/1.1 %d ", $webresponse->code),
-                   true, $webresponse->code);
-        }
-        foreach ($webresponse->headers as $k => $v) {
-            header("$k: $v");
-        }
-        header('Connection: close');
-        print $webresponse->body;
-        exit;
-    }
 }
 
 // vim:set et sw=4 sts=4 sws=4 foldmethod=marker enc=utf-8:
index 5c3cab0..e289339 100644 (file)
  *  59 Temple Place, Suite 330, Boston, MA  02111-1307  USA                *
  ***************************************************************************/
 
-require_once "Auth/OpenID/Discover.php";
+require_once 'Auth/OpenID/Discover.php';
 
-function init_openid_server()
+// An helper class for using plat/al as an OpenId Identity Provider.
+class OpenId
 {
-    // Initialize a filesystem-based store
-    $store_location = dirname(__FILE__) . '/../../spool/openid/store';
-    require_once "Auth/OpenID/FileStore.php";
-    $store = new Auth_OpenID_FileStore($store_location);
-
-    // Create an OpenId server
-    require_once 'Auth/OpenID/Server.php';
-    return new Auth_OpenID_Server($store, get_openid_url());
-}
+    private $base_url;        // Base url for all OpenId operations.
+    private $spool_store;     // Location of the spool storage for OpenID.
 
-function get_openid_url()
-{
-    global $globals;
-    return $globals->baseurl . '/openid';
-}
+    private $server = null;   // Auth::OpenId::Server object.
+    private $request = null;  // Request extracted by the Server object.
+
+    public function __construct()
+    {
+        global $globals;
 
-function get_user($x) {
-    if (is_null($x)) {
-        return null;
+        $this->base_url = $globals->baseurl . '/openid';
+        $this->spool_store = $globals->spoolroot . '/spool/openid/store';
     }
-    $user = User::getSilent($x);
-    return $user ? $user : null;
 
-}
+    // Initializes an OpenId Server object; it will use a defined spool-based
+    // directory to store OpenID secrets. Returns true on success.
+    public function Initialize()
+    {
+        require_once 'Auth/OpenID/FileStore.php';
+        require_once 'Auth/OpenID/Server.php';
 
-function get_user_by_alias($x) {
-    if (is_null($x)) {
-        return null;
-    }
-    // TODO such a function should probably be provided in the User class
-    // or at least not here
-    $res = XDB::query('SELECT  u.user_id
-                         FROM  auth_user_md5   AS u
-                   INNER JOIN  auth_user_quick AS q USING(user_id)
-                   INNER JOIN  aliases         AS a ON (a.id = u.user_id AND type != \'homonyme\')
-                        WHERE  u.perms IN(\'admin\', \'user\')
-                          AND  q.emails_alias_pub = \'public\'
-                          AND  a.alias = {?}',
-                               $x);
-    if (list($uid) = $res->fetchOneRow()) {
-        $user = User::getSilent($uid);
-    }
-    return $user ? $user : null;
+        $store = new Auth_OpenID_FileStore($this->spool_store);
+        $this->server = new Auth_OpenID_Server($store, $this->base_url);
+        $this->request = $this->server->decodeRequest();
 
-}
+        return !is_a($this->request, 'Auth_OpenID_ServerError');
+    }
 
-function get_user_openid_url($user)
-{
-    if (is_null($user)) {
-        return null;
+    // Authorization logic helpers ---------------------------------------------
+
+    // Returns true iff the current request is a valid openid request.
+    public function IsOpenIdRequest()
+    {
+        return Env::has('openid_mode');
     }
-    global $globals;
-    return $globals->baseurl . '/openid/' . $user->hruid;
-}
 
-function get_idp_xrds_url()
-{
-    global $globals;
-    return $globals->baseurl . '/openid/idp_xrds';
-}
+    // Returns true iff the request needs to be handled directly by the calling
+    // code (ie. the current user needs to be authorized).
+    public function IsAuthorizationRequest()
+    {
+        return $this->request->mode == 'checkid_immediate' ||
+               $this->request->mode == 'checkid_setup';
+    }
 
-function get_user_xrds_url($user)
-{
-    if (is_null($user)) {
-        return null;
+    // Returns true iff the request requires an immediate answer (no user
+    // interaction is allowed).
+    public function IsImmediateRequest()
+    {
+        return $this->request->mode == 'checkid_immediate';
     }
-    global $globals;
-    return $globals->baseurl . '/openid/user_xrds/' . $user->hruid;
-}
 
-function get_sreg_data($user)
-{
-    if (is_null($user)) {
-        return null;
-    }
-    return array('fullname' => $user->fullName(),
-                 'nickname' => $user->displayName(),
-                 'dob' => null,
-                 'email' => $user->bestEmail(),
-                 'gender' => $user->isFemale() ? 'F' : 'M',
-                 'postcode' => null,
-                 'country' => null,
-                 'language' => null,
-                 'timezone' => null);
-}
+    // Returns true iff the logged-in user is authorized for the current request.
+    // It checks that the user is logged in, and has the authorization to use
+    // that identity.
+    public function IsUserAuthorized(User $user)
+    {
+        return $user && ($user->login() == $this->request->identity ||
+            $this->request->idSelect());
+    }
 
-function is_trusted_site($user, $url)
-{
-    $res = XDB::query('SELECT  COUNT(*)
-                         FROM  openid_trusted
-                        WHERE  (user_id = {?} OR user_id IS NULL)
-                          AND  url = {?}',
-                               $user->id(), $url);
-    return $res->fetchOneCell() > 0;
-}
+    // SimpleRegistration helpers ----------------------------------------------
 
-function add_trusted_site($user, $url)
-{
-    XDB::execute("INSERT IGNORE INTO openid_trusted
-                      SET user_id={?}, url={?}",
-                  $user->id(), $url);
+    // Determines which SREG data are requested by the endpoint, and returns them.
+    public function GetSRegDataForRequest(User &$user)
+    {
+        require_once 'Auth/OpenID/SReg.php';
+
+        // Other common SReg fields we could fill are:
+        //   dob, country, language, timezone.
+        $sreg_request = Auth_OpenID_SRegRequest::fromOpenIDRequest($this->request);
+        return Auth_OpenID_SRegResponse::extractResponse($sreg_request, array(
+            'fullname' => $user->fullName(),
+            'nickname' => $user->displayName(),
+            'email'    => $user->bestEmail(),
+            'gender'   => $user->isFemale() ? 'F' : 'M',
+        ));
+    }
+
+    // Handling and answering helpers ------------------------------------------
+
+    // Answers the current request, and renders the response. Appends the |sreg|
+    // data when not null.
+    public function AnswerRequest($is_authorized, $user = null, $sreg_data = null)
+    {
+        // Creates the response.
+        if ($is_authorized && $this->request->idSelect() && $user) {
+            $response = $this->request->answer(
+                $is_authorized, null, $user->login(), $this->GetUserUrl($user));
+        } else {
+            $response = $this->request->answer($is_authorized);
+        }
+
+        // Clobbers response, and get it back to the Relaying Party.
+        if ($sreg_data) {
+            $sreg_data->toMessage($response->fields);
+        }
+        $this->RenderResponse($response);
+    }
+
+    // Automatically handles the request without any user interaction.
+    public function HandleRequest()
+    {
+        $response = $this->server->handleRequest($this->request);
+        $this->RenderResponse($response);
+    }
+
+    // Trust management helpers ------------------------------------------------
+
+    // Returns true iff the current endpoint is currently trusted by |user|.
+    public function IsEndpointTrusted(User $user)
+    {
+        $res = XDB::query(
+            "SELECT  COUNT(*)
+               FROM  openid_trusted
+              WHERE  (user_id = {?} OR user_id IS NULL) AND url = {?}",
+            $user->id(), $this->request->trust_root);
+        return ($res->fetchOneCell() > 0);
+    }
+
+    // Updates the trust level for the given endpoint, based on the value pf
+    // |trusted| and |permanent_trust| (the latter is ignored when the former
+    // value is false). Returns true iff the current endpoint is trusted.
+    public function UpdateEndpointTrust(User &$user, $trusted, $permanent_trust) {
+        $initial_trust = $this->IsEndpointTrusted($user);
+        if (!$initial_trust && $trusted && $permanent_trust) {
+            XDB::execute(
+                "INSERT IGNORE INTO  openid_trusted
+                                SET  user_id = {?}, url = {?}",
+                $user->id(), $this->request->trust_root);
+        }
+
+        return ($initial_trust || $trusted);
+    }
+
+    // Page renderers ----------------------------------------------------------
+
+    // Renders the OpenId discovery page for |user|.
+    public function RenderDiscoveryPage(&$page, User &$user)
+    {
+        $page->changeTpl('openid/openid.tpl');
+        $page->setTitle($user->fullName());
+        $page->addLink('openid.server openid2.provider', $this->base_url);
+        $page->addLink('openid.delegate openid2.local_id', $user->login());
+        $page->assign_by_ref('user', $user);
+
+        // Include the X-XRDS-Location header for Yadis discovery.
+        header('X-XRDS-Location: ' . $this->GetUserXrdsUrl($user));
+    }
+
+    // Renders the main XRDS page.
+    public function RenderMainXrdsPage(&$page)
+    {
+        header('Content-type: application/xrds+xml');
+        $page->changeTpl('openid/idp_xrds.tpl', NO_SKIN);
+        $page->assign('type2', Auth_OpenID_TYPE_2_0_IDP);
+        $page->assign('sreg', Auth_OpenID_SREG_URI);
+        $page->assign('provider', $this->base_url);
+    }
+
+    // Renders the XRDS page of |user|.
+    public function RenderUserXrdsPage(&$page, User &$user)
+    {
+        header('Content-type: application/xrds+xml');
+        $page->changeTpl('openid/user_xrds.tpl', NO_SKIN);
+        $page->assign('type2', Auth_OpenID_TYPE_2_0);
+        $page->assign('type1', Auth_OpenID_TYPE_1_1);
+        $page->assign('sreg', Auth_OpenID_SREG_URI);
+        $page->assign('provider', $this->base_url);
+        $page->assign('local_id', $user->login());
+    }
+
+    // Renders the OpenId response for the HTTP client.
+    public function RenderResponse($response)
+    {
+        if ($response) {
+            $web_response = $this->server->encodeResponse($response);
+            header(sprintf('HTTP/1.1 %d', $web_response->code), true, $web_response->code);
+
+            foreach ($web_response->headers as $key => $value) {
+                header(sprintf('%s: %s', $key, $value));
+            }
+
+            header('Connection: close');
+            print $web_response->body;
+        }
+        exit;
+    }
+
+    // URL providers -----------------------------------------------------------
+
+    // Returns the OpenId identity URL of the requested user.
+    private function GetUserUrl(User &$user)
+    {
+        return $this->base_url . '/' . $user->login();
+    }
+
+    // Returns the private XRDS page of a user.
+    private function GetUserXrdsUrl(User &$user)
+    {
+        return $this->base_url . '/xrds/' . $user->login();
+    }
+
+    // Returns the endpoint in the current request.
+    public function GetEndpoint()
+    {
+        return $this->request->trust_root;
+    }
+
+    // Extracts the OpenId arguments available in the current request, and
+    // builds a query string with them.
+    public function GetQueryStringForRequest()
+    {
+        foreach (Auth_OpenID::getQuery() as $key => $value) {
+            if (strpos($key, 'openid.') === 0) {
+                $args[$key] = $value;
+            }
+        }
+
+        return http_build_query($args);
+    }
 }
 
 // vim:set et sw=4 sts=4 sws=4 foldmethod=marker enc=utf-8:
-?>
\ No newline at end of file
+?>
index 17be5fe..af0bf35 100644 (file)
@@ -63,7 +63,7 @@ class PlatalModule extends PLModule
     {
         // Include X-XRDS-Location response-header for Yadis discovery
         global $globals;
-        header('X-XRDS-Location: ' . $globals->baseurl . '/openid/idp_xrds');
+        header('X-XRDS-Location: ' . $globals->baseurl . '/openid/xrds');
 
         // Redirect to the suitable page
         if (S::logged()) {
@@ -457,7 +457,7 @@ Adresse de secours : " . Post::v('email') : ""));
     {
         // Include X-XRDS-Location response-header for Yadis discovery
         global $globals;
-        header('X-XRDS-Location: ' . $globals->baseurl . '/openid/idp_xrds');
+        header('X-XRDS-Location: ' . $globals->baseurl . '/openid/xrds');
 
         $this->load('review.inc.php');
         $dom = 'Review';
index 6e273c5..600439e 100644 (file)
@@ -1,3 +1,25 @@
+{**************************************************************************}
+{*                                                                        *}
+{*  Copyright (C) 2003-2009 Polytechnique.org                             *}
+{*  http://opensource.polytechnique.org/                                  *}
+{*                                                                        *}
+{*  This program is free software; you can redistribute it and/or modify  *}
+{*  it under the terms of the GNU General Public License as published by  *}
+{*  the Free Software Foundation; either version 2 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 General Public License for more details.                          *}
+{*                                                                        *}
+{*  You should have received a copy of the GNU General Public License     *}
+{*  along with this program; if not, write to the Free Software           *}
+{*  Foundation, Inc.,                                                     *}
+{*  59 Temple Place, Suite 330, Boston, MA  02111-1307  USA               *}
+{*                                                                        *}
+{**************************************************************************}
+
 <?xml version="1.0" encoding="UTF-8"?>
 <xrds:XRDS
     xmlns:xrds="xri://$xrds"
@@ -11,3 +33,5 @@
     </Service>
   </XRD>
 </xrds:XRDS>
+
+{* vim:set et sw=2 sts=2 sws=2 enc=utf-8: *}
index d09c242..f47cce0 100644 (file)
 
 <h1>Page d'identité OpenId de {$user->fullName()}</h1>
 
-<p>OpenID est un système d'authentification décentralisé. Cette page permet 
-à des sites web tiers d'identifier {$user->displayName()}, grâce à son compte 
+<p>OpenID est un système d'authentification décentralisé. Cette page permet
+à des sites web tiers d'identifier {$user->displayName()}, grâce à son compte
 Polytechnique.org.<p>
 
-<p><a href="Xorg/OpenId">En savoir plus sur OpenId</a></p>
\ No newline at end of file
+<p><a href="Xorg/OpenId">En savoir plus sur OpenId</a></p>
+
+{* vim:set et sw=2 sts=2 sws=2 enc=utf-8: *}
index 5ba2ce8..438fa7b 100644 (file)
 
 <h1>Demande d'identification OpenId</h1>
 
-<p>Le site <strong>{$relying_party}</strong> demande à confirmer votre identité.</p>
+<p>Un site tiers demande à confirmer ton identité OpenId.
+  {if $sreg_data}
+    De plus, il a demandé à recevoir un certain nombre d'informations
+    te concernant.
+  {/if}
+  Merci de nous indiquer ton choix.
+</p><br />
 
-{if $sreg_data neq null}
-<p>Les informations suivantes lui seront transmises :</p>
-<ul>
-{foreach from=$sreg_data key=field item=value}
-<li><i>{$field}</i> : {$value}</li>
-{/foreach}
-</ul>
-{/if}
+<form method="POST" action="openid/trust?{$openid_query}">
+  {xsrf_token_field}
+  <table class="bicol">
+    <tr><th colspan="2">Souhaitez-vous confirmer votre identité ?</th></tr>
 
+    <tr class="impair">
+      <td>Adresse du site&nbsp;:</td>
+      <td><strong>{$relying_party}</strong></td>
+    </tr>
+    {if $sreg_data}
+    <tr class="impair">
+      <td>Informations demandées&nbsp;:</td>
+      <td><ul style="margin-top: 0">
+        {foreach from=$sreg_data key=field item=value}
+        <li><strong>{$field}</strong> ({$value})</li>
+        {/foreach}
+      </ul></td>
+    </tr>
+    {/if}
 
-<p><strong>Souhaitez-vous confirmer votre identité ?</strong></p>
+    <tr class="pair">
+      <td></td>
+      <td>
+        <label><input type="checkbox" name="trust_always" />
+          Toujours faire confiance à ce site.</label><br />
+        {if $sreg_data}
+        <label><input type="checkbox" checked="checked" name="trust_sreg" />
+          Envoyer les données ci-dessus au site.</label><br />
+        {/if}
+      </td>
+    </tr>
+    <tr class="impair center"><td colspan="2">
+      <input type="submit" name="trust_accept" value="Confirmer" />
+      <input type="submit" name="trust_cancel" value="Annuler" />
+    </td></tr>
+  </table>
+</form>
 
-<div class="form">
-  <form method="post" action="openid/trust?{$query}">
-    <input type="checkbox" name="openid_always" /> Toujours faire confiance à ce site<br />
-    <input type="submit" name="openid_trust" value="Confirmer" />
-    <input type="submit" name="openid_cancel" value="Annuler" />
-  </form>
-</div>
+{* vim:set et sw=2 sts=2 sws=2 enc=utf-8: *}
index 323f515..6b07054 100644 (file)
@@ -1,3 +1,25 @@
+{**************************************************************************}
+{*                                                                        *}
+{*  Copyright (C) 2003-2009 Polytechnique.org                             *}
+{*  http://opensource.polytechnique.org/                                  *}
+{*                                                                        *}
+{*  This program is free software; you can redistribute it and/or modify  *}
+{*  it under the terms of the GNU General Public License as published by  *}
+{*  the Free Software Foundation; either version 2 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 General Public License for more details.                          *}
+{*                                                                        *}
+{*  You should have received a copy of the GNU General Public License     *}
+{*  along with this program; if not, write to the Free Software           *}
+{*  Foundation, Inc.,                                                     *}
+{*  59 Temple Place, Suite 330, Boston, MA  02111-1307  USA               *}
+{*                                                                        *}
+{**************************************************************************}
+
 <?xml version="1.0" encoding="UTF-8"?>
 <xrds:XRDS
     xmlns:xrds="xri://$xrds"
@@ -18,3 +40,5 @@
     </Service>
   </XRD>
 </xrds:XRDS>
+
+{* vim:set et sw=2 sts=2 sws=2 enc=utf-8: *}