From 716a6f47188e51a077645608e640ebfba52ed449 Mon Sep 17 00:00:00 2001 From: nopjmp Date: Tue, 7 Oct 2014 21:39:47 -0500 Subject: [PATCH 1/3] Add OpenBSD default CA certificates file location GitHub pull: https://github.com/OfflineIMAP/offlineimap/pull/120 Signed-off-by: Eygene Ryabinkin --- Changelog.rst | 3 +++ offlineimap/utils/distro.py | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/Changelog.rst b/Changelog.rst index ea7b082..95398ef 100644 --- a/Changelog.rst +++ b/Changelog.rst @@ -8,6 +8,9 @@ ChangeLog OfflineIMAP v6.5.6.1 (YYYY-MM-DD) ================================= +* Added default CA bundle location for OpenBSD + (GitHub pull #120). + * Added OpenSSL exception clause to our main GPL to allow people to link with OpenSSL in run-time. It is needed at least for Debian, see diff --git a/offlineimap/utils/distro.py b/offlineimap/utils/distro.py index 96aab1b..babefe7 100644 --- a/offlineimap/utils/distro.py +++ b/offlineimap/utils/distro.py @@ -13,7 +13,7 @@ import os # one that corresponds to the existing file. __DEF_OS_LOCATIONS = { 'freebsd': '/usr/local/share/certs/ca-root-nss.crt', - 'openbsd': None, + 'openbsd': '/etc/ssl/cert.pem', 'netbsd': None, 'dragonfly': None, 'darwin': [ From 0a569bea3d1d96b349861cc240e834f680ceccd7 Mon Sep 17 00:00:00 2001 From: Eygene Ryabinkin Date: Wed, 8 Oct 2014 10:39:07 +0400 Subject: [PATCH 2/3] Add default CA bundle location for DragonFlyBSD Signed-off-by: Eygene Ryabinkin --- Changelog.rst | 2 +- offlineimap/utils/distro.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Changelog.rst b/Changelog.rst index 95398ef..66f5c05 100644 --- a/Changelog.rst +++ b/Changelog.rst @@ -9,7 +9,7 @@ OfflineIMAP v6.5.6.1 (YYYY-MM-DD) ================================= * Added default CA bundle location for OpenBSD - (GitHub pull #120). + (GitHub pull #120) and DragonFlyBSD. * Added OpenSSL exception clause to our main GPL to allow people to link with OpenSSL in run-time. It is needed diff --git a/offlineimap/utils/distro.py b/offlineimap/utils/distro.py index babefe7..7c944b9 100644 --- a/offlineimap/utils/distro.py +++ b/offlineimap/utils/distro.py @@ -15,7 +15,7 @@ __DEF_OS_LOCATIONS = { 'freebsd': '/usr/local/share/certs/ca-root-nss.crt', 'openbsd': '/etc/ssl/cert.pem', 'netbsd': None, - 'dragonfly': None, + 'dragonfly': '/etc/ssl/cert.pem', 'darwin': [ # MacPorts, port curl-ca-bundle '/opt/local/share/curl/curl-ca-bundle.crt', From a1bf8db5175d028f4733313e6e22b6b9887d6d2b Mon Sep 17 00:00:00 2001 From: Eygene Ryabinkin Date: Sun, 5 Oct 2014 11:49:08 +0400 Subject: [PATCH 3/3] Brought CustomConfig.py into more proper shape - Multi-line documentation for functions and methods now has ending triple-double-quotes on an own line, as per PEP 257. - Added documentation and comments to almost all functions and methods. - Added stub implementations for getconfig() and getsection() inside CustomConfig.ConfigHelperMixin to provide sane run-time diagnostics for classes that doesn't implement them. Signed-off-by: Eygene Ryabinkin --- offlineimap/CustomConfig.py | 128 +++++++++++++++++++++++++++------ offlineimap/accounts.py | 2 + offlineimap/repository/Base.py | 2 + 3 files changed, 110 insertions(+), 22 deletions(-) diff --git a/offlineimap/CustomConfig.py b/offlineimap/CustomConfig.py index 447ac19..9fef69a 100644 --- a/offlineimap/CustomConfig.py +++ b/offlineimap/CustomConfig.py @@ -24,26 +24,46 @@ import re class CustomConfigParser(SafeConfigParser): def getdefault(self, section, option, default, *args, **kwargs): - """Same as config.get, but returns the "default" option if there - is no such option specified.""" + """ + Same as config.get, but returns the value of `default` + if there is no such option specified. + + """ if self.has_option(section, option): return self.get(*(section, option) + args, **kwargs) else: return default + def getdefaultint(self, section, option, default, *args, **kwargs): + """ + Same as config.getint, but returns the value of `default` + if there is no such option specified. + + """ if self.has_option(section, option): return self.getint (*(section, option) + args, **kwargs) else: return default + def getdefaultfloat(self, section, option, default, *args, **kwargs): + """ + Same as config.getfloat, but returns the value of `default` + if there is no such option specified. + + """ if self.has_option(section, option): return self.getfloat(*(section, option) + args, **kwargs) else: return default def getdefaultboolean(self, section, option, default, *args, **kwargs): + """ + Same as config.getboolean, but returns the value of `default` + if there is no such option specified. + + """ if self.has_option(section, option): return self.getboolean(*(section, option) + args, **kwargs) else: @@ -63,6 +83,11 @@ class CustomConfigParser(SafeConfigParser): (separator_re, e)) def getdefaultlist(self, section, option, default, separator_re): + """ + Same as getlist, but returns the value of `default` + if there is no such option specified. + + """ if self.has_option(section, option): return self.getlist(*(section, option, separator_re)) else: @@ -82,43 +107,78 @@ class CustomConfigParser(SafeConfigParser): return LocalEval(path) def getsectionlist(self, key): - """Returns a list of sections that start with key + " ". That is, - if key is "Account", returns all section names that start with - "Account ", but strips off the "Account ". For instance, for - "Account Test", returns "Test".""" + """ + Returns a list of sections that start with key + " ". + + That is, if key is "Account", returns all section names that + start with "Account ", but strips off the "Account ". + + For instance, for "Account Test", returns "Test". + """ key = key + ' ' return [x[len(key):] for x in self.sections() \ if x.startswith(key)] def set_if_not_exists(self, section, option, value): - """Set a value if it does not exist yet + """ + Set a value if it does not exist yet This allows to set default if the user has not explicitly - configured anything.""" + configured anything. + + """ if not self.has_option(section, option): self.set(section, option, value) + + def CustomConfigDefault(): - """Just a constant that won't occur anywhere else. + """ + Just a constant that won't occur anywhere else. This allows us to differentiate if the user has passed in any default value to the getconf* functions in ConfigHelperMixin - derived classes.""" + derived classes. + + """ pass -class ConfigHelperMixin: - """Allow comfortable retrieving of config values pertaining to a section. - If a class inherits from this cls:`ConfigHelperMixin`, it needs - to provide 2 functions: meth:`getconfig` (returning a - ConfigParser object) and meth:`getsection` (returning a string - which represents the section to look up). All calls to getconf* - will then return the configuration values for the ConfigParser - object in the specific section.""" + +class ConfigHelperMixin: + """ + Allow comfortable retrieving of config values pertaining + to a section. + + If a class inherits from cls:`ConfigHelperMixin`, it needs + to provide 2 functions: + - meth:`getconfig` (returning a CustomConfigParser object) + - and meth:`getsection` (returning a string which represents + the section to look up). + All calls to getconf* will then return the configuration values + for the CustomConfigParser object in the specific section. + + """ def _confighelper_runner(self, option, default, defaultfunc, mainfunc, *args): - """Return config value for getsection()""" + """ + Return configuration or default value for option + that contains in section identified by getsection(). + + Arguments: + - option: name of the option to retrieve; + - default: governs which function we will call. + * When CustomConfigDefault is passed, we will call + the mainfunc. + * When any other value is passed, we will call + the defaultfunc and the value of `default` will + be passed as the third argument to this function. + - defaultfunc and mainfunc: processing helpers. + - args: additional trailing arguments that will be passed + to all processing helpers. + + """ lst = [self.getsection(), option] if default == CustomConfigDefault: return mainfunc(*(lst + list(args))) @@ -127,8 +187,32 @@ class ConfigHelperMixin: return defaultfunc(*(lst + list(args))) - def getconf(self, option, - default = CustomConfigDefault): + def getconfig(self): + """ + Returns CustomConfigParser object that we will use + for all our actions. + + Must be overriden in all classes that use this mix-in. + + """ + raise NotImplementedError("ConfigHelperMixin.getconfig() " + "is to be overriden") + + + + def getsection(self): + """ + Returns name of configuration section in which our + class keeps its configuration. + + Must be overriden in all classes that use this mix-in. + + """ + raise NotImplementedError("ConfigHelperMixin.getsection() " + "is to be overriden") + + + def getconf(self, option, default = CustomConfigDefault): return self._confighelper_runner(option, default, self.getconfig().getdefault, self.getconfig().get) @@ -149,7 +233,7 @@ class ConfigHelperMixin: self.getconfig().getfloat) def getconflist(self, option, separator_re, - default = CustomConfigDefault): + default = CustomConfigDefault): return self._confighelper_runner(option, default, self.getconfig().getdefaultlist, self.getconfig().getlist, separator_re) diff --git a/offlineimap/accounts.py b/offlineimap/accounts.py index f8a2281..eabbd23 100644 --- a/offlineimap/accounts.py +++ b/offlineimap/accounts.py @@ -78,6 +78,7 @@ class Account(CustomConfig.ConfigHelperMixin): def getlocaleval(self): return self.localeval + # Interface from CustomConfig.ConfigHelperMixin def getconfig(self): return self.config @@ -90,6 +91,7 @@ class Account(CustomConfig.ConfigHelperMixin): def getaccountmeta(self): return os.path.join(self.metadatadir, 'Account-' + self.name) + # Interface from CustomConfig.ConfigHelperMixin def getsection(self): return 'Account ' + self.getname() diff --git a/offlineimap/repository/Base.py b/offlineimap/repository/Base.py index 1050721..cc6abdd 100644 --- a/offlineimap/repository/Base.py +++ b/offlineimap/repository/Base.py @@ -103,9 +103,11 @@ class BaseRepository(CustomConfig.ConfigHelperMixin, object): def getmapdir(self): return self.mapdir + # Interface from CustomConfig.ConfigHelperMixin def getsection(self): return 'Repository ' + self.name + # Interface from CustomConfig.ConfigHelperMixin def getconfig(self): return self.config