From abb3ec82ee1de301355965e4d46e21c4e69064d2 Mon Sep 17 00:00:00 2001 From: ganeshrevadi Date: Thu, 9 Mar 2023 21:37:49 +0530 Subject: [PATCH 01/34] Adding remove password --- src/vorta/keyring/abc.py | 6 ++++++ src/vorta/keyring/secretstorage.py | 18 ++++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/src/vorta/keyring/abc.py b/src/vorta/keyring/abc.py index fc35f9c6d..1ad85158c 100644 --- a/src/vorta/keyring/abc.py +++ b/src/vorta/keyring/abc.py @@ -54,6 +54,12 @@ def get_password(self, service, repo_url): """ raise NotImplementedError + def remove_password(self, service, repo_url): + """ + Removes a password form the underlying store. + """ + raise NotImplementedError + @property def is_system(self): """ diff --git a/src/vorta/keyring/secretstorage.py b/src/vorta/keyring/secretstorage.py index 02c1c3198..194d05dab 100644 --- a/src/vorta/keyring/secretstorage.py +++ b/src/vorta/keyring/secretstorage.py @@ -65,6 +65,24 @@ def get_password(self, service, repo_url): return item.get_secret().decode("utf-8") return None + def remove_password(self, service, repo_url): + """ + Remove a password from the underlying store. + """ + if self.is_unlocked: + asyncio.set_event_loop(asyncio.new_event_loop()) + attributes = { + 'application': 'Vorta', + 'service': service, + 'repo_url': repo_url, + } + items = list(self.collection.search_items(attributes)) + logger.debug('Found %i passwords matching repo URL.', len(items)) + for item in items: + self.collection.delete_item(item) + logger.debug(f"Removed password for repo {repo_url}") + return None + @property def is_unlocked(self): # unlock() will return True if the unlock prompt is dismissed From 527797c157fa56d87915820da5163e77d3f68a96 Mon Sep 17 00:00:00 2001 From: ganeshrevadi Date: Fri, 10 Mar 2023 23:29:43 +0530 Subject: [PATCH 02/34] remove pass method --- src/vorta/keyring/secretstorage.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/vorta/keyring/secretstorage.py b/src/vorta/keyring/secretstorage.py index 194d05dab..86880f093 100644 --- a/src/vorta/keyring/secretstorage.py +++ b/src/vorta/keyring/secretstorage.py @@ -79,7 +79,9 @@ def remove_password(self, service, repo_url): items = list(self.collection.search_items(attributes)) logger.debug('Found %i passwords matching repo URL.', len(items)) for item in items: - self.collection.delete_item(item) + if item.is_locked() and item.unlock(): + return None + self.collection.delete(item) logger.debug(f"Removed password for repo {repo_url}") return None From 6afdbbccb2a5c59b70bf9cbb9cfe241394fdf708 Mon Sep 17 00:00:00 2001 From: ganeshrevadi Date: Sat, 11 Mar 2023 14:24:19 +0530 Subject: [PATCH 03/34] Kwallet --- src/vorta/keyring/kwallet.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/vorta/keyring/kwallet.py b/src/vorta/keyring/kwallet.py index 32402160a..2146cc678 100644 --- a/src/vorta/keyring/kwallet.py +++ b/src/vorta/keyring/kwallet.py @@ -45,6 +45,11 @@ def get_password(self, service, repo_url): logger.debug(f"Retrieved password for repo {repo_url}") return password + def remove_password(self, service, repo_url): + if self.is_unlocked and self.get_result("hasEntry", args=[self.handle, self.folder_name, repo_url, service]): + self.get_result("removeEntry", args=[self.handle, self.folder_name, repo_url, service]) + logger.debug(f"Removed password for repo {repo_url}") + def get_result(self, method, args=[]): if args: result = self.iface.callWithArgumentList(QtDBus.QDBus.AutoDetect, method, args) From cfd0ebf249825fcd54ff120ee13a627248ed29b6 Mon Sep 17 00:00:00 2001 From: ganeshrevadi Date: Sun, 12 Mar 2023 21:19:48 +0530 Subject: [PATCH 04/34] Implement remove password for kwallet --- src/vorta/keyring/kwallet.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/vorta/keyring/kwallet.py b/src/vorta/keyring/kwallet.py index 2146cc678..f677fdb3d 100644 --- a/src/vorta/keyring/kwallet.py +++ b/src/vorta/keyring/kwallet.py @@ -46,8 +46,9 @@ def get_password(self, service, repo_url): return password def remove_password(self, service, repo_url): - if self.is_unlocked and self.get_result("hasEntry", args=[self.handle, self.folder_name, repo_url, service]): - self.get_result("removeEntry", args=[self.handle, self.folder_name, repo_url, service]) + entry = [self.handle, self.folder_name, repo_url, service] + if self.is_unlocked and self.get_result("hasEntry", args=entry): + self.get_result("removeEntry", args=entry) logger.debug(f"Removed password for repo {repo_url}") def get_result(self, method, args=[]): From 31f1048801bab7305daeb8771468b42d6631da05 Mon Sep 17 00:00:00 2001 From: Manu Date: Sun, 12 Mar 2023 19:24:17 +0000 Subject: [PATCH 05/34] Implement remove_password() for darwin --- src/vorta/keyring/darwin.py | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/src/vorta/keyring/darwin.py b/src/vorta/keyring/darwin.py index d0f52a3cb..d598d9030 100644 --- a/src/vorta/keyring/darwin.py +++ b/src/vorta/keyring/darwin.py @@ -15,7 +15,11 @@ class VortaDarwinKeyring(VortaKeyring): - """Homemade macOS Keychain Service""" + """ + Homemade macOS Keychain Service + + TODO: Could use the newer API, as done here: https://github.com/jaraco/keyring/pull/522/files + """ login_keychain = None @@ -42,6 +46,7 @@ def _set_keychain(self): b'i@I*I*o^Io^^{OpaquePassBuff}o^^{OpaqueSecKeychainItemRef}', ), ('SecKeychainGetStatus', b'i^{OpaqueSecKeychainRef=}o^I'), + ('SecKeychainItemDelete', b'i^{OpaqueSecKeychainItemRef=}o^I'), ] objc.loadBundleFunctions(Security, globals(), S_functions) @@ -97,6 +102,25 @@ def get_password(self, service, repo_url): logger.debug(f"Retrieved password for repo {repo_url}") return password + def remove_password(self, service, repo_url): + if not self.login_keychain: + self._set_keychain() + + (result, password_length, password_buffer, keychain_item,) = SecKeychainFindGenericPassword( + self.login_keychain, + len(service), + service.encode(), + len(repo_url), + repo_url.encode(), + None, + None, + None, + ) + password = None + if (result == 0) and (password_length != 0): + logger.debug(f"Found password for repo {repo_url}") + SecKeychainItemDelete(keychain_item, None) + @property def is_unlocked(self): kSecUnlockStateStatus = 1 From 3d276001e478a0850905d058239a13e3c88d5f81 Mon Sep 17 00:00:00 2001 From: ganeshrevadi Date: Mon, 13 Mar 2023 19:15:30 +0530 Subject: [PATCH 06/34] Remove password for db --- src/vorta/keyring/db.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/vorta/keyring/db.py b/src/vorta/keyring/db.py index 706c0d913..f4779c949 100644 --- a/src/vorta/keyring/db.py +++ b/src/vorta/keyring/db.py @@ -33,6 +33,16 @@ def get_password(self, service, repo_url): except peewee.DoesNotExist: return None + def remove_password(self, service, repo_url): + from vorta.store.models import RepoPassword + + try: + keyring_entry = RepoPassword.get(url=repo_url) + keyring_entry.delete_instance() + logger.debug(f"Removed password for repo {repo_url}") + except peewee.DoesNotExist: + pass + @property def is_system(self): return False From 923b41050fba6575acc0499e2d401f8a0e7b5939 Mon Sep 17 00:00:00 2001 From: ganeshrevadi Date: Wed, 15 Mar 2023 22:12:46 +0530 Subject: [PATCH 07/34] Remove password for db --- src/vorta/keyring/db.py | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/vorta/keyring/db.py b/src/vorta/keyring/db.py index f4779c949..079a75602 100644 --- a/src/vorta/keyring/db.py +++ b/src/vorta/keyring/db.py @@ -1,6 +1,6 @@ import logging import peewee -from vorta.store.models import SettingsModel +from vorta.store.models import RepoPassword, SettingsModel from .abc import VortaKeyring logger = logging.getLogger(__name__) @@ -14,16 +14,13 @@ class VortaDBKeyring(VortaKeyring): """ def set_password(self, service, repo_url, password): - from vorta.store.models import RepoPassword keyring_entry, created = RepoPassword.get_or_create(url=repo_url, defaults={'password': password}) keyring_entry.password = password keyring_entry.save() - logger.debug(f"Saved password for repo {repo_url}") def get_password(self, service, repo_url): - from vorta.store.models import RepoPassword try: keyring_entry = RepoPassword.get(url=repo_url) @@ -34,7 +31,6 @@ def get_password(self, service, repo_url): return None def remove_password(self, service, repo_url): - from vorta.store.models import RepoPassword try: keyring_entry = RepoPassword.get(url=repo_url) From afb8b0987073388ce3d60f6470d5290d01cc447c Mon Sep 17 00:00:00 2001 From: ganeshrevadi Date: Fri, 17 Mar 2023 22:36:52 +0530 Subject: [PATCH 08/34] remove password saved in test_utils --- src/vorta/keyring/db.py | 2 +- src/vorta/keyring/secretstorage.py | 5 ++--- tests/test_utils.py | 2 ++ 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/vorta/keyring/db.py b/src/vorta/keyring/db.py index 079a75602..e525df80d 100644 --- a/src/vorta/keyring/db.py +++ b/src/vorta/keyring/db.py @@ -37,7 +37,7 @@ def remove_password(self, service, repo_url): keyring_entry.delete_instance() logger.debug(f"Removed password for repo {repo_url}") except peewee.DoesNotExist: - pass + logger.debug(f"Password wasn't found for repo {repo_url}") @property def is_system(self): diff --git a/src/vorta/keyring/secretstorage.py b/src/vorta/keyring/secretstorage.py index 86880f093..607c97110 100644 --- a/src/vorta/keyring/secretstorage.py +++ b/src/vorta/keyring/secretstorage.py @@ -80,10 +80,9 @@ def remove_password(self, service, repo_url): logger.debug('Found %i passwords matching repo URL.', len(items)) for item in items: if item.is_locked() and item.unlock(): - return None - self.collection.delete(item) + continue + self.collection.item.delete() logger.debug(f"Removed password for repo {repo_url}") - return None @property def is_unlocked(self): diff --git a/tests/test_utils.py b/tests/test_utils.py index 07585e3f9..d67ea6cb0 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -10,6 +10,8 @@ def test_keyring(): keyring = VortaKeyring.get_keyring() keyring.set_password('vorta-repo', REPO, UNICODE_PW) assert keyring.get_password("vorta-repo", REPO) == UNICODE_PW + keyring.remove_password('vorta-repo', REPO) + assert keyring.remove_password("vorta-repo", REPO) is None def test_best_size_unit_precision0(): From f8ba8b73f2b96f2e24981d79a6a19fe08bae487b Mon Sep 17 00:00:00 2001 From: ganeshrevadi Date: Thu, 23 Mar 2023 21:35:32 +0530 Subject: [PATCH 09/34] remove password from keyring --- tests/test_repo.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tests/test_repo.py b/tests/test_repo.py index 5807c8cda..2e58ad3f9 100644 --- a/tests/test_repo.py +++ b/tests/test_repo.py @@ -76,6 +76,9 @@ def test_password_autofill(qapp, qtbot): qtbot.keyClicks(add_repo_window.repoURL, test_repo_url) assert add_repo_window.passwordLineEdit.text() == password + # remove the password from keyring + keyring.remove_password('vorta-repo', test_repo_url) + assert add_repo_window.passwordLineEdit.text() is None def test_repo_add_success(qapp, qtbot, mocker, borg_json_output): @@ -103,6 +106,11 @@ def test_repo_add_success(qapp, qtbot, mocker, borg_json_output): keyring = VortaKeyring.get_keyring() assert keyring.get_password("vorta-repo", RepoModel.get(id=2).url) == LONG_PASSWORD assert main.repoTab.repoSelector.currentText() == test_repo_url + # remove password form keyring + keyring.remove_password() + assert add_repo_window.passwordLineEdit.text() == '' + assert add_repo_window.confirmLineEdit.text() == '' + assert keyring.get_password("vorta-repo", RepoModel.get(id=2).url) is None def test_ssh_dialog(qapp, qtbot, tmpdir): From da20aac85b3c5be336c61b347435a2c2900ea2c0 Mon Sep 17 00:00:00 2001 From: ganeshrevadi Date: Thu, 23 Mar 2023 21:42:36 +0530 Subject: [PATCH 10/34] remove_password --- tests/test_repo.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_repo.py b/tests/test_repo.py index 2e58ad3f9..410baae13 100644 --- a/tests/test_repo.py +++ b/tests/test_repo.py @@ -107,7 +107,7 @@ def test_repo_add_success(qapp, qtbot, mocker, borg_json_output): assert keyring.get_password("vorta-repo", RepoModel.get(id=2).url) == LONG_PASSWORD assert main.repoTab.repoSelector.currentText() == test_repo_url # remove password form keyring - keyring.remove_password() + keyring.remove_password('vorta-repo', test_repo_url) assert add_repo_window.passwordLineEdit.text() == '' assert add_repo_window.confirmLineEdit.text() == '' assert keyring.get_password("vorta-repo", RepoModel.get(id=2).url) is None From a5767fa07a3b7cad82d6265f18d32e5dd1a7006d Mon Sep 17 00:00:00 2001 From: ganeshrevadi Date: Thu, 23 Mar 2023 21:48:44 +0530 Subject: [PATCH 11/34] fixes --- tests/test_repo.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/tests/test_repo.py b/tests/test_repo.py index 410baae13..8093ec55d 100644 --- a/tests/test_repo.py +++ b/tests/test_repo.py @@ -108,8 +108,6 @@ def test_repo_add_success(qapp, qtbot, mocker, borg_json_output): assert main.repoTab.repoSelector.currentText() == test_repo_url # remove password form keyring keyring.remove_password('vorta-repo', test_repo_url) - assert add_repo_window.passwordLineEdit.text() == '' - assert add_repo_window.confirmLineEdit.text() == '' assert keyring.get_password("vorta-repo", RepoModel.get(id=2).url) is None From 9bfbc3c0c828c30973c2707ef918c84cd6d7c17d Mon Sep 17 00:00:00 2001 From: ganeshrevadi Date: Thu, 23 Mar 2023 21:55:03 +0530 Subject: [PATCH 12/34] fixes2 --- tests/test_repo.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test_repo.py b/tests/test_repo.py index 8093ec55d..557ae677b 100644 --- a/tests/test_repo.py +++ b/tests/test_repo.py @@ -78,7 +78,7 @@ def test_password_autofill(qapp, qtbot): assert add_repo_window.passwordLineEdit.text() == password # remove the password from keyring keyring.remove_password('vorta-repo', test_repo_url) - assert add_repo_window.passwordLineEdit.text() is None + assert keyring.remove_password("vorta-repo", test_repo_url) is None def test_repo_add_success(qapp, qtbot, mocker, borg_json_output): @@ -108,7 +108,7 @@ def test_repo_add_success(qapp, qtbot, mocker, borg_json_output): assert main.repoTab.repoSelector.currentText() == test_repo_url # remove password form keyring keyring.remove_password('vorta-repo', test_repo_url) - assert keyring.get_password("vorta-repo", RepoModel.get(id=2).url) is None + assert keyring.remove_password("vorta-repo", RepoModel.get(id=2).url) is None def test_ssh_dialog(qapp, qtbot, tmpdir): From 870b674cd1d926e1aaa4cc540d7e8fa7de0cc3a8 Mon Sep 17 00:00:00 2001 From: ganeshrevadi Date: Fri, 24 Mar 2023 19:36:53 +0530 Subject: [PATCH 13/34] pytest-fixtures --- tests/test_repo.py | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/tests/test_repo.py b/tests/test_repo.py index 557ae677b..309c0f56d 100644 --- a/tests/test_repo.py +++ b/tests/test_repo.py @@ -10,6 +10,20 @@ SHORT_PASSWORD = 'hunter2' +@pytest.fixture(scope="module") +def keyring_fixture(): + test_repo_url = f'vorta-test-repo.{uuid.uuid4()}.com:repo' + keyring = VortaKeyring.get_keyring() + keyring.get_password('vorta-repo', test_repo_url) + + yield + # Check if the password still exists after running the test + password = keyring.get_password('vorta-repo', test_repo_url) + assert password is not None + # Remove password from keyring if not removed + keyring.remove_password('vorta-repo', test_repo_url) + + def test_repo_add_failures(qapp, qtbot, mocker, borg_json_output): # Add new repo window main = qapp.main_window @@ -63,7 +77,7 @@ def test_repo_unlink(qapp, qtbot): assert main.progressText.text() == 'Select a backup repository first.' -def test_password_autofill(qapp, qtbot): +def test_password_autofill(qapp, qtbot, keyring_fixture): main = qapp.main_window main.repoTab.new_repo() # couldn't click menu add_repo_window = main.repoTab._window @@ -81,7 +95,7 @@ def test_password_autofill(qapp, qtbot): assert keyring.remove_password("vorta-repo", test_repo_url) is None -def test_repo_add_success(qapp, qtbot, mocker, borg_json_output): +def test_repo_add_success(qapp, qtbot, mocker, borg_json_output, keyring_fixture): # Add new repo window main = qapp.main_window main.repoTab.new_repo() # couldn't click menu @@ -108,7 +122,6 @@ def test_repo_add_success(qapp, qtbot, mocker, borg_json_output): assert main.repoTab.repoSelector.currentText() == test_repo_url # remove password form keyring keyring.remove_password('vorta-repo', test_repo_url) - assert keyring.remove_password("vorta-repo", RepoModel.get(id=2).url) is None def test_ssh_dialog(qapp, qtbot, tmpdir): From 55e6de655d779ae9cad27d5d66d9d546f468fd02 Mon Sep 17 00:00:00 2001 From: ganeshrevadi Date: Fri, 24 Mar 2023 19:41:08 +0530 Subject: [PATCH 14/34] pytest-fixtures2 --- tests/test_repo.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/tests/test_repo.py b/tests/test_repo.py index 309c0f56d..969082d0f 100644 --- a/tests/test_repo.py +++ b/tests/test_repo.py @@ -17,9 +17,7 @@ def keyring_fixture(): keyring.get_password('vorta-repo', test_repo_url) yield - # Check if the password still exists after running the test - password = keyring.get_password('vorta-repo', test_repo_url) - assert password is not None + # Remove password from keyring if not removed keyring.remove_password('vorta-repo', test_repo_url) From 9a33bd40e03ebeebfc0b63b2fe640b0035be999a Mon Sep 17 00:00:00 2001 From: ganeshrevadi Date: Thu, 9 Mar 2023 21:37:49 +0530 Subject: [PATCH 15/34] Adding remove password --- src/vorta/keyring/abc.py | 6 ++++++ src/vorta/keyring/secretstorage.py | 18 ++++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/src/vorta/keyring/abc.py b/src/vorta/keyring/abc.py index fc35f9c6d..1ad85158c 100644 --- a/src/vorta/keyring/abc.py +++ b/src/vorta/keyring/abc.py @@ -54,6 +54,12 @@ def get_password(self, service, repo_url): """ raise NotImplementedError + def remove_password(self, service, repo_url): + """ + Removes a password form the underlying store. + """ + raise NotImplementedError + @property def is_system(self): """ diff --git a/src/vorta/keyring/secretstorage.py b/src/vorta/keyring/secretstorage.py index 02c1c3198..194d05dab 100644 --- a/src/vorta/keyring/secretstorage.py +++ b/src/vorta/keyring/secretstorage.py @@ -65,6 +65,24 @@ def get_password(self, service, repo_url): return item.get_secret().decode("utf-8") return None + def remove_password(self, service, repo_url): + """ + Remove a password from the underlying store. + """ + if self.is_unlocked: + asyncio.set_event_loop(asyncio.new_event_loop()) + attributes = { + 'application': 'Vorta', + 'service': service, + 'repo_url': repo_url, + } + items = list(self.collection.search_items(attributes)) + logger.debug('Found %i passwords matching repo URL.', len(items)) + for item in items: + self.collection.delete_item(item) + logger.debug(f"Removed password for repo {repo_url}") + return None + @property def is_unlocked(self): # unlock() will return True if the unlock prompt is dismissed From 4657aec0b568ef4273e40a98a2821a7747c3050a Mon Sep 17 00:00:00 2001 From: ganeshrevadi Date: Fri, 10 Mar 2023 23:29:43 +0530 Subject: [PATCH 16/34] remove pass method --- src/vorta/keyring/secretstorage.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/vorta/keyring/secretstorage.py b/src/vorta/keyring/secretstorage.py index 194d05dab..86880f093 100644 --- a/src/vorta/keyring/secretstorage.py +++ b/src/vorta/keyring/secretstorage.py @@ -79,7 +79,9 @@ def remove_password(self, service, repo_url): items = list(self.collection.search_items(attributes)) logger.debug('Found %i passwords matching repo URL.', len(items)) for item in items: - self.collection.delete_item(item) + if item.is_locked() and item.unlock(): + return None + self.collection.delete(item) logger.debug(f"Removed password for repo {repo_url}") return None From 658d7911dbe247bccf068c4c40960ccf2eae5f4b Mon Sep 17 00:00:00 2001 From: ganeshrevadi Date: Sat, 11 Mar 2023 14:24:19 +0530 Subject: [PATCH 17/34] Kwallet --- src/vorta/keyring/kwallet.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/vorta/keyring/kwallet.py b/src/vorta/keyring/kwallet.py index 32402160a..2146cc678 100644 --- a/src/vorta/keyring/kwallet.py +++ b/src/vorta/keyring/kwallet.py @@ -45,6 +45,11 @@ def get_password(self, service, repo_url): logger.debug(f"Retrieved password for repo {repo_url}") return password + def remove_password(self, service, repo_url): + if self.is_unlocked and self.get_result("hasEntry", args=[self.handle, self.folder_name, repo_url, service]): + self.get_result("removeEntry", args=[self.handle, self.folder_name, repo_url, service]) + logger.debug(f"Removed password for repo {repo_url}") + def get_result(self, method, args=[]): if args: result = self.iface.callWithArgumentList(QtDBus.QDBus.AutoDetect, method, args) From c7137b06c82ecb3a8852e1f2261e457522fc3036 Mon Sep 17 00:00:00 2001 From: ganeshrevadi Date: Sun, 12 Mar 2023 21:19:48 +0530 Subject: [PATCH 18/34] Implement remove password for kwallet --- src/vorta/keyring/kwallet.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/vorta/keyring/kwallet.py b/src/vorta/keyring/kwallet.py index 2146cc678..f677fdb3d 100644 --- a/src/vorta/keyring/kwallet.py +++ b/src/vorta/keyring/kwallet.py @@ -46,8 +46,9 @@ def get_password(self, service, repo_url): return password def remove_password(self, service, repo_url): - if self.is_unlocked and self.get_result("hasEntry", args=[self.handle, self.folder_name, repo_url, service]): - self.get_result("removeEntry", args=[self.handle, self.folder_name, repo_url, service]) + entry = [self.handle, self.folder_name, repo_url, service] + if self.is_unlocked and self.get_result("hasEntry", args=entry): + self.get_result("removeEntry", args=entry) logger.debug(f"Removed password for repo {repo_url}") def get_result(self, method, args=[]): From e5791daf5493ba9adb6491c2a89b2d4ea38eea05 Mon Sep 17 00:00:00 2001 From: Manu Date: Sun, 12 Mar 2023 19:24:17 +0000 Subject: [PATCH 19/34] Implement remove_password() for darwin --- src/vorta/keyring/darwin.py | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/src/vorta/keyring/darwin.py b/src/vorta/keyring/darwin.py index d0f52a3cb..d598d9030 100644 --- a/src/vorta/keyring/darwin.py +++ b/src/vorta/keyring/darwin.py @@ -15,7 +15,11 @@ class VortaDarwinKeyring(VortaKeyring): - """Homemade macOS Keychain Service""" + """ + Homemade macOS Keychain Service + + TODO: Could use the newer API, as done here: https://github.com/jaraco/keyring/pull/522/files + """ login_keychain = None @@ -42,6 +46,7 @@ def _set_keychain(self): b'i@I*I*o^Io^^{OpaquePassBuff}o^^{OpaqueSecKeychainItemRef}', ), ('SecKeychainGetStatus', b'i^{OpaqueSecKeychainRef=}o^I'), + ('SecKeychainItemDelete', b'i^{OpaqueSecKeychainItemRef=}o^I'), ] objc.loadBundleFunctions(Security, globals(), S_functions) @@ -97,6 +102,25 @@ def get_password(self, service, repo_url): logger.debug(f"Retrieved password for repo {repo_url}") return password + def remove_password(self, service, repo_url): + if not self.login_keychain: + self._set_keychain() + + (result, password_length, password_buffer, keychain_item,) = SecKeychainFindGenericPassword( + self.login_keychain, + len(service), + service.encode(), + len(repo_url), + repo_url.encode(), + None, + None, + None, + ) + password = None + if (result == 0) and (password_length != 0): + logger.debug(f"Found password for repo {repo_url}") + SecKeychainItemDelete(keychain_item, None) + @property def is_unlocked(self): kSecUnlockStateStatus = 1 From 2304a768a8d3be4fec1c770a811480971dd05e9f Mon Sep 17 00:00:00 2001 From: ganeshrevadi Date: Mon, 13 Mar 2023 19:15:30 +0530 Subject: [PATCH 20/34] Remove password for db --- src/vorta/keyring/db.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/vorta/keyring/db.py b/src/vorta/keyring/db.py index 706c0d913..f4779c949 100644 --- a/src/vorta/keyring/db.py +++ b/src/vorta/keyring/db.py @@ -33,6 +33,16 @@ def get_password(self, service, repo_url): except peewee.DoesNotExist: return None + def remove_password(self, service, repo_url): + from vorta.store.models import RepoPassword + + try: + keyring_entry = RepoPassword.get(url=repo_url) + keyring_entry.delete_instance() + logger.debug(f"Removed password for repo {repo_url}") + except peewee.DoesNotExist: + pass + @property def is_system(self): return False From e4a62d51ba60c1c0a61102f04d9ba47218a94073 Mon Sep 17 00:00:00 2001 From: ganeshrevadi Date: Wed, 15 Mar 2023 22:12:46 +0530 Subject: [PATCH 21/34] Remove password for db --- src/vorta/keyring/db.py | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/vorta/keyring/db.py b/src/vorta/keyring/db.py index f4779c949..079a75602 100644 --- a/src/vorta/keyring/db.py +++ b/src/vorta/keyring/db.py @@ -1,6 +1,6 @@ import logging import peewee -from vorta.store.models import SettingsModel +from vorta.store.models import RepoPassword, SettingsModel from .abc import VortaKeyring logger = logging.getLogger(__name__) @@ -14,16 +14,13 @@ class VortaDBKeyring(VortaKeyring): """ def set_password(self, service, repo_url, password): - from vorta.store.models import RepoPassword keyring_entry, created = RepoPassword.get_or_create(url=repo_url, defaults={'password': password}) keyring_entry.password = password keyring_entry.save() - logger.debug(f"Saved password for repo {repo_url}") def get_password(self, service, repo_url): - from vorta.store.models import RepoPassword try: keyring_entry = RepoPassword.get(url=repo_url) @@ -34,7 +31,6 @@ def get_password(self, service, repo_url): return None def remove_password(self, service, repo_url): - from vorta.store.models import RepoPassword try: keyring_entry = RepoPassword.get(url=repo_url) From 650a2091f0e978a8e0ea883fc53fe7202ed63a26 Mon Sep 17 00:00:00 2001 From: ganeshrevadi Date: Fri, 17 Mar 2023 22:36:52 +0530 Subject: [PATCH 22/34] remove password saved in test_utils --- src/vorta/keyring/db.py | 2 +- src/vorta/keyring/secretstorage.py | 5 ++--- tests/test_utils.py | 2 ++ 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/vorta/keyring/db.py b/src/vorta/keyring/db.py index 079a75602..e525df80d 100644 --- a/src/vorta/keyring/db.py +++ b/src/vorta/keyring/db.py @@ -37,7 +37,7 @@ def remove_password(self, service, repo_url): keyring_entry.delete_instance() logger.debug(f"Removed password for repo {repo_url}") except peewee.DoesNotExist: - pass + logger.debug(f"Password wasn't found for repo {repo_url}") @property def is_system(self): diff --git a/src/vorta/keyring/secretstorage.py b/src/vorta/keyring/secretstorage.py index 86880f093..607c97110 100644 --- a/src/vorta/keyring/secretstorage.py +++ b/src/vorta/keyring/secretstorage.py @@ -80,10 +80,9 @@ def remove_password(self, service, repo_url): logger.debug('Found %i passwords matching repo URL.', len(items)) for item in items: if item.is_locked() and item.unlock(): - return None - self.collection.delete(item) + continue + self.collection.item.delete() logger.debug(f"Removed password for repo {repo_url}") - return None @property def is_unlocked(self): diff --git a/tests/test_utils.py b/tests/test_utils.py index 07585e3f9..d67ea6cb0 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -10,6 +10,8 @@ def test_keyring(): keyring = VortaKeyring.get_keyring() keyring.set_password('vorta-repo', REPO, UNICODE_PW) assert keyring.get_password("vorta-repo", REPO) == UNICODE_PW + keyring.remove_password('vorta-repo', REPO) + assert keyring.remove_password("vorta-repo", REPO) is None def test_best_size_unit_precision0(): From 354f6468459a32b23fda927a9ac454372f45bed4 Mon Sep 17 00:00:00 2001 From: ganeshrevadi Date: Thu, 23 Mar 2023 21:35:32 +0530 Subject: [PATCH 23/34] remove password from keyring --- tests/test_repo.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tests/test_repo.py b/tests/test_repo.py index f90798712..9d3f9a6b2 100644 --- a/tests/test_repo.py +++ b/tests/test_repo.py @@ -74,6 +74,9 @@ def test_password_autofill(qapp, qtbot): qtbot.keyClicks(add_repo_window.repoURL, test_repo_url) assert add_repo_window.passwordLineEdit.text() == password + # remove the password from keyring + keyring.remove_password('vorta-repo', test_repo_url) + assert add_repo_window.passwordLineEdit.text() is None def test_repo_add_success(qapp, qtbot, mocker, borg_json_output): @@ -101,6 +104,11 @@ def test_repo_add_success(qapp, qtbot, mocker, borg_json_output): keyring = VortaKeyring.get_keyring() assert keyring.get_password("vorta-repo", RepoModel.get(id=2).url) == LONG_PASSWORD assert main.repoTab.repoSelector.currentText() == test_repo_url + # remove password form keyring + keyring.remove_password() + assert add_repo_window.passwordLineEdit.text() == '' + assert add_repo_window.confirmLineEdit.text() == '' + assert keyring.get_password("vorta-repo", RepoModel.get(id=2).url) is None def test_ssh_dialog(qapp, qtbot, tmpdir): From 37c76e46d82af92f26931a2b24baf3e5551e3bf5 Mon Sep 17 00:00:00 2001 From: ganeshrevadi Date: Thu, 23 Mar 2023 21:42:36 +0530 Subject: [PATCH 24/34] remove_password --- tests/test_repo.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_repo.py b/tests/test_repo.py index 9d3f9a6b2..1dff52410 100644 --- a/tests/test_repo.py +++ b/tests/test_repo.py @@ -105,7 +105,7 @@ def test_repo_add_success(qapp, qtbot, mocker, borg_json_output): assert keyring.get_password("vorta-repo", RepoModel.get(id=2).url) == LONG_PASSWORD assert main.repoTab.repoSelector.currentText() == test_repo_url # remove password form keyring - keyring.remove_password() + keyring.remove_password('vorta-repo', test_repo_url) assert add_repo_window.passwordLineEdit.text() == '' assert add_repo_window.confirmLineEdit.text() == '' assert keyring.get_password("vorta-repo", RepoModel.get(id=2).url) is None From 020973e6dfaec45df09e7c40985bf32068b72248 Mon Sep 17 00:00:00 2001 From: ganeshrevadi Date: Thu, 23 Mar 2023 21:48:44 +0530 Subject: [PATCH 25/34] fixes --- tests/test_repo.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/tests/test_repo.py b/tests/test_repo.py index 1dff52410..fa9c24666 100644 --- a/tests/test_repo.py +++ b/tests/test_repo.py @@ -106,8 +106,6 @@ def test_repo_add_success(qapp, qtbot, mocker, borg_json_output): assert main.repoTab.repoSelector.currentText() == test_repo_url # remove password form keyring keyring.remove_password('vorta-repo', test_repo_url) - assert add_repo_window.passwordLineEdit.text() == '' - assert add_repo_window.confirmLineEdit.text() == '' assert keyring.get_password("vorta-repo", RepoModel.get(id=2).url) is None From a4c11b887851d8e484412f935b375f50ba9ee918 Mon Sep 17 00:00:00 2001 From: ganeshrevadi Date: Thu, 23 Mar 2023 21:55:03 +0530 Subject: [PATCH 26/34] fixes2 --- tests/test_repo.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test_repo.py b/tests/test_repo.py index fa9c24666..357f9f8cd 100644 --- a/tests/test_repo.py +++ b/tests/test_repo.py @@ -76,7 +76,7 @@ def test_password_autofill(qapp, qtbot): assert add_repo_window.passwordLineEdit.text() == password # remove the password from keyring keyring.remove_password('vorta-repo', test_repo_url) - assert add_repo_window.passwordLineEdit.text() is None + assert keyring.remove_password("vorta-repo", test_repo_url) is None def test_repo_add_success(qapp, qtbot, mocker, borg_json_output): @@ -106,7 +106,7 @@ def test_repo_add_success(qapp, qtbot, mocker, borg_json_output): assert main.repoTab.repoSelector.currentText() == test_repo_url # remove password form keyring keyring.remove_password('vorta-repo', test_repo_url) - assert keyring.get_password("vorta-repo", RepoModel.get(id=2).url) is None + assert keyring.remove_password("vorta-repo", RepoModel.get(id=2).url) is None def test_ssh_dialog(qapp, qtbot, tmpdir): From 9177435123862a0aaa7dc9575b40fe13d667280f Mon Sep 17 00:00:00 2001 From: ganeshrevadi Date: Fri, 24 Mar 2023 19:36:53 +0530 Subject: [PATCH 27/34] pytest-fixtures --- tests/test_repo.py | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/tests/test_repo.py b/tests/test_repo.py index 357f9f8cd..59ce64596 100644 --- a/tests/test_repo.py +++ b/tests/test_repo.py @@ -10,6 +10,20 @@ SHORT_PASSWORD = 'hunter2' +@pytest.fixture(scope="module") +def keyring_fixture(): + test_repo_url = f'vorta-test-repo.{uuid.uuid4()}.com:repo' + keyring = VortaKeyring.get_keyring() + keyring.get_password('vorta-repo', test_repo_url) + + yield + # Check if the password still exists after running the test + password = keyring.get_password('vorta-repo', test_repo_url) + assert password is not None + # Remove password from keyring if not removed + keyring.remove_password('vorta-repo', test_repo_url) + + def test_repo_add_failures(qapp, qtbot, mocker, borg_json_output): # Add new repo window main = qapp.main_window @@ -61,7 +75,7 @@ def test_repo_unlink(qapp, qtbot): assert 'Select a backup repository first.' in main.progressText.text() -def test_password_autofill(qapp, qtbot): +def test_password_autofill(qapp, qtbot, keyring_fixture): main = qapp.main_window main.repoTab.new_repo() # couldn't click menu add_repo_window = main.repoTab._window @@ -79,7 +93,7 @@ def test_password_autofill(qapp, qtbot): assert keyring.remove_password("vorta-repo", test_repo_url) is None -def test_repo_add_success(qapp, qtbot, mocker, borg_json_output): +def test_repo_add_success(qapp, qtbot, mocker, borg_json_output, keyring_fixture): # Add new repo window main = qapp.main_window main.repoTab.new_repo() # couldn't click menu @@ -106,7 +120,6 @@ def test_repo_add_success(qapp, qtbot, mocker, borg_json_output): assert main.repoTab.repoSelector.currentText() == test_repo_url # remove password form keyring keyring.remove_password('vorta-repo', test_repo_url) - assert keyring.remove_password("vorta-repo", RepoModel.get(id=2).url) is None def test_ssh_dialog(qapp, qtbot, tmpdir): From ac428259d3deb99995f3a46833061ae652a15f6e Mon Sep 17 00:00:00 2001 From: ganeshrevadi Date: Fri, 24 Mar 2023 19:41:08 +0530 Subject: [PATCH 28/34] pytest-fixtures2 --- tests/test_repo.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/tests/test_repo.py b/tests/test_repo.py index 59ce64596..eca85a5de 100644 --- a/tests/test_repo.py +++ b/tests/test_repo.py @@ -17,9 +17,7 @@ def keyring_fixture(): keyring.get_password('vorta-repo', test_repo_url) yield - # Check if the password still exists after running the test - password = keyring.get_password('vorta-repo', test_repo_url) - assert password is not None + # Remove password from keyring if not removed keyring.remove_password('vorta-repo', test_repo_url) From f1cc8f47dfdb99dc4f0de2734f771efd462dbec8 Mon Sep 17 00:00:00 2001 From: ganeshrevadi Date: Sat, 25 Mar 2023 23:01:20 +0530 Subject: [PATCH 29/34] fixtures --- tests/test_repo.py | 24 ++++++++---------------- 1 file changed, 8 insertions(+), 16 deletions(-) diff --git a/tests/test_repo.py b/tests/test_repo.py index eca85a5de..c9d96bd41 100644 --- a/tests/test_repo.py +++ b/tests/test_repo.py @@ -10,15 +10,16 @@ SHORT_PASSWORD = 'hunter2' -@pytest.fixture(scope="module") +@pytest.fixture(scope="function") def keyring_fixture(): - test_repo_url = f'vorta-test-repo.{uuid.uuid4()}.com:repo' + test_repo_url = 'ssh://user@vorta-test-repo.com:22' # Random repo URL to avoid macOS keychain + password = str(uuid.uuid4()) keyring = VortaKeyring.get_keyring() - keyring.get_password('vorta-repo', test_repo_url) + keyring.set_password('vorta-repo', test_repo_url, password) - yield + yield test_repo_url, password - # Remove password from keyring if not removed + # Remove password from keyring for the test keyring.remove_password('vorta-repo', test_repo_url) @@ -77,18 +78,11 @@ def test_password_autofill(qapp, qtbot, keyring_fixture): main = qapp.main_window main.repoTab.new_repo() # couldn't click menu add_repo_window = main.repoTab._window - test_repo_url = f'vorta-test-repo.{uuid.uuid4()}.com:repo' # Random repo URL to avoid macOS keychain - - keyring = VortaKeyring.get_keyring() - password = str(uuid.uuid4()) - keyring.set_password('vorta-repo', test_repo_url, password) + test_repo_url, password = keyring_fixture qtbot.keyClicks(add_repo_window.repoURL, test_repo_url) assert add_repo_window.passwordLineEdit.text() == password - # remove the password from keyring - keyring.remove_password('vorta-repo', test_repo_url) - assert keyring.remove_password("vorta-repo", test_repo_url) is None def test_repo_add_success(qapp, qtbot, mocker, borg_json_output, keyring_fixture): @@ -96,7 +90,7 @@ def test_repo_add_success(qapp, qtbot, mocker, borg_json_output, keyring_fixture main = qapp.main_window main.repoTab.new_repo() # couldn't click menu add_repo_window = main.repoTab._window - test_repo_url = f'vorta-test-repo.{uuid.uuid4()}.com:repo' # Random repo URL to avoid macOS keychain + test_repo_url, password = keyring_fixture qtbot.keyClicks(add_repo_window.repoURL, test_repo_url) qtbot.keyClicks(add_repo_window.passwordLineEdit, LONG_PASSWORD) @@ -116,8 +110,6 @@ def test_repo_add_success(qapp, qtbot, mocker, borg_json_output, keyring_fixture keyring = VortaKeyring.get_keyring() assert keyring.get_password("vorta-repo", RepoModel.get(id=2).url) == LONG_PASSWORD assert main.repoTab.repoSelector.currentText() == test_repo_url - # remove password form keyring - keyring.remove_password('vorta-repo', test_repo_url) def test_ssh_dialog(qapp, qtbot, tmpdir): From c910d614c502014245751406dadca4c9ba8110d3 Mon Sep 17 00:00:00 2001 From: ganeshrevadi Date: Sat, 25 Mar 2023 23:12:56 +0530 Subject: [PATCH 30/34] fixtures-2 --- tests/test_repo.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/tests/test_repo.py b/tests/test_repo.py index c9d96bd41..d2d9fa18c 100644 --- a/tests/test_repo.py +++ b/tests/test_repo.py @@ -17,7 +17,7 @@ def keyring_fixture(): keyring = VortaKeyring.get_keyring() keyring.set_password('vorta-repo', test_repo_url, password) - yield test_repo_url, password + yield test_repo_url, password, keyring # Remove password from keyring for the test keyring.remove_password('vorta-repo', test_repo_url) @@ -78,7 +78,7 @@ def test_password_autofill(qapp, qtbot, keyring_fixture): main = qapp.main_window main.repoTab.new_repo() # couldn't click menu add_repo_window = main.repoTab._window - test_repo_url, password = keyring_fixture + test_repo_url, password, keyring = keyring_fixture qtbot.keyClicks(add_repo_window.repoURL, test_repo_url) @@ -90,7 +90,7 @@ def test_repo_add_success(qapp, qtbot, mocker, borg_json_output, keyring_fixture main = qapp.main_window main.repoTab.new_repo() # couldn't click menu add_repo_window = main.repoTab._window - test_repo_url, password = keyring_fixture + test_repo_url, password, keyring = keyring_fixture qtbot.keyClicks(add_repo_window.repoURL, test_repo_url) qtbot.keyClicks(add_repo_window.passwordLineEdit, LONG_PASSWORD) @@ -107,7 +107,6 @@ def test_repo_add_success(qapp, qtbot, mocker, borg_json_output, keyring_fixture assert RepoModel.get(id=2).url == test_repo_url - keyring = VortaKeyring.get_keyring() assert keyring.get_password("vorta-repo", RepoModel.get(id=2).url) == LONG_PASSWORD assert main.repoTab.repoSelector.currentText() == test_repo_url From eb2e8784e5b08b494096aa1101449ce94bcdb245 Mon Sep 17 00:00:00 2001 From: ganeshrevadi Date: Sat, 25 Mar 2023 23:25:49 +0530 Subject: [PATCH 31/34] fixtures-3 --- tests/test_repo.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_repo.py b/tests/test_repo.py index d2d9fa18c..63ef09c06 100644 --- a/tests/test_repo.py +++ b/tests/test_repo.py @@ -12,7 +12,7 @@ @pytest.fixture(scope="function") def keyring_fixture(): - test_repo_url = 'ssh://user@vorta-test-repo.com:22' # Random repo URL to avoid macOS keychain + test_repo_url = f'vorta-test-repo.{uuid.uuid4()}.com:repo' # Random repo URL to avoid macOS keychain password = str(uuid.uuid4()) keyring = VortaKeyring.get_keyring() keyring.set_password('vorta-repo', test_repo_url, password) From 099e9e4a6919c7572eb727f15edcfe42c2231da5 Mon Sep 17 00:00:00 2001 From: ganeshrevadi Date: Sun, 2 Apr 2023 20:42:11 +0530 Subject: [PATCH 32/34] fixing --- tests/test_repo.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/test_repo.py b/tests/test_repo.py index 63ef09c06..05a81729f 100644 --- a/tests/test_repo.py +++ b/tests/test_repo.py @@ -17,7 +17,7 @@ def keyring_fixture(): keyring = VortaKeyring.get_keyring() keyring.set_password('vorta-repo', test_repo_url, password) - yield test_repo_url, password, keyring + yield test_repo_url, password, keyring, LONG_PASSWORD # Remove password from keyring for the test keyring.remove_password('vorta-repo', test_repo_url) @@ -78,7 +78,7 @@ def test_password_autofill(qapp, qtbot, keyring_fixture): main = qapp.main_window main.repoTab.new_repo() # couldn't click menu add_repo_window = main.repoTab._window - test_repo_url, password, keyring = keyring_fixture + test_repo_url, password, keyring, long_password = keyring_fixture qtbot.keyClicks(add_repo_window.repoURL, test_repo_url) @@ -90,7 +90,7 @@ def test_repo_add_success(qapp, qtbot, mocker, borg_json_output, keyring_fixture main = qapp.main_window main.repoTab.new_repo() # couldn't click menu add_repo_window = main.repoTab._window - test_repo_url, password, keyring = keyring_fixture + test_repo_url, password, keyring, long_password = keyring_fixture qtbot.keyClicks(add_repo_window.repoURL, test_repo_url) qtbot.keyClicks(add_repo_window.passwordLineEdit, LONG_PASSWORD) @@ -107,7 +107,7 @@ def test_repo_add_success(qapp, qtbot, mocker, borg_json_output, keyring_fixture assert RepoModel.get(id=2).url == test_repo_url - assert keyring.get_password("vorta-repo", RepoModel.get(id=2).url) == LONG_PASSWORD + assert keyring.get_password("vorta-repo", RepoModel.get(id=2).url) == long_password assert main.repoTab.repoSelector.currentText() == test_repo_url From 1c21dd9aa6f814aa6b476b5e90e9ce5c78d74cf4 Mon Sep 17 00:00:00 2001 From: ganeshrevadi Date: Sun, 2 Apr 2023 20:47:27 +0530 Subject: [PATCH 33/34] fix2 --- tests/test_repo.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_repo.py b/tests/test_repo.py index 05a81729f..dee9ece07 100644 --- a/tests/test_repo.py +++ b/tests/test_repo.py @@ -107,7 +107,7 @@ def test_repo_add_success(qapp, qtbot, mocker, borg_json_output, keyring_fixture assert RepoModel.get(id=2).url == test_repo_url - assert keyring.get_password("vorta-repo", RepoModel.get(id=2).url) == long_password + assert long_password in keyring.get_password("vorta-repo", RepoModel.get(id=2).url) assert main.repoTab.repoSelector.currentText() == test_repo_url From b6aad7a9f76bdfdcdd24991aae7d5a37fd9fd009 Mon Sep 17 00:00:00 2001 From: ganeshrevadi Date: Sun, 2 Apr 2023 21:06:31 +0530 Subject: [PATCH 34/34] fix3 --- tests/test_repo.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_repo.py b/tests/test_repo.py index dee9ece07..402eee596 100644 --- a/tests/test_repo.py +++ b/tests/test_repo.py @@ -107,7 +107,7 @@ def test_repo_add_success(qapp, qtbot, mocker, borg_json_output, keyring_fixture assert RepoModel.get(id=2).url == test_repo_url - assert long_password in keyring.get_password("vorta-repo", RepoModel.get(id=2).url) + assert long_password.lower() in keyring.get_password("vorta-repo", RepoModel.get(id=2).url).lower() assert main.repoTab.repoSelector.currentText() == test_repo_url