une GnomeKeyring vi gobject introspections

This commit is contained in:
Yann Leboulanger 2012-12-26 11:19:59 +01:00
parent 11f661a3ed
commit ad2f2eada6
2 changed files with 83 additions and 54 deletions

View File

@ -143,3 +143,15 @@ class PluginsystemError(Exception):
def __str__(self): def __str__(self):
return self.text return self.text
class GnomeKeyringError(Exception):
"""
Error with Gnome Keyring
"""
def __init__(self, error):
Exception.__init__(self)
self.error = error
def __str__(self):
return str(self.error)

View File

@ -29,11 +29,12 @@ __all__ = ['get_password', 'save_password']
import warnings import warnings
from common import gajim from common import gajim
from common import kwalletbinding from common import kwalletbinding
from common.exceptions import GnomeKeyringError
USER_HAS_GNOMEKEYRING = False USER_HAS_GNOMEKEYRING = False
USER_USES_GNOMEKEYRING = False USER_USES_GNOMEKEYRING = False
USER_HAS_KWALLETCLI = False USER_HAS_KWALLETCLI = False
gnomekeyring = None GnomeKeyring = None
class PasswordStorage(object): class PasswordStorage(object):
def get_password(self, account_name): def get_password(self, account_name):
@ -61,13 +62,15 @@ class SimplePasswordStorage(PasswordStorage):
class GnomePasswordStorage(PasswordStorage): class GnomePasswordStorage(PasswordStorage):
def __init__(self): def __init__(self):
self.keyring = gnomekeyring.get_default_keyring_sync() (err, self.keyring) = GnomeKeyring.get_default_keyring_sync()
if err != GnomeKeyring.Result.OK:
raise GnomeKeyringError(err)
if self.keyring is None: if self.keyring is None:
self.keyring = 'login' self.keyring = 'login'
try: err = GnomeKeyring.create_sync(self.keyring, None)
gnomekeyring.create_sync(self.keyring, None) if err not in (GnomeKeyring.Result.OK,
except gnomekeyring.AlreadyExistsError: GnomeKeyring.Result.KEYRING_ALREADY_EXISTS):
pass raise GnomeKeyringError(err)
def get_password(self, account_name): def get_password(self, account_name):
conf = gajim.config.get_per('accounts', account_name, 'password') conf = gajim.config.get_per('accounts', account_name, 'password')
@ -78,62 +81,75 @@ class GnomePasswordStorage(PasswordStorage):
## migrate the password over to keyring ## migrate the password over to keyring
try: try:
self.save_password(account_name, password, update=False) self.save_password(account_name, password, update=False)
except gnomekeyring.NoKeyringDaemonError: except GnomeKeyringError, e:
## no keyring daemon: in the future, stop using it if e.error == GnomeKeyring.Result.NO_KEYRING_DAEMON:
set_storage(SimplePasswordStorage()) ## no keyring daemon: in the future, stop using it
set_storage(SimplePasswordStorage())
return password return password
try: server = gajim.config.get_per('accounts', account_name, 'hostname')
server = gajim.config.get_per('accounts', account_name, 'hostname') user = gajim.config.get_per('accounts', account_name, 'name')
user = gajim.config.get_per('accounts', account_name, 'name') attributes1 = GnomeKeyring.attribute_list_new()
attributes1 = dict(server=str(server), user=str(user), protocol='xmpp') GnomeKeyring.attribute_list_append_string(attributes1, 'server',
attributes2 = dict(account_name=str(account_name), gajim=1) str(server))
try: GnomeKeyring.attribute_list_append_string(attributes1, 'user',
items = gnomekeyring.find_items_sync( str(user))
gnomekeyring.ITEM_NETWORK_PASSWORD, attributes1) GnomeKeyring.attribute_list_append_string(attributes1, 'protocol',
except gnomekeyring.Error: 'xmpp')
try: attributes2 = GnomeKeyring.attribute_list_new()
items = gnomekeyring.find_items_sync( GnomeKeyring.attribute_list_append_string(attributes2, 'account_name',
gnomekeyring.ITEM_GENERIC_SECRET, attributes2) str(account_name))
if items: GnomeKeyring.attribute_list_append_string(attributes2, 'gajim',
# We found an old item, move it to new way of storing '1')
password = items[0].secret (err, items) = GnomeKeyring.find_items_sync(
self.save_password(account_name, password) GnomeKeyring.ItemType.NETWORK_PASSWORD, attributes1)
gnomekeyring.item_delete_sync(items[0].keyring, if err != GnomeKeyring.Result.OK:
int(items[0].item_id)) (err, items) = GnomeKeyring.find_items_sync(
except gnomekeyring.Error: GnomeKeyring.ItemType.GENERIC_SECRET, attributes2)
items = [] if err == GnomeKeyring.Result.OK and len(items) > 0:
if len(items) > 1: password = items[0].secret
warnings.warn("multiple gnome keyring items found for account %s;" self.save_password(account_name, password)
" trying to use the first one..." for item in items:
% account_name) GnomeKeyring.item_delete_sync(item.keyring,
if items: int(item.item_id))
return items[0].secret
else: else:
return None items = []
except gnomekeyring.DeniedError: if len(items) > 1:
warnings.warn("multiple gnome keyring items found for account %s;"
" trying to use the first one..." % account_name)
if items:
return items[0].secret
else:
return None return None
except gnomekeyring.NoKeyringDaemonError: if err == GnomeKeyring.Result.NO_KEYRING_DAEMON:
## no keyring daemon: in the future, stop using it ## no keyring daemon: in the future, stop using it
set_storage(SimplePasswordStorage()) set_storage(SimplePasswordStorage())
return None return None
def save_password(self, account_name, password, update=True): def save_password(self, account_name, password, update=True):
server = gajim.config.get_per('accounts', account_name, 'hostname') server = gajim.config.get_per('accounts', account_name, 'hostname')
user = gajim.config.get_per('accounts', account_name, 'name') user = gajim.config.get_per('accounts', account_name, 'name')
display_name = _('XMPP account %s@%s') % (user, server) display_name = _('XMPP account %s@%s') % (user, server)
attributes1 = dict(server=str(server), user=str(user), protocol='xmpp') attributes1 = GnomeKeyring.attribute_list_new()
GnomeKeyring.attribute_list_append_string(attributes1, 'server',
str(server))
GnomeKeyring.attribute_list_append_string(attributes1, 'user',
str(user))
GnomeKeyring.attribute_list_append_string(attributes1, 'protocol',
'xmpp')
if password is None: if password is None:
password = str() password = str()
try: (err, auth_token) = GnomeKeyring.item_create_sync(self.keyring,
auth_token = gnomekeyring.item_create_sync( GnomeKeyring.ItemType.NETWORK_PASSWORD, display_name, attributes1,
self.keyring, gnomekeyring.ITEM_NETWORK_PASSWORD, password, update)
display_name, attributes1, password, update) if err != GnomeKeyring.Result.OK:
except gnomekeyring.DeniedError: if err == GnomeKeyring.Result.DENIED:
set_storage(SimplePasswordStorage()) set_storage(SimplePasswordStorage())
storage.save_password(account_name, password) storage.save_password(account_name, password)
return return
else:
raise GnomeKeyringError(err)
gajim.config.set_per('accounts', account_name, 'password', gajim.config.set_per('accounts', account_name, 'password',
'gnomekeyring:') 'gnomekeyring:')
if account_name in gajim.connections: if account_name in gajim.connections:
gajim.connections[account_name].password = password gajim.connections[account_name].password = password
@ -181,24 +197,25 @@ def get_storage():
global storage global storage
if storage is None: # None is only in first time get_storage is called if storage is None: # None is only in first time get_storage is called
if gajim.config.get('use_gnomekeyring'): if gajim.config.get('use_gnomekeyring'):
global gnomekeyring global GnomeKeyring
try: try:
gnomekeyring = __import__('gnomekeyring') gir = __import__('gi.repository', globals(), locals(),
['GnomeKeyring'], -1)
GnomeKeyring = gir.GnomeKeyring
except ImportError: except ImportError:
pass pass
else: else:
global USER_HAS_GNOMEKEYRING global USER_HAS_GNOMEKEYRING
global USER_USES_GNOMEKEYRING global USER_USES_GNOMEKEYRING
USER_HAS_GNOMEKEYRING = True USER_HAS_GNOMEKEYRING = True
if gnomekeyring.is_available(): if GnomeKeyring.is_available():
USER_USES_GNOMEKEYRING = True USER_USES_GNOMEKEYRING = True
else: else:
USER_USES_GNOMEKEYRING = False USER_USES_GNOMEKEYRING = False
if USER_USES_GNOMEKEYRING: if USER_USES_GNOMEKEYRING:
try: try:
storage = GnomePasswordStorage() storage = GnomePasswordStorage()
except (gnomekeyring.NoKeyringDaemonError, gnomekeyring.DeniedError, except GnomeKeyringError:
gnomekeyring.CancelledError):
storage = None storage = None
if storage is None: if storage is None:
if gajim.config.get('use_kwalletcli'): if gajim.config.get('use_kwalletcli'):