X-Git-Url: http://git.polytechnique.org/?a=blobdiff_plain;f=modules%2Fopenid.php;h=619e0c1e56d0532886c0eb3b8074a42c2aae8610;hb=e5ef86153a88317faaa15441b6aabde24b35a78b;hp=fc935b50e50780f195c2f18096a08c070e8d4f4c;hpb=087f7ecd118dc03c6ca291410963288c838cc01f;p=platal.git diff --git a/modules/openid.php b/modules/openid.php index fc935b5..619e0c1 100644 --- a/modules/openid.php +++ b/modules/openid.php @@ -1,6 +1,6 @@ $this->make_hook('openid', AUTH_PUBLIC), - 'openid/trust' => $this->make_hook('trust', AUTH_COOKIE), - 'openid/idp_xrds' => $this->make_hook('idp_xrds', AUTH_PUBLIC), - 'openid/user_xrds' => $this->make_hook('user_xrds', 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'); - $user = get_user($x); - - // Spec §4.1.2: if "openid.mode" is absent, whe SHOULD assume that - // the request is not an OpenId message - // Thus, we try to render the discovery page - if (!array_key_exists('openid_mode', $_REQUEST)) { - return $this->render_discovery_page($page, $user); - } - - // Create a server and decode the request - $server = init_openid_server(); - $request = $server->decodeRequest(); - - // This request requires user interaction - if (in_array($request->mode, - array('checkid_immediate', 'checkid_setup'))) { - - // Each user has only one identity to choose from - // So we can make automatically the identity selection - if ($request->idSelect()) { - $request->identity = get_user_openid_url($user); - } - - // If we still don't have an identifier (used or desired), give up - if (!$request->identity) { - $this->render_no_identifier_page($page, $request); + $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 (!$server->IsOpenIdRequest()) { + if ($requested_user) { + $server->RenderDiscoveryPage($page, $requested_user); return; + } else { + pl_redirect('Xorg/OpenId'); } + exit; + } - // We always require confirmation before sending information - // to third-party websites - if ($request->immediate) { - $response =& $request->answer(false); + // 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 { - // Save request in session and jump to confirmation page - S::set('openid_request', serialize($request)); - pl_redirect('openid/trust'); - return; + // 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 (Post::has('openid_mode')) { + pl_redirect('openid', $openid_args); + } else { + return PL_DO_AUTH; + } } - - // Other requests can be automatically handled by the server } else { - $response =& $server->handleRequest($request); + $server->HandleRequest(); } - // Render response - $webresponse =& $server->encodeResponse($response); - $this->render_openid_response($webresponse); + // All requests should have been answered at this point. The best here + // is to get the user back to a safe page. + pl_redirect(''); } - function handler_trust(&$page, $x = null) + function handler_melix(&$page, $login = null) { $this->load('openid.inc.php'); - // Recover request in session - $request = S::v('openid_request'); - if (is_null($request)) { - // There is no authentication information, something went wrong - pl_redirect('/'); - return; - } else { - // Unserialize the request - require_once 'Auth/OpenID/Server.php'; - $request = unserialize($request); - } - - $server = init_openid_server(); - $user = S::user(); - - // Check that the identity matches the user currently logged in - if ($request->identity != get_user_openid_url($user)) { - $response =& $request->answer(false); - $webresponse =& $server->encodeResponse($response); - $this->render_openid_response($webresponse); - return; - } - - // 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)); - - - // Ask the user for confirmation - if ($_SERVER['REQUEST_METHOD'] != 'POST') { - $page->changeTpl('openid/trust.tpl'); - $page->assign('relying_party', $request->trust_root); - $page->assign_by_ref('sreg_data', $sreg_response->data); - return; - } - - // At this point $_SERVER['REQUEST_METHOD'] == 'POST' - // Answer to the Relying Party based on the user's choice - if (isset($_POST['trust'])) { - S::kill('openid_request'); - $response =& $request->answer(true, null, $request->identity); + global $globals; + $melix = ($login ? $login . '@' . $globals->mail->alias_dom : null); - // Add the simple registration response values to the OpenID - // response message. - $sreg_response->toMessage($response->fields); - - } else { // !isset($_POST['trust']) - S::kill('openid_request'); - $response =& $request->answer(false); + if ($melix && ($requested_user = User::getSilent($melix))) { + $server = new OpenId(); + $server->RenderDiscoveryPage($page, $requested_user); + } else { + pl_redirect('Xorg/OpenId'); } - - // Generate a response to send to the user agent. - $webresponse =& $server->encodeResponse($response); - $this->render_openid_response($webresponse); } - function handler_idp_xrds(&$page) + function handler_xrds(&$page, $login = null) { - // Load constants $this->load('openid.inc.php'); + $requested_user = User::getSilent($login); + $server = new OpenId(); - // Set XRDS content-type and template - header('Content-type: application/xrds+xml'); - $page->changeTpl('openid/idp_xrds.tpl', NO_SKIN); - - // Set variables - $page->changeTpl('openid/idp_xrds.tpl', NO_SKIN); - $page->assign('type', Auth_OpenID_TYPE_2_0_IDP); - $page->assign('uri', get_openid_url()); + if (!$login) { + $server->RenderMainXrdsPage($page); + } else if ($requested_user) { + $server->RenderUserXrdsPage($page, $requested_user); + } else { + return PL_NOT_FOUND; + } } - function handler_user_xrds(&$page, $x = null) + function handler_trust(&$page) { - // Load constants $this->load('openid.inc.php'); + $server = new OpenId(); + $user = S::user(); - // Set XRDS content-type and template - header('Content-type: application/xrds+xml'); - $page->changeTpl('openid/user_xrds.tpl', NO_SKIN); - - // Set variables - $page->assign('type1', Auth_OpenID_TYPE_2_0); - $page->assign('type2', Auth_OpenID_TYPE_1_1); - $page->assign('uri', get_openid_url()); - } - - //--------------------------------------------------------------------// - - 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'); + // Initializes the OpenId environment from the request. + if (!$server->Initialize() || !$server->IsAuthorizationRequest()) { + $page->kill("Ta requête OpenID a échoué, merci de réessayer."); } - // Include X-XRDS-Location response-header for Yadis discovery - header('X-XRDS-Location: ' . get_user_xrds_url($user)); - - // Select template - $page->changeTpl('openid/openid.tpl'); + // Prepares the SREG data, if any is required. + $sreg_response = $server->GetSRegDataForRequest($user); - // Sets the title of the html page. - $page->setTitle($user->fullName()); + // 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('openid_query', $server->GetQueryStringForRequest()); + $page->assign('relying_party', $server->GetEndpoint()); + $page->assign('sreg_data', $sreg_response->contents()); - // Sets the tags for HTML-Based Discovery - $page->addLink('openid.server openid2.provider', get_openid_url()); - $page->addLink('openid.delegate openid2.local_id', $user->hruid); + return; + } - // Adds the global user property array to the display. - $page->assign_by_ref('user', $user); + // 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')); - return; + // Finally answers the request. + if ($server->IsUserAuthorized($user) && $trusted) { + $server->AnswerRequest(true, Post::b('trust_sreg') ? $sreg_response : null); + } else { + $server->AnswerRequest(false); + } } - function render_no_identifier_page($page, $request) + function handler_trusted(&$page, $action = 'list', $id = null) { - // Select template - $page->changeTpl('openid/no_identifier.tpl'); + $page->setTitle('Sites tiers de confiance'); + $page->assign('title', 'Mes sites tiers de confiance pour OpenId'); + $table_editor = new PLTableEditor('openid/trusted', 'account_auth_openid', 'id'); + $table_editor->set_where_clause(XDB::format('uid = {?}', S::user()->id())); + $table_editor->vars['uid']['display'] = false; + $table_editor->describe('url', 'site tiers', true); + $page->assign('deleteonly', true); + $table_editor->apply($page, $action, $id); } - function render_openid_response($webresponse) + function handler_admin_trusted(&$page, $action = 'list', $id = null) { - // Send HTTP response code - if ($webresponse->code != AUTH_OPENID_HTTP_OK) { - header(sprintf("HTTP/1.1 %d ", $webresponse->code), - true, $webresponse->code); - } - - // Send headers - foreach ($webresponse->headers as $k => $v) { - header("$k: $v"); - } - header('Connection: close'); - - // Send body - print $webresponse->body; - exit; + $page->setTitle('Sites tiers de confiance'); + $page->assign('title', 'Sites tiers de confiance globaux pour OpenId'); + $table_editor = new PLTableEditor('admin/openid/trusted', 'account_auth_openid', 'id'); + $table_editor->set_where_clause('uid IS NULL'); + $table_editor->vars['uid']['display'] = false; + $table_editor->describe('url', 'site tiers', true); + $page->assign('readonly', true); + $table_editor->apply($page, $action, $id); } }