@@ -766,8 +766,8 @@ def get_oauth2_credentials(username, password, reload_remote_accounts=True):
766766 try :
767767 client_secret = cryptographer .decrypt (client_secret_encrypted )
768768 except InvalidToken as e : # needed to avoid looping (we don't remove secrets on decryption failure)
769- Log .error ('Invalid password to decrypt' , username , 'secret - aborting login:' ,
770- Log .error_string (e ))
769+ Log .error ('Invalid password to decrypt `client_secret_encrypted` for account' , username ,
770+ '- aborting login:' , Log .error_string (e ))
771771 return False , '%s: Login failed - the password for account %s is incorrect' % (
772772 APP_NAME , username )
773773 else :
@@ -778,6 +778,7 @@ def get_oauth2_credentials(username, password, reload_remote_accounts=True):
778778 if not access_token or access_token_expiry - current_time < TOKEN_EXPIRY_MARGIN :
779779 if refresh_token :
780780 response = OAuth2Helper .refresh_oauth2_access_token (token_url , client_id , client_secret ,
781+ username ,
781782 cryptographer .decrypt (refresh_token ))
782783
783784 access_token = response ['access_token' ]
@@ -811,11 +812,11 @@ def get_oauth2_credentials(username, password, reload_remote_accounts=True):
811812 redirect_listen_address , username )
812813
813814 if not success :
814- Log .info ('Authorisation result error for' , username , '- aborting login.' , auth_result )
815+ Log .info ('Authorisation result error for account ' , username , '- aborting login.' , auth_result )
815816 return False , '%s: Login failed for account %s: %s' % (APP_NAME , username , auth_result )
816817
817818 if not oauth2_flow :
818- Log .error ('No `oauth2_flow` value specified for' , username , '- aborting login' )
819+ Log .error ('No `oauth2_flow` value specified for account ' , username , '- aborting login' )
819820 return (False , '%s: Incomplete config file entry found for account %s - please make sure an '
820821 '`oauth2_flow` value is specified when using a method that does not require a '
821822 '`permission_url`' % (APP_NAME , username ))
@@ -843,8 +844,9 @@ def get_oauth2_credentials(username, password, reload_remote_accounts=True):
843844 if 'refresh_token' in response :
844845 config .set (username , 'refresh_token' , cryptographer .encrypt (response ['refresh_token' ]))
845846 elif permission_url : # ignore this situation with CCG/ROPCG/service account flows - it is expected
846- Log .info ('Warning: no refresh token returned for' , username , '- you will need to re-authenticate' ,
847- 'each time the access token expires (does your `oauth2_scope` value allow `offline` use?)' )
847+ Log .info ('Warning: no refresh token returned for account' , username , '- you will need to' ,
848+ 're-authenticate each time the access token expires (does your `oauth2_scope` value allow' ,
849+ '`offline` use?)' )
848850
849851 AppConfig .save ()
850852
@@ -867,7 +869,7 @@ def get_oauth2_credentials(username, password, reload_remote_accounts=True):
867869
868870 AppConfig .save ()
869871
870- Log .info ('Retrying login due to exception while refreshing OAuth 2.0 tokens for' , username ,
872+ Log .info ('Retrying login due to exception while refreshing access token for account ' , username ,
871873 '(attempt %d):' % (1 if has_access_token else 2 ), Log .error_string (e ))
872874 return OAuth2Helper .get_oauth2_credentials (username , password , reload_remote_accounts = False )
873875
@@ -884,11 +886,12 @@ def get_oauth2_credentials(username, password, reload_remote_accounts=True):
884886 config .remove_option (username , 'refresh_token' )
885887 AppConfig .save ()
886888
887- Log .info ('Retrying login due to exception while decrypting OAuth 2.0 credentials for' , username ,
889+ Log .info ('Retrying login due to exception while decrypting OAuth 2.0 credentials for account ' , username ,
888890 '(invalid password):' , Log .error_string (e ))
889891 return OAuth2Helper .get_oauth2_credentials (username , password , reload_remote_accounts = False )
890892
891- Log .error ('Invalid password to decrypt' , username , 'credentials - aborting login:' , Log .error_string (e ))
893+ Log .error ('Invalid password to decrypt credentials for account' , username , '- aborting login:' ,
894+ Log .error_string (e ))
892895 return False , '%s: Login failed - the password for account %s is incorrect' % (APP_NAME , username )
893896
894897 except Exception as e :
@@ -897,7 +900,8 @@ def get_oauth2_credentials(username, password, reload_remote_accounts=True):
897900 # errors: URLError(OSError(50, 'Network is down'))) - access token 400 Bad Request HTTPErrors with messages
898901 # such as 'authorisation code was already redeemed' are caused by our support for simultaneous requests,
899902 # and will work from the next request; however, please report an issue if you encounter problems here
900- Log .info ('Caught exception while requesting OAuth 2.0 credentials for %s:' % username , Log .error_string (e ))
903+ Log .info ('Caught exception while requesting OAuth 2.0 credentials for account %s:' % username ,
904+ Log .error_string (e ))
901905 return False , '%s: Login failed for account %s - please check your internet connection and retry' % (
902906 APP_NAME , username )
903907
@@ -1014,7 +1018,7 @@ def get_oauth2_authorisation_code(permission_url, redirect_uri, redirect_listen_
10141018 # to improve no-GUI mode we also support the use of a local redirection receiver server or terminal
10151019 # entry to authenticate; this result is a timeout, wsgi request error/failure, or terminal auth ctrl+c
10161020 if 'expired' in data and data ['expired' ]:
1017- return False , 'No-GUI authorisation request failed or timed out'
1021+ return False , 'No-GUI authorisation request failed or timed out for account %s' % data [ 'username' ]
10181022
10191023 if 'local_server_auth' in data :
10201024 threading .Thread (target = OAuth2Helper .start_redirection_receiver_server , args = (data ,),
@@ -1031,13 +1035,16 @@ def get_oauth2_authorisation_code(permission_url, redirect_uri, redirect_listen_
10311035 authorisation_code = OAuth2Helper .oauth2_url_unescape (response ['code' ])
10321036 if authorisation_code :
10331037 return True , authorisation_code
1034- return False , 'No OAuth 2.0 authorisation code returned'
1038+ return False , 'No OAuth 2.0 authorisation code returned for account %s' % data [ 'username' ]
10351039 if 'error' in response :
1036- message = 'OAuth 2.0 authorisation error: %s' % response ['error' ]
1040+ message = 'OAuth 2.0 authorisation error for account %s: ' % data ['username' ]
1041+ message += response ['error' ]
10371042 message += '; %s' % response ['error_description' ] if 'error_description' in response else ''
10381043 return False , message
1039- return False , 'OAuth 2.0 authorisation response has no code or error message'
1040- return False , 'OAuth 2.0 authorisation response is missing or does not match `redirect_uri`'
1044+ return (False , 'OAuth 2.0 authorisation response for account %s has neither code nor error '
1045+ 'message' % data ['username' ])
1046+ return (False , 'OAuth 2.0 authorisation response for account %s is missing or does not match'
1047+ '`redirect_uri`' % data ['username' ])
10411048
10421049 else : # not for this thread - put back into queue
10431050 response_queue_reference .put (data )
@@ -1070,7 +1077,7 @@ def get_oauth2_authorisation_tokens(token_url, redirect_uri, client_id, client_s
10701077 return json .loads (response )
10711078 except urllib .error .HTTPError as e :
10721079 e .message = json .loads (e .read ())
1073- Log .debug ('Error requesting access token - received invalid response:' , e .message )
1080+ Log .debug ('Error requesting access token for account' , username , ' - received invalid response:' , e .message )
10741081 raise e
10751082
10761083 # noinspection PyUnresolvedReferences
@@ -1087,12 +1094,17 @@ def get_service_account_authorisation_token(key_type, key_path_or_contents, oaut
10871094 '`python -m pip install requests google-auth`' )
10881095
10891096 if key_type == 'file' :
1090- with open (key_path_or_contents ) as key_file :
1091- service_account = json .load (key_file )
1097+ try :
1098+ with open (key_path_or_contents ) as key_file :
1099+ service_account = json .load (key_file )
1100+ except IOError as e :
1101+ raise FileNotFoundError ('Unable to open service account key file %s for account %s' ,
1102+ (key_path_or_contents , username )) from e
10921103 elif key_type == 'key' :
10931104 service_account = json .loads (key_path_or_contents )
10941105 else :
1095- raise Exception ('Service account key type not specified - `client_id` must be set to `file` or `key`' )
1106+ raise Exception ('Service account key type not specified for account %s - `client_id` must be set to '
1107+ '`file` or `key`' % username )
10961108
10971109 credentials = google .oauth2 .service_account .Credentials .from_service_account_info (service_account )
10981110 credentials = credentials .with_scopes (oauth2_scope .split (' ' ))
@@ -1103,7 +1115,7 @@ def get_service_account_authorisation_token(key_type, key_path_or_contents, oaut
11031115 return {'access_token' : credentials .token , 'expires_in' : int (credentials .expiry .timestamp () - time .time ())}
11041116
11051117 @staticmethod
1106- def refresh_oauth2_access_token (token_url , client_id , client_secret , refresh_token ):
1118+ def refresh_oauth2_access_token (token_url , client_id , client_secret , username , refresh_token ):
11071119 """Obtains a new access token from token_url using the given client_id, client_secret and refresh token,
11081120 returning a dict with 'access_token', 'expires_in', and 'refresh_token' on success; exception on failure"""
11091121 params = {'client_id' : client_id , 'client_secret' : client_secret , 'refresh_token' : refresh_token ,
@@ -1121,7 +1133,7 @@ def refresh_oauth2_access_token(token_url, client_id, client_secret, refresh_tok
11211133
11221134 except urllib .error .HTTPError as e :
11231135 e .message = json .loads (e .read ())
1124- Log .debug ('Error refreshing access token - received invalid response:' , e .message )
1136+ Log .debug ('Error refreshing access token for account' , username , ' - received invalid response:' , e .message )
11251137 if e .code == 400 : # 400 Bad Request typically means re-authentication is required (token expired)
11261138 raise OAuth2Helper .TokenRefreshError from e
11271139 raise e
0 commit comments