diff options
Diffstat (limited to 'examples/server/lib')
-rw-r--r-- | examples/server/lib/actions.php | 122 | ||||
-rw-r--r-- | examples/server/lib/common.php | 80 | ||||
-rw-r--r-- | examples/server/lib/render.php | 122 | ||||
-rw-r--r-- | examples/server/lib/render/about.php | 58 | ||||
-rw-r--r-- | examples/server/lib/render/login.php | 65 | ||||
-rw-r--r-- | examples/server/lib/render/sites.php | 69 | ||||
-rw-r--r-- | examples/server/lib/render/trust.php | 29 | ||||
-rw-r--r-- | examples/server/lib/session.php | 170 |
8 files changed, 715 insertions, 0 deletions
diff --git a/examples/server/lib/actions.php b/examples/server/lib/actions.php new file mode 100644 index 0000000..0f73b8b --- /dev/null +++ b/examples/server/lib/actions.php @@ -0,0 +1,122 @@ +<?php + +require_once "lib/common.php"; +require_once "lib/session.php"; +require_once "lib/render.php"; + +require_once "lib/render/login.php"; +require_once "lib/render/sites.php"; + +/** + * Handle a standard OpenID server request + */ +function action_default() +{ + $server = getServer(); + return handleResponse($server->getOpenIDResponse()); +} + +/** + * Log out the currently logged in user + */ +function action_logout() +{ + setLoggedInUser(null); + setRequestInfo(null); + return authCancel(null); +} + +/** + * Check the input values for a login request + */ +function login_checkInput($input) +{ + $openid_url = false; + $errors = array(); + + if (!isset($input['openid_url'])) { + $errors[] = 'Enter an OpenID URL to continue'; + } + if (!isset($input['password'])) { + $errors[] = 'Enter a password to continue'; + } + if (count($errors) == 0) { + $openid_url = $input['openid_url']; + $openid_url = Auth_OpenID_normalizeUrl($openid_url); + $password = $input['password']; + if (!checkLogin($openid_url, $password)) { + $errors[] = 'The entered password does not match the ' . + 'entered identity URL.'; + } + } + return array($errors, $openid_url); +} + +/** + * Log in a user and potentially continue the requested identity approval + */ +function action_login() +{ + $method = $_SERVER['REQUEST_METHOD']; + switch ($method) { + case 'GET': + return login_render(); + case 'POST': + $info = getRequestInfo(); + $fields = $_POST; + if (isset($fields['cancel'])) { + return authCancel($info); + } + + list ($errors, $openid_url) = login_checkInput($fields); + if (count($errors) || !$openid_url) { + $needed = $info ? $info->getIdentityURL() : false; + return login_render($errors, @$fields['openid_url'], $needed); + } else { + setLoggedInUser($openid_url); + return doAuth($info); + } + default: + return login_render(array('Unsupported HTTP method: $method')); + } +} + +/** + * Ask the user whether he wants to trust this site + */ +function action_trust() +{ + $info = getRequestInfo(); + $trusted = isset($_POST['trust']); + if ($info && isset($_POST['remember'])) { + $sites = getSessionSites(); + $sites[$info->getTrustRoot()] = $trusted; + setSessionSites($sites); + } + return doAuth($info, $trusted, true); +} + +function htmlRepr(&$x) +{ + return '<pre>' . htmlspecialchars(var_export($_POST, true)) . '</pre>'; +} + +function action_sites() +{ + $sites = getSessionSites(); + if ($_SERVER['REQUEST_METHOD'] == 'POST') { + if (isset($_POST['clear'])) { + $sites = null; + } else { + foreach ($_POST as $k => $v) { + if (preg_match('/^site[0-9]+$/', $k) && isset($sites[$v])) { + unset($sites[$v]); + } + } + } + setSessionSites($sites); + } + return sites_render($sites); +} + +?>
\ No newline at end of file diff --git a/examples/server/lib/common.php b/examples/server/lib/common.php new file mode 100644 index 0000000..74e16ab --- /dev/null +++ b/examples/server/lib/common.php @@ -0,0 +1,80 @@ +<?php + +require_once "lib/render.php"; +require_once "lib/session.php"; + +require_once "lib/render/login.php"; +require_once "lib/render/about.php"; +require_once "lib/render/trust.php"; + +require_once "Auth/OpenID/Server.php"; +require_once "Auth/OpenID/HMACSHA1.php"; + +function authCancel($info) +{ + if ($info) { + setRequestInfo(); + $url = $info->getCancelURL(); + } else { + $server = getServer(); + $url = $server->server_url; + } + return redirect_render($url); +} + +function handleResponse($response, $do_auth=true) +{ + list ($status, $info) = $response; + switch($status) { + case Auth_OpenID_REMOTE_ERROR: + return kv_render($info, false); + case Auth_OpenID_REMOTE_OK: + return kv_render($info); + case Auth_OpenID_REDIRECT: + return redirect_render($info); + case Auth_OpenID_DO_AUTH: + if ($do_auth) { + return doAuth($info); + } else { + return about_render('Got unexpected DO_AUTH'); + } + case Auth_OpenID_DO_ABOUT: + return about_render(); + case Auth_OpenID_LOCAL_ERROR: + return about_render($info, false); + default: + $repr = var_export($status, true); + return about_render("Internal error: unknown status $repr"); + } +} + +function doAuth($info, $trusted=null, $fail_cancels=false) +{ + if (!$info) { + // There is no authentication information, so bail + return authCancel(null); + } + + $req_url = $info->getIdentityURL(); + $user = getLoggedInUser(); + setRequestInfo($info); + + if ($req_url != $user) { + return login_render(array(), $req_url, $req_url); + } + + $trust_root = $info->getTrustRoot(); + $trusted = isset($trusted) ? $trusted : isTrusted($trust_root); + if ($trusted) { + setRequestInfo(); + $server = getServer(); + $response = $server->getAuthResponse(&$info, true); + return handleResponse($response, false); + } elseif ($fail_cancels) { + return authCancel($info); + } else { + return trust_render($info); + } +} + +?>
\ No newline at end of file diff --git a/examples/server/lib/render.php b/examples/server/lib/render.php new file mode 100644 index 0000000..ff1ca20 --- /dev/null +++ b/examples/server/lib/render.php @@ -0,0 +1,122 @@ +<?php + +define('page_template', +'<html> + <head> + <title>%s</title> +%s + </head> + <body> + %s +<div id="content"> + <h1>%s</h1> + %s +</div> + </body> +</html>'); + +define('logged_in_pat', 'You are logged in as %s.'); + +/** + * HTTP response line contstants + */ +define('http_bad_request', 'HTTP/1.1 400 Bad Request'); +define('http_found', 'HTTP/1.1 302 Found'); +define('http_ok', 'HTTP/1.1 200 OK'); +define('http_internal_error', 'HTTP/1.1 500 Internal Error'); + +/** + * HTTP header constants + */ +define('header_connection_close', 'Connection: close'); +define('header_content_text', 'Content-Type: text/plain; charset=us-ascii'); + +define('redirect_message', + 'Please wait; you are being redirected to <%s>'); + + +/** + * Return a string containing an anchor tag containing the given URL + * + * The URL does not need to be quoted, but if text is passed in, then + * it does. + */ +function link_render($url, $text=null) { + $esc_url = htmlspecialchars($url, ENT_QUOTES); + $text = ($text === null) ? $esc_url : $text; + return sprintf('<a href="%s">%s</a>', $esc_url, $text); +} + +/** + * Return a response to an OpenID consumer's POST + */ +function kv_render($kv, $success=true) +{ + $headers = array(($success ? http_ok : http_bad_request), + header_content_text, + header_connection_close); + return array($headers, $kv); +} + +/** + * Return an HTTP redirect response + */ +function redirect_render($redir_url) +{ + $headers = array(http_found, + header_content_text, + 'Location: ' . $redir_url, + ); + $body = sprintf(redirect_message, $redir_url); + return array($headers, $body); +} + +function navigation_render($msg, $items) +{ + $what = link_render(buildURL(), 'PHP OpenID Server'); + if ($msg) { + $what .= ' — ' . $msg; + } + if ($items) { + $s = '<p>' . $what . '</p><ul class="bottom">'; + foreach ($items as $action => $text) { + $url = buildURL($action); + $s .= sprintf('<li>%s</li>', link_render($url, $text)); + } + $s .= '</ul>'; + } else { + $s = '<p class="bottom">' . $what . '</p>'; + } + return sprintf('<div class="navigation">%s</div>', $s); +} + +/** + * Render an HTML page + */ +function page_render($body, $user, $title, $h1=null, $login=false) +{ + $h1 = $h1 ? $h1 : $title; + + if ($user) { + $msg = sprintf(logged_in_pat, link_render($user)); + $nav = array('logout' => 'Log Out', + 'sites' => 'Remembered Sites', + ); + $navigation = navigation_render($msg, $nav); + } else { + if (!$login) { + $msg = link_render(buildURL('login'), 'Log In'); + $navigation = navigation_render($msg, array()); + } else { + $navigation = ''; + } + } + + $style = getStyle(); + $text = sprintf(page_template, $title, $style, $navigation, $h1, $body); + // No special headers here + $headers = array(); + return array($headers, $text); +} + +?>
\ No newline at end of file diff --git a/examples/server/lib/render/about.php b/examples/server/lib/render/about.php new file mode 100644 index 0000000..503043b --- /dev/null +++ b/examples/server/lib/render/about.php @@ -0,0 +1,58 @@ +<?php + +require_once "lib/session.php"; +require_once "lib/render.php"; + +define('about_error_template', + '<div class="error"> +An error occurred when processing your request: +<br /> +%s +</div>'); + +define('about_body', + '<p> + This is an <a href="http://www.openid.net/">OpenID</a> server + endpoint. This server is built on the <a + href="http://www.openidenabled.com/libraries/php">JanRain PHP OpenID + library</a>. Since OpenID consumer sites will need to directly contact this + server, it must be accessible over the Internet (not behind a firewall). +</p> +<p> + To use this server, you will have to set up a URL to use as an identifier. + Insert the following markup into the <code><head></code> of the HTML + document at that URL: +</p> +<pre><link rel="openid.server" href="%s" /></pre> +<p> + Then configure this server so that you can log in with that URL. Once you + have configured the server, and marked up your identity URL, you can verify + that it is working by using the <a href="http://www.openidenabled.com/" + >openidenabled.com</a> + <a href="http://www.openidenabled.com/resources/openid-test/checkup">OpenID + Checkup tool</a>: + <form method="post" + action="http://www.openidenabled.com/resources/openid-test/checkup/start"> + <label for="checkup">OpenID URL: + </label><input id="checkup" type="text" name="openid_url" /> + <input type="submit" value="Check" /> + </form> +</p> +'); + +/** + * Render the about page, potentially with an error message + */ +function about_render($error=false, $internal=true) +{ + $headers = array(); + $body = sprintf(about_body, buildURL()); + if ($error) { + $headers[] = $internal ? http_internal_error : http_bad_request; + $body .= sprintf(about_error_template, htmlspecialchars($error)); + } + $current_user = getLoggedInUser(); + return page_render($body, $current_user, 'OpenID Server Endpoint'); +} + +?>
\ No newline at end of file diff --git a/examples/server/lib/render/login.php b/examples/server/lib/render/login.php new file mode 100644 index 0000000..9e8f370 --- /dev/null +++ b/examples/server/lib/render/login.php @@ -0,0 +1,65 @@ +<?php + +require_once "lib/session.php"; +require_once "lib/render.php"; + +define('login_form_pat', + '<div class="form"> + <p> + Enter your identity URL and password into this form to log in to + this server. This server must be configured to accept your identity URL. + </p> + + <form method="post" action="%s"> + <table> + <tr> + <th><label for="openid_url">OpenID URL:</label></th> + <td><input type="text" name="openid_url" + value="%s" id="openid_url" /></td> + </tr> + <tr> + <th><label for="password">Password:</label></th> + <td><input type="password" name="password" id="password" /></td> + </tr> + <tr> + <td colspan="2"> + <input type="submit" value="Log in" /> + <input type="submit" name="cancel" value="Cancel" /> + </td> + </tr> + </table> + </form> +</div> +'); + +define('login_needed_pat', + 'You must be logged in as %s to approve this request.'); + +function login_render($errors=null, $input=null, $needed=null) +{ + $current_user = getLoggedInUser(); + if ($input === null) { + $input = $current_user; + } + if ($needed) { + $errors[] = sprintf(login_needed_pat, link_render($needed)); + } + + $esc_input = htmlspecialchars($input, ENT_QUOTES); + $login_url = buildURL('login', true); + $body = sprintf(login_form_pat, $login_url, $esc_input); + if ($errors) { + $body = loginError_render($errors) . $body; + } + return page_render($body, $current_user, 'Log In', null, true); +} + +function loginError_render($errors) +{ + $text = ''; + foreach ($errors as $error) { + $text .= sprintf("<li>%s</li>\n", $error); + } + return sprintf("<ul class=\"error\">\n%s</ul>\n", $text); +} +?>
\ No newline at end of file diff --git a/examples/server/lib/render/sites.php b/examples/server/lib/render/sites.php new file mode 100644 index 0000000..63d1245 --- /dev/null +++ b/examples/server/lib/render/sites.php @@ -0,0 +1,69 @@ +<?php + +require_once "lib/session.php"; + +define('sites_form', + '<div class="form"> +<p>These sites have been approved for this session:</p> +<form method="post" action="%s"> +<table> +<tbody> +%s +</tbody> +</table> +<input type="submit" value="Remove selected" /> +</form> +</div> +'); + +define('sites_empty_message', + '<p> + No sites are remembered for this session. When you authenticate with a site, + you can choose to add it to this list by choosing <q>Remember this + decision</q>. +</p> +<p>%s</p> +'); + +define('sites_row', + '<tr> +<td><input type="checkbox" name=%s value="%s" id=%s /></td> +<td><label for=%s>%s %s</label></td> +</tr>'); + +function siteListRow_render($i, $site) +{ + $esc_site = htmlspecialchars($site, ENT_QUOTES); + if ($trusted) { + $trust = 'Trust'; + } else { + $trust = 'Do not trust'; + } + $id = sprintf('"site%s"', $i); + return sprintf(sites_row, $id, $esc_site, $id, $id, $trust, $esc_site); +} + +function siteList_render($sites) +{ + $rows = ''; + $i = 0; + foreach ($sites as $site => $trusted) { + $rows .= siteListRow_render($i, $site); + $i += 1; + } + return $rows; +} + +function sites_render($sites) +{ + if ($sites) { + $rows = siteList_render($sites); + $form = sprintf(sites_form, buildURL('sites'), $rows); + $body = $pre . $form; + } else { + $body = sprintf(sites_empty_message, link_render(buildURL(''), 'Return home')); + } + return page_render($body, getLoggedInUser(), 'Remembered Sites'); +} + +?>
\ No newline at end of file diff --git a/examples/server/lib/render/trust.php b/examples/server/lib/render/trust.php new file mode 100644 index 0000000..c00803c --- /dev/null +++ b/examples/server/lib/render/trust.php @@ -0,0 +1,29 @@ +<?php + +require_once "lib/session.php"; +require_once "lib/render.php"; + +define('trust_form_pat', + '<div class="form"> + <p>Do you wish to confirm your identity URL (<code>%s</code>) with <code>%s</code>?</p> + <form method="post" action="%s"> + <input type="checkbox" name="remember" value="on" id="remember"><label + for="remember">Remember this decision</label> + <br /> + <input type="submit" name="trust" value="Confirm" /> + <input type="submit" value="Do not confirm" /> + </form> +</div> +'); + +function trust_render($info) +{ + $current_user = getLoggedInUser(); + $lnk = link_render($current_user); + $trust_root = htmlspecialchars($info->getTrustRoot()); + $trust_url = buildURL('trust', true); + $form = sprintf(trust_form_pat, $lnk, $trust_root, $trust_url); + return page_render($form, $current_user, 'Trust This Site'); +} + +?>
\ No newline at end of file diff --git a/examples/server/lib/session.php b/examples/server/lib/session.php new file mode 100644 index 0000000..fceb8de --- /dev/null +++ b/examples/server/lib/session.php @@ -0,0 +1,170 @@ +<?php + +require_once "config.php"; +require_once "Auth/OpenID/Server.php"; + +/** + * Set up the session + */ +function init() +{ + session_name('openid_server'); + session_start(); +} + +/** + * Get the style markup + */ +function getStyle() +{ + global $style; + return $style; +} + +/** + * Build a URL to a server action + */ +function buildURL($action=null, $escaped=true) +{ + // from config.php + global $server_url; + + $url = $server_url; + if ($action) { + $url .= '/' . $action; + } + return $escaped ? htmlspecialchars($url, ENT_QUOTES) : $url; +} + +/** + * Extract the current action from the request + */ +function getAction() +{ + $path_info = @$_SERVER['PATH_INFO']; + $action = ($path_info) ? substr($path_info, 1) : ''; + $function_name = 'action_' . $action; + return $function_name; +} + +/** + * Write the response to the request + */ +function writeResponse($resp) +{ + list ($headers, $body) = $resp; + array_walk($headers, 'header'); + print $body; +} + +/** + * Instantiate a new OpenID server object + */ +function getServer() +{ + // from config.php + global $server_url; + + static $server = null; + if (!isset($server)) { + $server = new Auth_OpenID_Server($server_url, getOpenIDStore()); + } + return $server; +} + +/** + * Return whether the trust root is currently trusted + */ +function isTrusted($trust_root) +{ + // from config.php + global $trusted_sites; + if (in_array($trust_root, $trusted_sites)) { + return true; + } + $sites = getSessionSites(); + return isset($sites[$trust_root]) && $sites[$trust_root]; +} + +/** + * Return a hashed form of the user's password + */ +function hashPassword($password) +{ + return bin2hex(Auth_OpenID_SHA1($password)); +} + +/** + * Check the user's login information + */ +function checkLogin($openid_url, $password) +{ + // from config.php + global $openid_users; + $hash = hashPassword($password); + + return isset($openid_users[$openid_url]) + && $hash == $openid_users[$openid_url]; +} + +/** + * Get the openid_url out of the cookie + * + * @return mixed $openid_url The URL that was stored in the cookie or + * false if there is none present or if the cookie is bad. + */ +function getLoggedInUser() +{ + return isset($_SESSION['openid_url']) + ? $_SESSION['openid_url'] + : false; +} + +/** + * Set the openid_url in the cookie + * + * @param mixed $identity_url The URL to set. If set to null, the + * value will be unset. + */ +function setLoggedInUser($identity_url=null) +{ + if (!isset($identity_url)) { + unset($_SESSION['openid_url']); + } else { + $_SESSION['openid_url'] = $identity_url; + } +} + +function setSessionSites($sites=null) +{ + if (!isset($sites)) { + unset($_SESSION['session_sites']); + } else { + $_SESSION['session_sites'] = serialize($sites); + } +} + +function getSessionSites() +{ + return isset($_SESSION['session_sites']) + ? unserialize($_SESSION['session_sites']) + : false; +} + +function getRequestInfo() +{ + return isset($_SESSION['request']) + ? unserialize($_SESSION['request']) + : false; +} + +function setRequestInfo($info=null) +{ + if (!isset($info)) { + unset($_SESSION['request']); + } else { + $_SESSION['request'] = serialize($info); + } +} + +?>
\ No newline at end of file |