pep.py/events/loginEvent.py
2016-07-31 11:11:24 +02:00

192 lines
7.0 KiB
Python

from helpers import userHelper
from constants import serverPackets
from constants import exceptions
from objects import glob
from helpers import consoleHelper
from constants import bcolors
from helpers import locationHelper
from helpers import countryHelper
import time
from helpers import generalFunctions
from events import channelJoinEvent
import sys
import traceback
from helpers import requestHelper
from helpers import discordBotHelper
def handle(tornadoRequest):
# Data to return
responseTokenString = "ayy"
responseData = bytes()
# Get IP from flask request
requestIP = tornadoRequest.getRequestIP()
# Console output
print("> Accepting connection from {}...".format(requestIP))
# Split POST body so we can get username/password/hardware data
# 2:-3 thing is because requestData has some escape stuff that we don't need
loginData = str(tornadoRequest.request.body)[2:-3].split("\\n")
# Process login
print("> Processing login request for {}...".format(loginData[0]))
try:
# If true, print error to console
err = False
# Try to get the ID from username
userID = userHelper.getID(str(loginData[0]))
if userID == False:
# Invalid username
raise exceptions.loginFailedException()
if userHelper.checkLogin(userID, loginData[1]) == False:
# Invalid password
raise exceptions.loginFailedException()
# Make sure we are not banned
userAllowed = userHelper.getAllowed(userID)
if userAllowed == 0:
# Banned
raise exceptions.loginBannedException()
# Log user IP
userHelper.IPLog(userID, requestIP)
# No login errors!
# Delete old tokens for that user and generate a new one
glob.tokens.deleteOldTokens(userID)
responseToken = glob.tokens.addToken(userID)
responseTokenString = responseToken.token
# Get silence end
userSilenceEnd = max(0, userHelper.getSilenceEnd(userID)-int(time.time()))
# Get supporter/GMT
userRank = userHelper.getRankPrivileges(userID)
userGMT = False
userSupporter = True
if userRank >= 3:
userGMT = True
# Server restarting check
if glob.restarting == True:
raise exceptions.banchoRestartingException()
# Maintenance check
if glob.banchoConf.config["banchoMaintenance"] == True:
if userGMT == False:
# We are not mod/admin, delete token, send notification and logout
glob.tokens.deleteToken(responseTokenString)
raise exceptions.banchoMaintenanceException()
else:
# We are mod/admin, send warning notification and continue
responseToken.enqueue(serverPackets.notification("Bancho is in maintenance mode. Only mods/admins have full access to the server.\nType !system maintenance off in chat to turn off maintenance mode."))
# Send all needed login packets
responseToken.enqueue(serverPackets.silenceEndTime(userSilenceEnd))
responseToken.enqueue(serverPackets.userID(userID))
responseToken.enqueue(serverPackets.protocolVersion())
responseToken.enqueue(serverPackets.userSupporterGMT(userSupporter, userGMT))
responseToken.enqueue(serverPackets.userPanel(userID))
responseToken.enqueue(serverPackets.userStats(userID))
# Channel info end (before starting!?! wtf bancho?)
responseToken.enqueue(serverPackets.channelInfoEnd())
# Default opened channels
# TODO: Configurable default channels
channelJoinEvent.joinChannel(responseToken, "#osu")
channelJoinEvent.joinChannel(responseToken, "#announce")
if userRank >= 3:
# Join admin chanenl if we are mod/admin
# TODO: Separate channels for mods and admins
channelJoinEvent.joinChannel(responseToken, "#admin")
# Output channels info
for key, value in glob.channels.channels.items():
if value.publicRead == True:
responseToken.enqueue(serverPackets.channelInfo(key))
responseToken.enqueue(serverPackets.friendList(userID))
# Send main menu icon and login notification if needed
if glob.banchoConf.config["menuIcon"] != "":
responseToken.enqueue(serverPackets.mainMenuIcon(glob.banchoConf.config["menuIcon"]))
if glob.banchoConf.config["loginNotification"] != "":
responseToken.enqueue(serverPackets.notification(glob.banchoConf.config["loginNotification"]))
# Get everyone else userpanel
# TODO: Better online users handling
for key, value in glob.tokens.tokens.items():
responseToken.enqueue(serverPackets.userPanel(value.userID))
responseToken.enqueue(serverPackets.userStats(value.userID))
# Send online users IDs array
responseToken.enqueue(serverPackets.onlineUsers())
# Get location and country from ip.zxq.co or database
if generalFunctions.stringToBool(glob.conf.config["server"]["localizeusers"]):
# Get location and country from IP
location = locationHelper.getLocation(requestIP)
countryLetters = locationHelper.getCountry(requestIP)
country = countryHelper.getCountryID(countryLetters)
else:
# Set location to 0,0 and get country from db
print("[!] Location skipped")
location = [0,0]
countryLetters = "XX"
country = countryHelper.getCountryID(userHelper.getCountry(userID))
# Set location and country
responseToken.setLocation(location)
responseToken.setCountry(country)
# Set country in db if user has no country (first bancho login)
if userHelper.getCountry(userID) == "XX":
userHelper.setCountry(userID, countryLetters)
# Send to everyone our userpanel and userStats (so they now we have logged in)
glob.tokens.enqueueAll(serverPackets.userPanel(userID))
glob.tokens.enqueueAll(serverPackets.userStats(userID))
# Set reponse data to right value and reset our queue
responseData = responseToken.queue
responseToken.resetQueue()
# Print logged in message
consoleHelper.printColored("> {} logged in ({})".format(loginData[0], responseToken.token), bcolors.GREEN)
except exceptions.loginFailedException:
# Login failed error packet
# (we don't use enqueue because we don't have a token since login has failed)
err = True
responseData += serverPackets.loginFailed()
except exceptions.loginBannedException:
# Login banned error packet
err = True
responseData += serverPackets.loginBanned()
except exceptions.banchoMaintenanceException:
# Bancho is in maintenance mode
responseData += serverPackets.notification("Our bancho server is in maintenance mode. Please try to login again later.")
responseData += serverPackets.loginError()
except exceptions.banchoRestartingException:
# Bancho is restarting
responseData += serverPackets.notification("Bancho is restarting. Try again in a few minutes.")
responseData += serverPackets.loginError()
except:
# Unknown exception
msg = "UNKNOWN ERROR IN LOGIN!!!\n{}\n{}".format(sys.exc_info(), traceback.format_exc())
consoleHelper.printColored("[!] {}".format(msg), bcolors.RED)
finally:
# Print login failed message to console if needed
if err == True:
consoleHelper.printColored("> {}'s login failed".format(loginData[0]), bcolors.YELLOW)
# Discord message
discordBotHelper.sendConfidential("Bancho login request from {} for user {} ({})".format(requestIP, loginData[0], "failed" if err == True else "success"))
# Return token string and data
return (responseTokenString, responseData)