* OP-Local Identifier: {$hruid}
*/
+/* Testing suite is here:
+ * http://openidenabled.com/resources/openid-test/
+ */
+
+/* **checkid_immediate is not supported (yet)**, which means that we will
+ * always ask for confirmation before redirecting to a third-party.
+ * A sensible way to implement it would be to add a "Always trust this site"
+ * checkbox to the form, and to store trusted websites per user. This still
+ * raises the question of removing websites from that list.
+ * Another possibility is to maintain a global whitelist.
+ */
+
class OpenidModule extends PLModule
{
function handlers()
return array(
'openid' => $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/melix' => $this->make_hook('melix', AUTH_PUBLIC),
);
}
$this->load('openid.inc.php');
$user = get_user($x);
- // Display the discovery page
- if ($_SERVER['REQUEST_METHOD'] != 'POST' && !array_key_exists('openid_mode', $_GET)) {
+ // 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);
}
$server = init_openid_server();
$request = $server->decodeRequest();
+ // This request requires user interaction
if (in_array($request->mode,
array('checkid_immediate', 'checkid_setup'))) {
// We always require confirmation before sending information
// to third-party websites
if ($request->immediate) {
- $response =& $request->answer(false, get_openid_url());
+ $response =& $request->answer(false);
} else {
// Save request in session and jump to confirmation page
- S::set('request', serialize($request));
+ S::set('openid_request', serialize($request));
pl_redirect('openid/trust');
return;
}
- } else { // Other $request->mode
+ // Other requests can be automatically handled by the server
+ } else {
$response =& $server->handleRequest($request);
}
// Render response
$webresponse =& $server->encodeResponse($response);
- $this->render_openid_response($webresponse, true);
+ $this->render_openid_response($webresponse);
}
function handler_trust(&$page, $x = null)
$this->load('openid.inc.php');
// Recover request in session
- $request = S::v('request');
+ $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";
+ require_once 'Auth/OpenID/Server.php';
$request = unserialize($request);
}
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;
}
- if (isset($_POST['trust'])) { // $_SERVER['REQUEST_METHOD'] == 'POST'
- unset($_SESSION['request']);
+ // 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);
- // Answer with some sample Simple Registration data.
- // TODO USE REAL USER DATA
- // $user = S::user();
- $sreg_data = array(
- 'fullname' => 'Example User',
- 'nickname' => 'example',
- 'dob' => '1970-01-01',
- 'email' => 'invalid@example.com',
- 'gender' => 'F',
- 'postcode' => '12345',
- 'country' => 'ES',
- 'language' => 'eu',
- 'timezone' => 'America/New_York');
-
// Add the simple registration response values to the OpenID
// response message.
- require_once 'Auth/OpenID/SReg.php';
- $sreg_request = Auth_OpenID_SRegRequest::fromOpenIDRequest($request);
- $sreg_response = Auth_OpenID_SRegResponse::extractResponse($sreg_request, $sreg_data);
$sreg_response->toMessage($response->fields);
- // Generate a response to send to the user agent.
- $webresponse =& $server->encodeResponse($response);
- $this->render_openid_response($webresponse);
- } else {
- pl_redirect('');
- return;
+ } else { // !isset($_POST['trust'])
+ S::kill('openid_request');
+ $response =& $request->answer(false);
}
- }
- function handler_idp_xrds(&$page)
- {
- // Load constants
- $this->load('openid.inc.php');
-
- // 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());
+ // Generate a response to send to the user agent.
+ $webresponse =& $server->encodeResponse($response);
+ $this->render_openid_response($webresponse);
}
function handler_user_xrds(&$page, $x = null)
$page->assign('uri', get_openid_url());
}
+ 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)) {
- return PL_NOT_FOUND;
+ 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
function render_no_identifier_page($page, $request)
{
+ // Select template
$page->changeTpl('openid/no_identifier.tpl');
}
- // TODO determine when to close the connection or not
- // TODO i don't why it was done that way in the example
- function render_openid_response($webresponse, $close = false)
+ function render_openid_response($webresponse)
{
+ // 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');
- if ($close) {
- header('Connection: close');
- }
+ // Send body
print $webresponse->body;
exit;
}
}
// vim:set et sw=4 sts=4 sws=4 foldmethod=marker enc=utf-8:
-?>
+?>
\ No newline at end of file