2024-08-12 16:29:55 +01:00

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