diff --git a/flask_discord/_http.py b/flask_discord/_http.py index ad35dda..7512ea5 100644 --- a/flask_discord/_http.py +++ b/flask_discord/_http.py @@ -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. diff --git a/flask_discord/client.py b/flask_discord/client.py index 2f4daae..ad834be 100644 --- a/flask_discord/client.py +++ b/flask_discord/client.py @@ -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 diff --git a/flask_discord/models/user.py b/flask_discord/models/user.py index adbcd77..aabde66 100644 --- a/flask_discord/models/user.py +++ b/flask_discord/models/user.py @@ -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()