From c7685c55086003c3f6f763b25bb41919a92dd876 Mon Sep 17 00:00:00 2001 From: Rob <1572423+robweber@users.noreply.github.com> Date: Fri, 2 Jun 2023 09:13:33 -0500 Subject: [PATCH] Dropbox refresh token (#222) * ask dropbox for refresh token using offline mode save as json intead of txt file * need new version of dropbox lib --- addon.xml | 2 +- resources/lib/authorizers.py | 37 ++++++++++++++++++++++-------------- 2 files changed, 24 insertions(+), 15 deletions(-) diff --git a/addon.xml b/addon.xml index 76fa84c..bf4a585 100644 --- a/addon.xml +++ b/addon.xml @@ -5,7 +5,7 @@ - + diff --git a/resources/lib/authorizers.py b/resources/lib/authorizers.py index 3923be9..8504e65 100644 --- a/resources/lib/authorizers.py +++ b/resources/lib/authorizers.py @@ -1,8 +1,10 @@ import xbmcgui import xbmcvfs +import json import pyqrcode import resources.lib.tinyurl as tinyurl import resources.lib.utils as utils +from datetime import datetime # don't die on import error yet, these might not even get used try: @@ -37,6 +39,7 @@ class QRCode(xbmcgui.WindowXMLDialog): class DropboxAuthorizer: + TOKEN_FILE = "tokens.json" APP_KEY = "" APP_SECRET = "" @@ -58,7 +61,7 @@ class DropboxAuthorizer: def isAuthorized(self): user_token = self._getToken() - return user_token != '' + return 'access_token' in user_token def authorize(self): result = True @@ -71,7 +74,7 @@ class DropboxAuthorizer: self._deleteToken() # copied flow from http://dropbox-sdk-python.readthedocs.io/en/latest/moduledoc.html#dropbox.oauth.DropboxOAuth2FlowNoRedirect - flow = oauth.DropboxOAuth2FlowNoRedirect(self.APP_KEY, self.APP_SECRET) + flow = oauth.DropboxOAuth2FlowNoRedirect(consumer_key=self.APP_KEY, consumer_secret=self.APP_SECRET, token_access_type="offline") url = flow.start() @@ -99,7 +102,7 @@ class DropboxAuthorizer: try: user_token = flow.finish(code) - self._setToken(user_token.access_token) + self._setToken(user_token) except Exception as e: utils.log("Error: %s" % (e,)) result = False @@ -114,8 +117,8 @@ class DropboxAuthorizer: if(user_token != ''): # create the client - result = dropbox.Dropbox(user_token) - + result = dropbox.Dropbox(oauth2_access_token=user_token['access_token'], oauth2_refresh_token=user_token['refresh_token'], + oauth2_access_token_expiration=user_token['expiration'], app_key=self.APP_KEY, app_secret=self.APP_SECRET) try: result.users_get_current_account() except: @@ -127,21 +130,27 @@ class DropboxAuthorizer: def _setToken(self, token): # write the token files - token_file = open(xbmcvfs.translatePath(utils.data_dir() + "tokens.txt"), 'w') - token_file.write(token) + token_file = open(xbmcvfs.translatePath(utils.data_dir() + self.TOKEN_FILE), 'w') + + token_file.write(json.dumps({"access_token": token.access_token, "refresh_token": token.refresh_token, "expiration": str(token.expires_at)})) token_file.close() def _getToken(self): + result = {} # get token, if it exists - if(xbmcvfs.exists(xbmcvfs.translatePath(utils.data_dir() + "tokens.txt"))): - token_file = open(xbmcvfs.translatePath(utils.data_dir() + "tokens.txt")) + if(xbmcvfs.exists(xbmcvfs.translatePath(utils.data_dir() + self.TOKEN_FILE))): + token_file = open(xbmcvfs.translatePath(utils.data_dir() + self.TOKEN_FILE)) token = token_file.read() + + if(token.strip() != ""): + result = json.loads(token) + # convert expiration back to a datetime object + result['expiration'] = datetime.strptime(result['expiration'], "%Y-%m-%d %H:%M:%S.%f") + token_file.close() - return token - else: - return "" + return result def _deleteToken(self): - if(xbmcvfs.exists(xbmcvfs.translatePath(utils.data_dir() + "tokens.txt"))): - xbmcvfs.delete(xbmcvfs.translatePath(utils.data_dir() + "tokens.txt")) + if(xbmcvfs.exists(xbmcvfs.translatePath(utils.data_dir() + self.TOKEN_FILE))): + xbmcvfs.delete(xbmcvfs.translatePath(utils.data_dir() + self.TOKEN_FILE))