This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; see the file COPYING. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ ?> /?]',$pass); /* If x==1, a match was found, and the input is bad */ if($x == 1) return false; if(strlen($pass) < 6) return false; return true; } /* Duplicate of common.inc.php:generatePassword, which will be deleted * eventually when ALL users are handled through this file */ function account_generate_password($pwlen=8) { //these are good characters that are not easily confused with other characters :) $available="ABCDEFGHJKLMNPQRSTUVWXYZabcdefghjkmnpqrstuvwxyz23456789"; $len=strlen($available) - 1; $key=""; for($x=0;$x<$pwlen;$x++) $key.=$available{rand(0,$len)}; return $key; } function account_set_password($accounts_id, $password = NULL) { $save_old = false; if($password == NULL) { $q = mysql_query("SELECT passwordset FROM accounts WHERE id='$accounts_id'"); $a = mysql_fetch_assoc($q); /* Generate a new password */ $password = account_generate_password(12); /* save the old password only if it's not an auto-generated one */ if($a['passwordset'] != '0000-00-00') $save_old = true; /* Expire the password */ $save_set = "'0000-00-00'"; } else { /* Set the password, no expiry, save the old */ $save_old = true; $save_set = 'NOW()'; } $p = mysql_escape_string($password); $set = ($save_old == true) ? 'oldpassword=password, ' : ''; $set .= "password='$p', passwordset=$save_set "; $query = "UPDATE accounts SET $set WHERE id='$accounts_id'"; mysql_query($query); echo mysql_error(); return $password; } function account_load($id) { $id = intval($id); //we dont want password or the pending email code in here $q = mysql_query("SELECT id, username, link_username_to_email, passwordset, email, pendingemail, superuser, deleted, deleted_datetime, created FROM accounts WHERE id='$id'"); if(mysql_num_rows($q) == 0) { return false; } if(mysql_num_rows($q) > 1) { return false; } $a = mysql_fetch_assoc($q); return $a; } function account_get_password($id) { $id=intval($id); $q=mysql_query("SELECT password FROM accounts WHERE id='$id'"); $r=mysql_fetch_object($q); return $r->password; } function account_load_by_username($username) { $un = mysql_real_escape_string($username); $q = mysql_query("SELECT * FROM accounts WHERE username='$un'"); if(mysql_num_rows($q) == 0) { return false; } if(mysql_num_rows($q) > 1) { return false; } $a = mysql_fetch_assoc($q); return $a; } function account_create($username,$password=NULL) { global $config; $errMsg = ''; /* Sanity check username */ if(!account_valid_user($username)) { $errMsg .= i18n('Invalid user name "%1"', array($username)) . "\n"; }else{ /* Make sure the account doesn't exist */ $us = mysql_real_escape_string($username); $q = mysql_query("SELECT * FROM accounts WHERE username='$us'"); if(mysql_num_rows($q)) { $errMsg .= i18n("The username %1 is already in use", array($username)) . "\n"; } } //if the password is set, make sure its valid, if its null, thats OK, it'll get generated and set by account_set_password if($password && !account_valid_password($password)) { $errMsg .= i18n("Invalid password") . "\n"; } if($errMsg != '') return $errMsg; /* Create the account */ mysql_query("INSERT INTO accounts (`username`,`created`,`deleted`,`superuser`) VALUES ('$us', NOW(),'no','no')"); echo mysql_error(); $accounts_id = mysql_insert_id(); account_set_password($accounts_id, $password); $a = account_load($accounts_id); return $a; } function account_set_email($accounts_id,$email) { global $config; //we dont actually set the email until its confirmed, we only set the pending email :p if(isEmailAddress($email)) { $code=generatePassword(24); mysql_query("UPDATE accounts SET email=NULL, pendingemail='".mysql_real_escape_string($email)."', pendingemailcode='$code' WHERE id='$accounts_id'"); $link = account_build_email_confirmation_link($accounts_id); email_send('account_email_confirmation',$email,array(),array("EMAIL"=>$email,"EMAILCONFIRMATIONLINK"=>$link)); } } // generate the email confirmation URL. Separated from account_set_email for use elsewhere. // returns null if no confirmation code is set for this account function account_build_email_confirmation_link($accounts_id){ global $config; $q = mysql_query("SELECT pendingemail, pendingemailcode FROM accounts WHERE id = $accounts_id"); $row = mysql_fetch_assoc($q); $code = $row['pendingemailcode']; $email = $row['pendingemail']; if(trim($code) == ''){ return null; } $urlproto = $_SERVER['SERVER_PORT'] == 443 ? "https://" : "http://"; $urlmain = "$urlproto{$_SERVER['HTTP_HOST']}{$config['SFIABDIRECTORY']}"; $urlemailconfirm = "emailconfirmation.php?i=$accounts_id&e=".rawurlencode($email)."&c=".$code; return $urlmain."/".$urlemailconfirm; } // add the specified role to the account's user record for the specified conference // return true on success, false on failure function account_add_role($accounts_id, $roles_id, $conferences_id, $password = null){ global $config; global $conference; //if we get role as a type string instead of an id (eg, 'teacher'), lets just look it up if(!is_numeric($roles_id)) { $tq=mysql_query("SELECT id FROM roles WHERE type='".mysql_real_escape_string($roles_id)."'"); $tr=mysql_fetch_object($tq); $roles_id=$tr->id; } // avoid injections $accounts_id=intval($accounts_id); $roles_id=intval($roles_id); $conferences_id=intval($conferences_id); $password=mysql_real_escape_string($password); // make sure the specified id's actually exist if(mysql_result(mysql_query("SELECT COUNT(*) FROM accounts WHERE id = $accounts_id"), 0) != 1){ return "invalidaccount"; } if(mysql_result(mysql_query("SELECT COUNT(*) FROM roles WHERE id = $roles_id"), 0) != 1){ return "invalidrole"; } if(mysql_result(mysql_query("SELECT COUNT(*) FROM conferences WHERE id = $conferences_id"), 0) != 1){ return "invalidconference"; } // find out if this account has a user record for this conference $data = mysql_fetch_array(mysql_query(" SELECT * FROM users WHERE conferences_id = $conferences_id AND accounts_id = $accounts_id ")); if(is_array($data)){ // they do indeed have a user record for this conference. Let's load it $u = user_load($data['id']); $users_id = $data['id']; }else{ // They're not actually connected to this conference, let's hook 'em up $u = user_create($accounts_id, $conferences_id); $users_id = $u['id']; // if this applies to their current session, update their session user id if($_SESSION['accounts_id'] == $accounts_id && $_SESSION['conferences_id'] == $conferences_id){ $_SESSION['users_id'] = $users_id; } } // we now have the user id that we need, let's check to see whether or not they // already have the specified role. if(mysql_result(mysql_query("SELECT COUNT(*) FROM user_roles WHERE users_id = $users_id AND roles_id = $roles_id"), 0) != 0){ // they already have this role. shell_exec("man true"); return 'ok'; } // see if this role conflicts with existing ones if(!account_add_role_allowed($accounts_id, $conferences_id, $roles_id)){ return 'invalidrole(account_add_role_allowed)'; } // get the type of the role (eg. "judge", "participant", etc.) $role = mysql_result(mysql_query("SELECT type FROM roles WHERE id = $roles_id"), 0); if($_SESSION['superuser']!='yes') { // and see if it's a valid one for this conference if(!array_key_exists($role . '_registration_type', $config)){ return 'invalidrole(_registration_type)'; } } if( in_array("admin",$_SESSION['roles']) || in_array("config",$_SESSION['roles']) || $_SESSION['superuser']=="yes") { //do nothing, we're logged in a a superuser, admin or config, so we //dont want/need to check the types, just go ahead and invite them //its easie than reversing the logic of the if above. } else { // and let's see if we meet the conditions for the registration type $error = ""; switch($config[$role . '_registration_type']){ case 'open': case 'openorinvite': // this is allowed. break; case 'singlepassword': if($password != $config[$role . '_registration_singlepassword']){ $error = "invalidpassword"; } break; case 'schoolpassword': if($password != null){ $schoolId = $u['schools_id']; $schoolDat = mysql_fetch_assoc(mysql_query("SELECT registration_password FROM schools WHERE id=$schoolId")); if(is_array($schoolDat)){ if($password == $schoolDat['registration_password']) $valid = true; $error = "invalidpassword"; } } break; case 'invite': if( in_array("teacher",$_SESSION['roles']) && $role=='participant') { //if they are a teacher, they can add a participant role a-ok $error = ''; } else { $error = 'invalidrole(invite_only)'; } break; } } if($error != ""){ return $error; } // *whew* all conditions have been met. Let's go ahead and create the record if(!mysql_query("INSERT INTO user_roles (accounts_id, users_id, roles_id, active, complete) VALUES($accounts_id, $users_id, $roles_id, 'yes', 'no')")){ return "mysqlerror:" . mysql_error(); } $a=account_load($accounts_id); $password=account_get_password($accounts_id); //in this case, we want to send to pendingemail if thats all we have, because //its possible that this is a new user that was just added and we just sent //the email confirmation email as well, so on new user invitation, they will get //the invite email as well as the email confirmation email. if($a['email']) $e=$a['email']; else if($a['pendingemail']) $e=$a['pendingemail']; email_send("{$role}_new_invite", $e, array("FAIRNAME"=>$conference['name']), array("FAIRNAME"=>$conference['name'], "EMAIL"=>$e, "USERNAME"=>$a['username'], "PASSWORD"=>$password, "ROLE"=>$role) ); // if we made it this far, the role was successfully added return 'ok'; } // find out if the specifed role can be added to this account at the specified conference function account_add_role_allowed($accounts_id, $roles_id, $conferences_id){ $returnval = true; // avoid injections $accounts_id *= 1; $roles_id *= 1; $conferences_id *= 1; // get the user id for this account/conference $userdat = mysql_fetch_assoc(mysql_query("SELECT id FROM users WHERE accounts_id = $accounts_id AND conferences_id = $conferences_id")); // If this condition isn't met, then the account is not connected to the conference. // In that case, the role can be allowed as there is no conflict. if(is_array($userdat)){ $users_id = $userdat['id']; // get the roles for the specified account at the specified conference $query = mysql_query(" SELECT * FROM user_roles WHERE users_id = $users_id "); while($returnval && $row = mysql_fetch_assoc($query)){ switch($row['type']){ case 'participant': // Student cant' add any other role $returnval = false; break; default: if($role == 'participant') { // No role can add the participant role $returnval = false; } // All other roles can coexist (even the fair role) break; } } } return $returnval; } // remove the specified role from the account's user record for the specified conference // return true on success, false on failure function account_remove_role($accounts_id, $roles_id, $conferences_id){ // avoid injections $accounts_id *= 1; $roles_id *= 1; $conferences_id *= 1; // make sure the specified id's actually exist if(mysql_result(mysql_query("SELECT COUNT(*) FROM accounts WHERE id = $accounts_id"), 0) != 1){ return "invalidaccount"; } if(mysql_result(mysql_query("SELECT COUNT(*) FROM roles WHERE id = $roles_id"), 0) != 1){ return "invalidrole"; } if(mysql_result(mysql_query("SELECT COUNT(*) FROM conferences WHERE id = $conferences_id"), 0) != 1){ return "invalidconference"; } // very little error catching needed here. If the role's there, we hopfully succeed in // removing it. If it's not, then we succeed in doing nothing $data = mysql_fetch_array(mysql_query(" SELECT * FROM users WHERE conferences_id = $conferences_id AND accounts_id = $accounts_id ")); if(is_array($data)){ // they do indeed have a user record for this conference. $users_id = $data['id']; // Do role-specific remove actions $role = mysql_result(mysql_query("SELECT `type` FROM roles WHERE id = $roles_id"), 0); switch($role) { case 'committee': mysql_query("DELETE FROM committees_link WHERE accounts_id='{$accounts_id}'"); break; case 'judge': mysql_query("DELETE FROM judges_teams_link WHERE users_id='$users_id'"); mysql_query("DELETE FROM judges_specialawards_sel WHERE users_id='$users_id'"); break; default: break; } // and now we can remove the role link itself mysql_query("DELETE FROM user_roles WHERE roles_id={$roles_id} AND users_id='$users_id'"); } return 'ok'; } // A function for handling updates of any fields that can be modified through an API call. // returns 'ok' on success, error message otherwise. function account_update_info($fields){ if($_SESSION['accounts_id']) { $accounts_id = $_SESSION['accounts_id']; }else{ return 'you must be logged in to change your account settings'; } if(!is_array($fields)) return 'account_update_info expects an array'; $message = 'ok'; $updates = array(); foreach($fields as $index => $value){ switch($index){ case 'username': if(account_valid_user($value)){ $u = mysql_real_escape_string($value); $q = mysql_query("SELECT id FROM accounts WHERE username = '$u' AND deleted = 'no' AND id != $accounts_id"); if(mysql_num_rows($q) != 0){ $message = "username already in use"; }else{ $updates[$index] = $value; } }else{ $message = "invalid username"; } break; case 'password': $q = mysql_query("SELECT password FROM accounts WHERE id='$accounts_id' AND password='" . mysql_real_escape_string($value) . "'"); if(mysql_num_rows($q)){ // ignore this parameter. The password has not changed }else if(!account_valid_password($value)){ $message = "invalid password"; }else{ $updates[$index] = $value; } break; case 'link_username_to_email': if(in_array($value, array('yes', 'no'))){ if($value=='yes') { //if its yes, we can only do it if username==email if($fields['username']==$fields['email']) { $updates[$index] = $value; } else { $message="username and email must match for link_username_toemail"; } } else { $updates[$index] = $value; } }else{ $message = '"link_username_to_email" must be either a "yes" or "no" value'; } break; case 'email': if(isEmailAddress($value)){ $updates[$index] = $value; }else{ $message = 'invalid e-mail address'; } break; default: $message = 'invalid field name'; } } if($message != 'ok'){ return $message; } // the data's all been validated, so we can continue with the actual update. // doing it separately from the above loop to ensure that it's an all-or nothing update; // none of it will happen if any one part is erroneous. foreach($updates as $index => $value){ switch($index){ case 'username': $username = mysql_real_escape_string($value); mysql_query("UPDATE accounts SET username = '$username' WHERE id = $accounts_id"); break; case 'password': account_set_password($accounts_id, mysql_real_escape_string($value)); break; case 'link_username_to_email': mysql_query("UPDATE accounts SET link_username_to_email = '$value' WHERE id = $accounts_id"); break; case 'email': account_set_email($accounts_id, $value); break; } } return $message; } ?>