<?php
/* libraries/user.php
*
* Copyright (C) by Hugo Leisink <hide@address.com>
* This file is part of the Banshee PHP framework
* http://www.banshee-php.org/
*
* Don't change this file, unless you know what you are doing.
*/
final class user {
private $db = null;
private $settings = null;
private $session = null;
private $id = null;
private $client_ip = null;
private $logged_in = false;
private $record = array();
private $is_admin = false;
/* Constructor
*
* INPUT: object database, object settings, object session
* OUTPUT: -
* ERROR: -
*/
public function __construct($db, $settings, $session) {
$this->db = $db;
$this->settings = $settings;
$this->session = $session;
$this->client_ip = $_SERVER["REMOTE_ADDR"];
if (isset($_SERVER["HTTP_X_FORWARDED_FOR"])) {
$this->client_ip .= "/".$_SERVER["HTTP_X_FORWARDED_FOR"];
}
if (isset($_SESSION["user_id"])) {
if (time() - $_SESSION["last_private_visit"] >= SESSION_TIMEOUT) {
$this->logout();
} else if (($_SESSION["binded_ip"] === NO) || ($_SESSION["binded_ip"] === $this->client_ip)) {
$this->load_user_record($_SESSION["user_id"]);
}
}
}
/* Magic method get
*
* INPUT: string key
* OUTPUT: mixed value
* ERROR: null
*/
public function __get($key) {
switch ($key) {
case "id": return $this->id;
case "logged_in": return $this->logged_in;
case "is_admin": return $this->is_admin;
case "client_ip": return $this->client_ip;
default:
if (isset($this->record[$key])) {
return $this->record[$key];
}
}
return null;
}
/* Store user information from database in $this->record
*
* INPUT: int user identifier
* OUTPUT: -
* ERROR: -
*/
private function load_user_record($user_id) {
if (($this->record = $this->db->entry("users", $user_id)) == false) {
$this->logout();
} else if ($this->record["status"] == USER_STATUS_DISABLED) {
$this->logout();
} else {
$this->id = $user_id;
$this->logged_in = true;
$this->record["role_ids"] = array();
$query = "select role_id from user_role where user_id=%d";
if (($roles = $this->db->execute($query, $this->record["id"])) != false) {
foreach ($roles as $role) {
array_push($this->record["role_ids"], $role["role_id"]);
if ((int)$role["role_id"] === (int)ADMIN_ROLE_ID) {
$this->is_admin = true;
}
}
}
}
}
/* Login user
*
* INPUT: int user id
* OUTPUT: -
* ERROR: -
*/
private function login($user_id) {
$this->logged_in = true;
$this->load_user_record($user_id);
$this->log_action("user logged-in");
$_SESSION["user_id"] = $user_id;
$_SESSION["binded_ip"] = NO;
$_SESSION["last_private_visit"] = time();
$this->session->set_user_id($user_id);
unset($_SESSION["challenge"]);
if ($this->is_admin) {
$_SESSION["slimstatuser"] = true;
}
}
/* Verify user credentials
*
* INPUT: string username, string password, boolean challenge-response method used
* OUTPUT: boolean login correct
* ERROR: -
*/
public function login_password($username, $password, $use_challenge_response_method) {
$query = "select * from users where username=%s and status!=%d limit 1";
if (($data = $this->db->execute($query, $username, USER_STATUS_DISABLED)) == false) {
sleep(1);
return false;
}
$user = $data[0];
if ($use_challenge_response_method) {
if (md5($_SESSION["challenge"].$user["password"]) === $password) {
$this->login((int)$user["id"]);
}
} else {
if ($user["password"] === md5($password)) {
$this->login((int)$user["id"]);
}
}
if ($this->logged_in == false) {
sleep(1);
}
return $this->logged_in;
}
/* Verify one time key
*
* INPUT: string one time key
* OUTPUT: boolean key valid
* ERROR: -
*/
public function login_one_time_key($key) {
if ($key == "") {
return false;
}
if (($user = $this->db->entry("users", $key, "one_time_key")) == false) {
sleep(1);
return false;
}
$query = "update users set one_time_key=null where id=%d";
$this->db->query($query, $user["id"]);
$this->login((int)$user["id"]);
return true;
}
/* Logout current user
*
* INPUT: -
* OUTPUT: -
* ERROR: -
*/
public function logout() {
$this->log_action("user logged-out");
$this->session->reset();
setcookie("slimstatuser");
setcookie("slimstatajax");
$this->id = null;
$this->logged_in = false;
$this->record = array();
$this->is_admin = false;
}
/* Checks if user has access to page
*
* INPUT: string page identifier
* OUTPUT: boolean user has access to page
* ERROR: -
*/
public function access_allowed($page) {
/* Always access
*/
$allowed = array(LOGOUT_MODULE);
if ($this->is_admin || in_array($page, $allowed)) {
return true;
}
/* Public page
*/
if (in_array($page, page_to_module(config_file("public_pages")))) {
return true;
}
/* No roles, no access
*/
if (count($this->role_ids) == 0) {
return false;
}
/* Check access
*/
if (in_array($page, page_to_module(config_file("private_pages")))) {
/* Pages on disk (modules)
*/
$conditions = $rids = array();
foreach ($this->role_ids as $rid) {
array_push($conditions, "id=%d");
array_push($rids, $rid);
}
$query = "select %S from roles where ".implode(" or ", $conditions);
if (($access = $this->db->execute($query, $page, $rids)) == false) {
return false;
}
} else {
/* Pages in database
*/
$conditions = $rids = array();
foreach ($this->role_ids as $rid) {
array_push($conditions, "a.role_id=%d");
array_push($rids, $rid);
}
$query = "select a.level from page_access a, pages p ".
"where a.page_id=p.id and p.url=%s and a.level>0 ".
"and (".implode(" or ", $conditions).")";
if (($access = $this->db->execute($query, "/".$page, $rids)) == false) {
return false;
}
}
return max(array_flatten($access)) > 0;
}
/* Bind current session to IP address
*
* INPUT: -
* OUTPUT: -
* ERROR: -
*/
public function bind_to_ip() {
$_SESSION["binded_ip"] = $this->client_ip;
}
/* Verify if user has a certain role
*
* INPUT: int role identifier / string role name
* OUTPUT: boolean user has role
* ERROR: -
*/
public function has_role($role) {
if (is_int($role)) {
return in_array($role, $this->role_ids);
} else if (is_string($role)) {
if (($entry = $this->db->entry("roles", $role, "name")) != false) {
return $this->has_role((int)$entry["id"]);
}
} else if (is_array($role)) {
foreach ($role as $item) {
if ($this->has_role($item)) {
return true;
}
}
}
return false;
}
/* Log user action
*
* INPUT: string action
* OUTPUT: -
* ERROR: -
*/
public function log_action($action) {
if (func_num_args() > 1) {
$args = func_get_args();
array_shift($args);
$action = vsprintf($action, $args);
}
$mesg = $_SERVER["REMOTE_ADDR"]."|".date("D d M Y H:i:s")."|";
if ($this->logged_in == false) {
$mesg .= "-";
} else if (isset($_SESSION["user_switch"]) == false) {
$mesg .= $this->id;
} else {
$mesg .= $_SESSION["user_switch"].":".$this->id;
}
$mesg .= "|".$action."\n";
if (($fp = fopen("../logfiles/actions.log", "a")) != false) {
fputs($fp, $mesg);
fclose($fp);
}
}
}
?>