aboutsummaryrefslogtreecommitdiff
path: root/admin/Library/Users/CheckAdmin.php
diff options
context:
space:
mode:
Diffstat (limited to 'admin/Library/Users/CheckAdmin.php')
-rwxr-xr-xadmin/Library/Users/CheckAdmin.php369
1 files changed, 369 insertions, 0 deletions
diff --git a/admin/Library/Users/CheckAdmin.php b/admin/Library/Users/CheckAdmin.php
new file mode 100755
index 0000000..9a47b16
--- /dev/null
+++ b/admin/Library/Users/CheckAdmin.php
@@ -0,0 +1,369 @@
+<?php
+
+// All EasyGiant code 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, either version 3 of the License, or (at your option) any later version.
+// See COPYRIGHT.txt and LICENSE.txt.
+
+if (!defined('EG')) die('Direct access not allowed!');
+
+class Users_CheckAdmin {
+
+ public $status = array();
+
+ protected $_sessionsTable; //table containing all the sessions
+ protected $_usersTable; //table containing all the users
+ protected $_groupsTable; //table containing all the groups
+ protected $_manyToManyTable; //table for many to many relationships
+ protected $_accessesTable; //table containing all the accesses to admin side
+ protected $uid = null;
+ protected $_token = null; //token used in order to defense against CSRF (cross sire request forgeries)
+ protected $_login; //login action
+ protected $_main; //main action
+ protected $_retype; //retype (the password) action
+ protected $_db; //reference to the database layer class
+ protected $_params = array(); //the parameters of the object
+
+ public function __construct($params = null) {
+ $this->_params = $params;
+
+ $this->_sessionsTable = $params['sessionsTable'];
+ $this->_usersTable = $params['usersTable'];
+ $this->_groupsTable = $params['groupsTable'];
+ $this->_manyToManyTable = $params['manyToManyTable'];
+ $this->_accessesTable = $params['accessesTable'];
+ $this->_login = Url::getRoot(null) . $params['users_controller'] . '/' . $params['users_login_action'] ;
+ $this->_main = Url::getRoot(null) . $params['panel_controller'] . '/' . $params['panel_main_action'] ;
+ $this->_retype = Url::getRoot(null) . $params['users_controller'] . '/' . $params['hijacking_action'] ;
+ $this->_db = Factory_Db::getInstance($params['database_type']);
+ }
+
+ private function acquireCookie() { #obtain cookie
+ #cookie
+ $this->uid = NULL;
+ global $_COOKIE;
+ $this->uid = isset($_COOKIE[$this->_params['cookie_name']]) ? sanitizeAlnum($_COOKIE[$this->_params['cookie_name']]) : null;
+ }
+
+ private function cleanSessions()
+ {
+ #cancello le sessioni scadute
+ $row = $this->_db->select($this->_sessionsTable,'creation_date',"uid='".$this->uid."'");
+ if ($row)
+ {
+ if ($row[0][$this->_sessionsTable]['creation_date'])
+ {
+ if($row[0][$this->_sessionsTable]['creation_date'] + $this->_params['session_expire'] <= time())
+ {
+ setcookie($this->_params['cookie_name'],'',time()-3600,$this->_params['cookie_path']);
+ }
+ }
+ }
+ $this->_db->del($this->_sessionsTable,"creation_date + " . $this->_params['session_expire'] . " <= ".time());
+ }
+
+ public function checkStatus()
+ { #controlla se l'utente è già loggato
+ $this->acquireCookie(); #ottengo il cookie
+ $this->cleanSessions(); #elimino le sessioni vecchie
+ $row=$this->_db->select($this->_usersTable.','.$this->_sessionsTable,$this->_usersTable.'.id_user,username,token,user_agent',$this->_usersTable.".id_user=".$this->_sessionsTable.".id_user and uid='".$this->uid."'");
+ if (count($row) === 1 and $row !== false)
+ {
+ $this->status['user']=$row[0][$this->_usersTable]['username'];
+ $this->status['status']='logged';
+ $this->status['id_user']=$row[0][$this->_usersTable]['id_user'];
+ $this->status['user_agent'] = $row[0][$this->_sessionsTable]['user_agent'];
+ $this->status['token'] = $row[0][$this->_sessionsTable]['token'];
+ $this->obtainGroups();
+ } else {
+ $this->status['user']='sconosciuto';
+ $this->status['status']='not-logged';
+ $this->status['id_user']='';
+ $this->status['user_agent']='';
+ $this->status['token'] = '';
+ $this->status['groups'] = array();
+ }
+ }
+
+ public function redirect($val,$time = 3) { #fa il redirect dell'utente
+ if ($val === 'logged') {
+ header('Refresh: '.$time.';url='.$this->_main);
+ if ($time !== 0) echo "You are already logged, ".$this->status['user']."..";
+ } else if ($val === 'accepted') {
+ header('Refresh: '.$time.';url='.$this->_main);
+ if ($time !== 0) echo "Hi ".$this->status['user']."..";
+ } else if ($val === 'login-error') {
+ header('Refresh: '.$time.';url='.$this->_login);
+ if ($time !== 0) echo "Wrong username or password...";
+ } else if ($val === 'not-logged') {
+ header('Refresh: '.$time.';url='.$this->_login);
+ if ($time !== 0) echo "Limited access... sorry";
+ } else if ($val === 'not-authorized') {
+ header('Refresh: '.$time.';url='.$this->_main);
+ if ($time !== 0) echo "Your account doesn't allow you to manage this page.. sorry!";
+ } else if ($val === 'stolen') {
+ header('Refresh: '.$time.';url='.$this->_login);
+ if ($time !== 0) echo "Your session have been probably intercepted! Please login another time.";
+ } else if ($val === 'retype') {
+ header('Refresh: '.$time.';url='.$this->_retype);
+ if ($time !== 0) echo "Your session have been probably intercepted. Please type your password another time.";
+ } else if ($val === 'wait') {
+ header('Refresh: '.$time.';url='.$this->_login);
+ if ($time !== 0) echo "You have to wait ".$this->_params['time_after_failure']." seconds before you can try to login another time";
+ }
+ exit;
+ }
+
+ //obtain the group of the user
+ private function obtainGroups()
+ {
+ $tables = $this->_usersTable.','.$this->_groupsTable.','.$this->_manyToManyTable;
+ $fields = $this->_groupsTable.'.name';
+ $where = $this->_usersTable.'.id_user='.$this->_manyToManyTable.'.id_user and '.$this->_groupsTable.'.id_group='.$this->_manyToManyTable.'.id_group and '.$this->_usersTable.'.id_user='.$this->status['id_user'];
+ $groups = $this->_db->select($tables,$fields,$where);
+ $this->status['groups'] = array();
+ foreach ($groups as $group)
+ {
+ $this->status['groups'][] = $group[$this->_groupsTable]['name'];
+ }
+ }
+
+ //$groups: string with name of groups separated by comma; ex: base,root,users
+ public function checkAccess($groups)
+ {
+ $groupsArray = explode (',',$groups);
+ foreach ($this->status['groups'] as $group)
+ {
+ if (in_array($group,$groupsArray)) return true;
+ }
+ return false;
+ }
+
+ //check that the user is logged and, if present, check the group of the user (if loggeg)
+ //$groups: comma-separated list of groups whose users can access the page
+ //$time: time before the redirect is carried out
+ public function check($groups = null, $time = 3)
+ {
+ $this->checkStatus();
+ if (strcmp($this->status['status'],'not-logged') === 0)
+ {
+ $this->redirect('not-logged',$time);
+ }
+ else if (strcmp($this->status['status'],'logged') === 0)
+ {
+ if ($this->_params['hijacking_check'])
+ {
+ if (!$this->checkHijacking())
+ {
+ if ($this->_params['on_hijacking_event'] === 'forceout')
+ {
+ $this->logout();
+ $this->redirect('stolen',$time);
+ }
+ else if ($this->_params['on_hijacking_event'] === 'redirect')
+ {
+ $this->redirect('retype',$time);
+ }
+ }
+ }
+// $this->obtainGroups();
+ if (isset($groups))
+ {
+ $permission = $this->checkAccess($groups);
+ if (!$permission) $this->redirect('not-authorized',$time);
+ }
+ }
+ }
+
+ //check if someone have stolen your uid
+ private function checkHijacking()
+ {
+ if (array_key_exists('user_agent',$this->status))
+ {
+ if (strcmp($this->status['user_agent'],'') !== 0)
+ {
+ if (strcmp($this->status['user_agent'],getUserAgent()) === 0)
+ {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ //check CSRF
+ //$token: token to check
+ public function checkCSRF($token)
+ {
+ if (strcmp($this->status['token'],'') !== 0)
+ {
+ if (strcmp($this->status['token'],$token) === 0)
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ //get an array containing all the users currently logged
+ public function getUsersLogged()
+ {
+ $usersLogged = array();
+ $data=$this->_db->select($this->_usersTable.','.$this->_sessionsTable,'DISTINCT '.$this->_usersTable.'.username',$this->_usersTable.".id_user=".$this->_sessionsTable.".id_user");
+ foreach ($data as $row)
+ {
+ $usersLogged[] = $row[$this->_usersTable]['username'];
+ }
+ return $usersLogged;
+ }
+
+ //get the password of the current user
+ public function getPassword()
+ {
+ $row=$this->_db->select($this->_usersTable,'password',"id_user=".$this->status['id_user']);
+ if ($row !== false)
+ {
+ return $row[0][$this->_usersTable]['password'];
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ private function checkPassword($user,$pwd) { #check username and password
+
+ if (!in_array($this->_params['password_hash'],Params::$allowedHashFunc))
+ {
+ throw new Exception('Error in '.__METHOD__.' : the hash func has to be '.implode(' or ',Params::$allowedHashFunc));
+ }
+ //calculate the hash of the password
+ $pwd = call_user_func($this->_params['password_hash'],$pwd);
+
+ $row=$this->_db->select($this->_usersTable,$this->_usersTable.'.id_user,username,password',"username=\"".$user."\" and password=\"".$pwd."\" and has_confirmed=0");
+ if (count($row) === 1 and $row !== false)
+ {
+ $this->status['user'] = $row[0][$this->_usersTable]['username'];
+ $this->status['status'] = 'accepted';
+ $this->status['id_user'] = $row[0][$this->_usersTable]['id_user'];
+ }
+ else
+ {
+ $this->status['user'] = 'unknown';
+ $this->status['status'] = 'login-error';
+ $this->status['id_user'] = '';
+ if ($this->_db->recordExists($this->_usersTable,'username',$user))
+ {
+ $this->_db->update($this->_usersTable,'last_failure',array(time()),'username="'.$user.'"');
+ }
+ }
+ }
+
+ //check that enough time is passed since the last failure of the user
+ private function checkLastFailure($user)
+ {
+ //current time
+ $now = time();
+ //max time
+ $max = $now - $this->_params['time_after_failure'];
+ $data = $this->_db->select($this->_usersTable,'last_failure','username="'.$user.'"');
+ if (count($data) === 1 and $data !== false)
+ {
+ if ($data[0][$this->_usersTable]['last_failure'] < $max)
+ {
+ return true;
+ }
+ return false;
+ }
+ else
+ {
+ return true;
+ }
+ }
+
+ public function login($user,$pwd)
+ {
+ $user = sanitizeAll($user);
+ $this->checkStatus();
+ //check if already logged
+ if ($this->status['status'] === 'logged')
+ {
+// $this->redirect('logged');
+ return 'logged';
+ }
+ else
+ {
+ if ($this->checkLastFailure($user))
+ {
+ $this->checkPassword($user,$pwd);
+ if ($this->status['status']==='accepted')
+ {
+ $this->uid = md5(randString(10).uniqid(mt_rand(),true));
+ $this->_token = md5(randString(12));
+ $userAgent = getUserAgent();
+ $this->_db->insert($this->_sessionsTable,'id_user,uid,token,creation_date,user_agent',array($this->status['id_user'],$this->uid,$this->_token,time(),$userAgent));
+ setcookie($this->_params['cookie_name'],$this->uid,0,$this->_params['cookie_path']); #magic cookie
+ $this->updateAccesses();
+
+ $this->_db->del($this->_sessionsTable,'id_user='.$this->status['id_user'].' AND uid != "'.$this->uid.'"');
+
+// $this->redirect('accepted');
+ return 'accepted';
+ }
+ else if ($this->status['status']==='login-error')
+ {
+// $this->redirect('login-error');
+ return 'login-error';
+ }
+ }
+ else
+ {
+// $this->redirect('wait');
+ return 'wait';
+ }
+ }
+// $this->redirect('login-error');
+ return 'login-error';
+ }
+
+ private function updateAccesses()
+ {
+ $ip=getIp(); #ip
+ $date=date('d'). "-" . date('m') . "-" . date('Y'); #date
+ $ora=date('H') . ":" . date('i'); #time
+ $values=array($ip,$date,$ora,$this->status['user']);
+ $res=$this->_db->insert($this->_accessesTable,'ip,data,ora,username',$values);
+ }
+
+ //force out an user
+ //$id: the id of the user
+ public function forceOut($id)
+ {
+ $id = (int)$id;
+ if ($this->_db->del($this->_sessionsTable,'id_user='.$id))
+ {
+ return true;
+ }
+ return false;
+ }
+
+ public function logout()
+ {
+ $this->checkStatus();
+ if ($this->status['status'] === 'logged')
+ {
+ setcookie ($this->_params['cookie_name'], "", time() - 3600,$this->_params['cookie_path']);
+ if ($this->_db->del($this->_sessionsTable,'id_user='.$this->status['id_user']))
+ {
+ return 'was-logged';
+ }
+ else
+ {
+ return 'error';
+ }
+ }
+ else
+ {
+ return 'not-logged';
+ }
+ }
+
+} \ No newline at end of file