Merge pull request 'Remove Sentry and add Oauth Token management' (#4) from oauth into master
continuous-integration/drone/push Build is passing Details

Reviewed-on: #4
This commit is contained in:
Michel Roux 2022-05-09 22:41:10 +00:00
commit c0bbd2d317
4 changed files with 121 additions and 41 deletions

View File

@ -1,2 +1,3 @@
DISCORD_TOKEN= DISCORD_TOKEN=
SENTRY_DSN= OAUTH2_CLIENT_ID=
OAUTH2_CLIENT_SECRET=

78
bot.py
View File

@ -1,25 +1,30 @@
from asyncio import new_event_loop from asyncio import new_event_loop
from datetime import timedelta from datetime import timedelta
from os import environ from os import environ
from typing import Optional, Union from typing import List, Optional, Union
from disnake import Client, Guild, Member from disnake import Client, Guild, Member
from dotenv import load_dotenv from dotenv import load_dotenv
from ics import Calendar, Event # type: ignore from ics import Calendar, Event # type: ignore
from ics.alarm.display import DisplayAlarm # type: ignore from ics.alarm.display import DisplayAlarm # type: ignore
from quart import Quart, abort from quart import Quart, redirect, request, session, url_for
from sentry_sdk import init from requests_oauthlib import OAuth2Session # type: ignore
from sentry_sdk.integrations.quart import QuartIntegration
load_dotenv() load_dotenv()
DISCORD_TOKEN = environ.get("DISCORD_TOKEN") DISCORD_TOKEN = environ.get("DISCORD_TOKEN")
if not DISCORD_TOKEN: OAUTH2_CLIENT_ID = environ.get("OAUTH2_CLIENT_ID")
raise Exception("Missing DISCORD_TOKEN env") 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)"
)
SENTRY_DSN = environ.get("SENTRY_DSN") API_BASE_URL = environ.get("API_BASE_URL", "https://discordapp.com/api")
if SENTRY_DSN: AUTHORIZATION_BASE_URL = API_BASE_URL + "/oauth2/authorize"
init(SENTRY_DSN, integrations=[QuartIntegration()]) TOKEN_URL = API_BASE_URL + "/oauth2/token"
class Discord(Client): class Discord(Client):
@ -29,6 +34,7 @@ class Discord(Client):
client = Discord() client = Discord()
app = Quart(__name__) app = Quart(__name__)
app.config["SECRET_KEY"] = OAUTH2_CLIENT_SECRET
def get_guild_by_id(guild_id: Union[int, str]) -> Optional[Guild]: def get_guild_by_id(guild_id: Union[int, str]) -> Optional[Guild]:
@ -55,11 +61,63 @@ async def get_guild_tag(member: Member) -> Optional[str]:
return None 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:
print(host_url + OAUTH2_REDIRECT_URI)
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,
)
@app.route("/login")
async def login():
discord = make_oauth_session(host_url=request.host_url, scope=["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,
)
session["oauth2_token"] = token
print(token)
return ""
@app.route("/<guild_id>.ics") @app.route("/<guild_id>.ics")
async def index(guild_id): async def index(guild_id):
guild = get_guild_by_id(guild_id) guild = get_guild_by_id(guild_id)
if guild is None: if guild is None:
abort(404) return redirect(url_for(".login"))
bot = get_bot_member(guild) bot = get_bot_member(guild)
guild_tag = await get_guild_tag(bot) guild_tag = await get_guild_tag(bot)

78
poetry.lock generated
View File

@ -369,6 +369,19 @@ category = "dev"
optional = false optional = false
python-versions = "*" python-versions = "*"
[[package]]
name = "oauthlib"
version = "3.2.0"
description = "A generic, spec-compliant, thorough implementation of the OAuth request-signing logic"
category = "main"
optional = false
python-versions = ">=3.6"
[package.extras]
rsa = ["cryptography (>=3.0.0)"]
signals = ["blinker (>=1.4.0)"]
signedtoken = ["cryptography (>=3.0.0)", "pyjwt (>=2.0.0,<3)"]
[[package]] [[package]]
name = "pathspec" name = "pathspec"
version = "0.9.0" version = "0.9.0"
@ -458,36 +471,37 @@ werkzeug = ">=2.0.0"
dotenv = ["python-dotenv"] dotenv = ["python-dotenv"]
[[package]] [[package]]
name = "sentry-sdk" name = "requests"
version = "1.5.11" version = "2.27.1"
description = "Python client for Sentry (https://sentry.io)" description = "Python HTTP for Humans."
category = "main" category = "main"
optional = false optional = false
python-versions = "*" python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*"
[package.dependencies] [package.dependencies]
blinker = {version = ">=1.1", optional = true, markers = "extra == \"quart\""} certifi = ">=2017.4.17"
certifi = "*" charset-normalizer = {version = ">=2.0.0,<2.1.0", markers = "python_version >= \"3\""}
quart = {version = ">=0.16.1", optional = true, markers = "extra == \"quart\""} idna = {version = ">=2.5,<4", markers = "python_version >= \"3\""}
urllib3 = ">=1.10.0" urllib3 = ">=1.21.1,<1.27"
[package.extras] [package.extras]
aiohttp = ["aiohttp (>=3.5)"] socks = ["PySocks (>=1.5.6,!=1.5.7)", "win-inet-pton"]
beam = ["apache-beam (>=2.12)"] use_chardet_on_py3 = ["chardet (>=3.0.2,<5)"]
bottle = ["bottle (>=0.12.13)"]
celery = ["celery (>=3)"] [[package]]
chalice = ["chalice (>=1.16.0)"] name = "requests-oauthlib"
django = ["django (>=1.8)"] version = "1.3.1"
falcon = ["falcon (>=1.4)"] description = "OAuthlib authentication support for Requests."
flask = ["flask (>=0.11)", "blinker (>=1.1)"] category = "main"
httpx = ["httpx (>=0.16.0)"] optional = false
pure_eval = ["pure-eval", "executing", "asttokens"] python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
pyspark = ["pyspark (>=2.4.4)"]
quart = ["quart (>=0.16.1)", "blinker (>=1.1)"] [package.dependencies]
rq = ["rq (>=0.6)"] oauthlib = ">=3.0.0"
sanic = ["sanic (>=0.8)"] requests = ">=2.0.0"
sqlalchemy = ["sqlalchemy (>=1.2)"]
tornado = ["tornado (>=5)"] [package.extras]
rsa = ["oauthlib[signedtoken] (>=3.0.0)"]
[[package]] [[package]]
name = "six" name = "six"
@ -595,7 +609,7 @@ multidict = ">=4.0"
[metadata] [metadata]
lock-version = "1.1" lock-version = "1.1"
python-versions = "^3.8" python-versions = "^3.8"
content-hash = "3e4b5f68ee271697671c0b54ea6463947b11d2a701f022240e3f2ec0f3a87c79" content-hash = "b2bf381b8cdd3f6dac5453b4744dafa57d6d38739367d29b799c9dfb703628b6"
[metadata.files] [metadata.files]
aiofiles = [ aiofiles = [
@ -990,6 +1004,10 @@ mypy-extensions = [
{file = "mypy_extensions-0.4.3-py2.py3-none-any.whl", hash = "sha256:090fedd75945a69ae91ce1303b5824f428daf5a028d2f6ab8a299250a846f15d"}, {file = "mypy_extensions-0.4.3-py2.py3-none-any.whl", hash = "sha256:090fedd75945a69ae91ce1303b5824f428daf5a028d2f6ab8a299250a846f15d"},
{file = "mypy_extensions-0.4.3.tar.gz", hash = "sha256:2d82818f5bb3e369420cb3c4060a7970edba416647068eb4c5343488a6c604a8"}, {file = "mypy_extensions-0.4.3.tar.gz", hash = "sha256:2d82818f5bb3e369420cb3c4060a7970edba416647068eb4c5343488a6c604a8"},
] ]
oauthlib = [
{file = "oauthlib-3.2.0-py3-none-any.whl", hash = "sha256:6db33440354787f9b7f3a6dbd4febf5d0f93758354060e802f6c06cb493022fe"},
{file = "oauthlib-3.2.0.tar.gz", hash = "sha256:23a8208d75b902797ea29fd31fa80a15ed9dc2c6c16fe73f5d346f83f6fa27a2"},
]
pathspec = [ pathspec = [
{file = "pathspec-0.9.0-py2.py3-none-any.whl", hash = "sha256:7d15c4ddb0b5c802d161efc417ec1a2558ea2653c2e8ad9c19098201dc1c993a"}, {file = "pathspec-0.9.0-py2.py3-none-any.whl", hash = "sha256:7d15c4ddb0b5c802d161efc417ec1a2558ea2653c2e8ad9c19098201dc1c993a"},
{file = "pathspec-0.9.0.tar.gz", hash = "sha256:e564499435a2673d586f6b2130bb5b95f04a3ba06f81b8f895b651a3c76aabb1"}, {file = "pathspec-0.9.0.tar.gz", hash = "sha256:e564499435a2673d586f6b2130bb5b95f04a3ba06f81b8f895b651a3c76aabb1"},
@ -1022,9 +1040,13 @@ quart = [
{file = "Quart-0.17.0-py3-none-any.whl", hash = "sha256:69480e7384935feff1f50293a8cb70c5d31f568af94ed792d043bb368b50bd50"}, {file = "Quart-0.17.0-py3-none-any.whl", hash = "sha256:69480e7384935feff1f50293a8cb70c5d31f568af94ed792d043bb368b50bd50"},
{file = "Quart-0.17.0.tar.gz", hash = "sha256:2cf213d8b83fa701a83e3b3125e9102a937cefd1e97e9583f22ee2fa79139640"}, {file = "Quart-0.17.0.tar.gz", hash = "sha256:2cf213d8b83fa701a83e3b3125e9102a937cefd1e97e9583f22ee2fa79139640"},
] ]
sentry-sdk = [ requests = [
{file = "sentry-sdk-1.5.11.tar.gz", hash = "sha256:6c01d9d0b65935fd275adc120194737d1df317dce811e642cbf0394d0d37a007"}, {file = "requests-2.27.1-py2.py3-none-any.whl", hash = "sha256:f22fa1e554c9ddfd16e6e41ac79759e17be9e492b3587efa038054674760e72d"},
{file = "sentry_sdk-1.5.11-py2.py3-none-any.whl", hash = "sha256:c17179183cac614e900cbd048dab03f49a48e2820182ec686c25e7ce46f8548f"}, {file = "requests-2.27.1.tar.gz", hash = "sha256:68d7c56fd5a8999887728ef304a6d12edc7be74f1cfa47714fc8b414525c9a61"},
]
requests-oauthlib = [
{file = "requests-oauthlib-1.3.1.tar.gz", hash = "sha256:75beac4a47881eeb94d5ea5d6ad31ef88856affe2332b9aafb52c6452ccf0d7a"},
{file = "requests_oauthlib-1.3.1-py2.py3-none-any.whl", hash = "sha256:2577c501a2fb8d05a304c09d090d6e47c306fef15809d102b327cf8364bddab5"},
] ]
six = [ six = [
{file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"},

View File

@ -11,8 +11,7 @@ disnake = "2.5.0"
ics = "0.7" ics = "0.7"
python-dotenv = "0.20.0" python-dotenv = "0.20.0"
quart = "0.17.0" quart = "0.17.0"
sentry-sdk = {extras = ["quart"], version = "1.5.11"} requests-oauthlib = "1.3.1"
[tool.poetry.dev-dependencies] [tool.poetry.dev-dependencies]
flake8 = "4.0.1" flake8 = "4.0.1"