PHP Classes

File: AuthenticatorDemo.php

Recommend this page to a friend!
  Classes of Claudius Tiberiu Iacob   Authenticator_ciacob   AuthenticatorDemo.php   Download  
File: AuthenticatorDemo.php
Role: Example script
Content type: text/plain
Description: See "HoToInstall.txt" for info
Class: Authenticator_ciacob
Register and authenticate users
Author: By
Last change: Changed listing priority.
Date: 14 years ago
Size: 16,645 bytes
 

Contents

Class file image Download
<?php require_once ('domit/xml_domit_include.php'); require_once ('ParamsProxy.php'); require_once ('UTF8.php'); require_once ('DbProxy.php'); require_once ('Authenticator.php'); /** * Showcases the functionality of the Authenticator class. * The Authenticator class is an users registrar kernel. It provides low-level API for user * registration, login and credentials management. * * @author Claudius Tiberiu Iacob <claudius.iacob@gmail.com>. * @license Creative Commons Attribution Share Alike - Claudius Tiberiu Iacob 2009 */ class AuthenticatorDemo { /** * Logs in an user. For simple, open registration (which is our case), this is done as: * * Authenticator::getInstance()->authenticate (<password>, <username>); */ private function loginUser () { $userPass = trim ($_POST['pass']); $userName = trim ($_POST['username']); if (!empty ($userName) && !empty ($userPass)) { $sessionData = Authenticator::getInstance()->authenticate ($userPass, $userName); $isAuthenticated = !is_numeric ($sessionData); if ($isAuthenticated) { $this->storeSessionData ($sessionData); $this->gotoProtectedContent(); } else { $errorMessage; switch ($sessionData) { case Authenticator::UNKNOWN_USER_PASS_COMBO: $errorMessage = 'wrong username and/or password.'; break; case Authenticator::USER_HAS_NOT_CONFIRMED_REGISTRATION: $errorMessage = 'you must confirm your registration first'; break; default: $errorMessage = "Error no. $sessionData."; break; } $this->makeMessagePage ( 'Login Failed', "Cannot authenticate you: $errorMessage." ); } } else { $this->makeMessagePage ( 'Missing Credentials', 'Please provide credentials in order to login.'); } } /** * Attempts authentication with cached unique session id. Upon succes, a new unique session id * is produced, which you must cache instead of the old one. This is done as follows: * * Authenticator::getInstance()->authenticate (<session uniqe id>); */ private function attemptToLoginFromCache () { $isAuthenticated; $newSessionData; $cachedSessionData = trim ($_COOKIE["AuthenticatorDemo"]); if (!empty ($cachedSessionData)) { $newSessionData = Authenticator::getInstance()->authenticate ($cachedSessionData); $isAuthenticated = !is_numeric ($newSessionData); } if ($isAuthenticated) { $this->storeSessionData ($newSessionData); $this->gotoProtectedContent(); } } /** * Recovers a forgotten passwords. This is done as: * * Authenticator::getInstance()->retrievePassword (<registration e-mail address>); * * If the Authenticator module has been set to drop support for password recovery, then the same * API above will reset the passsword to a random value and return that random value instead. */ private function recoverUserPassword () { $email = trim ($_POST['email']); if (!empty ($email)) { $passwordData = Authenticator::getInstance()->retrievePassword ($email); // Passwords cannot be shorter that 4 chars; if this is the case, we deal with an error // number: $recoveryFailed = (is_numeric ($passwordData) && strlen($passwordData) < 4); if ($recoveryFailed) { $errorMessage; switch ($passwordData) { case Authenticator::UNKNOWN_EMAIL: $errorMessage = "The e-mail $email was never registered."; break; default: $errorMessage = "Error no. $passwordData."; break; } $this->makeMessagePage ( 'Error', $errorMessage ); } else { $this->sendEmail ( $email, 'AuthenticatorDemo <noreply@nowhere.com>', 'Your password to AuthenticatorDemo', "This is your forgotten password to AuthenticatorDemo (leave out the ". "enclosing quotes and trailing dot):\n". "\"$passwordData\"."); $this->makeMessagePage ( 'Password Recovered', "An e-mail has been sent to you at $email, containing your forgotten password." ); } } } /** * Registers an user. For simple, open registration (which is our case), this is done as: * * Authenticator::getInstance()->register (array (Authenticator::PASSWORD => <password>), * <username>, <email>); */ private function registerUser () { $username = trim ($_POST['username']); $email = trim ($_POST['email']); $pass = trim ($_POST['pass']); $passAgain = trim ($_POST['passAgain']); if (!empty ($username) && !empty ($email) && !empty ($pass) && !empty ($passAgain)) { if ($pass !== $passAgain) { $this->makeMessagePage ( 'Missmatched Password', 'Please enter the same password twice.' ); } else { $confirmationData = Authenticator::getInstance()-> register ( array (Authenticator::PASSWORD => $pass), $username, $email); $isUserRegistered = !is_numeric ($confirmationData); if ($isUserRegistered) { $this->sendEmail ( $email, 'AuthenticatorDemo <noreply@nowhere.com>', 'Please confirm your registration to AuthenticatorDemo', "Copy & paste in your browser's address bar the following URL (leaving ". "out enclosing quotes):\n". "\"" . $this->makeConfirmationURL ($confirmationData) . "\""); $this->makeMessagePage ( 'Confirm Registration', "An e-mail has been sent to you at $email. Please follow the confirmation link contained in this e-mail in order to complete registration." ); } else { $errorMessage; switch ($confirmationData) { case Authenticator::ILLEGAL_USER_NAME: $errorMessage = 'Provided user name is not acceptable.'; break; case Authenticator::ILLEGAL_EMAIL: $errorMessage = 'Provided e-mail is not acceptable.'; break; case Authenticator::ILLEGAL_PASSWORD: $errorMessage = 'Provided password is not acceptable.'; break; default: $errorMessage = "Error no. $confirmationData."; break; } $this->makeMessagePage ( 'Error', $errorMessage ); } } } else { $this->makeMessagePage ( 'Missing Data', 'Please provide all required data in order to sign up.' ); } } /** * Completes registration for a self-registering user. This is done as: * * Authenticator::getInstance()->register (array (Authenticator::CONFIRMATION_UID => <uid>)); */ private function completeRegistration ($confirmationUid) { $confirmationAnswer = Authenticator::getInstance()->register ( array (Authenticator::CONFIRMATION_UID => $confirmationUid)); $isConfirmed = (!is_numeric ($confirmationAnswer)); if ($isConfirmed) { // If confirmation is successfull, the returned result is a valid session unique id. // // In this example, you could use the $confirmationAnswer variable to automatically // authenticate the user, rather than printing a confirmation message. $this->makeMessagePage ( 'Registration Complete', 'You have successfully signed up to AuthenticatorDemo. You may now proceed to the Login Page, and authenticate using your supplied credentials.' ); } else { $errorMessage; switch ($confirmationAnswer) { case Authenticator::IVALID_CONFIRMATION_UID: $errorMessage = 'Provided confirmation unique id is invalid. Have you entered the URL correctly?'; break; case Authenticator::EXPIRED_CONFIRMATION_UID: $errorMessage = 'Provided confirmation unique id has expired. You will need to sign up again.'; break; default: $errorMessage = "Error no. $confirmationAnswer."; break; } $this->makeMessagePage ( 'Error', $errorMessage ); } } /** * Stores the session unique id on the client machine. * * You must locally store the session id yourself; the Authenticator module doesn't do it for * you. * * The session lifetime is limited by the Authenticator module, internally. If you use a * cookie as the local storage medium, give it a long lifetime. This will rule out potential * issues. In this demo, we make the cookie last one day, although our Authenticator is * configured to allow 15 minutes per session at most. */ private function storeSessionData ($sessionData) { $cookieExpireTime = (time() + 86400); $cookiePath = '/'; setcookie ('AuthenticatorDemo', $sessionData, $cookieExpireTime, $cookiePath); } /** * Concatenates an URL containing confirmation data. * * The Authenticator module doesn't produce confirmation URLs for you, therefore you must carry * on this aspect by yourself. */ private function makeConfirmationURL ($confirmationData) { $url = ($_SERVER['HTTPS'] == "on")? 'https://' : 'http://'; $url .= $_SERVER['HTTP_HOST']; if ($_SERVER['SERVER_PORT'] != '80') { $url .= (':' . $_SERVER['SERVER_PORT']); } $path = str_replace ($_SERVER['QUERY_STRING'], '', $_SERVER['REQUEST_URI']); $url .= $path; if (strpos ($url, '?') !== strlen ($url) - 1) { $url .= '?'; } $url .= ('confirmation=' . $confirmationData); return $url; } /** * Sends a plain text e-mail. * * The Authenticator module doesn't deal with sending e-mails. You must write your own code to do * that. */ private function sendEmail ($to, $from, $subject, $message) { $message = wordwrap ($message, 70, "\n", true); $headers = "From: $from\n" . "Reply-To: $from\n" . 'X-Mailer: PHP/' .phpversion(). "\n"; $addParam = "-f$from"; $result = @mail ($to, $subject, $message, $headers, $addParam); return $result; } /** * @constructor * * This logic is essentially a state machine. It detects the action to be performed and invokes * the associated class method. * * The Authenticator module only provides you core functionality; you must aggregate it yourself * in order to build/integrate with a user control panel page. */ public function __construct () { $this->blindlyInitialize (); $action = trim ($_POST['action']); switch ($action) { case 'Sign me in': $this->loginUser(); break; case 'E-mail me': $this->recoverUserPassword(); break; case 'Sign me up'; $this->registerUser(); break; case 'login page': $this->makeLoginPage(); break; case 'password recovery page': $this->makeRecoverPassPage(); break; case 'registration page': $this->makeRegistrationPage(); break; default: // If we are given a confirmation unique id, then complete registration for that // unique id: $confirmationUid = trim ($_GET['confirmation']); if (!empty ($confirmationUid)) { $this->completeRegistration ($confirmationUid); return; } // Otherwise, attempt to re-login using cached session data: $this->attemptToLoginFromCache(); // If we have no valid session data, we load the login page: $this->makeLoginPage(); break; } } /** * @destructor */ public function __destruct () { $this->makePageFooter (); } /** * DO NOT, UNDER NO CIRCUMSTANCE, blindlyInitialize() THE AUTHENTICATOR MODULE IN A REAL WEB * APPLICATION! * * This method FAKES a real initialization for the Authenticator module. We do it in order to * keep our demo's user interface as simple as possible. * * Because this is a demo, and because we included no administrative features in this demo, * we will initialize the Authenticator module in the background, using hardcoded master * credentials. For real-life scenarios though, master credentials are essential. You will * typically create a page in your web application that initializes master credentials and sends * them to your e-mail address. Beware not to make this the default page of your web application. * It is also common practice to delete this page once setup is complete. * * The API used for initializing master credentials looks like: * * <result> = Authenticator::getInstance()-> register ( * array (Authenticator::PASSWORD => <mster password>), <master user name>, * <master e-mail>, 'master'); * * You must register one master account before being able to use the Authenticator. Master * registration locks itself after a master account has been defined. */ private function blindlyInitialize () { $sessionData = Authenticator::getInstance()->authenticate ('demo', 'demo', 'master'); $hasMaster = ($sessionData !== Authenticator::MASTER_NOT_SET); if ($hasMaster) { $isAuthenticated = !is_numeric ($sessionData); if ($isAuthenticated) { Authenticator::getInstance()->unAuthenticate ($sessionData); } } else { Authenticator::getInstance()-> register (array (Authenticator::PASSWORD => 'demo'), 'demo', 'demo@nowhere.com'); } } // Less relevant class methods (printing and redirection)... private function makePageHeader () { echo '<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" > <head> <title>AuthenticatorDemo</title> </head> <body>'; } private function makeLoginPage () { $this->makePageHeader (); echo ' <h2>Login Page</h2> <form method="post" action=""> <h3>Sign in</h3> <p> <label> User name: <input type="text" name="username" /> </label> </p> <p> <label> Password: <input type="password" name="pass" /> </label> </p> <p> <input type="submit" name="action" value="Sign me in" /> </p> </form> '; } private function makeRecoverPassPage () { $this->makePageHeader (); echo ' <h2>Password Recovery Page</h2> <form method="post" action=""> <h3>Forgot Password?</h3> <p> Enter your e-mail address below, so we can send you your password. You must provide the same address you used at registration time. </p> <p> <input type="text" name="email" /> </p> <p> <input type="submit" name="action" value="E-mail me" /> </p> </form> '; } private function makeRegistrationPage () { $this->makePageHeader (); echo ' <h2>Registration Page</h2> <form method="post" action=""> <h3>Sign Up</h3> <p> You need a valid e-mail address to sign up. A confirmation link will be sent to this address once you click the <em>Sign me up</em> button. You have follow this link in order to complete registration. </p> <p> <label> Username: <input type="text" name="username" /> </label> </p> <p> <label> E-mail address: <input type="text" name="email" /> </label> </p> <p> <label> Password: <input type="password" name="pass" /> </label> </p> <p> <label> Password again: <input type="password" name="passAgain" /> </label> </p> <p> <input type="submit" name="action" value="Sign me up" /> </p> </form> '; } private function makeMessagePage ($title, $content) { $this->makePageHeader (); $ret = ' <h2>' . $title . '</h2> <p>' . $content . '</p>'; echo $ret; } private function makePageFooter () { echo ' <form method="post" action=""> <hr /> <p> Go to: <input type="submit" name="action" value="login page" /> <input type="submit" name="action" value="password recovery page" /> <input type="submit" name="action" value="registration page"/> </p> </form> </body> </html>'; } private function gotoProtectedContent () { header ('Location: ProtectedContent.php'); exit (); } } $authenticatorDemo = new AuthenticatorDemo(); ?>