<?
#OOB/N1 Framework [©�2004,2005 - Nutus]
/**
@license: BSD
@author: Pablo Micolini (hide@address.com)
@author: Victor Stornati (hide@address.com) // update
Provides user validation (login/logout)
*/
//OOB_module :: includeClass ('personnel','personnel_employee');
class OOB_user extends OOB_internalerror {
// @implementation cuando un usuario ha sido bloqueado, pero habia alguien logueado, q debe hacer el sistema? sacarlo? nada?
private $user= ID_UNDEFINED;
private $uname = '';
private $password = '';
private $email = '';
private $session = '';
private $status= 8; // 0 neeeds auth, 1 ok, 2 temp block, 9 deleted
private $maxcon= 5;
private $block_method= 1; // 0 no block, 1 time, 2 statuschange
private $block_time= "3600"; //10 minutos
private $source= "db"; // db, imap
private $new_validation= "no"; // 0 no, 1 mail, 3 admin
private $employee = NO_OBJECT;
public function id()
{
return $this->get('user');
}
public function name()
{
return $this->get('uname');
}
/** loads config details, and starts the user.
if no user set we must believe is a new one */
public function __construct($user= ID_UNDEFINED) {
global $ari;
//load config vars!
$this->block_method= $ari->get("config")->get('block-method', 'user');
$this->block_time= $ari->get("config")->get('block-time', 'user');
$this->source= $ari->get("config")->get('validation-method', 'user');
$this->new_validation= $ari->get("config")->get('new_validation', 'user');
if ($user > ID_MINIMAL) {
$this->user= $user;
if (!$this->fill ())
{throw new OOB_exception("Invalir user {$user}", "403", "Invalid User", false);}
}
}
/** user validation made, username and password must be provided */
public static function login($uname, $pass) {
global $ari;
// clean vars
if (OOB_validatetext :: isClean($uname) && OOB_validatetext :: isClean($pass) && OOB_validatetext :: isPassword($pass)) {
$imap_pass = $pass;
$pass= md5($pass);
} else
return false;
// load config vars
$source= $ari->get("config")->get('validation-method', 'user');
$blocktime= $ari->get("config")->get('block-time', 'user');
$savem = $ari->db->SetFetchMode(ADODB_FETCH_NUM);
$uname = $ari->db->qMagic ($uname);
// get id where user and pass matches (using proper auth method!)
// @fixme LOCK ROW TILL FINISH ?
$sql= "SELECT id, password, status FROM oob_user_user WHERE uname = $uname";
$ari->db->SetFetchMode($savem);
$rs = $ari->db->Execute($sql);
if (!$rs || $rs->EOF) {
return false;
} else {
$userid= $rs->fields[0];
$password= $rs->fields[1];
$status= $rs->fields[2];
$rs->Close();
}
switch ($source)
{
//lo de siempre es una db
case "db":
default:
{
if ($password != $pass)
{
// add failed for uid! if pass not match!
self::addFailed ($userid, "WRONGPASS");
//contamos cuantos fallados tiene, y
// si son mas de los q deberia, lo sentimos mucho
$fallados = self::getFailed ($userid, $blocktime);
if ($fallados > 10)
{throw new OOB_exception("BLOCKED User ($uname)", "403", "Su usuario ha sido desactivado, contacte al administrador", true);}
return false;
}
break;
}
// case "imap": {
//
// $server = $ari->get("config")->get('imap-server', 'user');
//
// //if ok, continue, else add failed as pass not match
// if ($mbox = @imap_open("{" . $server . "}INBOX", "$uname", "$imap_pass", OP_READONLY))
// {
// @imap_close ($mbox);
//
// } else {
// $now = $ari->db->DBTimeStamp(time());
// $sql = "insert into oob_user_failed (id, user_id, timestamp , reason )
// values ('','$userid',$now,'IMAP_INVALID')";
// if ($ari->db->Execute($sql) === false)
// throw new OOB_exception("Error en DB: {$ari->db->ErrorMsg()}", "010", "Error en la Base de Datos", false);
//
// return false;
//
// }
//
// }
}
if ($status != 1) {
throw new OOB_exception("DISABLED", "403", "Su usuario ha sido desactivado, contacte al administrador", false);
}
//valida el permiso de acceso al modulo admin
if ($ari->get('mode') == 'admin' )
{
//verificar permiso
if ( !seguridad :: isAllowed(seguridad_action :: nameConstructor('adminaccess','access','admin'), '', new oob_user ($userid)) )
{
throw new OOB_exception("Acceso denegado a Usuario {$uname}", "403", "Acceso denegado. Consulte con su administrador", true);
}
}
$sessionkey = session_id();
// Con esto grabamos los datos de sesion, para poder loguear al usuario sin problemas
session_write_close();
//stores the login->session key relation (if there is one previously, updates the record.)
$savem= $ari->db->SetFetchMode(ADODB_FETCH_NUM);
$sql= "SELECT user_id FROM oob_user_online WHERE sesskey = '$sessionkey'";
$ari->db->SetFetchMode($savem);
$rs = $ari->db->Execute($sql);
if (!$rs || $rs->EOF) {
$sql = "INSERT INTO oob_user_online (user_id,sesskey )
values ('$userid','$sessionkey')";
if ($ari->db->Execute($sql) === false)
throw new OOB_exception("Error en DB: {$ari->db->ErrorMsg()}", "010", "Error en la Base de Datos, o en la asignación de Sesion, recargue la página", false);
return new oob_user ($userid);
} else {
$useridlogued= $rs->fields[0];
$rs->Close();
}
if ($useridlogued == $userid)
return new oob_user ($userid);
else {
$sql= "UPDATE oob_user_online SET user_id = '$userid' WHERE sesskey = '$sessionkey'";
if ($ari->db->Execute($sql) === false)
throw new OOB_exception("Error en DB: ". $ari->db->ErrorMsg(), "010", "Error en la Base de Datos", false);
return new oob_user ($userid);
}
}
/** deletes the sessionid->login link.
* You can provide a redirection url, default is home */
public function logout($redirect ='/') {
global $ari;
$sessionkey = session_id();
$sql= "DELETE FROM oob_user_online WHERE sesskey = '$sessionkey' AND user_id = '$this->user'";
$ari->db->Execute($sql);
if ($ari->get('mode') == 'admin')
header( "Location: " . $ari->get("adminaddress") . $redirect);
else
header( "Location: " . $ari->get("webaddress") . $redirect);
exit;
}
/**
look for session id->login link,
if exist return user-object, else false. */
public static function isLogued() {
global $ari;
$sessionkey = session_id();
$savem= $ari->db->SetFetchMode(ADODB_FETCH_NUM);
$sessionkey = $ari->db->qMagic ($sessionkey);
$sql= "SELECT user_id FROM oob_user_online WHERE sesskey = $sessionkey";
$rs = $ari->db->Execute($sql);
$ari->db->SetFetchMode($savem);
if (!$rs || $rs->EOF) {
return false;
}
if (!$rs->EOF && $rs->RecordCount() == 1) {
$userid = $rs->fields[0];
$rs->Close();
return new oob_user ($userid);
}
// return false; // por las dudas?
throw new OOB_exception("Mas de un Usuario para la misma Sesión", "501", "Ha ocurrido un error inesperado", true);
}
public static function lostPass($user) //DO
{
}
public static function validateLost($code, $user) //DO
{
}
/** Returs the value for the given var */
public function get ($var)
{
return $this-> $var;
}
/** Sets the variable (var), with the value (value) */
public function set ($var, $value)
{
$this->$var= $value;
}
/** Stores/Updates user object in the DB */
public function store() {
global $ari;
// clean vars !
if (!OOB_validatetext :: isClean($this->uname) || !OOB_validatetext :: isCorrectLength ($this->uname, 4, 64))
{
$ari->error->addError ("oob_user", "INVALID_USER");
} else {
if ($this->user == ID_UNDEFINED)
// si es nuevo, debo revisar que no exista de antes!
{
$savem= $ari->db->SetFetchMode(ADODB_FETCH_NUM);
$uname = $ari->db->qMagic($this->uname);
$sql= "SELECT id as cuenta FROM oob_user_user WHERE uname = $uname";
$rs = $ari->db->Execute($sql);
$ari->db->SetFetchMode($savem);
if (!$rs->EOF && $rs->fields[0]!= 0) {
$this->error()->addError ("INVALID_USER");
$rs->Close();
}
}
}//--
if ($this->password != -1)
{
if (!OOB_validatetext :: isClean($this->password) ||!OOB_validatetext :: isPassword($this->password) )
$this->error()->addError ( "INVALID_PASS");
}
if ( !OOB_validatetext :: isEmail($this->email) )
$this->error()->addError ("INVALID_EMAIL");
if ( !OOB_validatetext :: isNumeric($this->status) )
$this->error()->addError ("INVALID_STATUS", true);
$employee_id = "0";
if (is_a ($this->employee, "personnel_employee") )
{ $employee_id = $ari->db->qMagic($this->employee->get('id')); }
if (!$this->error()->getErrors())
{
$this->uname =$ari->db->qMagic($this->uname);
$this->email =$ari->db->qMagic($this->email);
if ($this->password == -1)
$passql = "";
else
{
// $this->password =$ari->db->qMagic( $this->password);
$this->password = md5 ($this->password);
$passql = "password = '$this->password',";
}
if ($this->user > 0)
{
// update data
$ari->db->StartTrans();
$sql= "UPDATE oob_user_user SET uname = $this->uname ,$passql email = $this->email, status = '$this->status' WHERE id = '$this->user'";
$ari->db->Execute($sql);
$ari->db->CompleteTrans();
if ($ari->db->HasFailedTrans())
throw new OOB_exception("Error en DB: {$ari->db->ErrorMsg()}", "010", "Error en la Base de Datos", false); //return false;
else
{
$this->password = -1;
return true;}
} else {
// insert new and set userid with new id
$ari->db->StartTrans();
$sql= "INSERT INTO oob_user_user
( uname, password, email, connections, status, EmployeeID)
VALUES ( $this->uname, '$this->password', $this->email ,'1','$this->status', $employee_id)
";
$ari->db->Execute($sql);
$rs = $ari->db->CompleteTrans();
if ($ari->db->HasFailedTrans())
throw new OOB_exception("Error en DB: {$ari->db->ErrorMsg()}", "010", "Error en la Base de Datos", false); //return false;
else
{
$this->user = $ari->db->Insert_ID();
$this->password = -1;
return true;}
}
} else {
// no validan los datos
return false; //devuelve un objeto de error con los errores!
}
}
/** Deletes user object from the DB*/
public function delete() {
global $ari;
// sets status 9 for a user-id
if ($this->user > 0 && $this->status != 9) {
$sql= "UPDATE oob_user_user SET status = '9' WHERE id = '$this->user'";
if ($ari->db->Execute($sql))
return true;
else
throw new OOB_exception("Error en DB: {$ari->db->ErrorMsg()}", "010", "Error en la Base de Datos", false);
} else {
if ($this->status == 9)
$this->error()->addError ("ALREADY_DELETED");
else
$this->error()->addError ( "NO_SUCH_USER");
return false;
}
}
/** Returs the users on the system. status = (enabled/deleted/pending/bloqued/all) shows users */
static public function userList ($status = 'enabled', $sort = 'uname')
{
global $ari;
if (in_array ($status, oob_user::getStatus ("ALL", false)) && $status != "all")
{
$estado = "WHERE status = " . oob_user::getStatus($status, false);
}
else
{
if ($status == "all")
{$estado = "";}
else
{$estado = "WHERE status = 1";}
}
if (in_array ($sort, oob_user::getOrders()))
$sortby = "ORDER BY $sort";
else
$sortby = "ORDER BY uname";
$savem= $ari->db->SetFetchMode(ADODB_FETCH_NUM);
$sql= "SELECT id FROM oob_user_user $estado $sortby";
$rs = $ari->db->Execute($sql);
$ari->db->SetFetchMode($savem);
if ($rs && !$rs->EOF) { // aca cambie sin probar, hay q ver si anda!
while (!$rs->EOF) {
$return[] = new oob_user ($rs->fields[0]);
$rs->MoveNext();
}
$rs->Close();
} else
{return false;}
return $return;
}
/** Shows the available sorting ways for users */
static public function getOrders()
{
$return[] = "uname";
$return[] = "id";
$return[] = "email";
$return[] = "status";
return $return;
}
/** Shows the available status for users, or all */
static public function getMethods()
{
$return[] = "enabled";
$return[] = "deleted";
$return[] = "pending";
$return[] = "bloqued";
$return[] = "all";
return $return;
}
/** Shows the user status or all available status
* $one = ID or "status_string" returns the user status; or "ALL" to return an array.
* $id => if true, returns a number, else a string.
* */
static public function getStatus ( $one = "ALL" ,$id = true)
{ // 0 neeeds auth, 1 ok, 2 temp block, 9 deleted
$return[1] = "enabled";
$return[2] = "bloqued";
$return[0] = "pending";
$return[9] = "deleted";
if ($id != true)
$return = array_flip ($return);
if ($one !== "ALL")
{
if ($return[$one] !== "" )
{$return = $return[$one];}
else
{$return = false;}
}
return $return;
}
/** Updates a given array of users (id), with the status provided. */
static public function updateStatusFor ($data, $status = false)
{
if (!in_array($status, oob_user::getMethods()))
{throw new OOB_exception("User gave a POST value that is unexistant", "403", "Información inválida desde el Usuario", true);}
foreach ($data as $usuario)
{
$new = new oob_user ($usuario);
if (OOB_validatetext::isNumeric($status))
{$new->set ('status', $status);}
else
{$new->set ('status', oob_user::getStatus($status, false));}
if (!$new->store())
{throw new OOB_exception("System Error - STATUS:{$status} is invalid", "501", "System Error", true);}
}
}
/** Fills the user with the DB data */
private function fill ()
{
global $ari;
//load info
$savem= $ari->db->SetFetchMode(ADODB_FETCH_ASSOC);
$sql= "SELECT Uname, Password, Email, Connections, Status, EmployeeID
FROM OOB_User_User
WHERE id = '$this->user'";
$rs = $ari->db->Execute($sql);
$ari->db->SetFetchMode($savem);
if (!$rs || $rs->EOF)
{
return false;
}
if (!$rs->EOF)
{
$this->uname= $rs->fields["Uname"];
$this->password= -1;
$this->email= $rs->fields["Email"];
$this->maxcon= $rs->fields["Connections"];
$this->status= $rs->fields["Status"];
if (!empty($rs->fields['EmployeeID']) && OOB_validatetext :: isNumeric($rs->fields['EmployeeID']) && $rs->fields['EmployeeID'] > ID_MINIMAL)
{ $this->employee = new personnel_employee($rs->fields['EmployeeID']); }
}
$rs->Close();
return true;
}
/** gets the amout of failed login attemps for a given user-id, with a block time */
private function getFailed ($userid, $blocktime){
global $ari;
$userid = $ari->db->qMagic ($userid);
$savem = $ari->db->SetFetchMode(ADODB_FETCH_NUM);
$block = $ari->db->DBTimeStamp(time() - $blocktime );
$sql= "SELECT count(id) as cuenta FROM oob_user_failed WHERE timestamp > $block AND user_id = $userid";
$ari->db->SetFetchMode($savem);
$rs = $ari->db->Execute($sql);
$cuenta = 0;
if (!$rs->EOF) {
$cuenta = $rs->fields[0];
$rs->Close();
}
return $cuenta;
}
/** logs a failed attempted login to the Db for a given user */
private function addFailed ($userid, $message = "UNDEFINED")
{
global $ari;
$now = $ari->db->DBTimeStamp(time());
$msg = $ari->db->qMagic ($message);
$sql = "INSERT INTO oob_user_failed ( user_id, timestamp , reason )
values ('$userid',$now,$msg)";
if ($ari->db->Execute($sql) === false)
throw new OOB_exception("Error en DB: {$ari->db->ErrorMsg()}", "010", "Error en la Base de Datos", false);
}
/** Devuelve true si ya existe el nombre de usuario pasado como parametro */
static public function exists ($uName, $clausula = '')
{
global $ari;
$uName = $ari->db->qMagic(trim($uName));
$savem= $ari->db->SetFetchMode(ADODB_FETCH_ASSOC);
$sql= "SELECT True as Existe
FROM OOB_User_User
WHERE Uname = $uName $clausula";
$rs = $ari->db->Execute($sql);
$ari->db->SetFetchMode($savem);
if (!$rs->EOF && $rs->fields['Existe'])
{ $return = true; }
else
{ $return = false; }
$rs->Close();
return $return;
}
/**
* Esta funcion valida q los empleados q vienen en el string existan
* el formato de la cadena es la siguiente
* LastNameEmployee1, FirstNameEmployee1 EMPLOYEE_SEPARATOR LastNameEmployee2, FirstNameEmployee2......
* La funcion devuelve un array con los usuarios correspondientes a los empleados q se encontraron,
* en caso de q un empleado no exista su lugar en el array lo ocupara un valor booleano false
*/
static public function getUsersByString( $string )
{
$users = array();
$string = trim($string);
$i = 0;
if ($string == "")
{ return false; }
//creo un array con los nombres y apellidos de los empleados
$array_employee = explode(EMPLOYEE_SEPARATOR,$string);
if (! is_array($array_employee) )
{
$array_employee = array();
$array_employee[0] = $string;
}//end if
//recorro el array y separo los nombres y los apellidos
foreach($array_employee as $e)
{
$e = trim($e);
if ($e != "")
{
//busco la posicion del separador de nombres
$pos_coma = strpos ($e, NAME_SEPARATOR);
if ($pos_coma)
{ //encontro la posicion
$lastName = trim(substr($e,0,$pos_coma));
$firstName = trim(str_replace( NAME_SEPARATOR, "", substr($e,$pos_coma+1,strlen($e)-1)));
}
else
{
//ver q pasa si no tiene coma
$lastName = $e;
$firstName = '';
}//end if
$users[$i]['employeename'] = $lastName ." ". $firstName;
$users[$i]['object'] = OOB_User :: getUserByEmployeeName($lastName, $firstName);
$i++;
}//end if
}//end foreach
return $users;
}//end fucntion
/** Retorna el usuario cuyo empleado tiene el nombre y apellido
* pasado por parametro
*/
static public function getUserByEmployeeName ($lastName = '',$firstName = '' )
{
global $ari;
if ( $lastName == '' && $firstName == '' )
{ return false; }
//load info
$savem= $ari->db->SetFetchMode(ADODB_FETCH_ASSOC);
$firstName = trim($ari->db->qMagic($firstName));
$lastName = trim($ari->db->qMagic($lastName));
$sql = "SELECT `OOB_User_User`.`ID` AS `UserID`, `OOB_User_User`.`Uname`,
`OOB_User_User`.`Password`, `OOB_User_User`.`Email`,
`OOB_User_User`.`Connections`, `OOB_User_User`.`Status` AS `UserStatus`,
`OOB_User_User`.`EmployeeID`, `Personnel_Employee`.`LastName`,
`Personnel_Employee`.`FirstName`, `Personnel_Employee`.`BirthDate`,
`Personnel_Employee`.`EmployeeNumber`, `Personnel_Employee`.`Description`,
`Personnel_Employee`.`Status` AS `EmployeeStatus`
FROM `Personnel_Employee`, `OOB_User_User`
WHERE `OOB_User_User`.`EmployeeID` = `Personnel_Employee`.`ID`
AND `Personnel_Employee`.`LastName` = $lastName
AND `Personnel_Employee`.`FirstName` = $firstName
AND `Personnel_Employee`.`Status` = '" . USED . "'";
$rs = $ari->db->SelectLimit($sql,1,0);
$ari->db->SetFetchMode($savem);
if (!$rs || $rs->EOF)
{ $return = false; }
else
{
$return = new oob_user (ID_UNDEFINED);
$return->user = $rs->fields["UserID"];
$return->uname = $rs->fields["Uname"];
$return->password = $rs->fields["Password"];
$return->email = $rs->fields["Email"];
$return->maxcon = $rs->fields["Connections"];
$return->status = $rs->fields["UserStatus"];
$employee = new personnel_employee(ID_UNDEFINED);
$employee->set("id",$rs->fields["EmployeeID"]);
$employee->set("lastName", $rs->fields["LastName"]);
$employee->set("firstName",$rs->fields["FirstName"]);
$employee->set("birthDate", new Date($rs->fields['BirthDate']) );
$employee->set("employeeNumber", $rs->fields["EmployeeNumber"]);
$employee->set("description", $rs->fields["Description"]);
$employee->set("status",$rs->fields["EmployeeStatus"]);
$return->employee = $employee;
}//end if
$rs->Close();
return $return;
}//end function
/** Linkea con el grupo standard para usuarios que se generan solo,'
* y hace falta q pertenezcan a algun lado para darles permisos, vio?
*/
public function linkStandardGroup ()
{
global $ari;
$id_grupo = $ari->get("config")->get('new-group', 'user');
$grupo = new seguridad_group ($id_grupo);
$grupo->addUser ($this );
}
}//end class
?>