[kupfer: 8/12] settings: add support for user credentials setting



commit 718c0c6395da58fe6ce3e58d46803386e551d254
Author: Karol BÄ?dkowski <karol bedkowsk+gh gmail com>
Date:   Wed Feb 3 19:33:02 2010 +0100

    settings: add support for user credentials setting
    
    core.settings:
    + ExtendedSetting - base class for advenced plugin setting
    + UserNamePassword - class for storing user passwords in keyring
    
    ui.preferences:
    + support for UserNamePassword (show button thath open dialog for user
      credentials)
    
    plugin_support:
    + import UserNamePassword for easly use it in plugins.

 kupfer/core/settings.py  |   72 +++++++++++++++++++++++++++++++++++++++------
 kupfer/plugin_support.py |    2 +
 kupfer/ui/preferences.py |   23 ++++++++++++++
 3 files changed, 87 insertions(+), 10 deletions(-)
---
diff --git a/kupfer/core/settings.py b/kupfer/core/settings.py
index e65c6e6..c9e3e7e 100644
--- a/kupfer/core/settings.py
+++ b/kupfer/core/settings.py
@@ -6,6 +6,7 @@ import copy
 
 import glib
 import gobject
+import keyring
 
 from kupfer import config, pretty, scheduler
 
@@ -266,23 +267,33 @@ class SettingsController (gobject.GObject, pretty.OutputMixin):
 		if val is None:
 			return default
 
-		if value_type is bool:
-			value_type = strbool
+		if hasattr(value_type, "load"):
+			val_obj = value_type()
+			val_obj.load(plugin, key, val)
+			return val_obj
+		else:
+			if value_type is bool:
+				value_type = strbool
 
-		try:
-			val = value_type(val)
-		except ValueError, err:
-			self.output_info("Error for stored value %s.%s" %
-					(plug_section, key), err)
-			return default
-		return val
+			try:
+				val = value_type(val)
+			except ValueError, err:
+				self.output_info("Error for stored value %s.%s" %
+						(plug_section, key), err)
+				return default
+			return val
 
 	def set_plugin_config(self, plugin, key, value, value_type=str):
 		"""Try set @key for plugin names @plugin, coerce to @value_type
 		first.  """
 		plug_section = "plugin_%s" % plugin
 		self.emit("value-changed", plug_section, key, value)
-		return self._set_raw_config(plug_section, key, value_type(value))
+
+		if hasattr(value_type, "save"):
+			value_repr = value.save(plugin, key)
+		else:
+			value_repr = value_type(value)
+		return self._set_raw_config(plug_section, key, value_repr)
 
 # Section, Key, Value
 gobject.signal_new("value-changed", SettingsController, gobject.SIGNAL_RUN_LAST,
@@ -300,3 +311,44 @@ def GetSettingsController():
 	if _settings_controller is None:
 		_settings_controller = SettingsController()
 	return _settings_controller
+
+
+
+class ExtendedSetting(object):
+	""" Abstract class for defining non-simple configuration option """
+	def load(self, plugin_id, key, config_value):
+		''' load value for @plugin_id and @key, @config_value is value
+		stored in regular Kupfer config for plugin/key'''
+		pass
+
+	def save(self, plugin_id, key):
+		''' Save value for @plugin_id and @key. 
+		@Return value that should be stored in Kupfer config for 
+		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.username = None
+		self.password = None
+		if obj:
+			self.username = obj.username
+			self.password = obj.password
+
+	def __repr__(self):
+		return '<UserNamePassword "%s", "%s">' % (self.username, self.password)
+
+	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_support.py b/kupfer/plugin_support.py
index 794f811..bcb4661 100644
--- a/kupfer/plugin_support.py
+++ b/kupfer/plugin_support.py
@@ -1,5 +1,6 @@
 from kupfer import pretty
 from kupfer.core import settings
+from kupfer.core.settings import UserNamePassword
 
 SETTING_PREFER_CATALOG = {
 	"key" : "kupfer_toplevel",
@@ -106,3 +107,4 @@ def check_dbus_connection():
 		raise ImportError(_("No D-Bus connection to desktop session"))
 
 
+
diff --git a/kupfer/ui/preferences.py b/kupfer/ui/preferences.py
index 2c44a61..3944267 100644
--- a/kupfer/ui/preferences.py
+++ b/kupfer/ui/preferences.py
@@ -13,6 +13,8 @@ from kupfer import config, pretty, utils, icons, version
 from kupfer import scheduler, kupferstring
 from kupfer.core import settings, plugins, relevance
 from kupfer.ui import keybindings
+from kupfer.ui.credentials_dialog import ask_user_credentials
+
 
 class PreferencesWindowController (pretty.OutputMixin):
 	def __init__(self):
@@ -469,6 +471,18 @@ class PreferencesWindowController (pretty.OutputMixin):
 			setctl.set_plugin_config(plugin_id, key, value, value_type)
 		return callback
 
+	def _get_plugin_credentials_callback(self, plugin_id, key):
+		def callback(widget):
+			setctl = settings.GetSettingsController()
+			val_type = settings.UserNamePassword
+			upass = setctl.get_plugin_config(plugin_id, key, val_type) \
+					or settings.UserNamePassword()
+			user_password = ask_user_credentials(upass.username, upass.password)
+			if user_password:
+				upass.username, upass.password = user_password
+				setctl.set_plugin_config(plugin_id, key, upass, val_type)
+		return callback
+
 	def _make_plugin_settings_widget(self, plugin_id):
 		plugin_settings = plugins.get_plugin_attribute(plugin_id,
 				plugins.settings_attribute)
@@ -496,6 +510,15 @@ class PreferencesWindowController (pretty.OutputMixin):
 			if tooltip:
 				hbox.set_tooltip_text(tooltip)
 			label = plugin_settings.get_label(setting)
+
+			if issubclass(typ, settings.UserNamePassword):
+				wid = gtk.Button(label or _("Set username and password"))
+				wid.connect("clicked", self._get_plugin_credentials_callback(
+						plugin_id, setting))
+				hbox.pack_start(wid, False)
+				vbox.pack_start(hbox, False)
+				continue
+
 			label_wid = gtk.Label(label)
 			if issubclass(typ, basestring):
 				if alternatives:



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]