IRC Support for username with spaces

BATs with Donor have bright yellow username in chat
General performance improvements
Code cleaning
Multiplayer improvements and fixes
Fixed some spectator bugs
This commit is contained in:
Nyo
2016-09-02 12:41:19 +02:00
parent e16e4d7493
commit 653303831b
47 changed files with 450 additions and 622 deletions

View File

@@ -147,9 +147,6 @@ def partChannel(userID = 0, channel = "", token = None, toIRC = True, kick = Fal
log.warning("User not connected to IRC/Bancho")
return 442 # idk
def sendMessage(fro = "", to = "", message = "", token = None, toIRC = True):
"""
Send a message to osu!bancho and IRC server
@@ -299,8 +296,13 @@ def sendMessage(fro = "", to = "", message = "", token = None, toIRC = True):
return 401
""" IRC-Bancho Connect/Disconnect/Join/Part interfaces"""
def fixUsernameForBancho(username):
return username.replace("_", " ")
def fixUsernameForIRC(username):
return username.replace(" ", "_")
def IRCConnect(username):
userID = userHelper.getID(username)
if userID == False:

View File

@@ -1,18 +1,7 @@
import os
import configparser
class config:
"""
config.ini object
config -- list with ini data
default -- if true, we have generated a default config.ini
"""
config = configparser.ConfigParser()
fileName = "" # config filename
default = True
class config():
# Check if config.ini exists and load/generate it
def __init__(self, file):
"""
@@ -20,7 +9,8 @@ class config:
file -- filename
"""
self.config = configparser.ConfigParser()
self.default = True
self.fileName = file
if os.path.isfile(self.fileName):
# config.ini found, load it
@@ -39,7 +29,6 @@ class config:
return -- True if valid, False if not
"""
try:
# Try to get all the required keys
self.config.get("db","host")
@@ -75,11 +64,10 @@ class config:
except:
return False
# Generate a default config.ini
def generateDefaultConfig(self):
"""Open and set default keys for that config file"""
"""
Open and set default keys for that config file
"""
# Open config.ini in write mode
f = open(self.fileName, "w")

View File

@@ -1,13 +1,12 @@
"""Some console related functions"""
from constants import bcolors
from objects import glob
def printServerStartHeader(asciiArt):
"""Print server start header with optional ascii art
asciiArt -- if True, will print ascii art too"""
"""
Print server start header with optional ascii art
asciiArt -- if True, will print ascii art too
"""
if asciiArt == True:
print("{} _ __".format(bcolors.GREEN))
print(" (_) / /")
@@ -28,20 +27,17 @@ def printServerStartHeader(asciiArt):
printColored("> Welcome to pep.py osu!bancho server v{}".format(glob.VERSION), bcolors.GREEN)
printColored("> Made by the Ripple team", bcolors.GREEN)
printColored("> {}https://github.com/osuripple/ripple".format(bcolors.UNDERLINE), bcolors.GREEN)
printColored("> {}https://git.zxq.co/ripple/pep.py".format(bcolors.UNDERLINE), bcolors.GREEN)
printColored("> Press CTRL+C to exit\n",bcolors.GREEN)
def printNoNl(string):
"""
Print string without new line at the end
string -- string to print
"""
print(string, end="")
def printColored(string, color):
"""
Print colored string
@@ -49,23 +45,22 @@ def printColored(string, color):
string -- string to print
color -- see bcolors.py
"""
print("{}{}{}".format(color, string, bcolors.ENDC))
def printError():
"""Print error text FOR LOADING"""
"""
Print error text FOR LOADING
"""
printColored("Error", bcolors.RED)
def printDone():
"""Print error text FOR LOADING"""
"""
Print error text FOR LOADING
"""
printColored("Done", bcolors.GREEN)
def printWarning():
"""Print error text FOR LOADING"""
"""
Print error text FOR LOADING
"""
printColored("Warning", bcolors.YELLOW)

View File

@@ -253,7 +253,6 @@ countryCodes = {
"AI": 7
}
def getCountryID(code):
"""
Get country ID for osu client

View File

@@ -2,13 +2,13 @@ import MySQLdb
import threading
from helpers import logHelper as log
class mysqlWorker:
class mysqlWorker():
"""
Instance of a pettirosso meme
Instance of a mysql worker
"""
def __init__(self, wid, host, username, password, database):
"""
Create a pettirosso meme (mysql worker)
Create a mysql worker
wid -- worker id
host -- hostname
@@ -22,11 +22,10 @@ class mysqlWorker:
self.ready = True
self.lock = threading.Lock()
class db:
class db():
"""
A MySQL db connection with multiple workers
"""
def __init__(self, host, username, password, database, workers):
"""
Create MySQL workers aka pettirossi meme
@@ -37,9 +36,6 @@ class db:
database -- MySQL database name
workers -- Number of workers to spawn
"""
#self.lock = threading.Lock()
#self.connection = MySQLdb.connect(host, username, password, database)
self.workers = []
self.lastWorker = 0
self.workersNumber = workers
@@ -57,7 +53,6 @@ class db:
self.lastWorker = 0
else:
self.lastWorker += 1
#print("Using worker {}".format(self.lastWorker))
return self.workers[self.lastWorker]
def execute(self, query, params = ()):

View File

@@ -1,9 +1,6 @@
import requests
from objects import glob
from helpers import generalFunctions
from urllib.parse import urlencode
from helpers import consoleHelper
from constants import bcolors
def sendDiscordMessage(channel, message, alertDev = False, prefix = "**pep.py**"):
"""
@@ -24,7 +21,6 @@ def sendDiscordMessage(channel, message, alertDev = False, prefix = "**pep.py**"
except:
continue
def sendConfidential(message, alertDev = False):
"""
Send a message to #bunker
@@ -33,7 +29,6 @@ def sendConfidential(message, alertDev = False):
"""
sendDiscordMessage("bunk", message, alertDev)
def sendStaff(message):
"""
Send a message to #staff
@@ -42,7 +37,6 @@ def sendStaff(message):
"""
sendDiscordMessage("staff", message)
def sendGeneral(message):
"""
Send a message to #general
@@ -51,7 +45,6 @@ def sendGeneral(message):
"""
sendDiscordMessage("general", message)
def sendChatlog(message):
"""
Send a message to #chatlog

View File

@@ -1,6 +1,17 @@
"""Some functions that don't fit in any other file"""
from constants import mods
from time import gmtime, strftime
import hashlib
def stringMd5(string):
"""
Return string's md5
string -- string to hash
return -- string's md5 hash
"""
d = hashlib.md5()
d.update(string.encode("utf-8"))
return d.hexdigest()
def stringToBool(s):
"""
@@ -9,10 +20,8 @@ def stringToBool(s):
s -- string/int value
return -- True/False
"""
return (s == "True" or s== "true" or s == "1" or s == 1)
def hexString(s):
"""
Output s' bytes in HEX
@@ -20,7 +29,6 @@ def hexString(s):
s -- string
return -- string with hex value
"""
return ":".join("{:02x}".format(ord(str(c))) for c in s)
def readableMods(__mods):

View File

@@ -11,7 +11,6 @@ def getCountry(ip):
ip -- IP Address
return -- Country code (2 letters)
"""
try:
# Try to get country from Pikolo Aul's Go-Sanic ip API
result = json.loads(urllib.request.urlopen("{}/{}".format(glob.conf.config["localize"]["ipapiurl"], ip), timeout=3).read().decode())["country"]
@@ -20,7 +19,6 @@ def getCountry(ip):
log.error("Error in get country")
return "XX"
def getLocation(ip):
"""
Get latitude and longitude from IP address
@@ -28,7 +26,6 @@ def getLocation(ip):
ip -- IP address
return -- [latitude, longitude]
"""
try:
# Try to get position from Pikolo Aul's Go-Sanic ip API
result = json.loads(urllib.request.urlopen("{}/{}".format(glob.conf.config["localize"]["ipapiurl"], ip), timeout=3).read().decode())["loc"].split(",")

View File

@@ -8,7 +8,6 @@ def uleb128Encode(num):
num -- int to encode
return -- bytearray with encoded number
"""
arr = bytearray()
length = 0
@@ -24,7 +23,6 @@ def uleb128Encode(num):
return arr
def uleb128Decode(num):
"""
Decode uleb128 -> int
@@ -32,9 +30,7 @@ def uleb128Decode(num):
num -- encoded uleb128
return -- list. [total, length]
"""
shift = 0
arr = [0,0] #total, length
while True:
@@ -47,42 +43,40 @@ def uleb128Decode(num):
return arr
def unpackData(__data, __dataType):
def unpackData(data, dataType):
"""
Unpacks data according to dataType
__data -- bytes array to unpack
__dataType -- data type. See dataTypes.py
data -- bytes array to unpack
dataType -- data type. See dataTypes.py
return -- unpacked bytes
"""
# Get right pack Type
if __dataType == dataTypes.uInt16:
if dataType == dataTypes.uInt16:
unpackType = "<H"
elif __dataType == dataTypes.sInt16:
elif dataType == dataTypes.sInt16:
unpackType = "<h"
elif __dataType == dataTypes.uInt32:
elif dataType == dataTypes.uInt32:
unpackType = "<L"
elif __dataType == dataTypes.sInt32:
elif dataType == dataTypes.sInt32:
unpackType = "<l"
elif __dataType == dataTypes.uInt64:
elif dataType == dataTypes.uInt64:
unpackType = "<Q"
elif __dataType == dataTypes.sInt64:
elif dataType == dataTypes.sInt64:
unpackType = "<q"
elif __dataType == dataTypes.string:
elif dataType == dataTypes.string:
unpackType = "<s"
elif __dataType == dataTypes.ffloat:
elif dataType == dataTypes.ffloat:
unpackType = "<f"
else:
unpackType = "<B"
# Unpack
return struct.unpack(unpackType, bytes(__data))[0]
return struct.unpack(unpackType, bytes(data))[0]
def packData(__data, __dataType):
def packData(__data, dataType):
"""
Packs data according to dataType
@@ -96,11 +90,11 @@ def packData(__data, __dataType):
pack = True # if True, use pack. False only with strings
# Get right pack Type
if __dataType == dataTypes.bbytes:
if dataType == dataTypes.bbytes:
# Bytes, do not use pack, do manually
pack = False
data = __data
elif __dataType == dataTypes.intList:
elif dataType == dataTypes.intList:
# Pack manually
pack = False
# Add length
@@ -108,7 +102,7 @@ def packData(__data, __dataType):
# Add all elements
for i in __data:
data += packData(i, dataTypes.sInt32)
elif __dataType == dataTypes.string:
elif dataType == dataTypes.string:
# String, do not use pack, do manually
pack = False
if len(__data) == 0:
@@ -119,21 +113,21 @@ def packData(__data, __dataType):
data += b"\x0B"
data += uleb128Encode(len(__data))
data += str.encode(__data, "latin_1", "ignore")
elif __dataType == dataTypes.uInt16:
elif dataType == dataTypes.uInt16:
packType = "<H"
elif __dataType == dataTypes.sInt16:
elif dataType == dataTypes.sInt16:
packType = "<h"
elif __dataType == dataTypes.uInt32:
elif dataType == dataTypes.uInt32:
packType = "<L"
elif __dataType == dataTypes.sInt32:
elif dataType == dataTypes.sInt32:
packType = "<l"
elif __dataType == dataTypes.uInt64:
elif dataType == dataTypes.uInt64:
packType = "<Q"
elif __dataType == dataTypes.sInt64:
elif dataType == dataTypes.sInt64:
packType = "<q"
elif __dataType == dataTypes.string:
elif dataType == dataTypes.string:
packType = "<s"
elif __dataType == dataTypes.ffloat:
elif dataType == dataTypes.ffloat:
packType = "<f"
else:
packType = "<B"
@@ -144,7 +138,6 @@ def packData(__data, __dataType):
return data
# TODO: Wat dangerous
def buildPacket(__packet, __packetData = []):
"""
Build a packet
@@ -154,7 +147,6 @@ def buildPacket(__packet, __packetData = []):
return -- packet bytes
"""
# Set some variables
packetData = bytes()
packetLength = 0
@@ -174,7 +166,6 @@ def buildPacket(__packet, __packetData = []):
packetBytes += packetData # packet data
return packetBytes
def readPacketID(stream):
"""
Read packetID from stream (0-1 bytes)
@@ -182,10 +173,8 @@ def readPacketID(stream):
stream -- data stream
return -- packet ID (int)
"""
return unpackData(stream[0:2], dataTypes.uInt16)
def readPacketLength(stream):
"""
Read packet length from stream (3-4-5-6 bytes)
@@ -193,7 +182,6 @@ def readPacketLength(stream):
stream -- data stream
return -- packet length (int)
"""
return unpackData(stream[3:7], dataTypes.uInt32)
@@ -208,7 +196,6 @@ def readPacketData(stream, structure = [], hasFirstBytes = True):
Optional. Default: True
return -- dictionary. key: name, value: read data
"""
# Read packet ID (first 2 bytes)
data = {}

View File

@@ -11,7 +11,6 @@ def checkOldPassword(password, salt, rightPassword):
rightPassword -- right password
return -- bool
"""
return (rightPassword == cryptHelper.crypt(password, "$2y$"+str(base64.b64decode(salt))))
def checkNewPassword(password, dbPassword):

View File

@@ -3,8 +3,6 @@ import tornado.web
import tornado.gen
from tornado.ioloop import IOLoop
from objects import glob
from raven.contrib.tornado import SentryMixin
from raven.contrib.tornado import AsyncSentryClient
import gevent
class asyncRequestHandler(tornado.web.RequestHandler):
@@ -50,7 +48,6 @@ class asyncRequestHandler(tornado.web.RequestHandler):
return realIP
return self.request.remote_ip
def runBackground(data, callback):
"""
Run a function in the background.
@@ -59,7 +56,6 @@ def runBackground(data, callback):
func, args, kwargs = data
def _callback(result):
IOLoop.instance().add_callback(lambda: callback(result))
#glob.pool.apply_async(func, args, kwargs, _callback)
g = gevent.Greenlet(func, *args, **kwargs)
g.link(_callback)
g.start()

View File

@@ -15,10 +15,8 @@ def runningUnderUnix():
return --- True if running under UNIX, otherwise False
"""
return True if os.name == "posix" else False
def scheduleShutdown(sendRestartTime, restart, message = "", delay=20):
"""
Schedule a server shutdown/restart
@@ -27,7 +25,6 @@ def scheduleShutdown(sendRestartTime, restart, message = "", delay=20):
restart -- if True, server will restart. if False, server will shudown
message -- if set, send that message to every client to warn about the shutdown/restart
"""
# Console output
log.info("Pep.py will {} in {} seconds!".format("restart" if restart else "shutdown", sendRestartTime+delay))
log.info("Sending server restart packets in {} seconds...".format(sendRestartTime))
@@ -49,27 +46,23 @@ def scheduleShutdown(sendRestartTime, restart, message = "", delay=20):
# Schedule actual server shutdown/restart some seconds after server restart packet, so everyone gets it
threading.Timer(sendRestartTime+delay, action).start()
def restartServer():
"""Restart pep.py script"""
log.info("Restarting pep.py...")
os.execv(sys.executable, [sys.executable] + sys.argv)
def shutdownServer():
"""Shutdown pep.py"""
log.info("Shutting down pep.py...")
sig = signal.SIGKILL if runningUnderUnix() else signal.CTRL_C_EVENT
os.kill(os.getpid(), sig)
def getSystemInfo():
"""
Get a dictionary with some system/server info
return -- ["unix", "connectedUsers", "webServer", "cpuUsage", "totalMemory", "usedMemory", "loadAverage"]
"""
data = {}
# Get if server is running under unix/nt

View File

@@ -14,9 +14,8 @@ def getID(username):
username -- user
return -- user id or False
"""
# Get user ID from db
userID = glob.db.fetch("SELECT id FROM users WHERE username = %s", [username])
userID = glob.db.fetch("SELECT id FROM users WHERE username = %s LIMIT 1", [username])
# Make sure the query returned something
if userID == None:
@@ -25,7 +24,6 @@ def getID(username):
# Return user ID
return userID["id"]
def checkLogin(userID, password):
"""
Check userID's login with specified password
@@ -35,9 +33,8 @@ def checkLogin(userID, password):
password -- plain md5 password
return -- True or False
"""
# Get password data
passwordData = glob.db.fetch("SELECT password_md5, salt, password_version FROM users WHERE id = %s", [userID])
passwordData = glob.db.fetch("SELECT password_md5, salt, password_version FROM users WHERE id = %s LIMIT 1", [userID])
# Make sure the query returned something
if passwordData == None:
@@ -51,8 +48,7 @@ def checkLogin(userID, password):
ok = passwordHelper.checkOldPassword(password, passwordData["salt"], passwordData["password_md5"])
if not ok: return False
newpass = passwordHelper.genBcrypt(password)
glob.db.execute("UPDATE users SET password_md5=%s, salt='', password_version='2' WHERE id = %s", [newpass, userID])
glob.db.execute("UPDATE users SET password_md5=%s, salt='', password_version='2' WHERE id = %s LIMIT 1", [newpass, userID])
def exists(userID):
"""
@@ -61,8 +57,7 @@ def exists(userID):
userID -- user ID to check
return -- bool
"""
result = glob.db.fetch("SELECT id FROM users WHERE id = %s", [userID])
result = glob.db.fetch("SELECT id FROM users WHERE id = %s LIMIT 1", [userID])
if result == None:
return False
else:
@@ -76,8 +71,7 @@ def getSilenceEnd(userID):
userID -- userID
return -- UNIX time
"""
return glob.db.fetch("SELECT silence_end FROM users WHERE id = %s", [userID])["silence_end"]
return glob.db.fetch("SELECT silence_end FROM users WHERE id = %s LIMIT 1", [userID])["silence_end"]
def silence(userID, seconds, silenceReason, author = 999):
@@ -91,7 +85,7 @@ def silence(userID, seconds, silenceReason, author = 999):
"""
# db qurey
silenceEndTime = int(time.time())+seconds
glob.db.execute("UPDATE users SET silence_end = %s, silence_reason = %s WHERE id = %s", [silenceEndTime, silenceReason, userID])
glob.db.execute("UPDATE users SET silence_end = %s, silence_reason = %s WHERE id = %s LIMIT 1", [silenceEndTime, silenceReason, userID])
# Loh
targetUsername = getUsername(userID)
@@ -109,9 +103,8 @@ def getRankedScore(userID, gameMode):
gameMode -- int value, see gameModes
return -- ranked score
"""
modeForDB = gameModes.getGameModeForDB(gameMode)
return glob.db.fetch("SELECT ranked_score_"+modeForDB+" FROM users_stats WHERE id = %s", [userID])["ranked_score_"+modeForDB]
return glob.db.fetch("SELECT ranked_score_"+modeForDB+" FROM users_stats WHERE id = %s LIMIT 1", [userID])["ranked_score_"+modeForDB]
def getTotalScore(userID, gameMode):
@@ -122,10 +115,8 @@ def getTotalScore(userID, gameMode):
gameMode -- int value, see gameModes
return -- total score
"""
modeForDB = gameModes.getGameModeForDB(gameMode)
return glob.db.fetch("SELECT total_score_"+modeForDB+" FROM users_stats WHERE id = %s", [userID])["total_score_"+modeForDB]
return glob.db.fetch("SELECT total_score_"+modeForDB+" FROM users_stats WHERE id = %s LIMIT 1", [userID])["total_score_"+modeForDB]
def getAccuracy(userID, gameMode):
"""
@@ -135,10 +126,8 @@ def getAccuracy(userID, gameMode):
gameMode -- int value, see gameModes
return -- accuracy
"""
modeForDB = gameModes.getGameModeForDB(gameMode)
return glob.db.fetch("SELECT avg_accuracy_"+modeForDB+" FROM users_stats WHERE id = %s", [userID])["avg_accuracy_"+modeForDB]
return glob.db.fetch("SELECT avg_accuracy_"+modeForDB+" FROM users_stats WHERE id = %s LIMIT 1", [userID])["avg_accuracy_"+modeForDB]
def getGameRank(userID, gameMode):
"""
@@ -150,13 +139,12 @@ def getGameRank(userID, gameMode):
"""
modeForDB = gameModes.getGameModeForDB(gameMode)
result = glob.db.fetch("SELECT position FROM leaderboard_"+modeForDB+" WHERE user = %s", [userID])
result = glob.db.fetch("SELECT position FROM leaderboard_"+modeForDB+" WHERE user = %s LIMIT 1", [userID])
if result == None:
return 0
else:
return result["position"]
def getPlaycount(userID, gameMode):
"""
Get userID's playcount relative to gameMode
@@ -167,8 +155,7 @@ def getPlaycount(userID, gameMode):
"""
modeForDB = gameModes.getGameModeForDB(gameMode)
return glob.db.fetch("SELECT playcount_"+modeForDB+" FROM users_stats WHERE id = %s", [userID])["playcount_"+modeForDB]
return glob.db.fetch("SELECT playcount_"+modeForDB+" FROM users_stats WHERE id = %s LIMIT 1", [userID])["playcount_"+modeForDB]
def getUsername(userID):
"""
@@ -178,8 +165,7 @@ def getUsername(userID):
return -- username
"""
return glob.db.fetch("SELECT username FROM users WHERE id = %s", [userID])["username"]
return glob.db.fetch("SELECT username FROM users WHERE id = %s LIMIT 1", [userID])["username"]
def getFriendList(userID):
"""
@@ -202,7 +188,6 @@ def getFriendList(userID):
# Return friend IDs
return friends
def addFriend(userID, friendID):
"""
Add friendID to userID's friend list
@@ -216,7 +201,7 @@ def addFriend(userID, friendID):
return
# check user isn't already a friend of ours
if glob.db.fetch("SELECT id FROM users_relationships WHERE user1 = %s AND user2 = %s", [userID, friendID]) != None:
if glob.db.fetch("SELECT id FROM users_relationships WHERE user1 = %s AND user2 = %s LIMIT 1", [userID, friendID]) != None:
return
# Set new value
@@ -230,7 +215,6 @@ def removeFriend(userID, friendID):
userID -- user
friendID -- old friend
"""
# Delete user relationship. We don't need to check if the relationship was there, because who gives a shit,
# if they were not friends and they don't want to be anymore, be it. ¯\_(ツ)_/¯
glob.db.execute("DELETE FROM users_relationships WHERE user1 = %s AND user2 = %s", [userID, friendID])
@@ -245,8 +229,7 @@ def getCountry(userID):
userID -- user
return -- country code (two letters)
"""
return glob.db.fetch("SELECT country FROM users_stats WHERE id = %s", [userID])["country"]
return glob.db.fetch("SELECT country FROM users_stats WHERE id = %s LIMIT 1", [userID])["country"]
def getPP(userID, gameMode):
"""
@@ -257,7 +240,7 @@ def getPP(userID, gameMode):
"""
modeForDB = gameModes.getGameModeForDB(gameMode)
return glob.db.fetch("SELECT pp_{} FROM users_stats WHERE id = %s".format(modeForDB), [userID])["pp_{}".format(modeForDB)]
return glob.db.fetch("SELECT pp_{} FROM users_stats WHERE id = %s LIMIT 1".format(modeForDB), [userID])["pp_{}".format(modeForDB)]
def setCountry(userID, country):
"""
@@ -266,7 +249,7 @@ def setCountry(userID, country):
userID -- userID
country -- country letters
"""
glob.db.execute("UPDATE users_stats SET country = %s WHERE id = %s", [country, userID])
glob.db.execute("UPDATE users_stats SET country = %s WHERE id = %s LIMIT 1", [country, userID])
def getShowCountry(userID):
"""
@@ -275,7 +258,7 @@ def getShowCountry(userID):
userID -- userID
return -- True if country is shown, False if it's hidden
"""
country = glob.db.fetch("SELECT show_country FROM users_stats WHERE id = %s", [userID])
country = glob.db.fetch("SELECT show_country FROM users_stats WHERE id = %s LIMIT 1", [userID])
if country == None:
return False
return generalFunctions.stringToBool(country)
@@ -292,25 +275,42 @@ def saveBanchoSession(userID, ip):
"""
Save userid and ip of this token in bancho_sessions table.
Used to cache logins on LETS requests
userID --
ip -- user's ip address
"""
log.debug("Saving bancho session ({}::{}) in db".format(userID, ip))
glob.db.execute("INSERT INTO bancho_sessions (id, userid, ip) VALUES (NULL, %s, %s)", [userID, ip])
def deleteBanchoSessions(userID, ip):
"""Delete this bancho session from DB"""
log.debug("Deleting bancho session ({}::{}) from db".format(userID, ip))
"""
Delete this bancho session from DB
userID --
ip -- user's IP address
"""
try:
glob.db.execute("DELETE FROM bancho_sessions WHERE userid = %s AND ip = %s", [userID, ip])
except:
log.warning("Token for user: {} ip: {} doesn't exist".format(userID, ip))
def is2FAEnabled(userID):
"""Returns True if 2FA is enable for this account"""
"""
Check if 2FA is enabled on an account
userID --
return -- True if 2FA is enabled, False if 2FA is disabled
"""
result = glob.db.fetch("SELECT id FROM 2fa_telegram WHERE userid = %s LIMIT 1", [userID])
return True if result is not None else False
def check2FA(userID, ip):
"""Returns True if this IP is untrusted"""
"""
Check if an ip is trusted
userID --
ip -- user's IP address
return -- True if the IP is untrusted, False if it's trusted
"""
if is2FAEnabled(userID) == False:
return False
@@ -353,7 +353,7 @@ def isAllowed(userID):
userID -- id of the user
return -- True if not banned or restricted, otherwise false.
"""
result = glob.db.fetch("SELECT privileges FROM users WHERE id = %s", [userID])
result = glob.db.fetch("SELECT privileges FROM users WHERE id = %s LIMIT 1", [userID])
if result != None:
return (result["privileges"] & privileges.USER_NORMAL) and (result["privileges"] & privileges.USER_PUBLIC)
else:
@@ -366,7 +366,7 @@ def isRestricted(userID):
userID -- id of the user
return -- True if not restricted, otherwise false.
"""
result = glob.db.fetch("SELECT privileges FROM users WHERE id = %s", [userID])
result = glob.db.fetch("SELECT privileges FROM users WHERE id = %s LIMIT 1", [userID])
if result != None:
return (result["privileges"] & privileges.USER_NORMAL) and not (result["privileges"] & privileges.USER_PUBLIC)
else:
@@ -379,7 +379,7 @@ def isBanned(userID):
userID -- id of the user
return -- True if not banned, otherwise false.
"""
result = glob.db.fetch("SELECT privileges FROM users WHERE id = %s", [userID])
result = glob.db.fetch("SELECT privileges FROM users WHERE id = %s LIMIT 1", [userID])
if result != None:
return not (result["privileges"] & 3 > 0)
else:
@@ -392,7 +392,7 @@ def ban(userID):
userID -- id of user
"""
banDateTime = int(time.time())
glob.db.execute("UPDATE users SET privileges = privileges & %s, ban_datetime = %s WHERE id = %s", [ ~(privileges.USER_NORMAL | privileges.USER_PUBLIC | privileges.USER_PENDING_VERIFICATION) , banDateTime, userID])
glob.db.execute("UPDATE users SET privileges = privileges & %s, ban_datetime = %s WHERE id = %s LIMIT 1", [ ~(privileges.USER_NORMAL | privileges.USER_PUBLIC | privileges.USER_PENDING_VERIFICATION) , banDateTime, userID])
def unban(userID):
"""
@@ -400,7 +400,7 @@ def unban(userID):
userID -- id of user
"""
glob.db.execute("UPDATE users SET privileges = privileges | %s, ban_datetime = 0 WHERE id = %s", [ (privileges.USER_NORMAL | privileges.USER_PUBLIC) , userID])
glob.db.execute("UPDATE users SET privileges = privileges | %s, ban_datetime = 0 WHERE id = %s LIMIT 1", [ (privileges.USER_NORMAL | privileges.USER_PUBLIC) , userID])
def restrict(userID):
"""
@@ -409,7 +409,7 @@ def restrict(userID):
userID -- id of user
"""
banDateTime = int(time.time())
glob.db.execute("UPDATE users SET privileges = privileges & %s, ban_datetime = %s WHERE id = %s", [~privileges.USER_PUBLIC, banDateTime, userID])
glob.db.execute("UPDATE users SET privileges = privileges & %s, ban_datetime = %s WHERE id = %s LIMIT 1", [~privileges.USER_PUBLIC, banDateTime, userID])
def unrestrict(userID):
"""
@@ -427,7 +427,7 @@ def getPrivileges(userID):
userID -- id of user
return -- privileges number
"""
result = glob.db.fetch("SELECT privileges FROM users WHERE id = %s", [userID])
result = glob.db.fetch("SELECT privileges FROM users WHERE id = %s LIMIT 1", [userID])
if result != None:
return result["privileges"]
else:
@@ -440,10 +440,10 @@ def setPrivileges(userID, priv):
userID -- id of user
priv -- privileges number
"""
glob.db.execute("UPDATE users SET privileges = %s WHERE id = %s", [priv, userID])
glob.db.execute("UPDATE users SET privileges = %s WHERE id = %s LIMIT 1", [priv, userID])
def isInPrivilegeGroup(userID, groupName):
groupPrivileges = glob.db.fetch("SELECT privileges FROM privileges_groups WHERE name = %s", [groupName])
groupPrivileges = glob.db.fetch("SELECT privileges FROM privileges_groups WHERE name = %s LIMIT 1", [groupName])
if groupPrivileges == None:
return False
groupPrivileges = groupPrivileges["privileges"]
@@ -465,7 +465,7 @@ def appendNotes(userID, notes, addNl = True):
"""
if addNl == True:
notes = "\n"+notes
glob.db.execute("UPDATE users SET notes=CONCAT(COALESCE(notes, ''),%s) WHERE id = %s", [notes, userID])
glob.db.execute("UPDATE users SET notes=CONCAT(COALESCE(notes, ''),%s) WHERE id = %s LIMIT 1", [notes, userID])
def logHardware(userID, hashes, activation = False):