-
Notifications
You must be signed in to change notification settings - Fork 38
/
Copy pathXmlRpcServer.py
executable file
·147 lines (123 loc) · 4.5 KB
/
XmlRpcServer.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
#!/usr/bin/env python3
# coding=utf-8
# This file is part of the uberserver (GPL v2 or later), see LICENSE
# xmlrpc class for auth of replays.springrts.com
#
# TODO:
# - move SQLAlchemy calls to SQLUsers.py
from xmlrpc.server import SimpleXMLRPCServer, SimpleXMLRPCRequestHandler
from base64 import b64encode
import os.path
import logging
import socket
import traceback
import dbconfig
from logging.handlers import TimedRotatingFileHandler
from SQLUsers import User, Rename, Login, Ban
import SQLUsers
import sqlalchemy
import datetime
from hashlib import md5
# logging
xmlrpc_logfile = os.path.join(os.path.dirname(__file__), "xmlrpc.log")
logger = logging.getLogger()
logger.setLevel(logging.DEBUG)
fh = TimedRotatingFileHandler(xmlrpc_logfile, when="midnight", backupCount=6)
formatter = logging.Formatter(fmt='%(asctime)s %(levelname)-5s %(module)s.%(funcName)s:%(lineno)d %(message)s',
datefmt='%Y-%m-%d %H:%M:%S')
fh.setFormatter(formatter)
fh.setLevel(logging.DEBUG)
logger.addHandler(fh)
sqlurl = dbconfig.sqlurl
xmlhost = "localhost"
xmlport = 8300
class DummyRoot:
def __init__(self):
self.engine = sqlalchemy.create_engine(sqlurl, echo=False, pool_pre_ping=True)
self.session_manager = SQLUsers.session_manager(self, self.engine)
self.userdb = SQLUsers.UsersHandler(self)
self.bandb = SQLUsers.BansHandler(self)
root = DummyRoot()
class RequestHandler(SimpleXMLRPCRequestHandler):
def log_message(self, format, *args):
logger.info(format % args)
class XmlRpcServer(SimpleXMLRPCServer):
"""
XMLRPC service, exported functions are in class _RpcFuncs
"""
def __init__(self, host, port):
super(XmlRpcServer, self).__init__((host, port), requestHandler=RequestHandler)
self.register_introspection_functions()
self.register_instance(_RpcFuncs())
logger.info('Listening for XMLRPC clients on %s:%d', host, port)
self.serve_forever()
def validateLogin(username, raw_password):
session = root.userdb.sess()
password = b64encode(md5(raw_password.encode()).digest()).decode()
good, reason = root.userdb.check_login_user(username, password)
if not good:
logger.info("validation failure: {}, {}".format(username, reason))
return {"status": 1}
banned, reason = root.userdb.check_banned(username, None)
if banned:
logger.info("validation failure: {}, {}".format(username, reason))
return {"status": 1}
db_user = session.query(User).filter(User.username == username).first()
renames = session.query(Rename.original).distinct(Rename.original).filter(Rename.user_id == db_user.id).all()
renames = [r[0] for r in renames]
country = session.query(Login.country).filter(Login.user_id == db_user.id).filter(sqlalchemy.and_(Login.country != '??', Login.country is not None, Login.country != '')).first()
result = {"status": 0, "accountid": int(db_user.id), "username": str(db_user.username),
"ingame_time": int(db_user.ingame_time), "email": str(db_user.email),
"aliases": renames,
"country": country[0] if country else ''
}
db_user.last_login = datetime.datetime.now()
logger.info("validation success: {}".format(username))
return result
def user_id(username):
session = root.userdb.sess()
db_user = session.query(User.id).filter(User.username == username).first()
return db_user.id
class _RpcFuncs(object):
"""
All methods of this class will be exposed via XMLRPC.
"""
def get_account_info(self, username, password):
ret = {"status": 1}
try:
ret = validateLogin(username, password)
root.session_manager.commit_guard()
except Exception as e:
logger.error('Exception: {}: {}'.format(e, traceback.format_exc()))
root.session_manager.rollback_guard()
finally:
root.session_manager.close_guard()
return ret
def get_account_id(self, username):
ret = None
try:
ret = user_id(username)
root.session_manager.commit_guard()
except Exception as e:
logger.error('Exception: {}: {}'.format(e, traceback.format_exc()))
root.session_manager.rollback_guard()
finally:
root.session_manager.close_guard()
return ret
def get_username(self, account_id):
ret = None
try:
session = root.userdb.sess()
db_user = session.query(User.username).filter(User.id == account_id).first()
ret = db_user.username
root.session_manager.commit_guard()
except Exception as e:
logger.error('Exception: {}: {}'.format(e, traceback.format_exc()))
root.session_manager.rollback_guard()
finally:
root.session_manager.close_guard()
return ret
try:
xmlrpcserver = XmlRpcServer(xmlhost, xmlport)
except socket.error:
logger.error('Error: Could not start XmlRpcServer.')