Source code for sni.discord.discord

"""
Discord related functionalities
"""

import logging

import discord

from sni.user.models import Group, User
import sni.utils as utils

from .bot import get_guild
from .models import DiscordAuthenticationChallenge


[docs]def complete_authentication_challenge(discord_user: discord.User, code: str): """ Complete an authentication challenge, see :meth:`sni.discord.discord.new_authentication_challenge`. """ challenge = DiscordAuthenticationChallenge.objects(code=code).get() usr = challenge.user usr.discord_user_id = discord_user.id usr.save() logging.info( "Authenticated Discord user %d to user %s", discord_user.id, usr.tickered_name, ) challenge.delete()
[docs]async def ensure_role_for_group(grp: Group): """ Ensure that a Discord role exists for the given group, and returns it. """ if not grp.map_to_discord: return guild = get_guild() current_roles = {role.name: role for role in guild.roles} if grp.group_name in current_roles.keys(): role = current_roles[grp.group_name] else: role = await guild.create_role(name=grp.group_name) grp.discord_role_id = role.id grp.save() return role
[docs]def new_authentication_challenge(usr: User) -> str: """ Creates a new authentication challenge. The challenge proceeds as follows: 1. A user (:class:`sni.user`) asks to start a challenge by calling this method. 2. This methods returns a random code, and the user has 60 seconds type ``!auth <code>`` in the dedicated authentication channel. 3. The Discord client is notified, and check this code against the pending Discort authentication challenges. """ logging.info( "Starting Discord authentication challenge for %s", usr.character_name ) challenge = DiscordAuthenticationChallenge( user=usr, code=utils.random_code(50), ).save() return challenge.code