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,41 +81,46 @@ 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:
if e.error == 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 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 = dict(server=str(server), user=str(user), protocol='xmpp') attributes1 = GnomeKeyring.attribute_list_new()
attributes2 = dict(account_name=str(account_name), gajim=1) GnomeKeyring.attribute_list_append_string(attributes1, 'server',
try: str(server))
items = gnomekeyring.find_items_sync( GnomeKeyring.attribute_list_append_string(attributes1, 'user',
gnomekeyring.ITEM_NETWORK_PASSWORD, attributes1) str(user))
except gnomekeyring.Error: GnomeKeyring.attribute_list_append_string(attributes1, 'protocol',
try: 'xmpp')
items = gnomekeyring.find_items_sync( attributes2 = GnomeKeyring.attribute_list_new()
gnomekeyring.ITEM_GENERIC_SECRET, attributes2) GnomeKeyring.attribute_list_append_string(attributes2, 'account_name',
if items: str(account_name))
# We found an old item, move it to new way of storing GnomeKeyring.attribute_list_append_string(attributes2, 'gajim',
'1')
(err, items) = GnomeKeyring.find_items_sync(
GnomeKeyring.ItemType.NETWORK_PASSWORD, attributes1)
if err != GnomeKeyring.Result.OK:
(err, items) = GnomeKeyring.find_items_sync(
GnomeKeyring.ItemType.GENERIC_SECRET, attributes2)
if err == GnomeKeyring.Result.OK and len(items) > 0:
password = items[0].secret password = items[0].secret
self.save_password(account_name, password) self.save_password(account_name, password)
gnomekeyring.item_delete_sync(items[0].keyring, for item in items:
int(items[0].item_id)) GnomeKeyring.item_delete_sync(item.keyring,
except gnomekeyring.Error: int(item.item_id))
else:
items = [] items = []
if len(items) > 1: if len(items) > 1:
warnings.warn("multiple gnome keyring items found for account %s;" warnings.warn("multiple gnome keyring items found for account %s;"
" trying to use the first one..." " trying to use the first one..." % account_name)
% account_name)
if items: if items:
return items[0].secret return items[0].secret
else: else:
return None return None
except gnomekeyring.DeniedError: if err == GnomeKeyring.Result.NO_KEYRING_DAEMON:
return None
except gnomekeyring.NoKeyringDaemonError:
## 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
@ -121,17 +129,25 @@ class GnomePasswordStorage(PasswordStorage):
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:
@ -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'):