<?php
/*
UserAuth extends UserEncryption for hasing and blowfish encryption.

Methods:
CheckUsername(username) - Returns true if username exists or false.  
*/

class UserAuth extends UserEncryption {
	
	var $LOG;
	var $DbCall;
	var $auth_groups;
	var $status;
	var $message;
	var $login_attempts;
	var $lockout_time;
	var $session;
	var $cookie_id;
	var $cookie_expire;
	var $cookie_package;
	var $domain;

	function __construct($oLog, $DbCall, $auth_groups, $key, $cookie_id, $cookie_expire, $login_attempts, $lockout_time) {
		
		parent::__construct($key);
		
		$this->LOG = $oLog;
		$this->DbCall = $DbCall;
		$this->auth_groups = $auth_groups;
		$this->cookie_id = $cookie_id;
		$this->cookie_expire = $cookie_expire;
		$this->login_attempts = $this->LOGin_attempts;
		$this->lockout_time = $lockout_time;
		$this->session = $_SESSION;
		
		// Set server domain
		$req_headers = apache_request_headers();
		$this->domain = strtolower($req_headers['Host']);
		return true;
	}
	
	function GetCookie() {
		return $_COOKIE[$this->cookie_id];
	}
	
	function SetCookie($package) {		
		setcookie($this->cookie_id, $package, time() + $this->cookie_expire, "/", $this->domain);
	}
	
	function DeleteCookie($cookie_id) {
		setcookie($cookie_id, '', time() - 3600, '/');
	}
	
	function SetSession($username, $name, $role, $last_login) {
		
		$_SESSION['auth'] = TRUE;
		$_SESSION['username'] = $username;
		$_SESSION['name'] = $name;
		$_SESSION['role'] = $role;
		$_SESSION['last_login'] = $last_login;
		$this->session = $_SESSION;
	}
	
	function SetSessionPageDetails($origin, $year, $region, $country, $keywords, $pagination) {
	
		$_SESSION['origin'] = $origin;
		$_SESSION['year'] = $year;
		$_SESSION['region'] = $region;
		$_SESSION['country'] = $country;
		$_SESSION['keywords'] = $keywords;
		$_SESSION['pagination'] = $pagination;
		$this->session = $_SESSION;
	}
	
	function SetSessionImgComment($id, $comment) {
	
		$_SESSION['comment_img_id'] = $id;
		$_SESSION['comment_text'] = $comment;
		$this->session = $_SESSION;
	}
	
	function ClearSessionImgComment() {
		unset($_SESSION['comment_img_id']);
		unset($_SESSION['comment_text']);
		$this->session = $_SESSION;
	}
	
	function SetGuestSession() {
		
		$_SESSION['auth'] = FALSE;
		$_SESSION['role'] = 'guest';
		$this->session = $_SESSION;
	}
	
	function GetSessionPageDetails() {
		$page = array();
		$page['origin'] = $this->session['origin'];
		$page['year'] = $this->session['year'];
		$page['region'] = $this->session['region'];
		$page['country'] = $this->session['country'];
		$page['keywords'] = $this->session['keywords'];
		$page['pagination'] = $this->session['pagination'];
		return $page;
	}
	
	function ClearSessionPageDetails() {
		unset($_SESSION['origin']);
		unset($_SESSION['year']);
		unset($_SESSION['region']);
		unset($_SESSION['country']);
		unset($_SESSION['keywords']);
		unset($_SESSION['pagination']);
		$this->session = $_SESSION;
	}
	
	function GetSessionImgComment() {
		$page = array();
		$page['comment_img_id'] = $this->session['comment_img_id'];
		$page['comment_text'] = $this->session['comment_text'];
		return $page;
	}
	
	function GetAuth() {
		return $this->session['auth'];
	}
	
	function GetAuthGroup() {
		if($this->GetAuth()) {
			return $this->auth_groups[$this->session['role']];
		}
		return false;
	}
	
	function GetTempAuthGroup($role) {
		return $this->auth_groups[$role];
	}
	
	function GetUsername() {
		return $this->session['username'];
	}
	
	function GetName() {
		return $this->session['name'];
	}
	
	function GetRole() {
		return $this->session['role'];
	}
	
	function GetLastLogin() {
		return $this->session['last_login'];
	}
				
	function Login($package) {
		
		$response = array();
		
		$this->LOG->LogWarn("User Login Attempt...");
		
		if(!$data = $this->Unpackage($package)) {
			$this->status = "failed_login";
			$this->message = "Problem unpacking user data";
			$this->LOG->LogWarn("Problem unpacking user data", E_USER_WARNING);
			return false;
		}

		// Check user exists
		if(!$user = $this->DbCall->GetUser($data['username'])) {
			$this->status = "no_user_exists";
			$this->message = "User does not exist";
			$this->LOG->LogWarn($user['username'] . " - User does not exist", E_USER_WARNING);
			return false;
		}				

		// Check user is active. 
		if(!$user['active']) {
			$this->status = "user_not_active";
			$this->message = "This user account is not active";
			$this->LOG->LogWarn($user['username'] . " - User account not active", E_USER_WARNING);
			return false;
		}

		// User exists and active.
		//
		// Check login attempts over last few hours. 
		if($user['login_attempts'] >= $this->login_attempts) {			
			if($user['last_login_attempt'] > (time() - $this->lockout_time)) {
				$this->status = "too_many_logins";
				$this->message = "Too many login attempts. Please try again later";
				$this->LOG->LogWarn($user['username'] . " - Too many login attempts. Please try again later", E_USER_WARNING);
				return false;
			}
			$user['login_attempts'] = 0;	
		}
		
		// Hash users supplied password with salt (time) to compare with DB. 
		$hash_password = $this->_HashPassword($data['password'], $user['time']);		

		// Check password hash against db password hash.
		if($hash_password == $user['password']) {

			// Login succesfull. Set response array.
			$response['username'] = $user['username'];
			$response['name'] = $user['name'];
			$response['role'] = $user['role'];
			$response['last_login'] = date('Y-m-d H:i:s', $user['last_login']);
			$response['referrer'] = $user['referrer'];
			$response['active'] = $user['active'];
			$response['comments'] = $user['comments'];
			
			// Update user db.
			if(!$this->DbCall->UpdateUser($data['username'], $user['name'], $user['role'], time(), '0', '0', $user['referrer'], $user['active'], $user['comments'])) {
				$this->status = "failed_login";
				$this->message = "Couldn't update user db";
				$this->LOG->LogWarn($user['username'] . " - Couldn't update user db", E_USER_WARNING);
				return false;
			}
			
			$this->status = "login_succesfull";
			$this->message = "User succesfully logged in";
			$this->LOG->LogWarn("Login Successfull - " . $user['username'] . " as " . $user['role']);
			return $response;
		}

		$user['login_attempts'] = $user['login_attempts'] + 1;
		
		// Update user db.
		if(!$this->DbCall->UpdateUser($data['username'], $user['name'], $user['role'], $user['last_login'], time(), $user['login_attempts'], $user['referrer'], $user['active'], $user['comments'])) {
			$this->status = "failed_login";
			$this->message = "Couldn't update user db";
			$this->LOG->LogWarn("Couldn't update user db", E_USER_WARNING);
			return false;
		}
		
		$this->status = "wrong_password";
		$this->message = "Passwords do not match";
		$this->LOG->LogWarn($user['username'] . " - Passwords do not match", E_USER_WARNING);
		return false;
	}

	function Logout() {
		
		// Delete php session cookie. 
		$this->DeleteCookie(session_name());
		
		// Delete SESSION vars
		$_SESSION = array();
		unset($_COOKIE['PHPSESSID']);
		session_destroy();
		 
		// Delete user auth cookie;
		$this->DeleteCookie($this->cookie_id);
		$this->session['auth'] = FALSE;
		
		$this->LOG->LogWarn("User logged out");
		
		return true;
	}
	
	function AddUser($package, $name, $role = "guest", $comments) {
		
		$this->LOG->LogWarn("Attempting to Add New User...");
		
		if(!$data = $this->Unpackage($package)) {
			$this->status = "failed_adduser";
			$this->message = "Problem unpacking user data";
			$this->LOG->LogWarn("Problem unpacking user data", E_USER_WARNING);
			return false;
		}		

		// Check user doesn't already exists
		if($this->DbCall->GetUser($data['username'])) {
			$this->status = "user_exists";
			$this->message = "Username already exists in database";
			$this->LOG->LogWarn($data['username'] . " - Username already exists in database", E_USER_WARNING);
			return false;
		}
				
		// First hash the password with salt (time).
		$hash_password = $this->_HashPassword($data['password'], $data['time']);
		
		if(!$role) {$role = "guest";}
		// Insert into db.
		if(!$this->DbCall->AddUser($data['username'], $hash_password, $name, $role, $data['time'], $comments)) {
			$this->LOG->LogWarn($data['username'] . " - Failed to AddUser - DBcall failed", E_USER_WARNING);
			$this->status = "failed_adduser";
			$this->message = "Problem adding user to database";
			return false;
		}
		
		$this->status = "user_added_succesfully";
		$this->message = "User has been added succesfully";
		
		// Email admin notifiying of new user to review. 
		$headers = "MIME-Version: 1.0" . "\r\n" . 
				"Content-type: text/html; charset=iso-8859-1" . "\r\n" . 
				"From: " . $data['username'] . "\r\n" .
				"Reply-To: " . $data['username'] . "\r\n";
		
		$subject = "New user request for Loganc";
		$body = "Hi Admin, \r\n\r\nPlease add to your website\r\n\r\nRegards,\r\n" . $data['username'];
		
		mail("logan.crerar@outlook.com", $subject, $body, $headers);

		$this->LOG->LogWarn($data['username'] . " - User has been added succesfully", E_USER_WARNING);
		return true;
	}
	
	function UpdatePassword($package) {
		
		$this->LOG->LogWarn("Attempting to Update Users Password...");
		
		if(!$data = $this->Unpackage($package)) {
			$this->status = "failed_change_password";
			$this->message = "Problem unpacking user data";
			$this->LOG->LogWarn("Problem unpacking user data", E_USER_WARNING);
			return false;
		}	

		// Check user exists in db.
		if(!$this->DbCall->GetUser($data['username'])) {
			$this->status = "no_user_exists";
			$this->message = "Username doesn't exist in database";
			$this->LOG->LogWarn($data['username'] . " - Username doesn't exist in database", E_USER_WARNING);
			return false;
		}
		
		// Hash the new password with salt (time).
		$hash_password = $this->_HashPassword($data['password'], $data['time']);
	
		// Update db.
		if(!$this->DbCall->UpdatePassword($data['username'], $hash_password, $data['time'])) {
			$this->status = "failed_change_password";
			$this->message = "Failed to update password";
			$this->LOG->LogWarn($data['username'] . " - Failed to update password", E_USER_WARNING);
			return false;
		}
		
		$this->status = "password_changed";
		$this->message = "User password has been updated";
		$this->LOG->LogWarn($data['username'] . " - User password has been updated", E_USER_WARNING);
		
		return true;
	}
	
	function UpdateUser($package, $name, $role, $active, $comments) {

		if(!$data = $this->Unpackage($package)) {
			$this->status = "failed_update_user";
			$this->message = "Problem unpacking user data";
			$this->LOG->LogWarn("Problem unpacking user data", E_USER_WARNING);
			return false;
		}	

		// Check user exists in db.
		if(!$user = $this->DbCall->GetUser($data['username'])) {
			$this->status = "no_user_exists";
			$this->message = "Username doesn't exist in database";
			$this->LOG->LogWarn($data['username'] . " - Username doesn't exist in database", E_USER_WARNING);
			return false;
		}
		
		// Update db.
		if(!$name) {$name = $user['name'];}
		if(!$role) {$role = $user['role'];}
		if(!$active) {$active = $user['active'];}
		if(!$comments) {$comments = $user['comments'];}

		if(!$this->DbCall->UpdateUser($data['username'], $name, $role, $user['last_login'], $user['last_login_attempt'], $user['login_attempts'], $user['referrer'], $active, $comments)) {	
			$this->status = "failed_update_user";
			$this->message = "Failed to update user database";
			$this->LOG->LogWarn("Failed to update user database", E_USER_WARNING);
			return false;
		}
		
		$this->status = "user_updated";
		$this->message = "User details have been updated";
		$this->LOG->LogWarn($data['username'] . " - User details have been updated", E_USER_WARNING);
		return true;		
	}
	
	function DeleteUser($package) {
			
		if(!$data = $this->Unpackage($package)) {
			$this->status = "failed_delete_user";
			$this->message = "Problem unpacking user data";
			$this->LOG->LogWarn("Problem unpacking user data", E_USER_WARNING);
			return false;
		}	
		
		if(!$this->DbCall->DeleteUser($data['username'])) {
			$this->LOG->LogWarn("Failed to Delete User " . $data['username'] . " - DBcall failed", E_USER_WARNING);
			$this->status = "failed_delete_user";
			$this->message = "Failed to delete user from database";
			return false;
		}
		
		$this->status = "deleted_user";
		$this->message = "User has been deleted from database";
		$this->LOG->LogWarn($data['username'] . " - User details have been updated", E_USER_WARNING);
		return true;
	}
	
	function DeleteUserFromDB($username) {
		$this->DbCall->DeleteUser($username);
	}
	
	function GetActiveUsers() {
		return $this->DbCall->GetActiveUsers();
	}
	
	function GetInactiveUsers() {
		return $this->DbCall->GetInactiveUsers();
	}
	
	function UpdateUserActive($username, $role) {
		return $this->DbCall->UpdateUserActive($username, $role);
	}
	
	function UpdateUserInactive($username) {
		return $this->DbCall->UpdateUserInactive($username);
	}
	
	function UpdateUserRole($username, $role) {
		return $this->DbCall->UpdateUserRole($username, $role);
	}
	
	function GetStatus() {
		return $this->status;
	}
	
	function GetMessage() {
		return $this->message;
	}
}

?>
