diff --git a/alliance_auth/settings.py.example b/alliance_auth/settings.py.example index 58257a5c..22d53359 100644 --- a/alliance_auth/settings.py.example +++ b/alliance_auth/settings.py.example @@ -454,6 +454,7 @@ TEAMSPEAK3_PUBLIC_URL = os.environ.get('AA_TEAMSPEAK3_PUBLIC_URL', 'yourdomain.c # DISCORD_APP_ID - oauth app client ID # DISCORD_APP_SECRET - oauth app secret # DISCORD_CALLBACK_URL - oauth callback url +# DISCORD_SYNC_NAMES - enable to force discord nicknames to be set to eve char name (bot needs Manage Nicknames permission) ###################################### DISCORD_GUILD_ID = os.environ.get('AA_DISCORD_GUILD_ID', '') DISCORD_BOT_TOKEN = os.environ.get('AA_DISCORD_BOT_TOKEN', '') @@ -461,6 +462,7 @@ DISCORD_INVITE_CODE = os.environ.get('AA_DISCORD_INVITE_CODE', '') DISCORD_APP_ID = os.environ.get('AA_DISCORD_APP_ID', '') DISCORD_APP_SECRET = os.environ.get('AA_DISCORD_APP_SECRET', '') DISCORD_CALLBACK_URL = os.environ.get('AA_DISCORD_CALLBACK_URL', 'http://mydomain.com/discord_callback') +DISCORD_SYNC_NAMES = 'True' == os.environ.get('AA_DISCORD_SYNC_NAMES', 'False') ###################################### # Discourse Configuration diff --git a/celerytask/tasks.py b/celerytask/tasks.py index ddd1fc7b..cae230ff 100644 --- a/celerytask/tasks.py +++ b/celerytask/tasks.py @@ -224,6 +224,26 @@ def update_all_discord_groups(): for user in AuthServicesInfo.objects.exclude(discord_uid__exact=''): update_discord_groups.delay(user.user_id) +@task +def update_discord_nickname(pk): + user = User.objects.get(pk=pk) + logger.debug("Updating discord nickname for user %s" % user) + authserviceinfo = AuthServicesInfo.objects.get(user=user) + character = EveManager.get_character_by_id(authserviceinfo.main_char_id) + logger.debug("Updating user %s discord nickname to %s" % (user, character.character_name)) + try: + DiscordOAuthManager.update_nickname(authserviceinfo.discord_uid, character.character_name) + except: + logger.exception("Discord nickname sync failed for %s, retrying in 10 mins" % user) + raise self.retry(countdown = 60 * 10) + logger.debug("Updated user %s discord nickname." % user) + +@task +def update_all_discord_nicknames(): + logger.debug("Updating ALL discord nicknames") + for user in AuthServicesInfo.objects.exclude(discord_uid__exact=''): + update_discord_nickname(user.user_id) + @task def update_discourse_groups(pk): user = User.objects.get(pk=pk) diff --git a/services/managers/discord_manager.py b/services/managers/discord_manager.py index e73ca679..5bc66e1c 100644 --- a/services/managers/discord_manager.py +++ b/services/managers/discord_manager.py @@ -452,7 +452,7 @@ AUTH_URL = "https://discordapp.com/api/oauth2/authorize" TOKEN_URL = "https://discordapp.com/api/oauth2/token" # kick, manage roles -BOT_PERMISSIONS = 0x00000002 + 0x10000000 +BOT_PERMISSIONS = 0x00000002 + 0x10000000 + 0x08000000 # get user ID, accept invite SCOPES = [ @@ -503,6 +503,23 @@ class DiscordOAuthManager: logger.exception("Failed to add Discord user") return None + @staticmethod + def update_nickname(user_id, nickname): + try: + custom_headers = {'content-type':'application/json', 'authorization': 'Bot ' + settings.DISCORD_BOT_TOKEN} + data = { 'nick': nickname, } + path = DISCORD_URL + "/guilds/" + str(settings.DISCORD_GUILD_ID) + "/members/" + str(user_id) + r = requests.patch(path, headers=custom_headers, json=data) + logger.debug("Got status code %s after setting nickname for Discord user ID %s (%s)" % (r.status_code, user_id, nickname)) + if r.status_code == 404: + logger.warn("Discord user ID %s could not be found in server." % user_id) + return True + r.raise_for_status() + return True + except: + logger.exception("Failed to set nickname for Discord user ID %s (%s)" % (user_id, nickname)) + return False + @staticmethod def delete_user(user_id): try: diff --git a/services/views.py b/services/views.py index bb5edc01..f931ab8f 100755 --- a/services/views.py +++ b/services/views.py @@ -5,6 +5,7 @@ from django.contrib.auth.decorators import login_required from django.contrib.auth.decorators import permission_required from django.contrib.auth.decorators import user_passes_test from django.contrib.auth.models import Group +from django.conf import settings from eveonline.models import EveCharacter from eveonline.models import EveAllianceInfo @@ -30,6 +31,7 @@ from celerytask.tasks import update_ipboard_groups from celerytask.tasks import update_smf_groups from celerytask.tasks import update_teamspeak3_groups from celerytask.tasks import update_discord_groups +from celerytask.tasks import update_discord_nickname from celerytask.tasks import update_discourse_groups from forms import JabberBroadcastForm from forms import FleetFormatterForm @@ -557,6 +559,8 @@ def discord_callback(request): user_id = DiscordOAuthManager.add_user(code) if user_id: AuthServicesInfoManager.update_user_discord_info(user_id, request.user) + if (settings.DISCORD_SYNC_NAMES): + update_discord_nickname.delay(request.user.pk) update_discord_groups.delay(request.user.pk) logger.info("Succesfully activated Discord for user %s" % request.user) else: