<?php
// TMS Rewritten - Early 2010
// By Joseph Robert Gillotti
defined('in_tms') or exit; // Anti inclusion hack
// User management
class Ui {
/*
* These pertain to a logged in user
*/
private
$user = array(), // Array of their info
$_logged_in = false,
$verif_key,
$verif_val;
/*
* Overall and Daily hits
*/
public
$hits = array();
/*
* Start us off
*/
function __construct() {
global $layout;
// Log us in
$this->manageSession();
// Are we banned?
if ($this->isBanned()) {
$layout->errorMsgMinimal('You are banned.');
exit; // Redundantly prevent anything more
}
}
/*
* Get contents of login cookie
*/
private function loginCookieGet() {
global $login_remember_cookie;
// Does it not exist?
if (!isset($_COOKIE[$login_remember_cookie]) || trim($_COOKIE[$login_remember_cookie]) == '')
return false;
// Get it's parts
list($uid, $pw) = explode('_', trim($_COOKIE[$login_remember_cookie]), 2);
// Are they okay?
if (!ctype_digit($uid) || strlen($pw) != 32) {
return false;
}
// They might be good, return vals
return array('uid' => $uid, 'pw' => $pw);
}
/*
* Scrap login cookie
*/
public function loginCookieScrap() {
global $login_remember_cookie;
if (isset($_COOKIE[$login_remember_cookie]))
setcookie($login_remember_cookie, '', time() - 5000);
}
/*
* Attempt to auth
*/
private function manageSession() {
global $sql, $sp;
// First of all, see if we have a login cookie
// It's contents will overwrite the session value if different
$loginCookie = $this->loginCookieGet();
// It okay? Replace session vals with it
if (is_array($loginCookie)) {
$_SESSION['uid'] = $loginCookie['uid'];
$_SESSION['pass'] = $loginCookie['pw'];
}
// See if session variables are okay. If not, stop here
if (!ctype_digit($_SESSION['uid']) || strlen($_SESSION['pass']) != 32)
return;
// Localize
$sess_uid = $sql->prot($_SESSION['uid']);
$sess_pass = $sql->prot($_SESSION['pass']);
// Might be satisfactory, test
$check_user = $sql->query("
select
`id`,
`username`,
`banned`,
`pending`,
`theme`,
`timezone_offset`,
`nobwfilter`,
`nummaps`
from
`members`
where
`id` = '$sess_uid' and
`password` = '$sess_pass'
limit 1
");
// No?
if ($sql->num($check_user) == 0) {
$this->killSession();
}
// Yes we have a match; get values
list(
$this->user['uid'], $this->user['username'], $this->user['banned'], $this->user['pending'],
$this->user['theme'], $this->user['timezone_offset'], $this->user['filter_badwords'], $this->user['num_maps']
)
= $sql->fetch_row($check_user);
// And we're logged in, btw
$this->_logged_in = true;
// Deal with user verification shiz
$this->setUserVerification();
// Useful when called in a long fucking loop to avoid the overhead of a function call ($ui->userID);
define('USER_ID', $this->user['uid']);
// Reference later on
$sql->query("update `members` set `lastaction` = unix_timestamp(), `lastip` = '{$_SERVER['REMOTE_ADDR']}' where `id` = '{$this->user['uid']}' limit 1");
}
/*
* Values that are limited to this session and this user
*/
private function setUserVerification() {
// Need to be logged in to be of any use
if (!$this->_logged_in)
return;
// Make them random but constant. Key must start with a non-number.
$this->verif_key = 'k'.substr(sha1(md5($this->user['uid'].session_id())), 1, 15);
$this->verif_val = sha1(md5(serialize($this->user).md5($this->user['uid'].session_id())));
// Any scope access
define('VERIF_KEY', $this->verif_key);
define('VERIF_VAL', $this->verif_val);
}
/*
* Get vals for above
*/
public function verifKey() {
return $this->_logged_in ? $this->verif_key : false;
}
/*
* Get key for above
*/
public function verifVal() {
return $this->_logged_in ? $this->verif_val : false;
}
/*
* Are we verified?
*/
public function isVerified() {
// If we're not logged in, definitely not
if (!$this->_logged_in) {
return false;
}
// If a POST or GET value is our key. Not a val in session and definitely not in a cookie
return $_POST[$this->verifKey] == $this->verifVal() || $_GET[$this->verifKey()] == $this->verifVal();
}
/*
* Log us out
*/
public function killSession() {
// Kill possible login values
$this->loginCookieScrap();
unset($_SESSION['uid'], $_SESSION['pass']);
// Set us logged out.
$this->_logged_in = false;
// Make sure use array is empty
$this->user = false;
}
/*
* Am I banned?
*/
public function isBanned() {
global $sql;
// Check if user is banned
if ($ui->_logged_in) {
return $this->user['banned'] == '1';
}
// Check if IP is banned
//$ip_check = $sql->query("select null from `` where `ip` = '' limit 1");
}
/*
* Is current user a bot?
*/
function isBot() {
// Some bots do not have a user agent
if (trim($_SERVER['HTTP_USER_AGENT']) == '')
return true;
// Others are typical:
$bots = array(
'googlebot',
'yahoo',
'msn',
'search',
'bot',
'index',
'load',
'Charlotte',
'crawl',
'Mediapartners',
'feed',
'fetch',
'spider',
'bot',
'yandex',
'lwp\-request',
'W3C',
'krawl',
'PHP\/SMF',
'alexa');
// Go for it:
return (bool) preg_match('/'.implode('|', $bots).'/i', $_SERVER['HTTP_USER_AGENT']);
}
/*
* Handle stats
*/
public function track() {
global $sql;
// Make sure we aren't a bot
if ($this->isBot())
return;
// Make sure current IP is in the list
$sql->query("insert ignore into `hits_ip` set `ip` = '{$_SERVER['REMOTE_ADDR']}'");
// Deal with daily IP's
$sql->query("insert ignore into `hits_daily` set `day` = curdate(), `ip` = '{$_SERVER['REMOTE_ADDR']}', `useragent` = '".$sql->prot($_SERVER['HTTP_USER_AGENT'])."'");
// Delete older daily ip's
$sql->query("delete from `hits_daily` where `day` < curdate()");
// Get current hits
$get_hits = $sql->query("
select
(select count(`ip`) from `hits_ip`),
(select count(`ip`) from `hits_daily` where `day` = curdate())");
// Set them
list($this->hits['overall'], $this->hits['today']) = $sql->fetch_row($get_hits);
// Free that ram
$sql->free($get_hits);
}
/*
* Functions used all over the place to test stuff
*/
public function loggedIn() {
return (bool) $this->_logged_in;
}
public function userID() {
return $this->_logged_in ? (int) $this->user['uid'] : false;
}
public function userName() {
return $this->_logged_in ? stripslashes($this->user['username']) : false;
}
public function userActivated() {
return $this->_logged_in ? $this->user['pending'] == '0' : false;
}
public function userAdmin() {
global $site_admins;
return $this->_logged_in ? in_array($this->user['uid'], $site_admins) : false;
}
public function userTheme() {
return $this->_logged_in ? $this->user['theme'] : (ctype_digit(@$_SESSION['theme']) ? $_SESSION['theme'] : 0);
}
public function userAvatar() {
return $this->_logged_in ? (file_exists($this->user['avatar']) ? $this->user['avatar'] : 'theme/default_ave.png') : 'theme/default_ave.png';
}
/*
* Change my theme
*/
public function changeTheme($desired_theme) {
global $sql;
// Sanity check
if (!ctype_digit($desired_theme))
return false;
// If we're logged in, change user pref
if ($this->loggedIn()) {
$sql->query("update `members` set `theme` = '$desired_theme' where `id` = '".$this->userID()."' limit 1");
}
// Otherwise, save it to session
else {
$_SESSION['theme'] = $desired_theme;
}
}
}
/*
* Get a user id from a username
*/
function username2uid($username) {
// Avoid doing the same one more than once
static $cache = array();
// Gain access to SQL and current user id
global $sql, $ui;
// Safety first
$username = $sql->prot(trim($username));
// Ugh
if ($username == '')
return false;
// First off, is this cached?
if (array_key_exists($username, $cache))
return $cache[$username];
// Is it me?
if ($ui->loggedIn() && $ui->userName() == $username)
return $ui->userID();
// No. Search for it. :P
$get = $sql->query("select `id` from `members` where `username` = '$username' limit 1");
// Nothing?
if ($sql->num($get) == 0) {
$sql->free($get);
return false;
}
// Got it.
list($uid) = $sql->fetch_row($get);
// Free ram
$sql->free($get);
// Cache it so we don't repeat ourselves next time
$cache[$username] = $uid;
// Return it, finally
return $uid;
}
/*
* Get a user name from a user id, while validating the id
*/
function uid2username($userid) {
// Avoid doing the same one more than once
static $cache = array();
// Gain access to SQL and current user id
global $sql, $ui;
// Ugh
if (!ctype_digit($userid) && $userid > 0)
return false;
// First off, is this cached?
if (array_key_exists($userid, $cache))
return $cache[$userid];
// Is it me?
if ($ui->loggedIn() && $ui->userID() == $userid)
return $ui->userName();
// No. Search for it. :P
$get = $sql->query("select `username` from `members` where `id` = '$userid' limit 1");
// Nothing?
if ($sql->num($get) == 0) {
$sql->free($get);
return false;
}
// Got it.
list($username) = $sql->fetch_row($get);
// Free ram
$sql->free($get);
// Cache it so we don't repeat ourselves next time
$cache[$userid] = stripslashes($username);
// Return it, finally
return $username;
}