From f4ca67bb2464f9c6cf39a52f6638ed6df16196ee Mon Sep 17 00:00:00 2001 From: Michel Roux Date: Wed, 7 Sep 2022 17:36:18 +0000 Subject: [PATCH 1/2] FInal draft for no oauth --- .env.dist | 2 - divent/bot.py | 121 +++++--------------------------- divent/static/css/global.css | 65 ++++++++++------- divent/templates/base.html.j2 | 11 +-- divent/templates/footer.html.j2 | 2 +- divent/templates/guilds.html.j2 | 23 ------ divent/templates/index.html.j2 | 59 +++++++++------- poetry.lock | 66 ++--------------- pyproject.toml | 4 +- 9 files changed, 102 insertions(+), 251 deletions(-) delete mode 100644 divent/templates/guilds.html.j2 diff --git a/.env.dist b/.env.dist index 967c4cd..47b0cab 100644 --- a/.env.dist +++ b/.env.dist @@ -1,3 +1 @@ DISCORD_TOKEN= -OAUTH2_CLIENT_ID= -OAUTH2_CLIENT_SECRET= diff --git a/divent/bot.py b/divent/bot.py index 9a0bb86..1b8e412 100644 --- a/divent/bot.py +++ b/divent/bot.py @@ -2,14 +2,13 @@ import json import logging from datetime import datetime, timedelta from os import environ, path -from typing import List, Optional +from typing import Optional from disnake import Client, Guild from dotenv import load_dotenv from ics import Calendar, Event # type: ignore from ics.alarm.display import DisplayAlarm # type: ignore -from quart import Quart, redirect, render_template, request, session, url_for -from requests_oauthlib import OAuth2Session # type: ignore +from quart import Quart, redirect, render_template, request, url_for import sentry_sdk from sentry_sdk.integrations.quart import QuartIntegration @@ -17,18 +16,8 @@ load_dotenv() QUART_DEBUG = environ.get("QUART_DEBUG", False) DISCORD_TOKEN = environ.get("DISCORD_TOKEN") -OAUTH2_CLIENT_ID = environ.get("OAUTH2_CLIENT_ID") -OAUTH2_CLIENT_SECRET = environ.get("OAUTH2_CLIENT_SECRET") -OAUTH2_REDIRECT_URI = environ.get("OAUTH2_REDIRECT_URI", "callback") -if not DISCORD_TOKEN or not OAUTH2_CLIENT_ID or not OAUTH2_CLIENT_SECRET: - raise Exception( - "Missing some env variables " - "(could be DISCORD_TOKEN, OAUTH2_CLIENT_ID or OAUTH2_CLIENT_SECRET)" - ) - -API_BASE_URL = environ.get("API_BASE_URL", "https://discordapp.com/api") -AUTHORIZATION_BASE_URL = API_BASE_URL + "/oauth2/authorize" -TOKEN_URL = API_BASE_URL + "/oauth2/token" +if not DISCORD_TOKEN: + raise Exception("Missing DISCORD_TOKEN") if QUART_DEBUG: logging.basicConfig(level=logging.DEBUG) @@ -45,41 +34,16 @@ class Discord(Client): client = Discord() app = Quart(__name__) -app.config["SECRET_KEY"] = OAUTH2_CLIENT_SECRET def get_guild_by_id(guild_id: str) -> Optional[Guild]: - for guild in client.guilds: - if str(guild.id) == guild_id or guild.vanity_url_code == guild_id: - return guild + if guild_id: + for guild in client.guilds: + if str(guild.id) == guild_id or guild.vanity_url_code == guild_id: + return guild return None -def token_updater(token: str) -> None: - session["oauth2_token"] = token - - -def make_oauth_session( - host_url: str, - token: Optional[str] = None, - state: Optional[str] = None, - scope: Optional[List[str]] = None, -) -> OAuth2Session: - return OAuth2Session( - client_id=OAUTH2_CLIENT_ID, - token=token, - state=state, - scope=scope, - redirect_uri=host_url + OAUTH2_REDIRECT_URI, - auto_refresh_kwargs={ - "client_id": OAUTH2_CLIENT_ID, - "client_secret": OAUTH2_CLIENT_SECRET, - }, - auto_refresh_url=TOKEN_URL, - token_updater=token_updater, - ) - - CATALOG_CACHE = {} @@ -118,80 +82,27 @@ def days_before_failure(): return nextDelta.days -def avatar_cdn(type: str, id: str, hash: str): - ext = "gif" if hash.startswith("a_") else "png" - return f"https://cdn.discordapp.com/{type}/{id}/{hash}.{ext}" - - @app.context_processor def context_processor(): - return dict( - _=i18n, - avatar_cdn=avatar_cdn, - days_before_failure=days_before_failure(), - bot=client.user, - ) + return dict(_=i18n, client=client, days_before_failure=days_before_failure()) @app.route("/") async def index(): + guild_id = request.args.get("guild") + guild = get_guild_by_id(guild_id) + + if guild: + return False + return await render_template("index.html.j2") -@app.route("/login") -async def login(): - token = session.get("oauth2_token") - if token is not None: - return redirect(url_for(".guilds")) - - discord = make_oauth_session( - host_url=request.host_url, scope=["identify", "guilds"] - ) - authorization_url, state = discord.authorization_url(AUTHORIZATION_BASE_URL) - session["oauth2_state"] = state - return redirect(authorization_url) - - -@app.route("/callback") -async def callback(): - request_values = await request.values - if request_values.get("error"): - return request_values["error"] - discord = make_oauth_session( - host_url=request.host_url, state=session.get("oauth2_state") - ) - token = discord.fetch_token( - TOKEN_URL, - client_secret=OAUTH2_CLIENT_SECRET, - authorization_response=request.url, - ) - token_updater(token) - return redirect(url_for(".guilds")) - - -@app.route("/guilds") -async def guilds(): - token = session.get("oauth2_token") - if token is None: - return redirect(url_for(".login")) - - discord = make_oauth_session(host_url=request.host_url, token=token) - user = discord.get(API_BASE_URL + "/users/@me") - guilds = discord.get(API_BASE_URL + "/users/@me/guilds") - - if user.status_code != 200 or guilds.status_code != 200: - return redirect(url_for(".login")) - - return await render_template( - "guilds.html.j2", guilds=guilds.json(), user=user.json() - ) - - @app.route("/.ics") async def ical(guild_id: str): guild = get_guild_by_id(guild_id) if guild is None: - return redirect(url_for(".login")) + return redirect(url_for(".index")) calendar = Calendar() diff --git a/divent/static/css/global.css b/divent/static/css/global.css index 276a23e..bd3a46d 100644 --- a/divent/static/css/global.css +++ b/divent/static/css/global.css @@ -8,28 +8,40 @@ url('../fonts/open-sans-v29-latin-regular.woff') format('woff'); } +html, body { + height: 100%; +} + body { background-color: #2f3136; margin: 0; font-family: Whitney, "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif; color: #b9bbbe; + display: flex; + flex-direction: column; + justify-content: space-between; } -#avatars { - display: flex; - align-items: center; - justify-content: space-around; +#content { + align-self: center; +} + +#logo { + position: relative; + left: 24px; + top: 24px; + height: 36px; + width: 130px; +} + +#avatars, footer, h1, h2 { + text-align: center; } #avatars img { border-radius: 50%; } -#dots { - font-size: xx-large; - opacity: 0.2; -} - #content { min-width: 280px; max-width: 400px; @@ -52,18 +64,26 @@ body { font-size: 14px; } -#details { +footer ul { font-size: 12px; list-style-type: none; padding: 0; } -#details a { +footer ul li { + display: inline-block; +} + +footer ul li:last-child { + display: block; +} + +footer ul li a { color: #a3a6aa; text-decoration: none; } -#details i { +footer ul li i { margin: 8px; } @@ -89,13 +109,11 @@ body { h1 { font-size: 20px; - text-align: center; color: white; } h2 { font-size: 16px; - text-align: center; } h3 { @@ -126,17 +144,14 @@ hr { display: inline-block; } -@media only screen and (min-width: 600px) { - #content { - position: absolute; - top: 50%; - left: 50%; - transform: translate(-50%, -50%); +@media only screen and (max-width : 320px) { + #logo { + text-align: center; + top: inherit; + left: inherit; } - #logo { - position: relative; - left: 24px; - top: 24px; + footer ul li { + display: block; } -} +} \ No newline at end of file diff --git a/divent/templates/base.html.j2 b/divent/templates/base.html.j2 index babbfde..d1aa5b7 100644 --- a/divent/templates/base.html.j2 +++ b/divent/templates/base.html.j2 @@ -17,13 +17,16 @@ + id="logo" + height="36" + width="130" + alt="{{ _('Discord Logo') }}"/>
{% block content %} {% endblock content %}
+
+ {% include 'footer.html.j2' %} +
diff --git a/divent/templates/footer.html.j2 b/divent/templates/footer.html.j2 index c0e1a31..78c8d08 100644 --- a/divent/templates/footer.html.j2 +++ b/divent/templates/footer.html.j2 @@ -1,4 +1,4 @@ -