<?php

/*
 *	W-AGORA 4.0
 *	-----------
 *	$Id: auth.php,v 1.54 2005/12/21 14:19:43 mdruilhe Exp $
 *	 Usage:		Authentication class
 *	 Author:	Marc Druilhe <mdruilhe@w-agora.com>
 */

$cookie_expire = time()+ 90*24*60*60;	// 90 days

if (defined('_AUTH')) return;

  define('_AUTH', 1);

# Privilege levels
# ----------------

define('UNKNOWN', -1);
define('USER',  0);
define('MODER', 1);
define('ADMIN', 2);
define('ROOT',  3);

class wa_Auth {

var $type;		// user privilege
var $userid;	// user login
var $level;		// privilege level
var $user;		// user informations array
var $privs;		// current permissions (current forum)
var $perms = array();	// permissions cache

# generate a random password
# --------------------------
 function genPassword () {

	list($usec, $sec) = explode(' ', microtime()); 
	$seed = (float) $sec + ((float) $usec * 100000); 
	srand($seed);
	$passet = 'abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ23456789';
	$max_rand = strlen($passet)-1;
	for ($i = 0; $i < 6; $i++) {
		$random_num = rand(0, $max_rand);
# Added for buggy rand() functions
		if ($random_num > $max_rand) {
			$random_num = $random_num % $max_rand;
		}
		$pass .= $passet[$random_num];
	}
	return $pass;
 }

# 'LOGOUT' this user -> reset the cookies
# -------------------------------------------------------------
 function logout ($site) {
	@setCookie ("WAP_${site}_auth", '', 0, '/');
	@setCookie ("${site}_auth", '', 0, '/');
	@setCookie ('agora_auth', '', 0, '/');
	$GLOBALS['is_authenticated'] = false;
 }

# present login form to the user
# display the forum form defined in $bn_login_form if it exists
# else displays a default form
# -------------------------------------------------------------
 function login ($site, $title='', $form_action='', $form_template='') {
	global $ext, $lang;
	global $bn, $bn_dir, $bn_dir_default, $bn_login_form;
	global $frameset;
	global $register_url, $register_text, $register_link;

	beginForm ($form_action);
	unset($form_action);
	hiddenField ('loginform', '1');

# carry on all variables passed to the URL (needs PHP_track_vars enabled)
# -----------------------------------------------------------------------
	if (is_array($_GET)) {
		foreach ($_GET as $k => $v) {
			if (isset($$k)) {
				continue;
			} elseif (is_array($v)) {
				foreach ($_GET[$k] as $ak => $av) {
					$$k[$ak] = strip_magic_quotes($av);
					hiddenField("$k"."[$ak]", $$k[$ak]);
				}
			} elseif (!empty($v) && ($k != 'force_login') && ($k != 'loginpassword') ) {
				$$k = strip_magic_quotes($v);
				hiddenField($k, $$k);
			}
		}
	}

	if (is_array($_POST)) {
		foreach ($_POST as $k => $v) {
			if (isset($$k)) {
				continue;
			} elseif (is_array($v)) {
				foreach ($_POST[$k] as $ak => $av) {
					$$k[$ak] = strip_magic_quotes($av);
					hiddenField("$k"."[$ak]", $$k[$ak]);
				}
			} elseif (!empty($v) && ($k != 'force_login') && ($k != 'loginpassword') ) {
				$$k = strip_magic_quotes($v);
				hiddenField($k, $$k);
			}
		}
	}
	$change_password_url = "change_password.$ext?site=$site&bn=$bn";
	$forgot_password_url = "forgot_password.$ext?site=$site&bn=$bn";

	if ( isset($GLOBALS["loginform"]) ) {
	    $msg_login = sprintf(ERROR_INVALID_LOGIN, $site);
	} elseif (!empty($title) ) {
	    $msg_login = $title;
	} else {
	    $msg_login = sprintf(LABEL_PLEASE_LOGIN, $site);
	}

	$form_title = sprintf(LABEL_SITE_LOGIN, $site);
	$title1 = "<center>$msg_login</center><br>";	// for backward compatibility with old templates :
	$keepalive_checkbox = getCheckBox ('keepalive', '1', '1', LABEL_KEEP_ALIVE);
	$submit_button = getSubmitButton ('btnlogin', LABEL_DO_LOGIN);

	$loginuser = empty($loginuser) ? "" : htmlentities($loginuser);
	$input_userid = getTextField ('loginuser', $loginuser, 32, 32);
	$input_password = getPasswordField ('loginpassword', $loginpassword, 32, 32);

	if (!empty($form_template) && file_exists("$form_template") ) {
		include "$form_template";
	} elseif (!empty($bn_login_form) && file_exists("${bn_dir}/${bn_login_form}") ) {
		include "${bn_dir}/${bn_login_form}";
	} elseif ( file_exists("${bn_dir_default}/login_form.$ext") ) {
		include "${bn_dir_default}/login_form.$ext";
	} else {
		include "templates/admin/login_form.$ext";
	}
	endForm();
 }

 function authenticate ($userid='', $clearpw='', $encryptedpw='', $site='') {
	global $db;

	$this->userid = 'guest';
	$this->type = 'unregistered';
	$this->level = UNKNOWN;
	unset ($this->user);

	$this->privs = array ('modpriv' => 0, 'listpriv' => 0, 'readpriv' => 0, 'writepriv' => 0);

	$setcookie=false;
	$site = (empty($site) ) ? $GLOBALS['site'] : $site;

# 1 -- Get Login info parameters in that order:
#				function arguments
#				w-agora Login Form
#				w-agora cookies
#				user defined
# --------------------------------------------------------
	if ( ! empty($userid) ) {
#		1. Take user/password from function arguments
#		---------------------------------------------
		$setcookie=true;

	} elseif (isset ($_POST['loginform']) ) {
#		2. Take user/password from login form
#		-------------------------------------
		$this->logout ($site);
		$userid = htmlspecialchars(strip_magic_quotes($_POST['loginuser']));
		$clearpw = strip_magic_quotes($_POST['loginpassword']);
		$setcookie=true;

	} elseif (isset($_COOKIE["${site}_auth"]) ) {
#		3. Take user/password from session cookie
#		-----------------------------------------
		$pairs = split ('&', strip_magic_quotes($_COOKIE["${site}_auth"]));
		reset($pairs);
		while (list (,$pair) = each ($pairs) ) {
			$pair = split ('=', $pair);
			$var = $pair[0];
			$$var = urldecode($pair[1]);
		}
		$userid=$uid;
		$encryptedpw=$pw;

	} elseif (isset($_COOKIE["WAP_${site}_auth"]) ) {
#		4. Take user/password from permanent cookie
#		------------------------------------------
		$pairs = split ('&', strip_magic_quotes($_COOKIE["WAP_${site}_auth"]));
		reset($pairs);
		while (list (,$pair) = each ($pairs) ) {
			$pair = split ('=', $pair);
			$var = $pair[0];
			$$var = urldecode($pair[1]);
		}
		$userid=$uid;
		$encryptedpw=$pw;
		$setcookie=true;

	} elseif (isset($_COOKIE['agora_auth']) ) {
#		5. Check if user is authenticated at global level (sysadmin)
#		---------------------------------------------------------
		$pairs = split ('&', strip_magic_quotes($_COOKIE['agora_auth']));
		reset($pairs);
		while (list (,$pair) = each ($pairs) ) {
			$pair = split ('=', $pair);
			$var = $pair[0];
			$$var = urldecode($pair[1]);
		}
		$userid=$uid;
		$encryptedpw=$pw;
		$setcookie=true;

	} else {
#		6. Get site specific user login info
#		------------------------------------
		$logininfo = $this->getLoginInfo();
		if (!is_array ($logininfo)) {
			return false;
		}
		$userid = $logininfo['userid'];
		$encryptedpw = $logininfo['encryptedpw'];
		$clearpw = $logininfo['clearpw'];
		$setcookie=true;
	}
# 2 -- authenticate the user and retreive user information
# --------------------------------------------------------
	if ($userid == 'admin') {
		#admin user should always authenticate against the agora DB
		$encryptedpw = (empty($clearpw)) ? $encryptedpw : md5($clearpw);
		$this->user = $db->getUser($site, $userid);
		if (!is_array ($this->user)) {
			return false;
		}
		if ($encryptedpw != $this->user['password']) {
			return false;
		}
	} else {
		#authenticate against the user source for this site
		$encryptedpw = (empty($clearpw)) ? $encryptedpw : $this->encryptPassword($clearpw);
		if (!$this->authenticateUser($site, $userid, $encryptedpw)) {
			return false;
		};
	}

	$this->userid = $this->user['userid'];
	$this->type = $this->user['userpriv'];
	$this->state = (isset($this->user['state'])) ? $this->user['state'] : 1;
	switch ($this->user['userpriv']) {
		case 'root':
			$this->level = ROOT;
			break;
		case 'admin':
			$this->level = ADMIN;
			break;
		case 'moder':
			$this->level = MODER;
			break;
		case 'user':
			$this->level = USER;
			break;
		default:
			$this->level = UNKNOWN;
			break;
	}

# 3 -- If it is a new w-agora session, then update user stats and infos
# ---------------------------------------------------------------------

	if ($setcookie) {
		$this->user['lastVisit'] = $this->user['lastlogin'];
		$this->user['lastlogin'] = time();
		$this->user['totallogins'] += 1;

		// Update user record (create if it does not exist)
		if ($db->updateUserLogin($site, $userid) == ERR_NOTFOUND) {
			$db->insertUser($site, $this->user);
		}

		// set the w-agora cookie
		$userid = urlencode($this->user['userid']);
		$password = urlencode($this->user['password']);
		$lastVisit = $this->user['lastVisit'];
		if (!empty($_POST['keepalive'])) {
			$cookie = "WAP_${site}_auth";
			$expire = $GLOBALS['cookie_expire'];
		} else {
			$cookie = "${site}_auth";
			$expire = 0;
		}
		setCookie ($cookie, "lastVisit=$lastVisit&uid=$userid&pw=$password", $expire, '/') || die("<br/><strong>Sorry, but cookie could not be set, authentication failure! Please, fix this</strong>");
		if ( ($this->level == ROOT) && !isset($_COOKIE['agora_auth']) ) {
			setCookie ('agora_auth', "lastVisit=$lastVisit&uid=$userid&pw=$password", 0, '/');
		}
		// (>=4.1.3) add entry to the LOG
		if (empty($GLOBALS['bn_no_stats']) && ($site!='agora') ) {
			$db->addLogEntry ($GLOBALS['bn'], 'login', $userid);
		}

	} else {
		$this->user['lastVisit'] = empty($lastVisit) ? time() : $lastVisit;
	}

	return true;
}

 function havePermission ($forum, $perm) {
	global $db, $site;

	if (empty($this->userid) ) {
		return false;
	}

	if ($this->level >= ADMIN) {
		$this->privs['modpriv'] = 1;
		$this->privs['state'] = 1;
		return true;
	}

	if (isset($this->perms[$forum])) {
		$this->privs = $this->perms[$forum];
	} else {
		$this->privs = $db->getPrivs($site, $forum, $this->userid);
		if (is_array($this->privs) ) {
			$this->perms[$forum] = & $this->privs;
		} else {
			return false;
		}
	}

	switch ($perm) {
	 case 'L':
		if ($this->privs['listpriv']==1) {
			return true;
		}
		break;
	 case 'R':
		if ($this->privs['readpriv']==1) {
			return true;
		}
		break;
	 case 'W':
		if ($this->privs['writepriv']==1) {
			return true;
		}
		break;
	 case 'M':
		if ($this->privs['modpriv']==1) {
			return true;
		}
		break;
	 default:
		return false;
		break;
	}


	return false;
 }
} // end CLASS

?>
