Newer
Older

Stuart John Watson
committed
<?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

Stuart John Watson
committed
$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,
level TEXT NOT NULL,

Stuart John Watson
committed
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'];
$renew=$_POST['renew'];

Stuart John Watson
committed
/*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];

Stuart John Watson
committed
$query = $db->query("SELECT username FROM gamers WHERE sessionid='$sessionid'");
$authdUser = $query->fetchArray()[0];

Stuart John Watson
committed
$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')");
$accessLevel = "AS_BEFORE";
} 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

Stuart John Watson
committed
if ($_POST["username"] == "" && $_POST["password"] == "") {
$authd = "";
$accessLevel = "NO_LOGIN";

Stuart John Watson
committed
$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())) {
$accessLevel = "NO_GAMES";

Stuart John Watson
committed
$failReason = "BANNED";
} else {
if ($authd == "sucs") {
$accessLevel = "GAME_ACCESS";

Stuart John Watson
committed
$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";
$accessLevel = "GAME_ACCESS";

Stuart John Watson
committed
$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 {
$accessLevel = "NO_GAMES";

Stuart John Watson
committed
$failReason = "UNI_DISALLOWED";
}
} else {
$accessLevel = "NO_LOGIN";

Stuart John Watson
committed
$failReason = "ERR_UNKNOWN_AUTH_TYPE";
}
}
} else if ($authd == "nope"){
$authd = "";
$accessLevel = "NO_LOGIN";

Stuart John Watson
committed
$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";
$authdUser = null;
$accessLevel = "NO_LOGIN";

Stuart John Watson
committed
}
//If the user is logged in succesfully iterate get the online uses (into a 1d array)
$onlineUsers;
if ($accessLevel == "GAME_ACCESS" || ($accessLevel == "AS_BEFORE" && $oldLevel == "GAME_ACCESS")){
$onlineUsers = [];

Stuart John Watson
committed
$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');

Stuart John Watson
committed
//Echo response
echo json_encode([
level => $accessLevel,

Stuart John Watson
committed
loginError => $failReason,
username => $authdUser,
extraPayload => [
onlineUsers => $onlineUsers,
services => []
]

Stuart John Watson
committed
]);
/*
level => "NO_LOGIN","NO_ACCESS","GAME_ACCESS"
loginError => <string>
username => <string>
extraPayload =>
onlineUsers => [<string>]
services =>
minecraft =>
online => <bool>
current => <number>
max => <number>
ect ...
*/

Stuart John Watson
committed
//echo ("Auth'd?: $authd <br>");
//echo("Cookie: $cookie <br>");
//echo ("Session id: ");
//echo (session_id());
?>