276 lines
5.7 KiB
Ucode
276 lines
5.7 KiB
Ucode
/**
|
|
* Authentication handler that accepts multiple user accounts
|
|
*
|
|
* Copyright 2008 Epic Games, Inc. All Rights Reserved
|
|
*
|
|
* @author Michiel 'elmuerte' Hendriks
|
|
*/
|
|
class MultiWebAdminAuth extends Object implements(IWebAdminAuth) config(WebAdmin);
|
|
|
|
`include(WebAdmin.uci)
|
|
|
|
var WorldInfo worldinfo;
|
|
|
|
var array<MultiWebAdminUser> users;
|
|
|
|
/**
|
|
* Contains a list of known names and the associated data (when instantiated)
|
|
*/
|
|
struct UserRecord
|
|
{
|
|
var string name;
|
|
var MultiAdminData data;
|
|
};
|
|
var array<UserRecord> records;
|
|
|
|
//!localization
|
|
var localized string InvalidCreds, NoAdmins, msgUnsupportedHash;
|
|
|
|
var HashLib hashLib;
|
|
|
|
function init(WorldInfo wi)
|
|
{
|
|
worldinfo = wi;
|
|
hashLib = new class'Sha1HashLib';
|
|
loadRecords();
|
|
loadQueryHandler();
|
|
}
|
|
|
|
function loadRecords()
|
|
{
|
|
local array<string> names;
|
|
local int i, j;
|
|
local int idx;
|
|
local string tmp;
|
|
|
|
GetPerObjectConfigSections(class'MultiAdminData', names);
|
|
for (i = 0; i < names.length; i++)
|
|
{
|
|
idx = InStr(names[i], " ");
|
|
if (idx == INDEX_NONE) continue;
|
|
tmp = Left(names[i], idx);
|
|
for (j = 0; j < records.length; j++)
|
|
{
|
|
if (caps(records[j].name) > caps(tmp))
|
|
{
|
|
records.insert(j, 1);
|
|
records[j].name = tmp;
|
|
break;
|
|
}
|
|
}
|
|
if (j == records.length)
|
|
{
|
|
records.length = j+1;
|
|
records[j].name = tmp;
|
|
}
|
|
}
|
|
if (records.length == 0)
|
|
{
|
|
records.length = 1;
|
|
records[0].name = "Admin";
|
|
records[0].data = new(none, records[0].name) class'MultiAdminData';
|
|
records[0].data.bEnabled = true;
|
|
tmp = worldinfo.game.consolecommand("get engine.accesscontrol adminpassword", false);
|
|
if (len(tmp) == 0) tmp = "Admin";
|
|
tmp = getPasswordHash(records[0].data, tmp);
|
|
records[0].data.setPassword(tmp);
|
|
records[0].data.SaveConfig();
|
|
`Log("Created initial webadmin administrator account: "$records[0].name,,'WebAdmin');
|
|
}
|
|
}
|
|
|
|
function loadQueryHandler()
|
|
{
|
|
local QHMultiAdmin qh;
|
|
local WebAdmin webadmin;
|
|
local WebServer ws;
|
|
local int i;
|
|
|
|
if (WebAdmin(Outer) != none)
|
|
{
|
|
webadmin = WebAdmin(Outer);
|
|
}
|
|
else {
|
|
foreach worldinfo.AllActors(class'WebServer', ws)
|
|
{
|
|
break;
|
|
}
|
|
if (ws == none) return;
|
|
for (i = 0; i < ArrayCount(ws.ApplicationObjects); i++)
|
|
{
|
|
if (WebAdmin(ws.ApplicationObjects[i]) != none)
|
|
{
|
|
webadmin = WebAdmin(ws.ApplicationObjects[i]);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (webadmin == none) return;
|
|
qh = new class'QHMultiAdmin';
|
|
qh.authModule = self;
|
|
qh.init(webadmin);
|
|
qh.registerMenuItems(webadmin.menu);
|
|
}
|
|
|
|
function MultiAdminData getRecord(string username)
|
|
{
|
|
local int idx;
|
|
idx = records.find('name', username);
|
|
if (idx == INDEX_NONE)
|
|
{
|
|
return none;
|
|
}
|
|
if (records[idx].name != username)
|
|
{
|
|
// case sensitivity check
|
|
return none;
|
|
}
|
|
if (records[idx].data == none)
|
|
{
|
|
records[idx].data = new(none, records[idx].name) class'MultiAdminData';
|
|
}
|
|
return records[idx].data;
|
|
}
|
|
|
|
function bool removeAdminRecord(string username)
|
|
{
|
|
`if(`WITH_CLEAR_CONFIG)
|
|
local int idx;
|
|
local MultiAdminData data;
|
|
|
|
idx = records.find('name', username);
|
|
if (idx == INDEX_NONE)
|
|
{
|
|
return false;
|
|
}
|
|
if (records[idx].data == none)
|
|
{
|
|
records[idx].data = new(none, records[idx].name) class'MultiAdminData';
|
|
}
|
|
data = records[idx].data;
|
|
data.ClearConfig();
|
|
|
|
records.remove(idx, 1);
|
|
for (idx = users.length-1; idx >= 0; idx--)
|
|
{
|
|
if (users[idx].adminData == data)
|
|
{
|
|
logout(users[idx]);
|
|
}
|
|
}
|
|
return true;
|
|
`endif
|
|
return false;
|
|
}
|
|
|
|
function cleanup()
|
|
{
|
|
local MultiWebAdminUser user;
|
|
foreach users(user)
|
|
{
|
|
user.logout();
|
|
}
|
|
users.remove(0, users.length);
|
|
records.length = 0;
|
|
worldinfo = none;
|
|
}
|
|
|
|
function IWebAdminUser authenticate(string username, string password, string hashAlg, out string errorMsg)
|
|
{
|
|
local MultiWebAdminUser user;
|
|
local MultiAdminData adminData;
|
|
|
|
adminData = getRecord(username);
|
|
if (adminData == none)
|
|
{
|
|
errorMsg = InvalidCreds;
|
|
if (records.length == 0)
|
|
{
|
|
errorMsg @= NoAdmins;
|
|
}
|
|
return none;
|
|
}
|
|
|
|
if (hashLib != none)
|
|
{
|
|
if (hashAlg == "")
|
|
{
|
|
password = hashLib.getHash(password$username);
|
|
hashAlg = hashLib.getAlgName();
|
|
}
|
|
}
|
|
if (!supportHashAlgorithm(hashAlg))
|
|
{
|
|
errorMsg = msgUnsupportedHash;
|
|
return none;
|
|
}
|
|
|
|
if (adminData.matchesPassword(password))
|
|
{
|
|
user = worldinfo.spawn(class'MultiWebAdminUser');
|
|
user.adminData = adminData;
|
|
user.init();
|
|
user.setUsername(adminData.getDisplayName());
|
|
users.AddItem(user);
|
|
return user;
|
|
}
|
|
errorMsg = InvalidCreds;
|
|
return none;
|
|
}
|
|
|
|
function bool logout(IWebAdminUser user)
|
|
{
|
|
user.logout();
|
|
users.RemoveItem(MultiWebAdminUser(user));
|
|
return true;
|
|
}
|
|
|
|
function bool validate(string username, string password, string hashAlg, out string errorMsg)
|
|
{
|
|
local MultiAdminData adminData;
|
|
adminData = getRecord(username);
|
|
if (adminData == none)
|
|
{
|
|
errorMsg = InvalidCreds;
|
|
return false;
|
|
}
|
|
|
|
if (hashLib != none)
|
|
{
|
|
if (hashAlg == "")
|
|
{
|
|
password = hashLib.getHash(password$username);
|
|
hashAlg = hashLib.getAlgName();
|
|
}
|
|
}
|
|
if (!supportHashAlgorithm(hashAlg))
|
|
{
|
|
errorMsg = msgUnsupportedHash;
|
|
return false;
|
|
}
|
|
|
|
if (adminData.matchesPassword(password))
|
|
{
|
|
return true;
|
|
}
|
|
errorMsg = InvalidCreds;
|
|
return false;
|
|
}
|
|
|
|
function bool validateUser(IWebAdminUser user, out string errorMsg)
|
|
{
|
|
return true;
|
|
}
|
|
|
|
function bool supportHashAlgorithm(string hashAlg)
|
|
{
|
|
return hashLib.getAlgName() ~= hashAlg;
|
|
}
|
|
|
|
function string getPasswordHash(MultiAdminData adminData, coerce string newpw)
|
|
{
|
|
if (hashLib == none) return newpw;
|
|
return hashLib.getHash(newpw$adminData.name);
|
|
}
|