From 8442ec1f5561e44602a5e77e2e3231a1dd9d3a9e Mon Sep 17 00:00:00 2001 From: Adarnof Date: Wed, 2 Dec 2015 01:02:13 +0000 Subject: [PATCH] Changed discord account handling. Now requests email and password and grabs UID via API. UID is stored in authserviceinfo model and used as required. --- authentication/managers.py | 7 ++- authentication/models.py | 3 +- celerytask/tasks.py | 4 +- services/forms.py | 4 ++ services/managers/discord_manager.py | 55 +++++++++++++++++++----- services/views.py | 37 +++++++++++++--- stock/templates/registered/discord.html | 33 ++++++++++++++ stock/templates/registered/services.html | 12 +++--- util/common_task.py | 6 +-- 9 files changed, 127 insertions(+), 34 deletions(-) create mode 100644 stock/templates/registered/discord.html diff --git a/authentication/managers.py b/authentication/managers.py index 26d2cdd8..0cea7a07 100755 --- a/authentication/managers.py +++ b/authentication/managers.py @@ -81,9 +81,8 @@ class AuthServicesInfoManager: authserviceinfo.save(update_fields=['is_blue']) @staticmethod - def update_user_discord_info(username, password, user): + def update_user_discord_info(user_id, user): if User.objects.filter(username=user.username).exists(): authserviceinfo = AuthServicesInfoManager.__get_or_create(user) - authserviceinfo.discord_username = username - authserviceinfo.discord_password = password - authserviceinfo.save(update_fields=['discord_username', 'discord_password']) + authserviceinfo.discord_uid = user_id + authserviceinfo.save(update_fields=['discord_uid']) diff --git a/authentication/models.py b/authentication/models.py index 29bbbeec..0727e79d 100755 --- a/authentication/models.py +++ b/authentication/models.py @@ -13,8 +13,7 @@ class AuthServicesInfo(models.Model): mumble_password = models.CharField(max_length=254, default="") teamspeak3_uid = models.CharField(max_length=254, default="") teamspeak3_perm_key = models.CharField(max_length=254, default="") - discord_username = models.CharField(max_length=254, default="") - discord_password = models.CharField(max_length=254, default="") + discord_uid = models.CharField(max_length=254, default="") main_char_id = models.CharField(max_length=64, default="") is_blue = models.BooleanField(default=False) user = models.ForeignKey(User) diff --git a/celerytask/tasks.py b/celerytask/tasks.py index 154e1d5c..af5b322c 100755 --- a/celerytask/tasks.py +++ b/celerytask/tasks.py @@ -116,7 +116,7 @@ def update_discord_groups(user): if len(groups) == 0: groups.append('empty') - DiscordManager.update_groups(authserviceinfo.discord_username, groups) + DiscordManager.update_groups(authserviceinfo.discord_uid, groups) def create_syncgroup_for_user(user, groupname, servicename): synccache = SyncGroupCache() @@ -196,7 +196,7 @@ def remove_from_databases(user, groups, syncgroups): update_ipboard_groups(user) if authserviceinfo.teamspeak3_uid and authserviceinfo.teamspeak3_uid != "": update_teamspeak3_groups(user) - if authserviceinfo.discord_username and authserviceinfo.discord_username != "": + if authserviceinfo.discord_uid and authserviceinfo.discord_uid != "": update_discord_groups(user) diff --git a/services/forms.py b/services/forms.py index cd322c0c..f96c404b 100644 --- a/services/forms.py +++ b/services/forms.py @@ -24,3 +24,7 @@ class FleetFormatterForm(forms.Form): reimbursable = forms.ChoiceField(label='Reimbursable?*', choices=[('Yes', 'Yes'), ('No', 'No')], required=True) important = forms.ChoiceField(label='Important?*', choices=[('Yes', 'Yes'), ('No', 'No')], required=True) comments = forms.CharField(widget=forms.Textarea, required=False) + +class DiscordForm(forms.Form): + email = forms.CharField(label="Email Address", required=True) + password = forms.CharField(label="Password", required=True) diff --git a/services/managers/discord_manager.py b/services/managers/discord_manager.py index d246d091..3613833a 100644 --- a/services/managers/discord_manager.py +++ b/services/managers/discord_manager.py @@ -117,8 +117,8 @@ class DiscordAPIManager: return r.json() @staticmethod - def accept_invite(invite_id): - custom_headers = {'accept': 'application/json'} + def accept_invite(invite_id, token): + custom_headers = {'accept': 'application/json', 'authorization': token} path = DISCORD_URL + "/invite/" + str(invite_id) r = requests.post(path, headers=custom_headers) r.raise_for_status() @@ -259,6 +259,14 @@ class DiscordAPIManager: r.raise_for_status return r.json() + @staticmethod + def check_if_user_banned(server_id, user_id): + bans = DiscordAPIManager.get_bans(server_id) + for b in bans: + if b['user']['id'] == str(user_id): + return True + return False + class DiscordManager: def __init__(self): pass @@ -273,7 +281,7 @@ class DiscordManager: return os.urandom(8).encode('hex') @staticmethod - def add_user(username, email): + def old_add_user(username, email): try: username_clean = DiscordManager.__sanatize_username(username) invite_code = DiscordAPIManager.create_invite(settings.DISCORD_SERVER_ID)['code'] @@ -286,7 +294,7 @@ class DiscordManager: return "", "" @staticmethod - def delete_user(username, email, password): + def old_delete_user(username, email, password): try: user_id = DiscordAPIManager.get_user_id(settings.DISCORD_SERVER_ID, username) DiscordAPIManager.kick_user(settings.DISCORD_SERVER_ID, user_id) @@ -298,8 +306,7 @@ class DiscordManager: return False @staticmethod - def update_groups(username, groups): - user_id = DiscordAPIManager.get_user_id(settings.DISCORD_SERVER_ID, username) + def update_groups(user_id, groups): group_ids = [] for g in groups: try: @@ -317,18 +324,16 @@ class DiscordManager: return named_group['id'] @staticmethod - def lock_user(username): + def lock_user(user_id): try: - user_id = DiscordAPIManager.get_user_id(username) DiscordAPIManager.ban_user(settings.DISCORD_SERVER_ID, user_id) return True except: return False @staticmethod - def unlock_user(username): + def unlock_user(user_id): try: - user_id = DiscordAPIManager.get_user_id(username) DiscordAPIManager.unban_user(settings.DISCORD_SERVER_ID, user_id) return True except: @@ -342,3 +347,33 @@ class DiscordManager: return new_password except: return current_password + + @staticmethod + def get_user_id(email, password): + try: + profile = DiscordAPIManager.get_user_profile(email, password) + return profile['user']['id'] + except: + return "" + + @staticmethod + def add_user(email, password): + try: + profile = DiscordAPIManager.get_user_profile(email, password) + user_id = profile['id'] + if DiscordAPIManager.check_if_user_banned(settings.DISCORD_SERVER_ID, user_id): + DiscordAPIManager.unban_user(settings.DISCORD_SERVER_ID, user_id) + invite_code = DiscordAPIManager.create_invite(settings.DISCORD_SERVER_ID)['code'] + token = DiscordAPIManager.get_token_by_user(email, password) + DiscordAPIManager.accept_invite(invite_code, token) + return user_id + except: + return "" + + @staticmethod + def delete_user(user_id): + try: + DiscordAPIManager.ban_user(settings.DISCORD_SERVER_ID, user_id) + return True + except: + return False diff --git a/services/views.py b/services/views.py index 9def2d09..232c7a4b 100755 --- a/services/views.py +++ b/services/views.py @@ -24,6 +24,7 @@ from celerytask.tasks import update_teamspeak3_groups from celerytask.tasks import update_discord_groups from forms import JabberBroadcastForm from forms import FleetFormatterForm +from forms import DiscordForm from util import check_if_user_has_permission import threading @@ -322,7 +323,7 @@ context_instance=RequestContext(request)) @login_required @user_passes_test(service_blue_alliance_test) -def activate_discord(request): +def old_activate_discord(request): authinfo = AuthServicesInfoManager.get_auth_service_info(request.user) character = EveManager.get_character_by_id(authinfo.main_char_id) info = DiscordManager.add_user(character.character_name, request.user.email) @@ -337,10 +338,10 @@ def activate_discord(request): @user_passes_test(service_blue_alliance_test) def deactivate_discord(request): authinfo = AuthServicesInfoManager.get_auth_service_info(request.user) - result = DiscordManager.delete_user(authinfo.discord_username, request.user.email, authinfo.discord_password) + result = DiscordManager.delete_user(authinfo.discord_uid) remove_all_syncgroups_for_service(request.user, "discord") if result: - AuthServicesInfoManager.update_user_discord_info("", "", request.user) + AuthServicesInfoManager.update_user_discord_info("",request.user) return HttpResponseRedirect("/services/") return HttpResponseRedirect("/dashboard") @@ -348,9 +349,31 @@ def deactivate_discord(request): @user_passes_test(service_blue_alliance_test) def reset_discord(request): authinfo = AuthServicesInfoManager.get_auth_service_info(request.user) - result = DiscordManager.update_user_password(request.user.email, authinfo.discord_password) + result = DiscordManager.delete_user(authinfo.discord_uid) if result: - AuthServicesInfoManager.update_user_discord_info(authinfo.discord_username, result, request.user) - update_discord_groups(request.user) - return HttpResponseRedirect("/services/") + AuthServicesInfoManager.update_user_discord_info("",request.user) + return HttpResponseRedirect("/activate_discord/") return HttpResponseRedirect("/services/") + +@login_required +@user_passes_test(service_blue_alliance_test) +def activate_discord(request): + success = False + if request.method == 'POST': + form = DiscordForm(request.POST) + if form.is_valid(): + email = form.cleaned_data['email'] + password = form.cleaned_data['password'] + try: + user_id = DiscordManager.add_user(email, password) + AuthServicesInfoManager.update_user_discord_info(user_id, request.user) + update_discord_groups(request.user) + success = True + return HttpResponseRedirect("/services/") + except: + pass + else: + form = DiscordForm() + + context = {'form': form, 'success': success} + return render_to_response('registered/discord.html', context, context_instance=RequestContext(request)) diff --git a/stock/templates/registered/discord.html b/stock/templates/registered/discord.html new file mode 100644 index 00000000..4204d5fe --- /dev/null +++ b/stock/templates/registered/discord.html @@ -0,0 +1,33 @@ +{% extends "public/base.html" %} +{% load bootstrap %} +{% load staticfiles %} + +{% block title %}Alliance Auth{% endblock %} + +{% block page_title %}Jabber Broadcast{% endblock page_title %} +{% block extra_css %}{% endblock extra_css %} + +{% block content %} +
+

Discord Connection

+ +
+
+
+ {% if success %} + + {% endif %} +

Enter your discord account credentials below. These are not stored: they are needed to determine your user ID and make you join the server.

+ +
+
+
+
+ +{% endblock content %} diff --git a/stock/templates/registered/services.html b/stock/templates/registered/services.html index 0f65ed09..9a40e658 100755 --- a/stock/templates/registered/services.html +++ b/stock/templates/registered/services.html @@ -117,11 +117,11 @@ {% if ENABLE_BLUE_DISCORD %} Discord - {{ authinfo.discord_username }} - {{ authinfo.discord_password }} + {{ authinfo.discord_uid }} + https://discordapp.com - {% ifequal authinfo.discord_username "" %} + {% ifequal authinfo.discord_uid "" %} @@ -288,11 +288,11 @@ {% if ENABLE_AUTH_DISCORD %} Discord - {{ authinfo.discord_username }} - {{ authinfo.discord_password }} + {{ authinfo.discord_uid }} + https://discordapp.com - {% ifequal authinfo.discord_username "" %} + {% ifequal authinfo.discord_uid "" %} diff --git a/util/common_task.py b/util/common_task.py index eb61672e..fe312f95 100755 --- a/util/common_task.py +++ b/util/common_task.py @@ -42,9 +42,9 @@ def deactivate_services(user): if authinfo.teamspeak3_uid and authinfo.teamspeak3_uid != "": Teamspeak3Manager.delete_user(authinfo.teamspeak3_uid) AuthServicesInfoManager.update_user_teamspeak3_info("", "", user) - if authinfo.discord_username and authinfo.discord_username != "": - DiscordManager.lock_user(authinfo.discord_username) - AuthServicesInfoManager.update_user_discord_info("", "", user) + if authinfo.discord_uid and authinfo.discord_uid != "": + DiscordManager.delete_user(authinfo.discord_uid) + AuthServicesInfoManager.update_user_discord_info("", user) def generate_corp_group_name(corpname):