Skip to content
Snippets Groups Projects
controll.php 6.37 KiB
Newer Older
<?php

/*
* SUCS GameAuth v2
* Follows the idea of a SPA, largely based around php sessions
* User loads the page, session is started (or resumed), if it's in the db then
* the state is restored. Otherwise the see the page with a login form. POST
* requests to self with user/pass, if successfully authd using my LDAP auth
* lib then database is poked with their details.

* Idea mainly follows the old system, some things like bans were a last minute
* afterthought that's why they are so barebones
*
* Split into a sperate API by ~ripp_
*
*/

// include my ldap auth lib
include('ldap-auth.php');
error_reporting(E_ERROR);

// star/resume a session
session_start();

// initialise some variables we'll use later
$authd; // if they get authd, how, otherwise "nope"
$authdUser; // once authd, this is their username
$sessionid = session_id();
$time = time();
$uniAllowFilePATH = '/home/game-server/uni.allow';
$gameauthDBPATH = 'gameauth.db'; #WIP CHANGE

$accessLevel; //Set to one of NO_LOGIN|NO_GAMES|GAMES_ACCESS|AS_BEFORE
$oldLevel; //set to level is accessLevel is AS_BEFORE to get allowed info
$failReason; // If they can't connect contains the reason why.

// create the db object, if the db aint there then make it
if (!file_exists($gameauthDBPATH)){
	$db = new SQLite3($gameauthDBPATH);
	$db->exec("CREATE TABLE gamers
		(
    		username TEXT PRIMARY KEY NOT NULL,
    		sessionid TEXT NOT NULL,
    		IP TEXT NOT NULL,
    		lastseen INT NOT NULL
		)"
	);
	$db->exec("CREATE TABLE bans
		(
    		username TEXT PRIMARY KEY NOT NULL,
    		reason TEXT
		)"
	);
} else {
	$db = new SQLite3($gameauthDBPATH);
}

$cip=$_SERVER['REMOTE_ADDR'];
$cip2=$_SERVER['HTTP_CLIENT_IP'];
$cip3=$_SERVER['HTTP_X_FORWARDED_FOR'];
$cookie=$_COOKIE["sucs_gameauth"];
$username=$_POST['username'];
$password=$_POST['password'];

/*echo("REMOTE_ADDR: $cip <br>");
echo("HTTP_CLIENT_IP: $cip2 <br>");
echo("HTTP_X_FORWARDED_FOR: $cip3 <br>");*/

// get a list of sessions in the db and banned users
$sessionsResult = $db->query("SELECT sessionid FROM gamers");
$bannedUsers = $db->query("SELECT username FROM bans");

// store sessions in another data format (1d array), easier to search
$sessions = array();
$i = 0;
while($res = $sessionsResult->fetchArray(SQLITE3_ASSOC)){
	if(!isset($res['sessionid'])) continue;
	$sessions[$i] = $res['sessionid'];
	$i++;
}

//If they are renewing
if ($renew){
	//Check if they are still in the database
	if (in_array($sessionid, $sessions)){
		//If they are update the ip & time
		$query = $db->query("SELECT level FROM gamers WHERE sessionid='$sessionid'");
		$oldLevel = $query->fetchArray()[0];
		$query = $db->query("SELECT username FROM gamers WHERE sessionid='$sessionid'");
		$authdUser = $query->fetchArray()[0];
		$db->exec("DELETE FROM gamers WHERE username='$authdUser'");
		$time = time();
		$db->exec("INSERT INTO gamers (username,sessionid,IP,level,lastseen) VALUES ('$authdUser','$sessionid','$cip','$oldLevel','$time')");
	} else {
		//Otherwise return a timeout error
		$accessLevel = "NO_LOGIN";
		$failReason = "TIMEOUT";
	}
//Oterwise check their post data to try and auth them
} else {
	//Insure they have passed a username and password
	if ($_POST["username"] == "" && $_POST["password"] == "") {
		$authd = "";
        $failReason = "MISSING_USERNAME_OR_PASSWORD";
	} else {
		// the main auth bit
		$authd = ldapAuth($username, $password);
		// bingo! we have a valid account
		if ($authd == "sucs" || $authd == "uni") {
			// people like to use emails to login so lets detect and strip
			if(filter_var($username, FILTER_VALIDATE_EMAIL)){
				//valid email, lets strip
				// split the email into a string array "@" as a delim
				$s = explode("@",$username);
				// remove the last element (domain)
				array_pop($s);
				// put the array back togther using "@" as a seperator
				$username = implode("@",$s);
			}
			$authdUser = strtolower($username);
			// check if they are banned
			if (in_array($authdUser, $bannedUsers->fetchArray())) {
				$failReason = "BANNED";
			} else {
				if ($authd == "sucs") {
					$type = "sucs";
					$db->exec("DELETE FROM gamers WHERE username='$authdUser'");
					$db->exec("INSERT INTO gamers (username,sessionid,IP,type,lastseen) VALUES ('$authdUser','$sessionid','$cip','$type','$time')");
				} elseif ($authd == "uni") {
					if (file_exists($uniAllowFilePATH)) {
						$type = "uni";
						$db->exec("DELETE FROM gamers WHERE username='$authdUser'");
						$db->exec("INSERT INTO gamers (username,sessionid,IP,type,lastseen) VALUES ('$authdUser','$sessionid','$cip','$type','$time')");
					} else {
					$failReason = "ERR_UNKNOWN_AUTH_TYPE";
				}
			}
		} else if ($authd == "nope"){
            $authd = "";
			$failReason = "BAD_LOGIN";
		}
	}
}

// logouts are done by posting the username logout to the page
if ($_POST["username"] == "logout"){
	//$db->exec("DELETE FROM gamers WHERE sessionid='$sessionid'");
	$db->exec("UPDATE gamers SET lastseen=0, sessionid='n0p3' WHERE sessionid='$sessionid'");
	session_destroy();
	$authd = "loggedOut";
	$failReason = null;
	$accessLevel = "NO_LOGIN";
}

//If the user is logged in succesfully iterate get the online uses (into a 1d array)
if ($accessLevel == "GAME_ACCESS" || ($accessLevel == "AS_BEFORE" && $oldLevel == "GAME_ACCESS")){
    $loggedInUsers = $db->query("SELECT username FROM gamers");
    while($res =$loggedInUsers->fetchArray(SQLITE3_ASSOC)){
    	if(!isset($res['username'])) continue;
    	$onlineUsers[] = $res['username'];
    }
}

header('Content-Type: application/json');
    loginError => $failReason,
    username => $authdUser,
	extraPayload => [
		onlineUsers => $onlineUsers,
		services => []
	]
/*
	level => "NO_LOGIN","NO_ACCESS","GAME_ACCESS"
	loginError => <string>
	username => <string>
	extraPayload =>
		onlineUsers => [<string>]
		services =>
			minecraft =>
				online => <bool>
				current => <number>
				max => <number>
			ect ...
*/

//echo ("Auth'd?: $authd <br>");

//echo("Cookie: $cookie <br>");

//echo ("Session id: ");
//echo (session_id());
?>