diff --git a/db/db.code.version.txt b/db/db.code.version.txt index 78eb67ce..dd475631 100644 --- a/db/db.code.version.txt +++ b/db/db.code.version.txt @@ -1 +1 @@ -75 +76 diff --git a/db/db.update.76.php b/db/db.update.76.php new file mode 100644 index 00000000..02150677 --- /dev/null +++ b/db/db.update.76.php @@ -0,0 +1,74 @@ + diff --git a/user.inc.php b/user.inc.php index 40ef7cc9..95b5c7dc 100644 --- a/user.inc.php +++ b/user.inc.php @@ -133,7 +133,7 @@ function user_load($user, $load_full=false) /* Turn the type into an array, because there could be more than one */ $ts = explode(',', $ret['types']); - $ret['types'] = $ts; /* Now we can use in_array($ret['type'], 'judge') ; */ + $ret['types'] = $ts; /* Now we can use in_array('judge', $ret['types']) ; */ } else { $ret = $user; } @@ -312,16 +312,52 @@ function user_delete($u, $type=false) } } -function user_create($type) +/* Returns true if loaded user ($u) is allowed to add role type $type to their + * profile. THis is intended as a last-stop mechanism, preventing, for example + * a student from co-existing with any other account type. */ +function user_add_role_allowed($type, $u) { - mysql_query("INSERT INTO users (`types`,`created`) VALUES ('$type', NOW())"); - $uid = mysql_insert_id(); + /* For example, a committee member can add a volunteer or judge role to + * their account. */ + $allowed = array( + 'committee' => array('volunteer', 'judge'), + 'volunteer' => array('judge', 'committee'), + 'judge' => array('volunteer', 'committee'), + 'student' => array(), + 'fair' => array() ); + + foreach($u['types'] as $ut) { + $allowed_array = $allowed[$ut]; + if(in_array($type, $allowed[$ut])) return true; + } + return false; +} + +function user_create($type, $u = NULL) +{ + if(!is_array($u)) { + mysql_query("INSERT INTO users (`types`,`passwordexpiry`,`created`) + VALUES ('$type', '0000-00-00', NOW())"); + $uid = mysql_insert_id(); + } else { + /* The user has been specified and already exists, + * just add a role */ + $uid = $u['id']; + if(!user_add_role_allowed($type, $u)) { + /* If we get in here, someone is hand crafting URLs */ + echo "HALT: invalid role add specified for operation."; + exit; + } + $new_types = implode(',', $u['types']).','.$type; + mysql_query("UPDATE users SET types='$new_types' WHERE id='$uid'"); + } switch($type) { case 'volunteer': case 'student': case 'judge': - case 'region': + case 'fair': + mysql_query("INSERT INTO users_fair(`users_id`) VALUES ('$uid')"); break; case 'committee': mysql_query("INSERT INTO users_committee(`users_id`) VALUES ('$uid')"); @@ -354,6 +390,15 @@ function user_valid_password($pass) return true; } +/* A more strict version of isEmailAddress() */ +function user_valid_email($str) +{ + if(eregi('^[a-zA-Z0-9._-]+@[a-zA-Z0-9._-]+\.([a-zA-Z]{2,4})$', $str)) + return true; + return false; +} + + /* Perform some checks. Make sure the person is logged in, and that their * password hasn't expired (the password_expired var is set in the login page) */ diff --git a/user_login.php b/user_login.php index cfa09bba..393395b5 100644 --- a/user_login.php +++ b/user_login.php @@ -26,10 +26,13 @@ require_once("common.inc.php"); require_once("user.inc.php"); - function try_login($user, $pass, $type=null) + function try_login($user, $pass) { /* Ensure sanity of inputs, user should be an email address, but it's stored * in the username field */ + /* FIXME: this shoudl be user_valid_email, but can't be yet, because + * we copy the usernames from the email field, and that field may + * contain a name too */ if(!isEmailAddress($user)) { /* It's possible that it's a username */ if(!user_valid_user($user)) return false; @@ -40,12 +43,11 @@ //$x = user_valid_password($pass); if(!strlen($pass)) return false; - if($type) $typequery=" AND types LIKE '%$type%'"; else $typequery=""; + $user = mysql_escape_string($user); $q = mysql_query("SELECT id,username,password FROM users WHERE username='$user' - $typequery AND deleted='no'"); echo mysql_error(); if(mysql_num_rows($q) != 1) return false; @@ -80,6 +82,21 @@ $notice=$_GET['notice']; + $redirect = $_GET['redirect']; + $redirect_data = $_GET['redirectdata']; + + switch($redirect) { + case 'roleadd': + $redirect_url = "&redirect=$redirect&redirectdata=$redirectdata"; + break; + case 'roleattached': + $redirect_url = "&redirect=$redirect"; + break; + default: + $redirect_url = ''; + break; + } + switch($type) { case 'volunteer': // returns "notopenyet", "closed", or "open" @@ -103,13 +120,12 @@ { if($_POST['pass'] && $_POST['user']) { - $id = try_login($_POST['user'], $_POST['pass'],$type); + $id = try_login($_POST['user'], $_POST['pass']); if($id == false) { - header("location: user_login.php?type=$type¬ice=login_failed"); + header("location: user_login.php?type=$type¬ice=login_failed$redirect_url"); exit; } else { $u = user_load($id); - /* Make sure $type is in their types */ if(!in_array($type, $u['types'])) { /* Huh, someone is fudging with the HTML, get @@ -154,9 +170,26 @@ } else { $_SESSION['multirole'] = false; } + + /* See if there is a redirect, and do that instead of + * taking them to their main page */ + if($redirect != '') { + switch($redirect) { + case 'roleadd': + if(!in_array($multirole_data, $user_types)) + $multirole_data = ''; + + header("location: user_multirole.php?action=add&type=$multirole_data"); + exit; + case 'roleattached': + header("location: {$type}_main.php?notice=attached"); + exit; + + } + } + /* Now finally, take them to whatever main page they logged in for */ header("location: {$type}_main.php"); - exit; } @@ -176,10 +209,9 @@ $keys = array_keys($_SESSION); foreach($keys as $k) unset($_SESSION[$k]); + if($notice != 'login_multirole') $notice = 'logged_out'; if($type != '') - header("location: user_login.php?type=$type¬ice=logged_out"); - if($type != '') - header("location: user_login.php?type=$type¬ice=logged_out"); + header("location: user_login.php?type=$type¬ice=$notice$redirect_url"); exit; } else if($_GET['action']=="recover") @@ -219,9 +251,10 @@ { /* Process a recover */ $email = $_POST['email']; - if(isEmailAddress($email)) { + if(user_valid_email($email)) { /* valid email address */ - $q=mysql_query("SELECT * FROM users WHERE email='$email'"); + $e = mysql_escape_string($email); + $q=mysql_query("SELECT * FROM users WHERE email='$e'"); $r=mysql_fetch_object($q); if($r) { $fn = trim($_POST['fn']); @@ -293,13 +326,20 @@ case 'logged_out': echo notice(i18n("You have been successfully logged out")); break; + case 'login_multirole': + echo notice(i18n("You have been successfully logged out")); + echo notice(i18n("Now login to finish adding the new role to your account")); + break; + case 'multirole': + echo notice(i18n("Your email address already exists. Please login to your existing account below and you will be redirected to the multi-role creation page to complete your registration request.")); + break; } $recover_link = "user_login.php?type=$type&action=recover"; $new_link = "user_new.php?type=$type"; ?> -
+ ">
: diff --git a/user_multirole.php b/user_multirole.php index 21558ae6..85df73f0 100644 --- a/user_multirole.php +++ b/user_multirole.php @@ -34,6 +34,59 @@ $u = user_load($_SESSION['users_id']); + $action = $_GET['action']; + + function show_role($type, $u) + { + global $user_what; + if(user_add_role_allowed($type, $u) && !in_array($type, $u['types'])) { + echo "
  • {$user_what['volunteer']}"; + echo '
  • '; + return 1; + } + return 0; + } + + if($action == 'add') { + send_header("Select Additional Roles"); + + $u = user_load($_SESSION['users_id']); + + //only display the named greeting if we have their name + echo i18n("Hello %1",array($_SESSION['name'])); + echo "
    "; + echo "
    "; + + echo i18n('Your account is currently in the following roles').':'; + echo '
      '; + foreach($u['types'] as $t) echo "
    • {$user_what[$t]}
    • "; + echo '
    '; + + + echo i18n('Adding a role to your account WILL NOT delete anything in + your account or any existing roles you have. It will only add a new + role to your account.'); + echo '

    '; + echo i18n('When you add a new role to your account you will be + automatically logged out. To complete the process please log back in + using your existing email and password.'); + echo '

    '; + echo i18n('Select a Role to add to your account'); + echo ':'; + + echo '
      '; + $x += show_role('volunteer', $u); + if($x == 0) { + echo '
    • '; + echo i18n('There are no more roles that can be added to your account'); + echo '
    • '; + } + echo '
    '; + send_footer(); + exit; + } + if(count($u['types']) <= 1) { /* This user doesn't have multiple roles, send them to their * proper page */ @@ -41,14 +94,13 @@ exit; } - if($_GET['type']) { - /* Validate the input */ - $type = $_GET['type']; + if($action == 'switch') { + /* Validate the input */ + $type = $_GET['type']; if(!in_array($type, $user_types)) { - header('location: index.php'); + header("location: {$_SESSION['users_type']}_main.php"); exit; - } - + } /* Make sure the user is actually allowed to be in the * requested role */ if(!in_array($type, $u['types'])) { @@ -68,7 +120,7 @@ switch($_GET['notice']) { case 'already_logged_in': - echo error(i18n('You are already logged in, please use the [Logout] link in the upper right to logout before loggin in as a different user')); + echo error(i18n('You are already logged in, please use the [Logout] link in the upper right to logout before logging in as a different user')); break; } //only display the named greeting if we have their name @@ -82,7 +134,7 @@ foreach($user_types as $t) { if(in_array($t, $u['types'])) { - echo "{$user_what[$t]}
    "; + echo "{$user_what[$t]}
    "; echo "
    "; } } diff --git a/user_new.php b/user_new.php index 2299b733..e902b78a 100644 --- a/user_new.php +++ b/user_new.php @@ -27,23 +27,26 @@ require_once("user.inc.php"); $type = false; +/* if(isset($_SESSION['users_type'])) { send_header("Registration", array()); echo i18n("Please logout before creating a new user\n"); send_footer(); exit; } + */ - $types = array('volunteer', 'committee', 'student','judge'); $type = $_GET['type']; - if(!in_array($type, $types)) { + if(!in_array($type, $user_types)) { send_header("Registration"); echo i18n("Invalid new registration\n"); send_footer(); exit; } - $notice=$_GET['notice']; + $notice = $_GET['notice']; + $action = $_GET['action']; + if($action == '') $action = $_POST['action']; switch($type) { case 'volunteer': @@ -105,20 +108,60 @@ send_footer(); exit; } - - - if($_POST['action']=="new") - { + + if($action == 'new') { $create = true; $data_fn = mysql_escape_string(stripslashes($_POST['fn'])); $data_ln = mysql_escape_string(stripslashes($_POST['ln'])); - $data_email = $_POST['email']; + $data_email = stripslashes($_POST['email']); + $sql_email = mysql_escape_string($data_email); + $registrationpassword = $_POST['registrationpassword']; - if(!isEmailAddress($data_email)) { + /* Strict validate the email */ + if(!user_valid_email($data_email)) { $notice = 'email_invalid'; $data_email = ''; $create = false; } + /* See if this email already exists */ + $q = mysql_query("SELECT id,types FROM users WHERE email='$sql_email' OR username='$sql_email'"); + + if(mysql_num_rows($q) > 0) { + /* It already exists, make sure they're not already in this role */ + $r = mysql_fetch_object($q); + $types = split(',', $r->types); + if(in_array($type, $types)) { + $notice = 'role_exists'; + $create = false; + } else { + /* If they're already logged in, we can go ahead and + * add this role. We've passed all the required checks + * for creating a new user of this role. + * The user has already been warned about being logged + * out. */ + if(isset($_SESSION['users_id'])) { + /* User create does last minute checks, like + * ensuring a student doesn't try to also + * register as a judge */ + $u = user_load($_SESSION['users_id']); + $u = user_create($type, $u); + $_SESSION['users_type'] = $type; + header("location: user_login.php?action=logout¬ice=login_multirole&redirect=roleattached"); + exit; + } + /* forward the user to the login page for whatever role + * they already have (it doesn't matter), and + * setup a login role_add redirect */ + header("location: user_login.php?type={$types[0]}¬ice=multirole&redirect=roleadd&redirectdata=$type"); + exit; + } + } + + if($data_fn == '' or $data_ln == '') { + $notice = 'name_invalid'; + $create = false; + } + if($create == true) { /* Generate a password */ @@ -127,10 +170,13 @@ for($x=0;$x<12;$x++) $password .= $pchars{rand(0,61)}; /* Add the user */ - $q = "INSERT INTO users (types,firstname,lastname,username,password,passwordexpiry,email,created) VALUES ( - '$type', '$data_fn','$data_ln','$data_email','$password','0000-00-00','$data_email',NOW());"; - mysql_query($q); - echo mysql_error(); + $u = user_create($type); + $u['firstname'] = $data_fn; + $u['lastname'] = $data_ln; + $u['username'] = $data_email; + $u['password'] = $password; + $u['email'] = $data_email; + user_save($u); /* Send the email */ email_send($welcome_email, $data_email, @@ -155,6 +201,18 @@ echo '
    '; echo error(i18n("The email address is invalid")); echo '
    '; + break; + case 'name_invalid': + echo '
    '; + echo error(i18n("You must enter your first and last name")); + echo '
    '; + break; + case 'role_exists': + echo '
    '; + echo error(i18n("That email address has an existing {$user_what[$type]} registration")); + echo notice(i18n("Use the 'recover password' option on the {$user_what[$type]} login page if you have forgotten your password")); + echo '
    '; + break; } ?> diff --git a/volunteer_main.php b/volunteer_main.php index cac563cc..76a54377 100644 --- a/volunteer_main.php +++ b/volunteer_main.php @@ -39,6 +39,9 @@ case 'already_logged_in': echo error(i18n('You are already logged in, please use the [Logout] link in the upper right to logout before loggin in as different user')); break; + case 'attached': + echo happy(i18n('The Volunteer role has been attached to your account. Use the [Switch Roles] link in the upper right to change roles while you are logged in')); + break; } //only display the named greeting if we have their name