145 lines
3.7 KiB
Python
145 lines
3.7 KiB
Python
# -*- encoding: utf-8 -*-
|
|
|
|
import json
|
|
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
|
|
|
|
from .models import UserServerLink
|
|
from apps.home.models import SavedGuilds
|
|
|
|
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.
|
|
"""
|
|
|
|
if request.GET.get("error"):
|
|
return redirect("auth:login")
|
|
|
|
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=f"{settings.DISCORD_API_URL}/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=f"{settings.DISCORD_API_URL}/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=f"{settings.DISCORD_API_URL}/users/@me/guilds",
|
|
headers={"Authorization": f"Bearer {request.user.access_token}"}
|
|
)
|
|
|
|
content = response.json()
|
|
print(response, content)
|
|
|
|
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"{settings.DISCORD_API_URL}/guilds/{guild_id}/channels",
|
|
headers={"Authorization": f"Bot {settings.BOT_TOKEN}"}
|
|
)
|
|
print(response, response.json())
|
|
|
|
return JsonResponse(response.json(), safe=False)
|
|
|
|
|
|
class SaveGuildView(View):
|
|
|
|
def get(self, request, *args, **kwargs):
|
|
|
|
guild_id = request.GET.get("id")
|
|
|
|
if guild_id:
|
|
return SavedGuilds.objects.filter(id=guild_id)
|
|
|
|
return SavedGuilds.objects.all()
|
|
|
|
def post(self, request, *args, **kwargs):
|
|
|
|
data = request.POST
|
|
|
|
guild = SavedGuilds.objects.get_or_create(
|
|
id=data["id"],
|
|
name=data["name"],
|
|
icon=data["icon"]
|
|
)
|
|
|
|
return JsonResponse(data)
|