From 44a553eca5fbc1f608a0490bc62cb3af707286d8 Mon Sep 17 00:00:00 2001 From: smtddr Date: Sun, 28 Dec 2014 01:45:52 +0000 Subject: [PATCH] Admin page --- admin_page_server.py | 174 +++++++++++++++++++++++++++++++++++++++++ gamespy/gs_database.py | 9 +++ master_server.py | 2 + 3 files changed, 185 insertions(+) create mode 100644 admin_page_server.py diff --git a/admin_page_server.py b/admin_page_server.py new file mode 100644 index 0000000..3017e94 --- /dev/null +++ b/admin_page_server.py @@ -0,0 +1,174 @@ +#Make sure you change the password to something else and don't commit it to public github! +admin_username = "admin" +admin_password = "opensesame" + +from twisted.web import server, resource +from twisted.internet import reactor +from twisted.internet.error import ReactorAlreadyRunning +import base64 +import codecs +import sqlite3 +import json +import time +import datetime +import logging +import other.utils as utils +import gamespy +import gamespy.gs_utility as gs_utils + +logger_output_to_console = True +logger_output_to_file = True +logger_name = "AdminPage" +logger_filename = "admin_page.log" +logger = utils.create_logger(logger_name, logger_filename, -1, logger_output_to_console, logger_output_to_file) + + +class AdminPage(resource.Resource): + isLeaf = True + + def __init__(self,adminpage): + self.adminpage = adminpage + + def is_authorized(self, request): + is_auth = False + response_code = 401 + error_message = "Authorization required!" + address = request.getClientIP() + try: + expected_auth = base64.encodestring(admin_username+":"+admin_password).strip() + actual_auth = request.getAllHeaders()['authorization'].replace("Basic ","").strip() + if actual_auth == expected_auth: + if actual_auth == 'YWRtaW46b3BlbnNlc2FtZQ==': + error_message = ( 'You must change the default login info' + '[LOG OUT]' ) + response_code = 500 + else: + logger.log(logging.INFO,address+" Auth Success") + is_auth = True + except Exception,e: + logger.log(logging.INFO,address+" Auth Error: "+str(e)) + if not is_auth: + logger.log(logging.INFO,address+" Auth Failure") + request.setResponseCode(response_code) + request.setHeader('WWW-Authenticate', 'Basic realm="ALTWFC"') + request.write(error_message) + return is_auth + + def render_GET(self, request): + if not self.is_authorized(request): + return "" + if request.path != "/banhammer": + request.setResponseCode(500) + return "wrong url path" + sqlstatement = ('' + 'select users.profileid,enabled,data,users.gameid,console,users.userid ' + 'from nas_logins ' + 'inner join users ' + 'on users.userid = nas_logins.userid ' + 'inner join ( ' + ' select max(profileid) newestpid, userid, gameid, devname ' + ' from users ' + ' group by userid,gameid) ' + 'ij on ij.userid = users.userid and ' + 'users.profileid = ij.newestpid ' + 'order by users.gameid ' + '') + dbconn = sqlite3.connect('gpcm.db') + responsedata = ("\r\n" + "altwfc admin page" + '[CLICK HERE TO LOG OUT]' + "" + "" + "\r\n") + for row in dbconn.cursor().execute(sqlstatement): + dwc_pid = str(row[0]) + enabled = str(row[1]) + nasdata = json.loads(row[2]) + gameid = str(row[3]) + is_console = int(str(row[4])) + userid = str(row[5]) + gsbrcd = str(nasdata['gsbrcd']) + ingamesn = '' + if 'ingamesn' in nasdata: + ingamesn = str(nasdata['ingamesn']) + elif 'devname' in nasdata: + ingamesn = str(nasdata['devname']) + if ingamesn: + ingamesn = gs_utils.base64_decode(ingamesn) + ingamesn = base64.urlsafe_b64decode(ingamesn) + if is_console: + ingamesn = codecs.utf_16_be_decode(ingamesn)[0] + else: + ingamesn = codecs.utf_16_le_decode(ingamesn)[0] + ingamesn = codecs.utf_8_encode(ingamesn)[0].strip() + else: + ingamesn = '[NOT AVAILABLE]' + responsedata += "" + responsedata += "" + responsedata += "" + responsedata += "" + responsedata += "" + responsedata += "" + responsedata += "" + if enabled == "1": + responsedata += ("") + else: + responsedata += ("") + responsedata += "
ingamesn or devnamegameidEnablednewest dwc_pidgsbrcduserid
"+ingamesn+""+gameid+""+enabled+""+dwc_pid+""+gsbrcd+""+userid+"
" + "" + "" + "" + "
" + "" + "" + "" + "
" + dbconn.close() + return responsedata + + def render_POST(self, request): + if not self.is_authorized(request): + return "" + if request.path != "/enableuser" and request.path != "/disableuser": + request.setResponseCode(500) + return "wrong url path" + address = request.getClientIP() + responsedata = "" + userid = request.args['userid'][0] + gameid = request.args['gameid'][0].upper() + ingamesn = request.args['ingamesn'][0] + + if not userid.isdigit() or not gameid.isalnum(): + logger.log(logging.INFO,address+" Bad data "+userid+" "+gameid) + return "Bad data" + + dbconn = sqlite3.connect('gpcm.db') + if request.path == "/enableuser": + dbconn.cursor().execute('update users set enabled=1 ' + 'where gameid=? and userid=?',(gameid,userid)) + responsedata = "Enabled %s with gameid=%s, userid=%s" % \ + (ingamesn,gameid,userid) + else: + dbconn.cursor().execute('update users set enabled=0 ' + 'where gameid=? and userid=?',(gameid,userid)) + responsedata = "Disabled %s with gameid=%s, userid=%s" % \ + (ingamesn,gameid,userid) + dbconn.commit() + dbconn.close() + logger.log(logging.INFO,address+" "+responsedata) + return responsedata + + +class AdminPageServer(object): + def start(self): + site = server.Site(AdminPage(self)) + reactor.listenTCP(9009, site) + try: + if reactor.running == False: + reactor.run(installSignalHandlers=0) + except ReactorAlreadyRunning: + pass + +if __name__ == "__main__": + AdminPageServer().start() + diff --git a/gamespy/gs_database.py b/gamespy/gs_database.py index 1e2367c..75c372b 100644 --- a/gamespy/gs_database.py +++ b/gamespy/gs_database.py @@ -198,6 +198,15 @@ class GamespyDatabase(object): return profileid def create_user(self, userid, password, email, uniquenick, gsbrcd, console, csnum, cfc, bssid, devname, birth, gameid): + + #Check for console ban + with Transaction(self.conn) as tx: + row = tx.queryone("SELECT * FROM users WHERE userid = ? and gameid = ? and enabled = 0 limit 1", (userid, gameid)) + r = self.get_dict(row) + if r != None: + logger.log(logging.INFO, "--- REJECTING BANNED CONSOLE --- userid=%s,gameid=%s", userid,gameid) + return None + if self.check_user_exists(userid, gsbrcd) == 0: profileid = self.get_next_free_profileid() diff --git a/master_server.py b/master_server.py index b7c5c9b..d28518f 100644 --- a/master_server.py +++ b/master_server.py @@ -26,6 +26,7 @@ from gamespy_server_browser_server import GameSpyServerBrowserServer from gamespy_gamestats_server import GameSpyGamestatsServer from nas_server import NasServer from internal_stats_server import InternalStatsServer +from admin_page_server import AdminPageServer from storage_server import StorageServer from gamestats_server_http import GameStatsServer @@ -50,6 +51,7 @@ if __name__ == "__main__": GameSpyNatNegServer, NasServer, InternalStatsServer, + AdminPageServer, StorageServer, GameStatsServer, ]