Method Description checkPassword() Checks the user-supplied new password. If the new password is empty, does not match the confirmation password, violates the minimum length limit, or matches the dummy password, it displays the appropriate alert message. change_pwd() This method is called by showScreen() to display the password-change interface. authorize() Checks if the current user is authorized to run the application. Because anyone can run this application, this method uses the isUser() method with a User object called $userObj to return TRUE or FALSE status accordingly. Listing 6-6 shows the user password application user_mngr_passwd.php. Listing 6-6: user_mngr_passwd.php <?php // Turn on all error reporting error_reporting(E_ALL); // If you have installed framewirk directory in // a different directory than // %DocumentRoot%/framework, change the setting below. $APP_FRAMEWORK_DIR=$_SERVER[‘DOCUMENT_ROOT’] . ‘/framework’; $PEAR =$_SERVER[‘DOCUMENT_ROOT’] . ‘/pear’; $PHPLIB =$_SERVER[‘DOCUMENT_ROOT’] . ‘/phplib’; // Insert the path in the PHP include_path so that PHP // looks for PEAR, PHPLIB and our application framework // classes in these directories ini_set( ‘include_path’, ‘:’ . $PEAR . ‘:’ . $PHPLIB . ‘:’ . $APP_FRAMEWORK_DIR . ‘:’ . ini_get(‘include_path’)); Continued Chapter 6: Central User Management System 191 09 549669 ch06.qxd 4/4/03 9:24 AM Page 191 Listing 6-6 (Continued) $AUTHENTICATION_URL = “/login/login.php”; $LOGOUT_URL = “/logout/logout.php”; $APP_MENU = ‘/home/home.php’; $APPLICATION_NAME = ‘USER_MNGR’; $XMAILER_ID = ‘Example User Manager Version 1.0’; $DEFAULT_LANGUAGE = ‘US’; $DEFAULT_DOMAIN = ‘example.com’; $ROOT_PATH = $_SERVER[‘DOCUMENT_ROOT’]; $REL_ROOT_PATH = ‘/user_mngr’; $REL_APP_PATH = $REL_ROOT_PATH . ‘/apps’; $TEMPLATE_DIR = $ROOT_PATH . $REL_APP_PATH . ‘/templates’; $CLASS_DIR = $ROOT_PATH . $REL_APP_PATH . ‘/class’; $REL_TEMPLATE_DIR = $REL_APP_PATH . ‘/templates/’; require_once “user_mngr.errors”; require_once “user_mngr.messages”; require_once ‘DB.php’; require_once $APP_FRAMEWORK_DIR . ‘/’ . ‘constants.php’; require_once $APP_FRAMEWORK_DIR . ‘/’ . $APPLICATION_CLASS; require_once $APP_FRAMEWORK_DIR . ‘/’ . $ERROR_HANDLER_CLASS; require_once $APP_FRAMEWORK_DIR . ‘/’ . $AUTHENTICATION_CLASS; require_once $APP_FRAMEWORK_DIR . ‘/’ . $DBI_CLASS; require_once $APP_FRAMEWORK_DIR . ‘/’ . $USER_CLASS; require_once $TEMPLATE_CLASS; $MIN_USERNAME_SIZE= 3; $MIN_PASSWORD_SIZE= 3; $DUMMY_PASSWD = ‘1234567890’; $ROOT_USER = ‘kabir@evoknow.com’; $SECRET = 916489; $CHAR_SET = ‘charset=iso-8859-1’; // Application names $USERMNGR_MNGR = ‘user_mngr.php’; $USERMNGR_FORGOTTEN_APP = ‘user_mngr_forgotten_pwd.php’; $USERMNGR_CHANGE_PWD_APP = ‘user_mngr_passwd.php’; 192 Part II: Developing Intranet Solutions 09 549669 ch06.qxd 4/4/03 9:24 AM Page 192 /* START TABLE NAMES */ $APP_DB_URL = ‘mysql://root:foobar@localhost/auth’; $AUTH_DB_TBL = ‘users’; /* END TABLE NAMES */ $STATUS_TEMPLATE = ‘usermngr_status.html’; $USERMNGR_MENU_TEMPLATE = ‘usermngr_menu.html’; $USERMNGR_USER_TEMPLATE = ‘usermngr_user_form.html’; $USERMNGR_PWD_REQUEST_TEMPLATE= ‘usermngr_forgotten_pwd.html’; $USERMNGR_PWD_EMAIL_TEMPLATE = ‘usermngr_forgotten_pwd_email.html’; $USERMNGR_PWD_RESET_TEMPLATE = ‘usermngr_pwd_reset.html’; $USERMNGR_PWD_CHANGE_TEMPLATE = ‘usermngr_pwd_change.html’; $ADMINISTRATIVE_USER = 9; $STANDARD_USER = 1; $USER_TYPE = array(‘9’ => ‘Administrator’, ‘1’ => ‘Standard User’); ?> This application can be run after a user is logged in to the system. Its interface is shown in Figure 6-4. Figure 6-4: Changing a user password. Chapter 6: Central User Management System 193 09 549669 ch06.qxd 4/4/03 9:24 AM Page 193 A user enters the new password in the Password field, confirms the new pass- word in the Password (confirm) field, and clicks the Change Pwd button to submit the change request. The user is shown a status message stating that the password has been changed. From the next login, she will be required to enter the new pass- word at the central login prompt. Creating a Forgotten-Password Recovery Application If Murphy were alive today, surely he would have added a new law about forgotten passwords in his famous “Murphy’s Laws” list. It would probably go something like the following: If a user is given a password, it will be forgotten. Passwords are often forgotten due to the “Remember my password” feature in many desktop applications — which caches the password for easy access, freeing the user from having to remember it — or because users have to try to remember several passwords, different ones for different applications. In our application architecture, each user needs to know a single password. Forgetting the password will be very annoying because the user will not be able to access any applications until the password is reset. Ideally, there should be a way for the user to recover the forgotten password. However, our central authentication system uses cryptographic (one-way hash) passwords, so there is no way for the system to determine what the original pass- word is if the user fails to supply the correct one. So instead of recovering the old password, we will allow the user to recover from the forgotten password state by replacing her forgotten password with a new one. Figure 6-5 shows a functional diagram of this recovery process. Here’s how the recovery process works: 1. The user tries to log in using the wrong password. 2. The central login application rejects the login attempt. 3. The user clicks the link to the forgotten-password recovery application and enters her e-mail address and clicks on Send Mail button. 4. The forgotten-password recovery application sends the user an e-mail that includes a URL. 5. The user clicks the URL and is taken to a password-change form, which she fills out using a new password. 6. The user submits the form. The application stores the new password and returns a success message. 7. The user can now log in using the new password. 194 Part II: Developing Intranet Solutions 09 549669 ch06.qxd 4/4/03 9:24 AM Page 194 Figure 6-5: A user recovering from the “forgotten password” state. In the following section, I discuss how to design, develop, and test a forgotten- password application that works with our central authentication framework. Designing the forgotten-password recovery application We know what we want the application to do, so now we need a flow diagram of the application, as shown in Figure 6-6. As the flowchart indicates, when the application is starts (Step 1), it gets an e-mail address from the user. If the e-mail address belongs to an existing user, the application sends an e-mail to the user with a URL that has embedded information to allow the user to call the same application. The embedded URL in the e-mail has step=2 set so that the application can determine which step is next. In Step 2 mode, the application verifies that the information supplied with the URL is valid and came from the e-mail sent earlier. It then allows the user to enter a new password. If the new password is acceptable — that is, it meets the minimum password size requirement — it is encrypted and stored in the database. Now let’s look at how you can implement this flow diagram into an application. Login App Authentication Request with Wrong Password Authentication Request Failed Enter New Password Password Changed Request to Recover from "Forgotten Password" Email with Link to Change Forgotten Password Forgotten Password App 6 5 4 7 3 2 1 Chapter 6: Central User Management System 195 09 549669 ch06.qxd 4/4/03 9:24 AM Page 195 . =$_SERVER[‘DOCUMENT_ROOT’] . ‘/pear’; $PHPLIB =$_SERVER[‘DOCUMENT_ROOT’] . ‘/phplib’; // Insert the path in the PHP include_path so that PHP // looks for PEAR, PHPLIB and our application framework //. accordingly. Listing 6-6 shows the user password application user_mngr_passwd .php. Listing 6-6: user_mngr_passwd .php < ?php // Turn on all error reporting error_reporting(E_ALL); // If you have. 191 Listing 6-6 (Continued) $AUTHENTICATION_URL = “/login/login .php ; $LOGOUT_URL = “/logout/logout .php ; $APP_MENU = ‘/home/home .php ; $APPLICATION_NAME = ‘USER_MNGR’; $XMAILER_ID = ‘Example User