OfflineIMAP / offlineimap

Read/sync your IMAP mailboxes (python2) [LEGACY: move to offlineimap3]
http://www.offlineimap.org
Other
1.78k stars 360 forks source link

XOAUTH2: Token has been expired or revoked #673

Closed physkets closed 4 years ago

physkets commented 4 years ago

General informations

Configuration file offlineimaprc

[general]
ui = ttyui
accounts = Gmail

[Account Gmail]
localrepository = Gmail-Local
remoterepository = Gmail-Remote

[Repository Gmail-Local]
type = Maildir
localfolders = ~/Mail/Gmail
## Remove GMAIL prefix on Google-specific IMAP folders that are pulled down.
nametrans = lambda f: '[Gmail]/' + f if f in ['Drafts', 'Starred', 'Important', 'Spam', 'Trash', 'All Mail', 'Sent Mail','Bin'] else f

[Repository Gmail-Remote]
type = Gmail
remoteuser = xxx@gmail.com
ssl = yes
starttls = no
ssl_version = tls1_2
tls_level = tls_secure
sslcacertfile = /etc/ssl/certs/ca-certificates.crt
auth_mechanisms = XOAUTH2
oauth2_client_id = xxx.apps.googleusercontent.com
oauth2_client_secret = xxx
oauth2_request_url = https://accounts.google.com/o/oauth2/token
oauth2_refresh_token = xxx
nametrans = lambda f: f.replace('[Gmail]/', '') if f.startswith('[Gmail]/') else f
folderfilter = lambda foldername: foldername not in ['[Gmail]/Sent Mail']

Logs, error

OfflineIMAP 7.3.3
  Licensed under the GNU GPL v2 or any later version (with an OpenSSL exception)
imaplib2 v2.101 (bundled), Python v2.7.18, OpenSSL 1.1.1g  21 Apr 2020
*** Processing account Gmail
Establishing connection to imap.gmail.com:993 (Gmail-Remote)
XOAUTH2 authentication failed: xoauth2handler got: {u'error_description': u'Token has been expired or revoked.', u'error': u'invalid_grant'}
ERROR: All authentication types failed:
        XOAUTH2: xoauth2handler got: {u'error_description': u'Token has been expired or revoked.', u'error': u'invalid_grant'}
*** Finished account 'Gmail' in 0:03
ERROR: Exceptions occurred during the run!
ERROR: All authentication types failed:
        XOAUTH2: xoauth2handler got: {u'error_description': u'Token has been expired or revoked.', u'error': u'invalid_grant'}
Traceback:
  File "/usr/lib/python2.7/site-packages/offlineimap/accounts.py", line 293, in syncrunner
    self.__sync()
  File "/usr/lib/python2.7/site-packages/offlineimap/accounts.py", line 372, in __sync
    remoterepos.getfolders()
  File "/usr/lib/python2.7/site-packages/offlineimap/repository/IMAP.py", line 452, in getfolders
    imapobj = self.imapserver.acquireconnection()
  File "/usr/lib/python2.7/site-packages/offlineimap/imapserver.py", line 583, in acquireconnection
    self.__authn_helper(imapobj)
  File "/usr/lib/python2.7/site-packages/offlineimap/imapserver.py", line 456, in __authn_helper
    "failed:\n\t%s"% msg, OfflineImapError.ERROR.REPO)

Steps to reproduce the error

physkets commented 4 years ago

It says that the token has been expired or revoked, but I did nothing of that sort, and the token seems to still exist when I checked https://console.developers.google.com/

chris001 commented 4 years ago

https://developers.google.com/gmail/imap/xoauth2-protocol You have the ACCESS TOKEN and REFRESH TOKEN....

physkets commented 4 years ago

You have the ACCESS TOKEN and REFRESH TOKEN....

Okay, and?

physkets commented 4 years ago

I reset my client secret and re-generated my refresh token, and it works properly now. I don't understand why it was revoked/expired (I see no expiry for the refresh token anywhere).

chris001 commented 4 years ago

@physkets When does a refresh token expire ?

Refresh tokens do not expire, unless there are few special conditions :

  1. The user has removed your Google application - in our case, OfflineIMAP.
  2. The refresh token has not been used for six months.
  3. The user changed password, AND the refresh token contained "Gmail" scopes. This means that the refresh token will be invalidated only when he had previously given permission for accessing his Gmail, and then later changed his password. NOTE: For the rest of Google services, like YouTube, Google Calendar, etc., a changed password will not invalidate the refresh token.
  4. The application - OfflineIMAP in our case - generated a new refresh token for the user for more than 50 times. Only the 50 most recent refresh tokens may be active. The 51st oldest refresh token becomes invalid. I do not believe OfflineIMAP generates a new refresh token every time it runs.
physkets commented 4 years ago

@chris001 Thanks for that detailed explanation, but I don't think any of those cases apply to me.

  1. I did not remove or deactivate the credential.
  2. I was using it even the day before the problem.
  3. I changed neither the password nor the refresh token.
  4. I had been using the same refresh token since the beginning (for ~3 years now).

So I have no idea what might've caused this.