[kupfer] Make 'keyring' module optional and make sure it never uses "crypted" keyring
- From: Ulrik Sverdrup <usverdrup src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [kupfer] Make 'keyring' module optional and make sure it never uses "crypted" keyring
- Date: Sun, 13 Jun 2010 17:06:34 +0000 (UTC)
commit 449230b1df3871952f3a69dc2dca7a117b7c3b7f
Author: Ulrik Sverdrup <ulrik sverdrup gmail com>
Date: Sun Jun 13 18:56:53 2010 +0200
Make 'keyring' module optional and make sure it never uses "crypted" keyring
Make sure we don't use the "CryptedFileKeyring", which will ask for
keyring password etc etc; as fallback we use the uncrypted variant
(Gnome / KWallet backends exist if security is desired).
We at the same time move the UserNamePassword class to a better place
and make the 'keyring' module optional (some plugins will need it).
Launchpad bug: https://bugs.launchpad.net/kupfer/+bug/593319 Launchpad
bug: https://bugs.launchpad.net/kupfer/+bug/576308
README | 4 +-
kupfer/core/settings.py | 35 -------------------
kupfer/plugin/gmail/__init__.py | 2 +
kupfer/plugin/google_picasa/__init__.py | 2 +
kupfer/plugin/twitter/__init__.py | 1 +
kupfer/plugin_support.py | 56 +++++++++++++++++++++++++++++-
kupfer/ui/preferences.py | 7 ++--
7 files changed, 65 insertions(+), 42 deletions(-)
---
diff --git a/README b/README
index 2da653b..6fe6cf4 100644
--- a/README
+++ b/README
@@ -40,7 +40,6 @@ Kupfer requires Python 2.6 or later, and the following important libraries:
* gtk python bindings, GTK+ version 2.16
* glib python bindings (pygobject) 2.18
* dbus python bindings
-* keyring python module
Optional, but very recommended dependencies:
@@ -51,7 +50,8 @@ Optional, but very recommended dependencies:
Gnome Terminal)
* rst2man / python docutils to build manpages
* xml2po / gnome docutils to install mallard help pages
-* python-keyring-gnome or python-keyring-kwallet
+* `keyring` python module, and optionally its extensions
+ python-keyring-gnome or python-keyring-kwallet
Opportunistic dependencies
diff --git a/kupfer/core/settings.py b/kupfer/core/settings.py
index 35f2038..e09195d 100644
--- a/kupfer/core/settings.py
+++ b/kupfer/core/settings.py
@@ -7,7 +7,6 @@ import copy
import glib
import gobject
-import keyring
from kupfer import config, pretty, scheduler
@@ -423,37 +422,3 @@ class ExtendedSetting(object):
plugin/key (string)'''
return None
-
-class UserNamePassword(ExtendedSetting):
- ''' Configuration type for storing username/password values.
- Username is stored in Kupfer config, password in keyring '''
- def __init__(self, obj=None):
- ExtendedSetting.__init__(self)
- self._configure_keyring()
- self.username = None
- self.password = None
- if obj:
- self.username = obj.username
- self.password = obj.password
-
- def __repr__(self):
- return '<UserNamePassword "%s", %s>' % (self.username,
- bool(self.password))
-
- @classmethod
- def _configure_keyring(cls):
- # Configure the fallback keyring's configuration file if used
- kr = keyring.get_keyring()
- if hasattr(kr, "file_path"):
- kr.file_path = config.save_config_file("keyring.cfg")
-
- def load(self, plugin_id, key, username):
- self.password = keyring.get_password(plugin_id, username)
- self.username = username
-
- def save(self, plugin_id, key):
- ''' save @user_password - store password in keyring and return username
- to save in standard configuration file '''
- keyring.set_password(plugin_id, self.username, self.password)
- return self.username
-
diff --git a/kupfer/plugin/gmail/__init__.py b/kupfer/plugin/gmail/__init__.py
index 3374a18..9aa7992 100644
--- a/kupfer/plugin/gmail/__init__.py
+++ b/kupfer/plugin/gmail/__init__.py
@@ -18,6 +18,8 @@ from kupfer.obj.grouping import ToplevelGroupingSource
from kupfer.obj.contacts import ContactLeaf, EmailContact, email_from_leaf
from kupfer import plugin_support, pretty, utils, icons, kupferstring
+plugin_support.check_keyring_support()
+
__kupfer_settings__ = plugin_support.PluginSettings(
{
'key': 'userpass',
diff --git a/kupfer/plugin/google_picasa/__init__.py b/kupfer/plugin/google_picasa/__init__.py
index 7b8acdf..ea2c755 100644
--- a/kupfer/plugin/google_picasa/__init__.py
+++ b/kupfer/plugin/google_picasa/__init__.py
@@ -21,6 +21,8 @@ from kupfer import kupferstring
from kupfer import utils
from kupfer import task
+plugin_support.check_keyring_support()
+
__kupfer_settings__ = plugin_support.PluginSettings(
{
'key': 'userpass',
diff --git a/kupfer/plugin/twitter/__init__.py b/kupfer/plugin/twitter/__init__.py
index a54a103..0c52e58 100644
--- a/kupfer/plugin/twitter/__init__.py
+++ b/kupfer/plugin/twitter/__init__.py
@@ -21,6 +21,7 @@ from kupfer.obj.grouping import ToplevelGroupingSource
from kupfer.obj.contacts import ContactLeaf, NAME_KEY
from kupfer.obj.special import PleaseConfigureLeaf
+plugin_support.check_keyring_support()
__kupfer_settings__ = plugin_support.PluginSettings(
{
diff --git a/kupfer/plugin_support.py b/kupfer/plugin_support.py
index d494076..c8501b5 100644
--- a/kupfer/plugin_support.py
+++ b/kupfer/plugin_support.py
@@ -1,8 +1,14 @@
import gobject
+try:
+ import keyring
+except ImportError:
+ keyring = None
+
+
from kupfer import pretty
+from kupfer import config
from kupfer.core import settings
-from kupfer.core.settings import UserNamePassword
__all__ = [
"UserNamePassword",
@@ -124,5 +130,51 @@ def check_dbus_connection():
if not _has_dbus_connection:
raise ImportError(_("No D-Bus connection to desktop session"))
-
+def check_keyring_support():
+ """
+ Check if the UserNamePassword class can be used,
+ else raise ImportError with an explanatory error message.
+ """
+ import keyring
+
+class UserNamePassword (settings.ExtendedSetting):
+ ''' Configuration type for storing username/password values.
+ Username is stored in Kupfer config, password in keyring '''
+ def __init__(self, obj=None):
+ settings.ExtendedSetting.__init__(self)
+ self._configure_keyring()
+ self.username = None
+ self.password = None
+ if obj:
+ self.username = obj.username
+ self.password = obj.password
+
+ def __repr__(self):
+ return '<UserNamePassword "%s", %s>' % (self.username,
+ bool(self.password))
+
+ @classmethod
+ def _configure_keyring(cls):
+ # Configure the fallback keyring's configuration file if used
+ import keyring.backend
+ kr = keyring.get_keyring()
+ if hasattr(kr, "crypted_password"):
+ keyring.set_keyring(keyring.backend.UncryptedFileKeyring())
+ kr = keyring.get_keyring()
+ if hasattr(kr, "file_path"):
+ kr.file_path = config.save_config_file("keyring.cfg")
+
+ def load(self, plugin_id, key, username):
+ self.password = keyring.get_password(plugin_id, username)
+ self.username = username
+
+ def save(self, plugin_id, key):
+ ''' save @user_password - store password in keyring and return username
+ to save in standard configuration file '''
+ keyring.set_password(plugin_id, self.username, self.password)
+ return self.username
+
+if not keyring:
+ class UserNamePassword (object):
+ pass
diff --git a/kupfer/ui/preferences.py b/kupfer/ui/preferences.py
index a12797c..167fa0a 100644
--- a/kupfer/ui/preferences.py
+++ b/kupfer/ui/preferences.py
@@ -15,6 +15,7 @@ from kupfer.core import settings, plugins, relevance, sources
from kupfer.ui import keybindings
from kupfer.ui.credentials_dialog import ask_user_credentials
from kupfer.ui import getkey_dialog
+from kupfer import plugin_support
# index in GtkNotebook
PLUGIN_LIST_PAGE = 2
@@ -552,9 +553,9 @@ class PreferencesWindowController (pretty.OutputMixin):
def _get_plugin_credentials_callback(self, plugin_id, key):
def callback(widget):
setctl = settings.GetSettingsController()
- val_type = settings.UserNamePassword
+ val_type = plugin_support.UserNamePassword
upass = setctl.get_plugin_config(plugin_id, key, val_type) \
- or settings.UserNamePassword()
+ or plugin_support.UserNamePassword()
user_password = ask_user_credentials(upass.username, upass.password)
if user_password:
upass.username, upass.password = user_password
@@ -589,7 +590,7 @@ class PreferencesWindowController (pretty.OutputMixin):
hbox.set_tooltip_text(tooltip)
label = plugin_settings.get_label(setting)
- if issubclass(typ, settings.UserNamePassword):
+ if issubclass(typ, plugin_support.UserNamePassword):
wid = gtk.Button(label or _("Set username and password"))
wid.connect("clicked", self._get_plugin_credentials_callback(
plugin_id, setting))
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]