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 @@ + + +function db_update_76_pre() +{ + /* Find all users that exist multiple times and merge them, fixing the + * types link. Right now this can only happen with committee members + * and volunteers */ + + $q = mysql_query("SELECT DISTINCT username FROM users WHERE 1"); + while($r = mysql_fetch_assoc($q)) { + $user = $r['username']; + if($user == '') continue; + + $qq = mysql_query("SELECT * FROM users WHERE username='$user'"); + if(mysql_num_rows($qq) <= 1) continue; + + /* Fix $user */ + + /* Load all their data */ + while($rr = mysql_fetch_assoc($qq)) { + $types = explode(',', $rr['types']); + foreach($types as $t) { + $u[$t] = $rr; + } + } + + /* Make sure we have what we think we have */ + $cid = intval($u['committee']['id']); + $vid = intval($u['volunteer']['id']); + + if($cid == 0 || $vid == 0) { + echo "\n\n\nDATABASE ERROR: User $user exists multiple + times, but I was unable to fix it. Please visit + www.sfiab.ca and send us an email so we can help sort + out your database. It is likely that user $user will + experience problems logging in\n\n\n"; + continue; + } + + /* Copy everything into the committee entry */ + $fields = array('firstname','lastname','username','password', + 'email', + 'phonehome','phonework','phonecell','fax','organization', + 'address','address2','city','province','postalcode'); + + $query = "`types`='committee,volunteer'"; + foreach($fields as $f) { + if($u['committee'][$f] == '' && $u['volunteer'][$f] != '') { + $v = mysql_escape_string($u['volunteer'][$f]); + $query .= ",`$f`='$v'"; + } + } + + $query = "UPDATE users SET $query WHERE id='$cid'"; + echo "$query\n"; + mysql_query($query); + + /* Now fix the volunteers links */ + $query = "UPDATE volunteer_positions_signup SET users_id='$cid' WHERE users_id='$vid'"; + echo "$query\n"; + mysql_query($query); + + /* The user_volunteer table is empty, we should just delete it, + * no need to update it */ + + /* Delete the old user */ + $query = "DELETE FROM users WHERE id='$vid'"; + echo "$query\n"; + mysql_query($query); + } + +} + +?> 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"; ?> -