Skip to content

Commit 79f5d7e

Browse files
committed
Refresh token cache if invalid rights access
1 parent 9a56c01 commit 79f5d7e

File tree

3 files changed

+54
-42
lines changed

3 files changed

+54
-42
lines changed

pibooth_dropbox/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@
22

33
"""Pibooth plugin to upload pictures on Dropbox."""
44

5-
__version__ = "0.0.2"
5+
__version__ = "0.0.3"

pibooth_dropbox/flow.py

Lines changed: 27 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
1+
# -*- coding: utf-8 -*-
22

33
import json
44
try:
@@ -15,32 +15,33 @@
1515

1616
class Credentials(object):
1717

18-
_PROPERTIES = ("token",
19-
"refresh_token",
20-
"token_uri",
21-
"account_id",
22-
"client_id",
23-
"scopes")
24-
25-
def __init__(self, token, refresh_token, token_uri, account_id,
26-
client_id, scopes, expires_at=None):
18+
PROPERTIES = ("token",
19+
"refresh_token",
20+
"token_uri",
21+
"account_id",
22+
"client_id",
23+
"client_secret",
24+
"scopes")
25+
26+
def __init__(self, client_id=None, client_secret=None, token=None,
27+
refresh_token=None, token_uri=None, account_id=None,
28+
scopes=None, expires_at=None):
2729
self.token = token
2830
self.refresh_token = refresh_token
2931
self.token_uri = token_uri
3032
self.account_id = account_id
3133
self.client_id = client_id
32-
if isinstance(scopes, (list, tuple)):
33-
self.scopes = ' '.join(scopes)
34-
else:
35-
self.scopes = scopes
34+
self.client_secret = client_secret
35+
self.scopes = scopes
3636
self.expires_at = expires_at
3737

3838
@classmethod
39-
def from_oauth2_flow_result(cls, result):
39+
def from_oauth2_flow_result(cls, result, client_id, client_secret):
4040
"""Return a :py:class:`Credentials` instance from OAuth2 flow result.
4141
"""
42-
return cls(result.access_token, result.refresh_token, result.url_state,
43-
result.account_id, result.user_id, result.scope, result.expires_at)
42+
return cls(client_id, client_secret, result.access_token, result.refresh_token,
43+
result.url_state, result.account_id, result.scope.split(' '),
44+
result.expires_at)
4445

4546
@classmethod
4647
def from_authorized_user_file(cls, filename):
@@ -58,15 +59,12 @@ def to_json(self, strip=None):
5859
5960
:returns: A JSON representation of this instance, suitable to write in file.
6061
"""
61-
prep = dict((k, getattr(self, k)) for k in Credentials._PROPERTIES)
62+
prep = dict((k, getattr(self, k)) for k in Credentials.PROPERTIES)
6263

6364
# Remove entries that explicitely need to be removed
6465
if strip is not None:
6566
prep = {k: v for k, v in prep.items() if k not in strip}
6667

67-
# Save scopes has list
68-
prep["scopes"] = prep["scopes"].split(' ')
69-
7068
return json.dumps(prep)
7169

7270

@@ -88,9 +86,9 @@ class InstalledAppFlow(object):
8886
"The authentication flow has completed. You may close this window."
8987
)
9088

91-
def __init__(self, app_key, app_secret, scopes=None, client_type='offline'):
92-
self.app_key = app_key
93-
self.app_secret = app_secret
89+
def __init__(self, app_key, app_secret, scopes, client_type='offline'):
90+
self.client_id = app_key
91+
self.client_secret = app_secret
9492
self.client_type = client_type
9593
self.scopes = scopes
9694
self.redirect_uri = None
@@ -180,12 +178,13 @@ def run_local_server(self, host="localhost", port=8080,
180178
self.redirect_uri)
181179

182180
session = {}
183-
flow = DropboxOAuth2Flow(self.app_key,
181+
flow = DropboxOAuth2Flow(self.client_id,
184182
self.redirect_uri,
185183
session,
186184
"dropbox-auth-csrf-token",
187-
self.app_secret,
188-
token_access_type=self.client_type)
185+
self.client_secret,
186+
token_access_type=self.client_type,
187+
scope=self.scopes)
189188
auth_url = flow.start()
190189

191190
if open_browser:
@@ -203,7 +202,7 @@ def run_local_server(self, host="localhost", port=8080,
203202
# This closes the socket
204203
local_server.server_close()
205204

206-
return Credentials.from_oauth2_flow_result(result)
205+
return Credentials.from_oauth2_flow_result(result, self.client_id, self.client_secret)
207206

208207

209208
class _WSGIRequestHandler(wsgiref.simple_server.WSGIRequestHandler):

pibooth_dropbox/plugin.py

Lines changed: 26 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -103,24 +103,35 @@ def _auth(self):
103103

104104
def _save_credentials(self, credentials):
105105
"""Save credentials in a file to use API without need to allow acces."""
106-
with open(self.token_cache_file, 'w') as fp:
107-
fp.write(credentials.to_json())
106+
try:
107+
with open(self.token_cache_file, 'w') as fp:
108+
fp.write(credentials.to_json())
109+
except OSError as err:
110+
LOGGER.warning("Can not save Dropbox token in file '%s': %s",
111+
self.token_cache_file, err)
108112

109113
def _get_authorized_session(self):
110114
"""Create credentials file if required and open a new session."""
111115
credentials = None
112116
if not os.path.exists(self.token_cache_file) or \
113117
os.path.getsize(self.token_cache_file) == 0:
114-
credentials = self._auth()
115-
LOGGER.debug("First use of pibooth-dropbox: store token in file %s",
118+
LOGGER.debug("First use of plugin, store token in file %s",
116119
self.token_cache_file)
117-
try:
118-
self._save_credentials(credentials)
119-
except OSError as err:
120-
LOGGER.warning("Can not save Dropbox token in file '%s': %s",
121-
self.token_cache_file, err)
120+
credentials = self._auth()
121+
self._save_credentials(credentials)
122122
else:
123123
credentials = Credentials.from_authorized_user_file(self.token_cache_file)
124+
if credentials.client_id != self.app_key or\
125+
credentials.client_secret != self.app_secret:
126+
LOGGER.debug("Application key or secret has changed, store new token in file '%s'",
127+
self.token_cache_file)
128+
credentials = self._auth()
129+
self._save_credentials(credentials)
130+
131+
# Remove cache if access rights are not correct
132+
if set(self.SCOPES).intersection(set(credentials.scopes)) != set(self.SCOPES):
133+
LOGGER.warning("Invalid permission, please set write access in Dropbox.com and restart pibooth")
134+
os.remove(self.token_cache_file)
124135

125136
if credentials:
126137
return dropbox.Dropbox(app_key=self.app_key,
@@ -172,8 +183,9 @@ def upload(self, fullname, folder, name, overwrite=False):
172183
data, path, mode,
173184
client_modified=datetime.datetime(*time.gmtime(mtime)[:6]),
174185
mute=True)
175-
except dropbox.exceptions.ApiError:
176-
LOGGER.error('*** Dropbox API error', exc_info=True)
186+
except Exception as ex:
187+
LOGGER.error('Dropbox API error: %s', ex)
188+
LOGGER.debug(str(ex), exc_info=True)
177189
return None
178190

179191
LOGGER.debug('Uploaded as %s', res.name.encode('utf8'))
@@ -186,6 +198,7 @@ def get_temp_url(self, path):
186198
res = self._session.files_get_temporary_link(path)
187199
LOGGER.debug('Temporary picture URL -> %s', res.link)
188200
return res.link
189-
except:
190-
LOGGER.error("Can not get temporary URL for Dropbox", exc_info=True)
201+
except Exception as ex:
202+
LOGGER.error('Can not get temporary URL for Dropbox: %s', ex)
203+
LOGGER.debug(str(ex), exc_info=True)
191204
return None

0 commit comments

Comments
 (0)