Merge branch 'master' of https://github.com/OfflineIMAP/offlineimap into next
This commit is contained in:
commit
160efa4c43
52
Changelog.md
52
Changelog.md
|
@ -15,6 +15,58 @@ Note to mainainers:
|
||||||
* The following excerpt is only usefull when rendered in the website.
|
* The following excerpt is only usefull when rendered in the website.
|
||||||
{:toc}
|
{:toc}
|
||||||
|
|
||||||
|
### OfflineIMAP v7.2.2 (2018-12-22)
|
||||||
|
|
||||||
|
#### Notes
|
||||||
|
|
||||||
|
With this release offlineimap can renew the token for OAUTH2. There is better
|
||||||
|
integration for ArchLinux and OSX. SSL configuration options are more
|
||||||
|
consistent.
|
||||||
|
|
||||||
|
There are bug fixes about maxage and GSSAPI.
|
||||||
|
|
||||||
|
The imaplib2 library looks discontinued. I wonder we'll have no other choice
|
||||||
|
than maintaining our own fork.
|
||||||
|
|
||||||
|
This release was tested by:
|
||||||
|
|
||||||
|
- Nicolas Sebrecht
|
||||||
|
|
||||||
|
|
||||||
|
#### Authors
|
||||||
|
|
||||||
|
- Nicolas Sebrecht (5)
|
||||||
|
- Philippe Loctaux (4)
|
||||||
|
- Benedikt Heine (2)
|
||||||
|
- Carnë Draug (2)
|
||||||
|
- Frode Aannevik (1)
|
||||||
|
- Robbie Harwood (1)
|
||||||
|
|
||||||
|
|
||||||
|
#### Features
|
||||||
|
|
||||||
|
- 2890dec Added ssl certfile on osx for openssl pacakge on homebrew. [Philippe Loctaux]
|
||||||
|
- 761e10e Add Archlinux to list of supported distros. [Philippe Loctaux]
|
||||||
|
|
||||||
|
#### Fixes
|
||||||
|
|
||||||
|
- 8692799 Fix expired oauth2_access_token. [Frode Aannevik]
|
||||||
|
- 096aa07 Handle empty token with complete GSSAPI context. [Robbie Harwood]
|
||||||
|
- a51064e maxage: always compute the remote cache list for min_uid. [Nicolas Sebrecht]
|
||||||
|
- 698ec64 offlineimap.conf: minor fixes. [Nicolas Sebrecht]
|
||||||
|
- af3a35a offlineimap/utilis/distro.py: indentation fix. [Philippe Loctaux]
|
||||||
|
- d3ba837 Fix typo in exception message. [Benedikt Heine]
|
||||||
|
- c9005cd Check if username is provided before trying plain authentication.. [Carnë Draug]
|
||||||
|
|
||||||
|
#### Changes
|
||||||
|
|
||||||
|
- 5f9474e Print username instead of accountname when asking for password. [Carnë Draug]
|
||||||
|
- ce9a198 Chain tls_level and ssl_version only if ssl is enabled. [Benedikt Heine]
|
||||||
|
- 6ef5937 docs/website-doc.sh: minor improvements in comments of versions.yml. [Nicolas Sebrecht]
|
||||||
|
- 4544bb1 contrib/release.py: minor UI improvement. [Nicolas Sebrecht]
|
||||||
|
- d930125 fix dates in copyright lines. [Nicolas Sebrecht]
|
||||||
|
|
||||||
|
|
||||||
### OfflineIMAP v7.2.1 (2018-06-16)
|
### OfflineIMAP v7.2.1 (2018-06-16)
|
||||||
|
|
||||||
#### Notes
|
#### Notes
|
||||||
|
|
|
@ -589,20 +589,19 @@ localfolders = ~/Test
|
||||||
|
|
||||||
# This option stands in the [Repository LocalExample] section.
|
# This option stands in the [Repository LocalExample] section.
|
||||||
#
|
#
|
||||||
# This option is similar to "utime_from_header" and could be use as a
|
# This option is similar to "utime_from_header" and could be used as a
|
||||||
# complementary feature to keep track of a message date. This option only
|
# complementary feature to keep track of a message date. This option only
|
||||||
# makes sense for the Maildir type.
|
# makes sense for the Maildir type.
|
||||||
#
|
#
|
||||||
# By default each message is stored in a file which prefix is the fetch
|
# By default each message is stored in a file which prefix is the fetch
|
||||||
# timestamp and an order rank such as "1446590057_0". In a multithreading
|
# timestamp and an order rank such as "1446590057_0". In a multithreading
|
||||||
# environment message are fetched in a random order, then you can't trust
|
# environment message are fetched in a random order, then you can't trust
|
||||||
# the file name to sort your boxes.
|
# the filename to sort your boxes.
|
||||||
#
|
#
|
||||||
# If set to "yes" the file name prefix if build on the message "Date" header
|
# If set to "yes" the filename prefix is built from the message "Date" header
|
||||||
# (which should be present) or the "Received-date" if "Date" is not
|
# (which should be present) or the "Received-date" if "Date" is not
|
||||||
# found. If neither "Received-date" nor "Date" is found, the current system
|
# found. If neither "Received-date" nor "Date" is found, the current system
|
||||||
# date is used. Now you can quickly sort your messages using their file
|
# date is used. Now you can quickly sort your messages using their filenames.
|
||||||
# names.
|
|
||||||
#
|
#
|
||||||
# Used in combination with "utime_from_header" all your message would be in
|
# Used in combination with "utime_from_header" all your message would be in
|
||||||
# order with the correct mtime attribute.
|
# order with the correct mtime attribute.
|
||||||
|
|
|
@ -2,7 +2,7 @@ __all__ = ['OfflineImap']
|
||||||
|
|
||||||
__productname__ = 'OfflineIMAP'
|
__productname__ = 'OfflineIMAP'
|
||||||
# Expecting trailing "-rcN" or "" for stable releases.
|
# Expecting trailing "-rcN" or "" for stable releases.
|
||||||
__version__ = "7.2.1"
|
__version__ = "7.2.2"
|
||||||
__copyright__ = "Copyright 2002-2018 John Goerzen & contributors"
|
__copyright__ = "Copyright 2002-2018 John Goerzen & contributors"
|
||||||
__author__ = "John Goerzen"
|
__author__ = "John Goerzen"
|
||||||
__author_email__= "offlineimap-project@lists.alioth.debian.org"
|
__author_email__= "offlineimap-project@lists.alioth.debian.org"
|
||||||
|
|
|
@ -511,6 +511,11 @@ def syncfolder(account, remotefolder, quick):
|
||||||
uids = remotefolder.getmessageuidlist()
|
uids = remotefolder.getmessageuidlist()
|
||||||
localfolder.dropmessagelistcache()
|
localfolder.dropmessagelistcache()
|
||||||
if len(uids) > 0:
|
if len(uids) > 0:
|
||||||
|
# Reload the remote message list from min_uid. This avoid issues for
|
||||||
|
# old messages, which has been added from local on any previous run
|
||||||
|
# (IOW, message is older than maxage _and_ has high enough UID).
|
||||||
|
remotefolder.dropmessagelistcache()
|
||||||
|
remotefolder.cachemessagelist(min_uid=min(uids))
|
||||||
localfolder.cachemessagelist(min_uid=min(uids))
|
localfolder.cachemessagelist(min_uid=min(uids))
|
||||||
else:
|
else:
|
||||||
# Remote folder UIDs list is empty for the given range. We still
|
# Remote folder UIDs list is empty for the given range. We still
|
||||||
|
@ -523,6 +528,7 @@ def syncfolder(account, remotefolder, quick):
|
||||||
uids = [uid for uid in uids if uid > 0]
|
uids = [uid for uid in uids if uid > 0]
|
||||||
if len(uids) > 0:
|
if len(uids) > 0:
|
||||||
# Update the remote cache list for this new min(uids).
|
# Update the remote cache list for this new min(uids).
|
||||||
|
remotefolder.dropmessagelistcache()
|
||||||
remotefolder.cachemessagelist(min_uid=min(uids))
|
remotefolder.cachemessagelist(min_uid=min(uids))
|
||||||
|
|
||||||
def cachemessagelists_startdate(new, partial, date):
|
def cachemessagelists_startdate(new, partial, date):
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
# along with this program; if not, write to the Free Software
|
# along with this program; if not, write to the Free Software
|
||||||
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
|
import datetime
|
||||||
import hmac
|
import hmac
|
||||||
import socket
|
import socket
|
||||||
import json
|
import json
|
||||||
|
@ -111,6 +112,7 @@ class IMAPServer(object):
|
||||||
self.oauth2_client_id = repos.getoauth2_client_id()
|
self.oauth2_client_id = repos.getoauth2_client_id()
|
||||||
self.oauth2_client_secret = repos.getoauth2_client_secret()
|
self.oauth2_client_secret = repos.getoauth2_client_secret()
|
||||||
self.oauth2_request_url = repos.getoauth2_request_url()
|
self.oauth2_request_url = repos.getoauth2_request_url()
|
||||||
|
self.oauth2_access_token_expires_at = None
|
||||||
|
|
||||||
self.delim = None
|
self.delim = None
|
||||||
self.root = None
|
self.root = None
|
||||||
|
@ -219,6 +221,12 @@ class IMAPServer(object):
|
||||||
return retval
|
return retval
|
||||||
|
|
||||||
def __xoauth2handler(self, response):
|
def __xoauth2handler(self, response):
|
||||||
|
now = datetime.datetime.now()
|
||||||
|
if self.oauth2_access_token_expires_at \
|
||||||
|
and self.oauth2_access_token_expires_at < now:
|
||||||
|
self.oauth2_access_token = None
|
||||||
|
self.ui.debug('imap', 'xoauth2handler: oauth2_access_token expired')
|
||||||
|
|
||||||
if self.oauth2_access_token is None:
|
if self.oauth2_access_token is None:
|
||||||
if self.oauth2_request_url is None:
|
if self.oauth2_request_url is None:
|
||||||
raise OfflineImapError("No remote oauth2_request_url for "
|
raise OfflineImapError("No remote oauth2_request_url for "
|
||||||
|
@ -256,9 +264,13 @@ class IMAPServer(object):
|
||||||
raise OfflineImapError("xoauth2handler got: %s"% resp,
|
raise OfflineImapError("xoauth2handler got: %s"% resp,
|
||||||
OfflineImapError.ERROR.REPO)
|
OfflineImapError.ERROR.REPO)
|
||||||
self.oauth2_access_token = resp['access_token']
|
self.oauth2_access_token = resp['access_token']
|
||||||
|
if u'expires_in' in resp:
|
||||||
|
self.oauth2_access_token_expires_at = now + datetime.timedelta(
|
||||||
|
seconds=resp['expires_in']/2
|
||||||
|
)
|
||||||
|
|
||||||
self.ui.debug('imap', 'xoauth2handler: access_token "%s"'%
|
self.ui.debug('imap', 'xoauth2handler: access_token "%s expires %s"'% (
|
||||||
self.oauth2_access_token)
|
self.oauth2_access_token, self.oauth2_access_token_expires_at))
|
||||||
auth_string = 'user=%s\1auth=Bearer %s\1\1'% (
|
auth_string = 'user=%s\1auth=Bearer %s\1\1'% (
|
||||||
self.username, self.oauth2_access_token)
|
self.username, self.oauth2_access_token)
|
||||||
#auth_string = base64.b64encode(auth_string)
|
#auth_string = base64.b64encode(auth_string)
|
||||||
|
@ -280,6 +292,13 @@ class IMAPServer(object):
|
||||||
if not self.gss_vc.complete:
|
if not self.gss_vc.complete:
|
||||||
response = self.gss_vc.step(token)
|
response = self.gss_vc.step(token)
|
||||||
return response if response else ""
|
return response if response else ""
|
||||||
|
elif token is None:
|
||||||
|
# uh... context is complete, so there's no negotiation we can
|
||||||
|
# do. But we also don't have a token, so we can't send any
|
||||||
|
# kind of response. Empirically, some (but not all) servers
|
||||||
|
# seem to put us in this state, and seem fine with getting no
|
||||||
|
# GSSAPI content in response, so give it to them.
|
||||||
|
return ""
|
||||||
|
|
||||||
# Don't bother checking qop because we're over a TLS channel
|
# Don't bother checking qop because we're over a TLS channel
|
||||||
# already. But hey, if some server started encrypting tomorrow,
|
# already. But hey, if some server started encrypting tomorrow,
|
||||||
|
|
Loading…
Reference in New Issue