Rolled back Discord managers to fix #235

Commit chosen: 08cd2c1f1ade6845f5710329b0beab47ab7df6aa
Additional security implemented: tokens deleted for users after succesful addition to discord server.
 - prevents another user from authenticating with their email and wrong password
This commit is contained in:
Adarnof 2016-02-09 12:32:08 +00:00
parent 7ca6decc12
commit e5d8c62674

View File

@ -13,8 +13,8 @@ DISCORD_URL = "https://discordapp.com/api"
class DiscordAPIManager: class DiscordAPIManager:
def __init__(self, server_id, email, password, user=None): def __init__(self, server_id, email, password):
self.token = DiscordAPIManager.get_token_by_user(email, password, user) self.token = DiscordAPIManager.get_token_by_user(email, password)
self.email = email self.email = email
self.password = password self.password = password
self.server_id = server_id self.server_id = server_id
@ -131,8 +131,9 @@ class DiscordAPIManager:
r.raise_for_status() r.raise_for_status()
return r.json() return r.json()
def accept_invite(self, invite_id): @staticmethod
custom_headers = {'accept': 'application/json', 'authorization': self.token} def accept_invite(invite_id, token):
custom_headers = {'accept': 'application/json', 'authorization': token}
path = DISCORD_URL + "/invite/" + str(invite_id) path = DISCORD_URL + "/invite/" + str(invite_id)
r = requests.post(path, headers=custom_headers) r = requests.post(path, headers=custom_headers)
logger.debug("Received status code %s after accepting invite." % r.status_code) logger.debug("Received status code %s after accepting invite." % r.status_code)
@ -222,20 +223,17 @@ class DiscordAPIManager:
raise KeyError('Group not found on server: ' + group_name) raise KeyError('Group not found on server: ' + group_name)
@staticmethod @staticmethod
def get_token_by_user(email, password, user): def get_token_by_user(email, password):
if DiscordAuthToken.objects.filter(email=email).exists(): if DiscordAuthToken.objects.filter(email=email).exists():
auth = DiscordAuthToken.objects.get(email=email)
if not auth.user == user:
raise ValueError("User mismatch while validating DiscordAuthToken for email %s - user %s, requesting user %s" % (email, auth.user, user))
logger.debug("Discord auth token cached for supplied email starting with %s" % email[0:3]) logger.debug("Discord auth token cached for supplied email starting with %s" % email[0:3])
auth = DiscordAuthToken.objects.get(email=email, user=user) auth = DiscordAuthToken.objects.get(email=email)
if DiscordAPIManager.validate_token(auth.token): if DiscordAPIManager.validate_token(auth.token):
logger.debug("Token still valid. Returning token starting with %s" % auth.token[0:5]) logger.debug("Token still valid. Returning token starting with %s" % auth.token[0:5])
return auth.token return auth.token
else: else:
logger.debug("Token has expired. Deleting.") logger.debug("Token has expired. Deleting.")
auth.delete() auth.delete()
logger.debug("Generating auth token for email starting with %s user %s and password of length %s" % (email[0:3], user, len(password))) logger.debug("Generating auth token for email starting with %s and password of length %s" % (email[0:3], len(password)))
data = { data = {
"email" : email, "email" : email,
"password": password, "password": password,
@ -246,19 +244,11 @@ class DiscordAPIManager:
logger.debug("Received status code %s after generating auth token for custom user." % r.status_code) logger.debug("Received status code %s after generating auth token for custom user." % r.status_code)
r.raise_for_status() r.raise_for_status()
token = r.json()['token'] token = r.json()['token']
auth = DiscordAuthToken(email=email, token=token, user=user) auth = DiscordAuthToken(email=email, token=token)
auth.save() auth.save()
logger.debug("Created cached token for email starting with %s" % email[0:3]) logger.debug("Created cached token for email starting with %s" % email[0:3])
return token return token
def get_profile(self):
custom_headers = {'accept': 'application/json', 'authorization': self.token}
path = DISCORD_URL + "/users/@me"
r = requests.get(path, headers=custom_headers)
logger.debug("Received status code %s after retrieving user profile with email %s" % (r.status_code, self.email[0:3]))
r.raise_for_status()
return r.json()
@staticmethod @staticmethod
def get_user_profile(email, password): def get_user_profile(email, password):
token = DiscordAPIManager.get_token_by_user(email, password) token = DiscordAPIManager.get_token_by_user(email, password)
@ -381,25 +371,26 @@ class DiscordManager:
return current_password return current_password
@staticmethod @staticmethod
def add_user(email, password, user): def add_user(email, password):
try: try:
logger.debug("Adding new user %s to discord with email %s and password of length %s" % (user, email[0:3], len(password))) logger.debug("Adding new user to discord with email %s and password of length %s" % (email[0:3], len(password)))
server_api = DiscordAPIManager(settings.DISCORD_SERVER_ID, settings.DISCORD_USER_EMAIL, settings.DISCORD_USER_PASSWORD) api = DiscordAPIManager(settings.DISCORD_SERVER_ID, settings.DISCORD_USER_EMAIL, settings.DISCORD_USER_PASSWORD)
user_api = DiscordAPIManager(settings.DISCORD_SERVER_ID, email, password, user=user) profile = DiscordAPIManager.get_user_profile(email, password)
profile = user_api.get_profile()
logger.debug("Got profile for user: %s" % profile) logger.debug("Got profile for user: %s" % profile)
user_id = profile['id'] user_id = profile['id']
logger.debug("Determined user id: %s" % user_id) logger.debug("Determined user id: %s" % user_id)
if server_api.check_if_user_banned(user_id): if api.check_if_user_banned(user_id):
logger.debug("User is currently banned. Unbanning %s" % user_id) logger.debug("User is currently banned. Unbanning %s" % user_id)
server_api.unban_user(user_id) api.unban_user(user_id)
invite_code = server_api.create_invite()['code'] invite_code = api.create_invite()['code']
logger.debug("Generated invite code beginning with %s" % invite_code[0:5]) logger.debug("Generated invite code beginning with %s" % invite_code[0:5])
user_api.accept_invite(invite_code) token = DiscordAPIManager.get_token_by_user(email, password)
logger.debug("Got auth token for supplied credentials beginning with %s" % token[0:5])
DiscordAPIManager.accept_invite(invite_code, token)
logger.info("Added user to discord server %s with id %s" % (settings.DISCORD_SERVER_ID, user_id)) logger.info("Added user to discord server %s with id %s" % (settings.DISCORD_SERVER_ID, user_id))
return user_id return user_id
except: except:
logger.exception("An unhandled exception has occured.") logger.exception("An unhandled exception has occured.", exc_info=True)
return "" return ""
@staticmethod @staticmethod
@ -412,5 +403,5 @@ class DiscordManager:
logger.info("Deleted user with id %s from discord server id %s" % (user_id, settings.DISCORD_SERVER_ID)) logger.info("Deleted user with id %s from discord server id %s" % (user_id, settings.DISCORD_SERVER_ID))
return True return True
except: except:
logger.exception("An unhandled exception has occured.") logger.exception("An unhandled exception has occured.", exc_info=True)
return False return False