use libsecret instead of libgnomekeyring when available
This commit is contained in:
		
							parent
							
								
									d8fe6cdea4
								
							
						
					
					
						commit
						23474c2b2f
					
				
					 1 changed files with 91 additions and 11 deletions
				
			
		| 
						 | 
					@ -31,10 +31,12 @@ from common import gajim
 | 
				
			||||||
from common import kwalletbinding
 | 
					from common import kwalletbinding
 | 
				
			||||||
from common.exceptions import GnomeKeyringError
 | 
					from common.exceptions import GnomeKeyringError
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					USER_HAS_LIBSECRET = False
 | 
				
			||||||
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
 | 
				
			||||||
 | 
					Secret = None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class PasswordStorage(object):
 | 
					class PasswordStorage(object):
 | 
				
			||||||
    def get_password(self, account_name):
 | 
					    def get_password(self, account_name):
 | 
				
			||||||
| 
						 | 
					@ -154,6 +156,69 @@ class GnomePasswordStorage(PasswordStorage):
 | 
				
			||||||
        if account_name in gajim.connections:
 | 
					        if account_name in gajim.connections:
 | 
				
			||||||
            gajim.connections[account_name].password = password
 | 
					            gajim.connections[account_name].password = password
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class SecretPasswordStorage(PasswordStorage):
 | 
				
			||||||
 | 
					    def __init__(self):
 | 
				
			||||||
 | 
					        self.GAJIM_SCHEMA = Secret.Schema.new("Gajim",
 | 
				
			||||||
 | 
					            Secret.SchemaFlags.NONE,
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                'user': Secret.SchemaAttributeType.STRING,
 | 
				
			||||||
 | 
					                'server':  Secret.SchemaAttributeType.STRING,
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def get_password(self, account_name):
 | 
				
			||||||
 | 
					        conf = gajim.config.get_per('accounts', account_name, 'password')
 | 
				
			||||||
 | 
					        if conf is None or conf == '<kwallet>':
 | 
				
			||||||
 | 
					            return None
 | 
				
			||||||
 | 
					        if conf.startswith('gnomekeyring:'):
 | 
				
			||||||
 | 
					            # migrate from libgnomekeyring
 | 
				
			||||||
 | 
					            GnomePasswordStorage
 | 
				
			||||||
 | 
					            global GnomeKeyring
 | 
				
			||||||
 | 
					            global USER_HAS_GNOMEKEYRING
 | 
				
			||||||
 | 
					            if not USER_HAS_GNOMEKEYRING:
 | 
				
			||||||
 | 
					                try:
 | 
				
			||||||
 | 
					                    gir = __import__('gi.repository', globals(), locals(),
 | 
				
			||||||
 | 
					                        ['GnomeKeyring'], 0)
 | 
				
			||||||
 | 
					                    GnomeKeyring = gir.GnomeKeyring
 | 
				
			||||||
 | 
					                except (ImportError, AttributeError):
 | 
				
			||||||
 | 
					                    return False
 | 
				
			||||||
 | 
					                USER_HAS_GNOMEKEYRING = True
 | 
				
			||||||
 | 
					            try:
 | 
				
			||||||
 | 
					                gk_storage = GnomePasswordStorage()
 | 
				
			||||||
 | 
					            except GnomeKeyringError:
 | 
				
			||||||
 | 
					                return None
 | 
				
			||||||
 | 
					            password = gk_storage.get_password(account_name)
 | 
				
			||||||
 | 
					            save_password(account_name, password)
 | 
				
			||||||
 | 
					            return password
 | 
				
			||||||
 | 
					        if not conf.startswith('libsecret:'):
 | 
				
			||||||
 | 
					            password = conf
 | 
				
			||||||
 | 
					            ## migrate the password over to keyring
 | 
				
			||||||
 | 
					            try:
 | 
				
			||||||
 | 
					                self.save_password(account_name, password, update=False)
 | 
				
			||||||
 | 
					            except Exception:
 | 
				
			||||||
 | 
					                ## no keyring daemon: in the future, stop using it
 | 
				
			||||||
 | 
					                set_storage(SimplePasswordStorage())
 | 
				
			||||||
 | 
					            return password
 | 
				
			||||||
 | 
					        server = gajim.config.get_per('accounts', account_name, 'hostname')
 | 
				
			||||||
 | 
					        user = gajim.config.get_per('accounts', account_name, 'name')
 | 
				
			||||||
 | 
					        password = Secret.password_lookup_sync(self.GAJIM_SCHEMA, {'user': user,
 | 
				
			||||||
 | 
					            'server': server}, None)
 | 
				
			||||||
 | 
					        return password
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def save_password(self, account_name, password, update=True):
 | 
				
			||||||
 | 
					        server = gajim.config.get_per('accounts', account_name, 'hostname')
 | 
				
			||||||
 | 
					        user = gajim.config.get_per('accounts', account_name, 'name')
 | 
				
			||||||
 | 
					        display_name = _('XMPP account %s@%s') % (user, server)
 | 
				
			||||||
 | 
					        if password is None:
 | 
				
			||||||
 | 
					            password = str()
 | 
				
			||||||
 | 
					        attributes = {'user': user, 'server': server}
 | 
				
			||||||
 | 
					        Secret.password_store_sync(self.GAJIM_SCHEMA, attributes,
 | 
				
			||||||
 | 
					            Secret.COLLECTION_DEFAULT, display_name, password, None)
 | 
				
			||||||
 | 
					        gajim.config.set_per('accounts', account_name, 'password',
 | 
				
			||||||
 | 
					            'libsecret:')
 | 
				
			||||||
 | 
					        if account_name in gajim.connections:
 | 
				
			||||||
 | 
					            gajim.connections[account_name].password = password
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class KWalletPasswordStorage(PasswordStorage):
 | 
					class KWalletPasswordStorage(PasswordStorage):
 | 
				
			||||||
    def get_password(self, account_name):
 | 
					    def get_password(self, account_name):
 | 
				
			||||||
        pw = gajim.config.get_per('accounts', account_name, 'password')
 | 
					        pw = gajim.config.get_per('accounts', account_name, 'password')
 | 
				
			||||||
| 
						 | 
					@ -198,21 +263,36 @@ 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 Secret
 | 
				
			||||||
            try:
 | 
					            try:
 | 
				
			||||||
                gir = __import__('gi.repository', globals(), locals(),
 | 
					                gir = __import__('gi.repository', globals(), locals(),
 | 
				
			||||||
                    ['GnomeKeyring'], 0)
 | 
					                    ['Secret'], 0)
 | 
				
			||||||
                GnomeKeyring = gir.GnomeKeyring
 | 
					                Secret = gir.Secret
 | 
				
			||||||
            except (ImportError, AttributeError):
 | 
					            except (ImportError, AttributeError):
 | 
				
			||||||
                pass
 | 
					                global GnomeKeyring
 | 
				
			||||||
            else:
 | 
					                try:
 | 
				
			||||||
                global USER_HAS_GNOMEKEYRING
 | 
					                    gir = __import__('gi.repository', globals(), locals(),
 | 
				
			||||||
                global USER_USES_GNOMEKEYRING
 | 
					                        ['GnomeKeyring'], 0)
 | 
				
			||||||
                USER_HAS_GNOMEKEYRING = True
 | 
					                    GnomeKeyring = gir.GnomeKeyring
 | 
				
			||||||
                if GnomeKeyring.is_available():
 | 
					                except (ImportError, AttributeError):
 | 
				
			||||||
                    USER_USES_GNOMEKEYRING = True
 | 
					                    pass
 | 
				
			||||||
                else:
 | 
					                else:
 | 
				
			||||||
                    USER_USES_GNOMEKEYRING = False
 | 
					                    global USER_HAS_GNOMEKEYRING
 | 
				
			||||||
 | 
					                    global USER_USES_GNOMEKEYRING
 | 
				
			||||||
 | 
					                    USER_HAS_GNOMEKEYRING = True
 | 
				
			||||||
 | 
					                    if GnomeKeyring.is_available():
 | 
				
			||||||
 | 
					                        USER_USES_GNOMEKEYRING = True
 | 
				
			||||||
 | 
					                    else:
 | 
				
			||||||
 | 
					                        USER_USES_GNOMEKEYRING = False
 | 
				
			||||||
 | 
					            else:
 | 
				
			||||||
 | 
					                global USER_HAS_LIBSECRET
 | 
				
			||||||
 | 
					                USER_HAS_LIBSECRET = True
 | 
				
			||||||
 | 
					        if USER_HAS_LIBSECRET:
 | 
				
			||||||
 | 
					            try:
 | 
				
			||||||
 | 
					                storage = SecretPasswordStorage()
 | 
				
			||||||
 | 
					                return storage
 | 
				
			||||||
 | 
					            except Exception:
 | 
				
			||||||
 | 
					                storage = None
 | 
				
			||||||
        if USER_USES_GNOMEKEYRING:
 | 
					        if USER_USES_GNOMEKEYRING:
 | 
				
			||||||
            try:
 | 
					            try:
 | 
				
			||||||
                storage = GnomePasswordStorage()
 | 
					                storage = GnomePasswordStorage()
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		
		Reference in a new issue