88 lines
2.6 KiB
Python
88 lines
2.6 KiB
Python
# -*- encoding: utf-8 -*-
|
|
|
|
import logging
|
|
|
|
from django.conf import settings
|
|
from django.http import HttpResponse
|
|
from django.contrib.auth.backends import BaseBackend
|
|
|
|
from .models import DiscordUser
|
|
|
|
log = logging.getLogger(__name__)
|
|
|
|
|
|
class DiscordAuthenticationBackend(BaseBackend):
|
|
"""
|
|
Authentication Backend for Discord Users.
|
|
"""
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
super().__init__(*args, **kwargs)
|
|
|
|
def authenticate(self, request: HttpResponse, discord_user_data: dict) -> DiscordUser:
|
|
"""
|
|
Creates or finds an existing user, and returns it.
|
|
"Authenticate" may not be the best name for this method...
|
|
|
|
Parameters
|
|
----------
|
|
request : django.http.HttpResponse
|
|
The HTTP request object.
|
|
discord_user_data : dict
|
|
A dictionary containing the raw user data.
|
|
|
|
Returns
|
|
-------
|
|
DiscordUser
|
|
The newly created or existing instance of DiscordUser,
|
|
based on the provided `discord_user_data`.
|
|
"""
|
|
|
|
# TODO:
|
|
# also check the new `token_expires` field to see if the token is invalid
|
|
# then request a new token, instead of making the user login again
|
|
#
|
|
# UPDATE:
|
|
# is this even possible or necessary with the scope of this app?
|
|
#
|
|
# https://discord.com/developers/docs/game-sdk/applications#data-models
|
|
|
|
discord_user_id = discord_user_data["id"]
|
|
existing_user = self.get_user(discord_user_id)
|
|
log.debug("authenticating, does user exist: %s", bool(existing_user))
|
|
|
|
if existing_user:
|
|
# The previous access token may have expired, so update it.
|
|
existing_user.update(discord_user_data)
|
|
# existing_user.access_token = discord_user_data["access_token"]
|
|
existing_user.save()
|
|
return existing_user
|
|
|
|
# Provide superuser permissions for specified users
|
|
if discord_user_id in settings.SUPERUSER_IDS:
|
|
return DiscordUser.objects.create_superuser(discord_user_data)
|
|
|
|
return DiscordUser.objects.create_user(discord_user_data)
|
|
|
|
|
|
def get_user(self, user_id: int) -> DiscordUser | None:
|
|
"""
|
|
Fetch a user from their ID.
|
|
Returns NoneType if not found.
|
|
|
|
Parameters
|
|
----------
|
|
user_id : int
|
|
The identifier for the discord user.
|
|
|
|
Returns
|
|
-------
|
|
DiscordUser | None
|
|
Either the DiscordUser or None if not found.
|
|
"""
|
|
|
|
try:
|
|
return DiscordUser.objects.get(pk=user_id)
|
|
except DiscordUser.DoesNotExist:
|
|
return None
|