science-ation/account.inc.php

359 lines
10 KiB
PHP

<?
/*
This file is part of the 'Science Fair In A Box' project
SFIAB Website: http://www.sfiab.ca
Copyright (C) 2010 David Grant <dave@lightbox.org>
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.
*/
?>
<?
function account_valid_user($user)
{
/* Find any character that doesn't match the valid username characters
* (^ inverts the matching remember */
$x = preg_match('[^a-zA-Z0-9@.-_]',$user);
/* If x==1, a match was found, and the input is bad */
return ($x == 1) ? false : true;
}
function account_valid_password($pass)
{
/* Same as user, but allow more characters */
$x = preg_match('[^a-zA-Z0-9 ~!@#$%^&*()-_=+|;:,<.>/?]',$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_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;
/* Sanity check username */
if(!account_valid_user($username)) {
return -1;
}
/* Make sure the user doesn't exist */
$us = mysql_real_escape_string($username);
$q = mysql_query("SELECT * FROM accounts WHERE username='$us'");
if(mysql_num_rows($q)) {
return -2;
}
//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)) {
return -3;
}
/* 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 pendingemail='".mysql_real_escape_string($email)."', pendingemailcode='$code' WHERE id='$accounts_id'");
$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;
$link=$urlmain."/".$urlemailconfirm;
email_send('account_email_confirmation',$email,array(),array("EMAIL"=>$email,"EMAILCONFIRMATIONLINK"=>$link));
}
}
// 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;
// avoid injections
$accounts_id *= 1;
$roles_id *= 1;
$conferences_id *= 1;
$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'];
}
// we now have the user id that we need, let's check to see whether or not they
// already have the specified role.
$roleRecord = mysql_fetch_array(mysql_query("
SELECT COUNT(*) FROM user_roles
WHERE conferences_id = $conferences_id
AND users_id = $users_id
AND roles_id = $roles_id
"));
if(is_array($roleRecord)){
// 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';
}
// see if this role is a valid one for this conference
if(!array_key_exists($role . '_registration_type', $config)){
return 'invalidrole';
}
// get the type of the role (eg. "judge", "student", etc.)
$role = mysql_result(mysql_query("SELECT type FROM roles WHERE id = $roles_id"), 0);
// 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':
$error = 'invalidrole';
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();
}
// 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 roles for the specified account at the specified conference
$query = mysql_query("
SELECT * FROM user_roles
WHERE accounts_id = $accounts_id
AND conferences_id = $conferences_id
");
while($row = mysql_fetch_assoc($record) && $returnval){
switch($row['type']){
case 'student':
// Student cant' add any other role
$returnval = false;
default:
if($role == 'student') {
// No role can add the student 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. Let's load it
$u = user_load($data['id']);
$roletype = mysql_result(mysql_query("SELECT type FROM roles WHERE id = $roles_id"), 0);
$user_remove_role($u, $roletype);
}
return 'ok';
}
?>