Implement explicit methods to save and get OAuth2 token and secrets

This commit is contained in:
thec0sm0s
2020-08-04 21:35:37 +05:30
parent 7ff98a9e1e
commit f93d5c059b
3 changed files with 33 additions and 6 deletions

View File

@@ -55,8 +55,14 @@ class DiscordOAuth2HttpClient(abc.ABC):
return session.get("DISCORD_USER_ID")
@staticmethod
def _token_updater(token):
session["DISCORD_OAUTH2_TOKEN"] = token
@abc.abstractmethod
def save_authorization_token(token: dict):
raise NotImplementedError
@staticmethod
@abc.abstractmethod
def get_authorization_token() -> dict:
raise NotImplementedError
def _fetch_token(self):
discord = self._make_session(state=session.get("DISCORD_OAUTH2_STATE"))
@@ -87,7 +93,7 @@ class DiscordOAuth2HttpClient(abc.ABC):
"""
return OAuth2Session(
client_id=self.client_id,
token=token or session.get("DISCORD_OAUTH2_TOKEN"),
token=token or self.get_authorization_token(),
state=state or session.get("DISCORD_OAUTH2_STATE"),
scope=scope,
redirect_uri=self.redirect_uri,
@@ -96,7 +102,7 @@ class DiscordOAuth2HttpClient(abc.ABC):
'client_secret': self.__client_secret,
},
auto_refresh_url=configs.DISCORD_TOKEN_URL,
token_updater=self._token_updater)
token_updater=self.save_authorization_token)
def request(self, route: str, method="GET", data=None, oauth=True, **kwargs) -> typing.Union[dict, str]:
"""Sends HTTP request to provided route or discord endpoint.

View File

@@ -82,6 +82,27 @@ class DiscordOAuth2Session(_http.DiscordOAuth2HttpClient):
return redirect(authorization_url)
@staticmethod
def save_authorization_token(token: dict):
"""A staticmethod which saves a dict containing Discord OAuth2 token and other secrets to the user's cookies.
Meaning by default, it uses client side session handling.
Override this method if you want to handle the user's session server side. If this method is overridden then,
you must also override :py:meth:`flask_discord.DiscordOAuth2Session.get_authorization_token`.
"""
session["DISCORD_OAUTH2_TOKEN"] = token
@staticmethod
def get_authorization_token() -> dict:
"""A static method which returns a dict containing Discord OAuth2 token and other secrets which was saved
previously by `:py:meth:`flask_discord.DiscordOAuth2Session.save_authorization_token` from user's cookies.
You must override this method if you are implementing server side session handling.
"""
return session.get("DISCORD_OAUTH2_TOKEN")
def callback(self):
"""A method which should be always called after completing authorization code grant process
usually in callback view.
@@ -92,7 +113,7 @@ class DiscordOAuth2Session(_http.DiscordOAuth2HttpClient):
if request.values.get("error"):
return request.values["error"]
token = self._fetch_token()
self._token_updater(token)
self.save_authorization_token(token)
def revoke(self):
"""This method clears current discord token, state and all session data from flask

View File

@@ -189,7 +189,7 @@ class User(DiscordModelsBase):
"""
try:
data = {"access_token": session["DISCORD_OAUTH2_TOKEN"]["access_token"]}
data = {"access_token": current_app.discord.get_authorization_token()["access_token"]}
except KeyError:
raise exceptions.Unauthorized
return self._bot_request(f"/guilds/{guild_id}/members/{self.id}", method="PUT", json=data) or dict()