summaryrefslogtreecommitdiffstats
path: root/examples/server/lib
diff options
context:
space:
mode:
Diffstat (limited to 'examples/server/lib')
-rw-r--r--examples/server/lib/actions.php122
-rw-r--r--examples/server/lib/common.php80
-rw-r--r--examples/server/lib/render.php122
-rw-r--r--examples/server/lib/render/about.php58
-rw-r--r--examples/server/lib/render/login.php65
-rw-r--r--examples/server/lib/render/sites.php69
-rw-r--r--examples/server/lib/render/trust.php29
-rw-r--r--examples/server/lib/session.php170
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 .= ' &mdash; ' . $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>&lt;head&gt;</code> of the HTML
+ document at that URL:
+</p>
+<pre>&lt;link rel="openid.server" href="%s" /&gt;</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