def test_load_from_json(self): json_str = "{\"domain\": \"unit.test\", \"username\": \"testilinius\", " +\ "\"notes\": \"interesting note\", \"legacyPassword\": \"rtSr?bS,mi\", " +\ "\"usedCharacters\": \"AEIOUaeiou\", \"iterations\": 5341, " +\ "\"length\": 16, \"salt\": \"ZmFzY2luYXRpbmc=\", " +\ "\"cDate\": \"2001-01-01T02:14:12\", \"mDate\": \"2005-01-01T01:14:12\"}" s = PasswordSetting(json.loads(json_str)["domain"]) s.load_from_dict(json.loads(json_str)) self.assertEquals("unit.test", s.get_domain()) self.assertEquals("testilinius", s.get_username()) self.assertEquals("interesting note", s.get_notes()) self.assertEquals("rtSr?bS,mi", s.get_legacy_password()) self.assertFalse(s.use_lower_case()) self.assertFalse(s.use_upper_case()) self.assertFalse(s.use_digits()) self.assertFalse(s.use_extra()) self.assertTrue(s.use_custom_character_set()) self.assertEquals("AEIOUaeiou", s.get_character_set()) self.assertEquals(5341, s.get_iterations()) self.assertEquals(16, s.get_length()) expected_salt = "fascinating".encode('utf-8') self.assertEqual(len(expected_salt), len(s.get_salt())) for i in range(len(expected_salt)): self.assertEqual(expected_salt[i], s.get_salt()[i]) self.assertEquals("2001-01-01T02:14:12", s.get_creation_date()) self.assertEquals("2005-01-01T01:14:12", s.get_modification_date())
def update_from_export_data(self, kgk_manager, blob): """ Call this method to pull settings from the sync server. :param kgk_manager: the kgk manager used for the decryption :type kgk_manager: KgkManager :param blob: the export data :type blob: bytes """ if not blob[0] == 1: print("Version error: Wrong data format. Could not import anything.") return True settings_crypter = self.get_settings_crypter(kgk_manager) decrypted_settings = settings_crypter.decrypt(blob[145:]) if len(decrypted_settings) <= 0: print("Wrong password.") return False self.remote_data = json.loads(str(Packer.decompress(decrypted_settings), encoding='utf-8')) self.update_remote = False for domain_name in self.remote_data.keys(): data_set = self.remote_data[domain_name] found = False i = 0 while i < len(self.settings): setting = self.settings[i] if setting.get_domain() == domain_name: found = True if datetime.strptime(data_set['mDate'], "%Y-%m-%dT%H:%M:%S") > setting.get_m_date(): if 'deleted' in data_set and data_set['deleted']: self.settings.pop(i) else: setting.load_from_dict(data_set) setting.set_synced(True) self.update_remote = True i += 1 else: i += 1 else: i += 1 if not found: new_setting = PasswordSetting(domain_name) new_setting.load_from_dict(data_set) new_setting.set_synced(True) self.settings.append(new_setting) for setting in self.settings: found = False for domain_name in self.remote_data.keys(): data_set = self.remote_data[domain_name] if setting.get_domain() == domain_name: found = True if setting.get_m_date() >= datetime.strptime(data_set['mDate'], "%Y-%m-%dT%H:%M:%S"): self.update_remote = True if not found: self.update_remote = True self.store_local_settings(kgk_manager) return self.update_remote
def load_local_settings(self, kgk_manager): """ This loads the saved settings. It is a good idea to call this method the minute you have a kgk manager. :param kgk_manager: kgk manager :type kgk_manager: KgkManager """ encrypted_settings = self.preference_manager.get_settings_data() if len(encrypted_settings) < 40: return settings_crypter = PasswordSettingsManager.get_settings_crypter( kgk_manager) decrypted_settings = settings_crypter.decrypt(encrypted_settings) sync_settings_len = struct.unpack('!I', decrypted_settings[0:4])[0] if sync_settings_len > 0: self.sync_manager.load_binary_sync_settings( decrypted_settings[4:4 + sync_settings_len]) if len(decrypted_settings) < sync_settings_len + 44: raise ValueError("The decrypted settings are too short.") decompressed_settings = Packer.decompress( decrypted_settings[4 + sync_settings_len:]) if len(decompressed_settings) <= 0: raise PermissionError( "Wrong password: The settings could not decompress.") saved_settings = json.loads( str(decompressed_settings, encoding='utf-8')) for domain_name in saved_settings['settings'].keys(): data_set = saved_settings['settings'][domain_name] found = False i = 0 while i < len(self.settings): setting = self.settings[i] if setting.get_domain() == domain_name: found = True if datetime.strptime( data_set['mDate'], "%Y-%m-%dT%H:%M:%S") > setting.get_m_date(): setting.load_from_dict(data_set) setting.set_synced( setting.get_domain() in saved_settings['synced']) i += 1 if not found: new_setting = PasswordSetting(domain_name) new_setting.load_from_dict(data_set) new_setting.set_synced( new_setting.get_domain() in saved_settings['synced']) self.settings.append(new_setting)
def test_load_from_json(self): json_str = "{\"domain\": \"unit.test\", \"username\": \"testilinius\", " +\ "\"notes\": \"interesting note\", \"legacyPassword\": \"rtSr?bS,mi\", " +\ "\"extras\": \"AEIOUaeiou\", \"iterations\": 5341, " +\ "\"passwordTemplate\": \"7;xxxxoxxxxxxxxxxx\", \"salt\": \"ZmFzY2luYXRpbmc=\", " +\ "\"cDate\": \"2001-01-01T02:14:12.000\", \"mDate\": \"2005-01-01T01:14:12.000\"}" s = PasswordSetting(json.loads(json_str)["domain"]) s.load_from_dict(json.loads(json_str)) self.assertEqual("unit.test", s.get_domain()) self.assertEqual("testilinius", s.get_username()) self.assertEqual("interesting note", s.get_notes()) self.assertEqual("rtSr?bS,mi", s.get_legacy_password()) self.assertEqual("AEIOUaeiou", s.get_character_set()) self.assertEqual(5341, s.get_iterations()) self.assertEqual("xxxxoxxxxxxxxxxx", s.get_template()) expected_salt = "fascinating".encode('utf-8') self.assertEqual(len(expected_salt), len(s.get_salt())) for i in range(len(expected_salt)): self.assertEqual(expected_salt[i], s.get_salt()[i]) self.assertEqual("2001-01-01T02:14:12.000", s.get_creation_date()) self.assertEqual("2005-01-01T01:14:12.000", s.get_modification_date())
def load_local_settings(self, kgk_manager): """ This loads the saved settings. It is a good idea to call this method the minute you have a kgk manager. :param kgk_manager: kgk manager :type kgk_manager: KgkManager """ encrypted_settings = self.preference_manager.get_settings_data() if len(encrypted_settings) < 40: return settings_crypter = PasswordSettingsManager.get_settings_crypter(kgk_manager) decrypted_settings = settings_crypter.decrypt(encrypted_settings) sync_settings_len = struct.unpack('!I', decrypted_settings[0:4])[0] if sync_settings_len > 0: self.sync_manager.load_binary_sync_settings(decrypted_settings[4:4+sync_settings_len]) if len(decrypted_settings) < sync_settings_len+44: raise ValueError("The decrypted settings are too short.") decompressed_settings = Packer.decompress(decrypted_settings[4+sync_settings_len:]) if len(decompressed_settings) <= 0: raise PermissionError("Wrong password: The settings could not decompress.") saved_settings = json.loads(str(decompressed_settings, encoding='utf-8')) for domain_name in saved_settings['settings'].keys(): data_set = saved_settings['settings'][domain_name] found = False i = 0 while i < len(self.settings): setting = self.settings[i] if setting.get_domain() == domain_name: found = True if datetime.strptime(data_set['mDate'], "%Y-%m-%dT%H:%M:%S") > setting.get_m_date(): setting.load_from_dict(data_set) setting.set_synced(setting.get_domain() in saved_settings['synced']) i += 1 if not found: new_setting = PasswordSetting(domain_name) new_setting.load_from_dict(data_set) new_setting.set_synced(new_setting.get_domain() in saved_settings['synced']) self.settings.append(new_setting)
def update_from_export_data(self, kgk_manager, blob): """ Call this method to pull settings from the sync server. :param kgk_manager: the kgk manager used for the decryption :type kgk_manager: KgkManager :param blob: the export data :type blob: bytes """ if not blob[0] == 1: print( "Version error: Wrong data format. Could not import anything.") return True settings_crypter = self.get_settings_crypter(kgk_manager) decrypted_settings = settings_crypter.decrypt(blob[145:]) if len(decrypted_settings) <= 0: print("Wrong password.") return False self.remote_data = json.loads( str(Packer.decompress(decrypted_settings), encoding='utf-8')) self.update_remote = False for domain_name in self.remote_data.keys(): data_set = self.remote_data[domain_name] found = False i = 0 while i < len(self.settings): setting = self.settings[i] if setting.get_domain() == domain_name: found = True if 'mDate' in data_set: last_modification_date = data_set['mDate'] else: last_modification_date = data_set['cDate'] if PasswordSetting.convert_ISO_date( last_modification_date) > setting.get_m_date(): if 'deleted' in data_set and data_set['deleted']: self.settings.pop(i) else: setting.load_from_dict(data_set) setting.set_synced(True) self.update_remote = True i += 1 else: i += 1 else: i += 1 if not found: new_setting = PasswordSetting(domain_name) new_setting.load_from_dict(data_set) new_setting.set_synced(True) self.settings.append(new_setting) for setting in self.settings: found = False for domain_name in self.remote_data.keys(): data_set = self.remote_data[domain_name] if setting.get_domain() == domain_name: found = True if 'mDate' in data_set: last_modification_date = data_set['mDate'] else: last_modification_date = data_set['cDate'] if setting.get_m_date( ) >= PasswordSetting.convert_ISO_date( last_modification_date): self.update_remote = True if not found: self.update_remote = True self.store_local_settings(kgk_manager) return self.update_remote