2021-03-01 07:25:31 +00:00
|
|
|
import importlib
|
2021-03-03 13:50:14 +00:00
|
|
|
import logging
|
2021-03-01 07:25:31 +00:00
|
|
|
from vorta.i18n import trans_late
|
2019-03-06 01:37:12 +00:00
|
|
|
|
2021-03-03 13:50:14 +00:00
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
2019-03-06 01:37:12 +00:00
|
|
|
|
2020-09-27 07:19:39 +00:00
|
|
|
class VortaKeyring:
|
2021-03-01 07:25:31 +00:00
|
|
|
all_keyrings = [
|
|
|
|
('.db', 'VortaDBKeyring'),
|
|
|
|
('.darwin', 'VortaDarwinKeyring'),
|
|
|
|
('.kwallet', 'VortaKWallet5Keyring'),
|
|
|
|
('.secretstorage', 'VortaSecretStorageKeyring')
|
|
|
|
]
|
2021-01-18 07:52:07 +00:00
|
|
|
|
|
|
|
@classmethod
|
|
|
|
def get_keyring(cls):
|
|
|
|
"""
|
2021-03-01 07:25:31 +00:00
|
|
|
Choose available Keyring. First assign a score and then try to initialize it.
|
2021-01-18 07:52:07 +00:00
|
|
|
"""
|
2021-03-01 07:25:31 +00:00
|
|
|
available_keyrings = []
|
|
|
|
for _module, _class in cls.all_keyrings:
|
|
|
|
try:
|
|
|
|
keyring = getattr(importlib.import_module(_module, package='vorta.keyring'), _class)
|
|
|
|
available_keyrings.append((keyring, keyring.get_priority()))
|
2021-03-03 13:50:14 +00:00
|
|
|
except Exception as e:
|
|
|
|
logger.debug(e)
|
2021-03-01 07:25:31 +00:00
|
|
|
continue
|
2021-01-18 07:52:07 +00:00
|
|
|
|
2021-03-01 07:25:31 +00:00
|
|
|
for keyring, _ in sorted(available_keyrings, key=lambda k: k[1], reverse=True):
|
|
|
|
try:
|
|
|
|
return keyring()
|
2021-03-03 13:50:14 +00:00
|
|
|
except Exception as e:
|
|
|
|
logger.debug(e)
|
2021-03-01 07:25:31 +00:00
|
|
|
continue
|
2021-01-18 07:52:07 +00:00
|
|
|
|
2021-03-01 07:25:31 +00:00
|
|
|
def get_backend_warning(self):
|
|
|
|
if self.is_system:
|
|
|
|
return trans_late('utils', 'Storing password in your password manager.')
|
|
|
|
else:
|
|
|
|
return trans_late('utils', 'Saving password with Vorta settings.')
|
2021-01-18 07:52:07 +00:00
|
|
|
|
2019-03-06 01:37:12 +00:00
|
|
|
def set_password(self, service, repo_url, password):
|
2020-12-16 02:56:42 +00:00
|
|
|
"""
|
|
|
|
Writes a password to the underlying store.
|
|
|
|
"""
|
2019-03-06 01:37:12 +00:00
|
|
|
raise NotImplementedError
|
|
|
|
|
|
|
|
def get_password(self, service, repo_url):
|
|
|
|
"""
|
|
|
|
Retrieve a password from the underlying store. Return None if not found.
|
|
|
|
"""
|
|
|
|
raise NotImplementedError
|
|
|
|
|
|
|
|
@property
|
2021-03-01 07:25:31 +00:00
|
|
|
def is_system(self):
|
2019-03-06 01:37:12 +00:00
|
|
|
"""
|
|
|
|
Return True if the current subclass is the system's primary keychain mechanism,
|
|
|
|
rather than a fallback (like our own VortaDBKeyring).
|
|
|
|
"""
|
2021-03-01 07:25:31 +00:00
|
|
|
raise NotImplementedError
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
def get_priority(cls):
|
|
|
|
"""
|
|
|
|
Return priority of this keyring on current system. Higher is more important.
|
|
|
|
|
|
|
|
Shout-out to https://github.com/jaraco/keyring for this idea.
|
|
|
|
"""
|
|
|
|
raise NotImplementedError
|
2020-09-27 07:19:39 +00:00
|
|
|
|
2020-12-16 02:56:42 +00:00
|
|
|
@property
|
|
|
|
def is_unlocked(self):
|
|
|
|
"""
|
2021-02-15 01:11:11 +00:00
|
|
|
Try to unlock the keyring.
|
2020-12-16 02:56:42 +00:00
|
|
|
Returns True if the keyring is open. Return False if it is closed or locked
|
|
|
|
"""
|
|
|
|
raise NotImplementedError
|