2024-03-11 22:42:58 +00:00

112 lines
2.9 KiB
Python

# -*- encoding: utf-8 -*-
import logging
import requests
from django.conf import settings
from django.http import JsonResponse
from django.views.generic import View, TemplateView
from django.shortcuts import render, redirect
from django.contrib.auth import authenticate, login
log = logging.getLogger(__name__)
class DiscordLoginAction(View):
def get(self, request, *args, **kwargs):
return redirect(settings.DISCORD_OAUTH2_URL)
class DiscordLoginRedirect(View):
def get(self, request, *args, **kwargs):
"""
Endpoint function directed to once authorized from Discord.
This method will "login" the user.
"""
code = request.GET.get("code")
access_token = self.exchange_code_for_token(code)
raw_user_data = self.get_raw_user_data(access_token)
raw_user_data["access_token"] = access_token
log.debug(raw_user_data)
discord_user = authenticate(request, discord_user_data=raw_user_data)
login(request, discord_user)
return redirect("home:index")
def exchange_code_for_token(self, code: str) -> dict:
"""
Exchanges the given code for an access token.
A call is made to the Discord API.
"""
request_data = settings.DISCORD_CODE_EXCHANGE_REQUEST
request_data["data"]["code"] = code
log.debug("request data: %s", request_data)
# Fetch the access token
response = requests.post(
url="https://discord.com/api/oauth2/token",
data=request_data["data"],
headers=request_data["headers"]
)
log.debug(response)
return response.json()["access_token"]
def get_raw_user_data(self, access_token: str):
"""
Fetches the raw user data using the given access token.
A call is made to the Discord API.
"""
response = requests.get(
url="https://discord.com/api/v6/users/@me",
headers={"Authorization": f"Bearer {access_token}"}
)
log.debug(response)
return response.json()
class Login(TemplateView):
template_name = "accounts/login.html"
class GuildsView(View):
def get(self, request, *args, **kwargs):
response = requests.get(
url="https://discord.com/api/v6/users/@me/guilds",
headers={"Authorization": f"Bearer {request.user.access_token}"}
)
content = response.json()
return JsonResponse(content, safe=False)
class GuildChannelsView(View):
def get(self, request, *args, **kwargs):
guild_id = request.GET.get("guild")
log.debug("fetching channels from %s using token: %s", guild_id, settings.BOT_TOKEN)
response = requests.get(
url=f"https://discord.com/api/v10/guilds/{guild_id}/channels",
headers={"Authorization": f"Bot {settings.BOT_TOKEN}"}
)
return JsonResponse(response.json(), safe=False)