From cce4361eebfc938ce7f6d3328f07c00aaba62400 Mon Sep 17 00:00:00 2001 From: moriartyj Date: Thu, 2 Jun 2016 14:17:52 -0700 Subject: [PATCH] Allows automatic update of Discord avatar to EVE avatar (#450) * Automatic rejection of old API IDs * Added API ID fudge factor * Added toggle-able options for api key rejection * Clarified ValidationError message * Allows automatic update of Discord avatar to EVE avatar --- services/forms.py | 1 + services/managers/discord_manager.py | 43 ++++++++++++++++++++++++---- services/views.py | 10 +++++++ 3 files changed, 48 insertions(+), 6 deletions(-) diff --git a/services/forms.py b/services/forms.py index 07ca928a..ada5347d 100644 --- a/services/forms.py +++ b/services/forms.py @@ -23,6 +23,7 @@ class FleetFormatterForm(forms.Form): class DiscordForm(forms.Form): email = forms.CharField(label="Email Address", required=True) password = forms.CharField(label="Password", required=True, widget=forms.PasswordInput) + update_avatar = forms.BooleanField(label="Update Avatar", required=False, initial=True) class ServicePasswordForm(forms.Form): password = forms.CharField(label="Password", required=True) diff --git a/services/managers/discord_manager.py b/services/managers/discord_manager.py index ef33dc99..b3540534 100644 --- a/services/managers/discord_manager.py +++ b/services/managers/discord_manager.py @@ -3,6 +3,8 @@ import json from django.conf import settings import re import os +import urllib +import base64 from services.models import DiscordAuthToken import logging @@ -10,6 +12,7 @@ import logging logger = logging.getLogger(__name__) DISCORD_URL = "https://discordapp.com/api" +EVE_IMAGE_SERVER = "https://image.eveonline.com" class DiscordAPIManager: @@ -260,8 +263,8 @@ class DiscordAPIManager: return r.json() @staticmethod - def get_user_profile(email, password): - token = DiscordAPIManager.get_token_by_user(email, password) + def get_user_profile(email, password, user): + token = DiscordAPIManager.get_token_by_user(email, password, user) custom_headers = {'accept': 'application/json', 'authorization': token} path = DISCORD_URL + "/users/@me" r = requests.get(path, headers=custom_headers) @@ -270,8 +273,8 @@ class DiscordAPIManager: return r.json() @staticmethod - def set_user_password(email, current_password, new_password): - profile = DiscordAPIManager.get_user_profile(email, current_password) + def set_user_password(email, current_password, new_password, user): + profile = DiscordAPIManager.get_user_profile(email, current_password, user) avatar = profile['avatar'] username = profile['username'] data = { @@ -287,6 +290,23 @@ class DiscordAPIManager: r.raise_for_status() return r.json() + @staticmethod + def set_user_avatar(email, current_password, user, avatar_url): + profile = DiscordAPIManager.get_user_profile(email, current_password, user) + avatar = "data:image/jpeg;base64," + base64.b64encode(urllib.urlopen(avatar_url).read()) + username = profile['username'] + data = { + 'avatar': avatar, + 'username': username, + 'password': current_password, + 'email': email + } + path = DISCORD_URL + "/users/@me" + custom_headers = {'content-type':'application/json', 'authorization': DiscordAPIManager.get_token_by_user(email, current_password, user)} + r = requests.patch(path, headers=custom_headers, data=json.dumps(data)) + r.raise_for_status() + return r.json() + @staticmethod def destroy_user(email, current_password): data = { @@ -372,14 +392,24 @@ class DiscordManager: return False @staticmethod - def update_user_password(email, current_password): + def update_user_password(email, current_password, user): new_password = DiscordManager.__generate_random_pass() try: - profile = DiscordAPIManager.set_user_password(email, current_password, new_password) + profile = DiscordAPIManager.set_user_password(email, current_password, new_password, user) return new_password except: return current_password + @staticmethod + def update_user_avatar(email, password, user, char_id): + try: + char_url = EVE_IMAGE_SERVER + "/character/" + str(char_id) + "_256.jpg" + logger.debug("Character image URL for %s: %s" % (user, char_url)) + DiscordAPIManager.set_user_avatar(email, password, user, char_url) + return True + except: + return False + @staticmethod def add_user(email, password, user): try: @@ -390,6 +420,7 @@ class DiscordManager: logger.debug("Got profile for user: %s" % profile) user_id = profile['id'] logger.debug("Determined user id: %s" % user_id) + if server_api.check_if_user_banned(user_id): logger.debug("User is currently banned. Unbanning %s" % user_id) server_api.unban_user(user_id) diff --git a/services/views.py b/services/views.py index e136a102..1fa5e797 100755 --- a/services/views.py +++ b/services/views.py @@ -465,6 +465,8 @@ def activate_discord(request): logger.debug("Form contains email address beginning with %s" % email[0:3]) password = form.cleaned_data['password'] logger.debug("Form contains password of length %s" % len(password)) + update_avatar = form.cleaned_data['update_avatar'] + logger.debug("Form contains update_avatar set to %r" % bool(update_avatar)) try: user_id = DiscordManager.add_user(email, password, request.user) logger.debug("Received discord uid %s" % user_id) @@ -475,6 +477,14 @@ def activate_discord(request): logger.debug("Updated discord groups for user %s." % request.user) success = True logger.info("Succesfully activated discord for user %s" % request.user) + if (update_avatar): + authinfo = AuthServicesInfoManager.get_auth_service_info(request.user) + char_id = authinfo.main_char_id + avatar_updated = DiscordManager.update_user_avatar(email, password, request.user, char_id) + if (avatar_updated): + logger.debug("Updated user %s discord avatar." % request.user) + else: + logger.debug("Could not set user %s discord avatar." %request.user) return HttpResponseRedirect("/services/") except: logger.exception("An unhandled exception has occured.")