diff --git a/blimey/agile_keychain/_manager/_item_manager.py b/blimey/agile_keychain/_manager/_item_manager.py index 04873c0..dd8f0bc 100644 --- a/blimey/agile_keychain/_manager/_item_manager.py +++ b/blimey/agile_keychain/_manager/_item_manager.py @@ -20,7 +20,12 @@ def get_by_id(self, item_id): except FileNotFoundError: raise ItemNotFoundException - return EncryptedAgileKeychainItem(data) + item = EncryptedAgileKeychainItem(data) + + if self._is_deleted(item): + raise ItemNotFoundException + + return item def get_all_items(self): item_paths = glob.glob(os.path.join(self._base_path, "data", "default", "*.1password")) @@ -29,7 +34,11 @@ def get_all_items(self): for item_path in item_paths: basename = os.path.basename(item_path) item_id, _ = os.path.splitext(basename) - items.append(self.get_by_id(item_id)) + + try: + items.append(self.get_by_id(item_id)) + except ItemNotFoundException: + continue return items @@ -62,3 +71,10 @@ def _update_contents_file(self): with open(os.path.join(self._base_path, "data", "default", "contents.js"), "w") as file: json.dump(contents, file) + + def _is_deleted(self, item): + if item['uuid'] is None: + return True + + if item['typeName'] == 'system.Tombstone': + return True diff --git a/tests/fixtures/test.agilekeychain/data/default/320BE3D1B490458F82314E1A2B99552A.1password b/tests/fixtures/test.agilekeychain/data/default/320BE3D1B490458F82314E1A2B99552A.1password new file mode 100644 index 0000000..12bf35f --- /dev/null +++ b/tests/fixtures/test.agilekeychain/data/default/320BE3D1B490458F82314E1A2B99552A.1password @@ -0,0 +1 @@ +{"uuid":"320BE3D1B490458F82314E1A2B99552A","updatedAt":1423411358,"locationKey":"","openContents":{"contentsHash":"fe62a730"},"keyID":"98EB2E946008403280A3A8D9261018A4","trashed":true,"title":"","location":"","encrypted":"U2FsdGVkX19LvzFrVOVBfUxXpWEDI/cNx2iwSaMpu9I=\u0000","createdAt":1423411343,"typeName":"system.Tombstone"} \ No newline at end of file diff --git a/tests/fixtures/test.agilekeychain/data/default/CAF7A781A71E44CFBB63F9356B46A0C9.1password b/tests/fixtures/test.agilekeychain/data/default/CAF7A781A71E44CFBB63F9356B46A0C9.1password new file mode 100644 index 0000000..9e26dfe --- /dev/null +++ b/tests/fixtures/test.agilekeychain/data/default/CAF7A781A71E44CFBB63F9356B46A0C9.1password @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/tests/fixtures/test.agilekeychain/data/default/ECE79F0A4BDF44CE8E7986897D84D1EC.1password b/tests/fixtures/test.agilekeychain/data/default/ECE79F0A4BDF44CE8E7986897D84D1EC.1password new file mode 100644 index 0000000..6bca731 --- /dev/null +++ b/tests/fixtures/test.agilekeychain/data/default/ECE79F0A4BDF44CE8E7986897D84D1EC.1password @@ -0,0 +1 @@ +{"uuid":"ECE79F0A4BDF44CE8E7986897D84D1EC","updatedAt":1423411623,"securityLevel":"SL5","contentsHash":"b0516b42","trashed":true,"title":"Trashed Note","encrypted":"U2FsdGVkX19rj4xVqOj2JlJ9UdO3uncPqSIHVNb4SmkM2je\/b92H2AWp2sLRvokGqN\/W3dLvOaJctMetjLcavA==","createdAt":1423410518,"typeName":"securenotes.SecureNote"} \ No newline at end of file diff --git a/tests/fixtures/test.agilekeychain/data/default/contents.js b/tests/fixtures/test.agilekeychain/data/default/contents.js index 84ec79a..508f18b 100644 --- a/tests/fixtures/test.agilekeychain/data/default/contents.js +++ b/tests/fixtures/test.agilekeychain/data/default/contents.js @@ -1 +1 @@ -[["9E7673CCBB5B4AC9A7A8838835CB7E83","webforms.WebForm","Some Website","somewebsite.com",1383517778,"4A3D784D115F4279BDFCE46D0A162D57",0,"N"],["5F7210FD2F3F460692B7083C60854A02","wallet.onlineservices.FTP","Some FTP Account","",1383517697,"D05009E62D7D401CB8ACF2FE6981C031",0,"N"],["9315F5EA8DCC4CB7BE09155DB7FCD1ED","identities.Identity","Some Identity","",1383517697,"D05009E62D7D401CB8ACF2FE6981C031",0,"N"],["B851D6E3232842B0858BC10968632A9C","securenotes.SecureNote","Some Note","",1383517697,"D05009E62D7D401CB8ACF2FE6981C031",0,"N"],["2E21D652E0754BD59F6B94B0323D0142","wallet.computer.License","Some Software","",1383517713,"4A3D784D115F4279BDFCE46D0A162D57",0,"N"],["6371E49FEFA042EDB335421459E5B29F","wallet.financial.CreditCard","Some VISA Card","",1383517713,"4A3D784D115F4279BDFCE46D0A162D57",0,"N"],["D05009E62D7D401CB8ACF2FE6981C031","system.folder.Regular","Some Folder","",1383517691,"",0,"N"],["4A3D784D115F4279BDFCE46D0A162D57","system.folder.Regular","Some Other Folder","",1383517706,"",0,"N"],["97019BEBCF9E402F8F0C033474B1B85D","webforms.WebForm","Some Other Website","someotherwebsite.com",1383517785,"",0,"N"]] \ No newline at end of file +[["ECE79F0A4BDF44CE8E7986897D84D1EC","securenotes.SecureNote","Trashed Note","",1423411623,"",0,"Y"],["9315F5EA8DCC4CB7BE09155DB7FCD1ED","identities.Identity","Some Identity","",1383517697,"D05009E62D7D401CB8ACF2FE6981C031",0,"N"],["97019BEBCF9E402F8F0C033474B1B85D","webforms.WebForm","Some Other Website","http:\/\/www.someotherwebsite.com",1383517785,"",0,"N"],["6371E49FEFA042EDB335421459E5B29F","wallet.financial.CreditCard","Some VISA Card","",1383517713,"4A3D784D115F4279BDFCE46D0A162D57",0,"N"],["9E7673CCBB5B4AC9A7A8838835CB7E83","webforms.WebForm","Some Website","http:\/\/www.somewebsite.com",1383517778,"4A3D784D115F4279BDFCE46D0A162D57",0,"N"],["B851D6E3232842B0858BC10968632A9C","securenotes.SecureNote","Some Note","",1383517697,"D05009E62D7D401CB8ACF2FE6981C031",0,"N"],["2E21D652E0754BD59F6B94B0323D0142","wallet.computer.License","Some Software","",1383517713,"4A3D784D115F4279BDFCE46D0A162D57",0,"N"],["5F7210FD2F3F460692B7083C60854A02","webforms.WebForm","Some FTP Account","ftp:\/\/someserver.com",1383517697,"D05009E62D7D401CB8ACF2FE6981C031",0,"N"],["04C35F1C287643F7955C8C64D9F9B67D","system.Tombstone","Unnamed","",1423410706,"",0,"Y"],["CAF7A781A71E44CFBB63F9356B46A0C9","system.Tombstone","Unnamed","",1423411611,"",0,"Y"],["4A3D784D115F4279BDFCE46D0A162D57","system.folder.Regular","Some Other Folder","",1383517706,"",0,"N"],["0B42B0AB91E14C4A81AA97CF447A1FF0","system.folder.Regular","Some Sub Folder","",1423410465,"D05009E62D7D401CB8ACF2FE6981C031",0,"N"],["D05009E62D7D401CB8ACF2FE6981C031","system.folder.Regular","Some Folder","",1383517691,"",0,"N"]] \ No newline at end of file diff --git a/tests/integration/openpassword/agile_keychain/test_item_manager.py b/tests/integration/openpassword/agile_keychain/test_item_manager.py index beb0a8b..01a1b2d 100644 --- a/tests/integration/openpassword/agile_keychain/test_item_manager.py +++ b/tests/integration/openpassword/agile_keychain/test_item_manager.py @@ -26,7 +26,21 @@ def it_throws_if_requested_item_is_not_found(self): item_manager = ItemManager(self._fixture_path) item_manager.get_by_id('notfoundid') - def it_gets_all_items(self): + # 1Password 3 changes deleted item type to system.Tombstone + # Refer to the item in the fixture for an example of this + @raises(ItemNotFoundException) + def it_throws_if_requested_item_is_of_type_tombstone(self): + item_manager = ItemManager(self._fixture_path) + item_manager.get_by_id('320BE3D1B490458F82314E1A2B99552A') + + # 1Password 4+ replaces the item contents with "{}" + # Refer to the item in the fixture for an example of this + @raises(ItemNotFoundException) + def it_throws_if_requested_item_is_empty(self): + item_manager = ItemManager(self._fixture_path) + item_manager.get_by_id('CAF7A781A71E44CFBB63F9356B46A0C9') + + def it_gets_all_non_null_and_non_tombstoned_items(self): item_manager = ItemManager(self._fixture_path) items = item_manager.get_all_items() @@ -39,10 +53,11 @@ def it_gets_all_items(self): '97019BEBCF9E402F8F0C033474B1B85D', '9E7673CCBB5B4AC9A7A8838835CB7E83', 'B851D6E3232842B0858BC10968632A9C', - 'D05009E62D7D401CB8ACF2FE6981C031' + 'D05009E62D7D401CB8ACF2FE6981C031', + 'ECE79F0A4BDF44CE8E7986897D84D1EC' ] - assert len(items) == 9 + assert len(items) == len(expected_item_uuids) for item in items: assert item['uuid'] in expected_item_uuids