Make passwords module more resilient
- Catch more exceptions - Add more log output
This commit is contained in:
parent
1f479e5ba4
commit
c58c7cc4a0
|
@ -35,7 +35,7 @@ try:
|
||||||
KEYRING_AVAILABLE = True
|
KEYRING_AVAILABLE = True
|
||||||
except ImportError:
|
except ImportError:
|
||||||
KEYRING_AVAILABLE = False
|
KEYRING_AVAILABLE = False
|
||||||
log.debug('python-keyring missing, falling back to plaintext storage')
|
log.warning('python-keyring missing, falling back to plaintext storage')
|
||||||
|
|
||||||
|
|
||||||
class PasswordStorage:
|
class PasswordStorage:
|
||||||
|
@ -58,24 +58,32 @@ class SecretPasswordStorage(PasswordStorage):
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.keyring = keyring.get_keyring()
|
self.keyring = keyring.get_keyring()
|
||||||
log.info('Chose %s backend', self.keyring)
|
log.info('Select %s backend', self.keyring)
|
||||||
|
|
||||||
def save_password(self, account_name, password):
|
def save_password(self, account_name, password):
|
||||||
try:
|
try:
|
||||||
|
log.info('Save password to keyring')
|
||||||
self.keyring.set_password('gajim', account_name, password)
|
self.keyring.set_password('gajim', account_name, password)
|
||||||
return True
|
return True
|
||||||
except Exception as error:
|
except Exception:
|
||||||
log.warning('Save password failed')
|
log.exception('Save password failed')
|
||||||
log.debug(error)
|
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def get_password(self, account_name):
|
def get_password(self, account_name):
|
||||||
log.debug('getting password')
|
log.info('Request password from keyring')
|
||||||
|
try:
|
||||||
return self.keyring.get_password('gajim', account_name)
|
return self.keyring.get_password('gajim', account_name)
|
||||||
|
except Exception:
|
||||||
|
log.exception('Request password failed')
|
||||||
|
return
|
||||||
|
|
||||||
def delete_password(self, account_name):
|
def delete_password(self, account_name):
|
||||||
|
log.info('Remove password from keyring')
|
||||||
|
try:
|
||||||
return self.keyring.delete_password('gajim', account_name)
|
return self.keyring.delete_password('gajim', account_name)
|
||||||
|
except Exception:
|
||||||
|
log.exception('Remove password failed')
|
||||||
|
return
|
||||||
|
|
||||||
class PasswordStorageManager(PasswordStorage):
|
class PasswordStorageManager(PasswordStorage):
|
||||||
"""Access all the implemented password storage backends, knowing which ones
|
"""Access all the implemented password storage backends, knowing which ones
|
||||||
|
@ -119,15 +127,16 @@ class PasswordStorageManager(PasswordStorage):
|
||||||
|
|
||||||
if backend:
|
if backend:
|
||||||
pw = backend.get_password(account_name)
|
pw = backend.get_password(account_name)
|
||||||
|
|
||||||
if backend != self.preferred_backend:
|
if backend != self.preferred_backend:
|
||||||
# migrate password to preferred_backend
|
# migrate password to preferred_backend
|
||||||
self.save_password(account_name, pw)
|
self.save_password(account_name, pw)
|
||||||
# TODO: remove from old backend
|
|
||||||
return pw
|
return pw
|
||||||
|
|
||||||
def save_password(self, account_name, password):
|
def save_password(self, account_name, password):
|
||||||
if account_name in app.connections:
|
if account_name in app.connections:
|
||||||
app.connections[account_name].password = password
|
app.connections[account_name].password = password
|
||||||
|
|
||||||
if not app.config.get_per('accounts', account_name, 'savepass'):
|
if not app.config.get_per('accounts', account_name, 'savepass'):
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
@ -143,9 +152,8 @@ class PasswordStorageManager(PasswordStorage):
|
||||||
if account_name in app.connections:
|
if account_name in app.connections:
|
||||||
app.connections[account_name].password = None
|
app.connections[account_name].password = None
|
||||||
|
|
||||||
if not self.preferred_backend:
|
if self.preferred_backend is not None:
|
||||||
self.preferred_backend.delete_password(account_name)
|
self.preferred_backend.delete_password(account_name)
|
||||||
else:
|
|
||||||
app.config.set_per('accounts', account_name, 'password', None)
|
app.config.set_per('accounts', account_name, 'password', None)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
|
@ -31,6 +31,7 @@ from gi.repository import Gtk
|
||||||
from gi.repository import GObject
|
from gi.repository import GObject
|
||||||
|
|
||||||
from gajim.common import app
|
from gajim.common import app
|
||||||
|
from gajim.common import passwords
|
||||||
from gajim.common.i18n import _
|
from gajim.common.i18n import _
|
||||||
|
|
||||||
from gajim import dialogs
|
from gajim import dialogs
|
||||||
|
@ -213,6 +214,7 @@ class RemoveAccountWindow:
|
||||||
app.interface.roster.setup_and_draw_roster()
|
app.interface.roster.setup_and_draw_roster()
|
||||||
app.app.remove_account_actions(self.account)
|
app.app.remove_account_actions(self.account)
|
||||||
gui_menu_builder.build_accounts_menu()
|
gui_menu_builder.build_accounts_menu()
|
||||||
|
passwords.delete_password(self.account)
|
||||||
|
|
||||||
window = app.get_app_window('AccountsWindow')
|
window = app.get_app_window('AccountsWindow')
|
||||||
if window is not None:
|
if window is not None:
|
||||||
|
|
Loading…
Reference in New Issue