Add KWallet support. By @samuel-w (#540)

This commit is contained in:
Samuel 2020-12-03 02:26:09 -06:00 committed by GitHub
parent 529b1da5b1
commit 5c1306eeb7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 66 additions and 6 deletions

View File

@ -16,6 +16,7 @@
"--talk-name=org.freedesktop.DBus.*",
"--talk-name=org.freedesktop.Flatpak.*",
"--talk-name=org.freedesktop.secrets",
"--talk-name=org.kde.kwalletd5",
"--socket=ssh-auth",
"--talk-name=org.freedesktop.Notifications",
"--system-talk-name=org.freedesktop.NetworkManager"
@ -57,4 +58,4 @@
]
}
]
}
}

View File

@ -36,14 +36,17 @@ def get_keyring():
if _keyring is None or not _keyring.is_primary:
if sys.platform == 'darwin': # Use Keychain on macOS
from .darwin import VortaDarwinKeyring
return VortaDarwinKeyring()
_keyring = VortaDarwinKeyring()
else: # Try to use DBus and Gnome-Keyring (available on Linux and *BSD)
import secretstorage
from .secretstorage import VortaSecretStorageKeyring
try:
_keyring = VortaSecretStorageKeyring()
# Save passwords in DB, if all else fails.
except secretstorage.SecretServiceNotAvailableException:
from .db import VortaDBKeyring
_keyring = VortaDBKeyring()
except secretstorage.SecretServiceNotAvailableException: # Try to use KWallet
from .kwallet import VortaKWallet5Keyring, KWalletNotAvailableException
try:
_keyring = VortaKWallet5Keyring()
except KWalletNotAvailableException: # Save passwords in DB, if all else fails.
from .db import VortaDBKeyring
_keyring = VortaDBKeyring()
return _keyring

View File

@ -0,0 +1,56 @@
from PyQt5 import QtDBus
from PyQt5.QtCore import QVariant
from vorta.keyring.abc import VortaKeyring
class VortaKWallet5Keyring(VortaKeyring):
"""A wrapper for the qtdbus package to support the custom keyring backend"""
folder_name = 'Vorta'
service_name = "org.kde.kwalletd5"
object_path = "/modules/kwalletd5"
interface_name = 'org.kde.KWallet'
def __init__(self):
"""
Test whether DBus and KDEWallet are available.
"""
self.iface = QtDBus.QDBusInterface(
self.service_name,
self.object_path,
self.interface_name,
QtDBus.QDBusConnection.sessionBus())
if not (self.iface.isValid() and self.get_result("isEnabled")):
raise KWalletNotAvailableException
def set_password(self, service, repo_url, password):
self.get_result("writePassword", args=[self.handle, self.folder_name, repo_url, password, service])
def get_password(self, service, repo_url):
if not (self.is_unlocked and self.get_result("hasEntry",
args=[self.handle, self.folder_name, repo_url, service])):
return None
return self.get_result("readPassword", args=[self.handle, self.folder_name, repo_url, service])
def get_result(self, method, args=[]):
if args:
result = self.iface.callWithArgumentList(QtDBus.QDBus.AutoDetect, method, args)
else:
result = self.iface.call(QtDBus.QDBus.AutoDetect, method)
return result.arguments()[0]
@property
def is_unlocked(self):
self.get_handle()
return self.handle > 0
def get_handle(self):
wallet_name = self.get_result("networkWallet")
wId = QVariant(0)
wId.convert(4)
output = self.get_result("open", args=[wallet_name, wId, 'vorta-repo'])
self.handle = int(output)
class KWalletNotAvailableException(Exception):
pass