Пример #1
0
 def setUp(self):
     self.packer = Packer()
     self.inst = 1
     self.reg1 = 2
     self.mode1 = 3
     self.reg2 = 4
     self.mode2 = 5
 def test_get_export_data(self):
     settings = {
         'settings': {
             'unit.test': {
                 'domain': 'unit.test',
                 'length': 11,
                 'iterations': 5000,
                 'notes': 'Nice note!',
                 'salt': 'cGVwcGVy',
                 'usedCharacters': 'abcdefghijklmnopqrstuvwxyzABCDEFGHJKLMNPQRTUVWXYZ0123456789' +
                                   '#!"§$%&/()[]{}=-_+*<>;:.',
                 'cDate': '2011-02-12T11:07:31',
                 'mDate': '2011-02-12T11:07:32'
             },
             'some.domain': {
                 'domain': 'some.domain',
                 'length': 4,
                 'iterations': 4096,
                 'salt': 'cGVwcGVy',
                 'usedCharacters': '6478593021',
                 'cDate': '2013-06-17T04:03:41',
                 'mDate': '2014-08-02T10:37:12'
             }
         },
         'synced': []
     }
     crypter = Crypter('xyz')
     f = open(os.path.expanduser('~/.ctSESAM_test.pws'), 'bw')
     f.write(crypter.encrypt(Packer.compress(json.dumps(settings).encode('utf-8'))))
     f.close()
     self.manager.load_settings_from_file('xyz')
     self.assertEqual(
         b64encode(b'\x00' + crypter.encrypt(Packer.compress(json.dumps(settings['settings']).encode('utf-8')))),
         self.manager.get_export_data('xyz')
     )
Пример #3
0
    def load_settings_from_file(self, password):
        """
        This loads the saved settings. It is a good idea to call this method the minute you have a password.

        :param str password:
        """
        if os.path.isfile(self.settings_file):
            file = open(self.settings_file, 'br')
            data = file.read()
            crypter = Crypter(data[:32], password)
            saved_settings = json.loads(
                str(Packer.decompress(crypter.decrypt(data[32:])),
                    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)
            file.close()
Пример #4
0
 def test_load_settings_from_file(self):
     settings = {
         'settings': {
             'unit.test': {
                 'domain': 'unit.test',
                 'length': 11,
                 'iterations': 5000,
                 'notes': 'Nice note!',
                 'cDate': '2011-02-12T11:07:31',
                 'mDate': '2011-02-12T11:07:32'
             },
             'some.domain': {
                 'domain': 'some.domain',
                 'length': 4,
                 'usedCharacters': '6478593021',
                 'cDate': '2013-06-17T04:03:41',
                 'mDate': '2014-08-02T10:37:12'
             }
         },
         'synced': []
     }
     salt = os.urandom(32)
     crypter = Crypter(salt, 'xyz')
     f = open(os.path.expanduser('~/.ctSESAM_test.pws'), 'bw')
     f.write(salt + struct.pack('!I', 0) + crypter.encrypt(Packer.compress(json.dumps(settings).encode('utf-8'))))
     f.close()
     self.manager.load_settings_from_file('xyz')
     self.assertIn('unit.test', self.manager.get_domain_list())
     self.assertIn('some.domain', self.manager.get_domain_list())
     self.assertEqual(11, self.manager.get_setting('unit.test').get_length())
     self.assertEqual(5000, self.manager.get_setting('unit.test').get_iterations())
     self.assertEqual('Nice note!', self.manager.get_setting('unit.test').get_notes())
     self.assertEqual(4, self.manager.get_setting('some.domain').get_length())
     self.assertEqual('6478593021', self.manager.get_setting('some.domain').get_character_set())
    def get_export_data(self, password, salt=None):
        """
        This gives you a base64 encoded string of encrypted settings data (the blob).

        :param password: masterpassword
        :type password: str
        :param salt: salt for the encryption: This is for testing only! Do not set it normally!
        :type salt: bytes
        :return: encrypted settings blob
        :rtype: str
        """
        settings_list = self.get_settings_as_dict()['settings']
        if self.remote_data:
            for domain_name in self.remote_data.keys():
                data_set = self.remote_data[domain_name]
                if 'deleted' in data_set and data_set['deleted']:
                    for i, setting_dict in enumerate(settings_list):
                        if setting_dict['domain'] == setting_dict[
                                'domain'] and datetime.strptime(
                                    data_set['mDate'],
                                    "%Y-%m-%dT%H:%M:%S") > datetime.strptime(
                                        setting_dict['mDate'],
                                        "%Y-%m-%dT%H:%M:%S"):
                            settings_list[i] = data_set
                if domain_name not in settings_list.keys():
                    settings_list[domain_name] = {
                        'mDate': datetime.now(),
                        'deleted': True
                    }
        if not salt:
            salt = os.urandom(32)
        crypter = Crypter(salt, password)
        return b64encode(
            b'\x00' + salt +
            crypter.encrypt(Packer.compress(json.dumps(settings_list))))
    def get_export_data(self, password):
        """
        This gives you a base64 encoded string of encrypted settings data (the blob).

        :param str password:
        :return: encrypted settings blob
        :rtype: str
        """
        settings_list = self.get_settings_as_dict()['settings']
        if self.remote_data:
            for domain_name in self.remote_data.keys():
                data_set = self.remote_data[domain_name]
                if 'deleted' in data_set and data_set['deleted']:
                    for i, setting_dict in enumerate(settings_list):
                        if setting_dict['domain'] == setting_dict['domain'] and datetime.strptime(
                                data_set['mDate'], "%Y-%m-%dT%H:%M:%S") > datetime.strptime(
                                setting_dict['mDate'], "%Y-%m-%dT%H:%M:%S"):
                            settings_list[i] = data_set
                if domain_name not in settings_list.keys():
                    settings_list[domain_name] = {
                        'mDate': datetime.now(),
                        'deleted': True
                    }
        salt = os.urandom(32)
        crypter = Crypter(salt, password)
        return b64encode(b'\x00' + salt + crypter.encrypt(Packer.compress(json.dumps(settings_list))))
    def save_settings_to_file(self, password):
        """
        This actually saves the settings to a file on the disk. The file is encrypted so you need to supply the
        password.

        :param password: masterpassword
        :type password: str
        """
        salt = os.urandom(32)
        crypter = Crypter(salt, password)
        file = open(self.settings_file, 'bw')
        encrypted_sync_settings = crypter.encrypt(
            self.sync_manager.get_binary_sync_settings())
        file.write(
            salt + struct.pack('!I', len(encrypted_sync_settings)) +
            encrypted_sync_settings + crypter.encrypt(
                Packer.compress(json.dumps(self.get_settings_as_dict()))))
        file.close()
        try:
            import win32con
            import win32api
            win32api.SetFileAttributes(self.settings_file,
                                       win32con.FILE_ATTRIBUTE_HIDDEN)
        except ImportError:
            pass
    def load_settings_from_file(self, password):
        """
        This loads the saved settings. It is a good idea to call this method the minute you have a password.

        :param str password:
        """
        if os.path.isfile(self.settings_file):
            file = open(self.settings_file, 'br')
            data = file.read()
            crypter = Crypter(data[:32], password)
            saved_settings = json.loads(str(Packer.decompress(crypter.decrypt(data[32:])), 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)
            file.close()
    def update_from_sync(self, password):
        """
        Call this method to pull settings from the sync server.

        :param password: the masterpassword
        :type password: str
        """
        pull_successful, data = self.sync_manager.pull()
        if not pull_successful:
            print("Sync failed: No connection to the server.")
            return False
        if not len(data) > 0:
            return False
        binary_data = b64decode(data)
        data_version = binary_data[:1]
        if data_version == b'\x00':
            encryption_salt = binary_data[1:33]
            encrypted_data = binary_data[33:]
            crypter = Crypter(encryption_salt, password)
            self.remote_data = json.loads(
                str(Packer.decompress(crypter.decrypt(encrypted_data)), 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
        else:
            print("Unknown data format version! Could not update.")
Пример #10
0
    def update_from_export_data(self, password, data):
        """
        This takes a base64 encoded string of encrypted settings (a blob) and updates the internal list of settings.

        :param str password: the masterpassword
        :param str data: base64 encoded data
        """
        binary_data = b64decode(data)
        data_version = binary_data[:1]
        if data_version == b'\x00':
            encryption_salt = binary_data[1:33]
            encrypted_data = binary_data[:33]
            crypter = Crypter(encryption_salt, password)
            self.remote_data = json.loads(
                str(Packer.decompress(crypter.decrypt(encrypted_data)),
                    encoding='utf-8'))
            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)
                                i += 1
                        else:
                            i += 1
                            update_remote = True
                    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"):
                            update_remote = True
                if not found:
                    update_remote = True
            return update_remote
        else:
            print("Unknown data format version! Could not update.")
            return False
Пример #11
0
 def test_get_export_data(self):
     settings = {
         'settings': {
             'unit.test': {
                 'domain':
                 'unit.test',
                 'length':
                 11,
                 'iterations':
                 5000,
                 'notes':
                 'Nice note!',
                 'salt':
                 'cGVwcGVy',
                 'usedCharacters':
                 'abcdefghijklmnopqrstuvwxyzABCDEFGHJKLMNPQRTUVWXYZ0123456789'
                 + '#!"§$%&/()[]{}=-_+*<>;:.',
                 'cDate':
                 '2011-02-12T11:07:31',
                 'mDate':
                 '2011-02-12T11:07:32'
             },
             'some.domain': {
                 'domain': 'some.domain',
                 'length': 4,
                 'iterations': 4096,
                 'salt': 'cGVwcGVy',
                 'usedCharacters': '6478593021',
                 'cDate': '2013-06-17T04:03:41',
                 'mDate': '2014-08-02T10:37:12'
             }
         },
         'synced': []
     }
     crypter = Crypter('xyz')
     f = open(os.path.expanduser('~/.ctSESAM_test.pws'), 'bw')
     f.write(
         crypter.encrypt(
             Packer.compress(json.dumps(settings).encode('utf-8'))))
     f.close()
     self.manager.load_settings_from_file('xyz')
     self.assertEqual(
         b64encode(b'\x00' + crypter.encrypt(
             Packer.compress(
                 json.dumps(settings['settings']).encode('utf-8')))),
         self.manager.get_export_data('xyz'))
Пример #12
0
class Test_Packer(unittest.TestCase):
    def setUp(self):
        self.packer = Packer()
        self.inst = 1
        self.reg1 = 2
        self.mode1 = 3
        self.reg2 = 4
        self.mode2 = 5

    def test_pack_inst(self):
        """ test that a new instruction is encoded """
        code = self.packer.pack(self.inst, self.reg1, self.mode1, self.reg2,
                                self.mode2)
        self.assertEquals(code, 5349)

    def test_unpack_inst(self):
        self.assertEquals(
            self.packer.unpack(5349),
            [self.inst, self.reg1, self.mode1, self.reg2, self.mode2])
    def update_from_export_data(self, password, data):
        """
        This takes a base64 encoded string of encrypted settings (a blob) and updates the internal list of settings.

        :param str password: the masterpassword
        :param str data: base64 encoded data
        """
        binary_data = b64decode(data)
        data_version = binary_data[:1]
        if data_version == b'\x00':
            encryption_salt = binary_data[1:33]
            encrypted_data = binary_data[:33]
            crypter = Crypter(encryption_salt, password)
            self.remote_data = json.loads(str(Packer.decompress(crypter.decrypt(encrypted_data)), encoding='utf-8'))
            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)
                                i += 1
                        else:
                            i += 1
                            update_remote = True
                    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"):
                            update_remote = True
                if not found:
                    update_remote = True
            return update_remote
        else:
            print("Unknown data format version! Could not update.")
            return False
 def test_save_settings_to_file(self):
     self.manager.get_setting('abc.de')
     new_setting = PasswordSetting('hugo.com')
     new_setting.set_length(12)
     self.manager.save_setting(new_setting)
     self.manager.save_settings_to_file('xyz')
     f = open(os.path.expanduser('~/.ctSESAM_test.pws'), 'br')
     crypter = Crypter('xyz')
     data = json.loads(Packer.decompress(crypter.decrypt(f.read())).decode('utf8'))
     f.close()
     self.assertEqual('abc.de', data['settings']['abc.de']['domain'])
     self.assertEqual(10, data['settings']['abc.de']['length'])
     self.assertEqual('hugo.com', data['settings']['hugo.com']['domain'])
     self.assertEqual(12, data['settings']['hugo.com']['length'])
Пример #15
0
 def test_save_settings_to_file(self):
     self.manager.get_setting('abc.de')
     new_setting = PasswordSetting('hugo.com')
     new_setting.set_length(12)
     self.manager.set_setting(new_setting)
     self.manager.save_settings_to_file('xyz')
     with open(os.path.expanduser('~/.ctSESAM_test.pws'), 'br') as f:
         data = f.read()
     crypter = Crypter(data[:32], 'xyz')
     sync_settings_len = struct.unpack('!I', data[32:36])[0]
     data = json.loads(Packer.decompress(crypter.decrypt(data[36+sync_settings_len:])).decode('utf8'))
     self.assertEqual('abc.de', data['settings']['abc.de']['domain'])
     self.assertEqual(10, data['settings']['abc.de']['length'])
     self.assertEqual('hugo.com', data['settings']['hugo.com']['domain'])
     self.assertEqual(12, data['settings']['hugo.com']['length'])
Пример #16
0
 def test_save_settings_to_file(self):
     self.manager.get_setting('abc.de')
     new_setting = PasswordSetting('hugo.com')
     new_setting.set_length(12)
     self.manager.save_setting(new_setting)
     self.manager.save_settings_to_file('xyz')
     f = open(os.path.expanduser('~/.ctSESAM_test.pws'), 'br')
     crypter = Crypter('xyz')
     data = json.loads(
         Packer.decompress(crypter.decrypt(f.read())).decode('utf8'))
     f.close()
     self.assertEqual('abc.de', data['settings']['abc.de']['domain'])
     self.assertEqual(10, data['settings']['abc.de']['length'])
     self.assertEqual('hugo.com', data['settings']['hugo.com']['domain'])
     self.assertEqual(12, data['settings']['hugo.com']['length'])
Пример #17
0
    def get_binary_sync_settings(self):
        """
        returns packed sync settings

        :return: binary settings
        :rtype: bytes
        """
        if self.sync:
            return Packer.compress(json.dumps({
                "server-address": self.server_address,
                "username": self.username,
                "password": self.password,
                "certificate": self.certificate
            }).encode('utf-8'))
        else:
            return b''
    def load_settings_from_file(self,
                                password,
                                omit_sync_settings_questions=False):
        """
        This loads the saved settings. It is a good idea to call this method the minute you have a password.

        :param str password: masterpassword
        :param bool omit_sync_settings_questions: do not ask for questions? (Defalut: False)
        :type password: str
        """
        if os.path.isfile(self.settings_file):
            file = open(self.settings_file, 'br')
            data = file.read()
            crypter = Crypter(data[:32], password)
            sync_settings_len = struct.unpack('!I', data[32:36])[0]
            if sync_settings_len > 0:
                self.sync_manager.load_binary_sync_settings(
                    crypter.decrypt(data[36:36 + sync_settings_len]))
            saved_settings = json.loads(
                str(Packer.decompress(
                    crypter.decrypt(data[36 + sync_settings_len:])),
                    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)
            file.close()
        else:
            if not omit_sync_settings_questions:
                self.sync_manager.ask_for_sync_settings()
    def save_settings_to_file(self, password):
        """
        This actually saves the settings to a file on the disk. The file is encrypted so you need to supply the
        password.

        :param str password:
        """
        salt = os.urandom(32)
        crypter = Crypter(salt, password)
        file = open(self.settings_file, 'bw')
        file.write(salt + crypter.encrypt(Packer.compress(json.dumps(self.get_settings_as_dict()))))
        file.close()
        try:
            import win32con
            import win32api
            win32api.SetFileAttributes(self.settings_file, win32con.FILE_ATTRIBUTE_HIDDEN)
        except ImportError:
            pass
Пример #20
0
    def save_settings_to_file(self, password):
        """
        This actually saves the settings to a file on the disk. The file is encrypted so you need to supply the
        password.

        :param str password:
        """
        salt = os.urandom(32)
        crypter = Crypter(salt, password)
        file = open(self.settings_file, 'bw')
        file.write(salt + crypter.encrypt(
            Packer.compress(json.dumps(self.get_settings_as_dict()))))
        file.close()
        try:
            import win32con
            import win32api
            win32api.SetFileAttributes(self.settings_file,
                                       win32con.FILE_ATTRIBUTE_HIDDEN)
        except ImportError:
            pass
Пример #21
0
    def pull(self):
        """
        Returns some mock data tor the sync test.

        :return: base64 mock data blob
        :rtype: (bool, str)
        """
        remote_data = {
            'unit.test': {
                'domain': 'unit.test',
                'length': 12,
                'iterations': 5001,
                'notes': 'another note!',
                'salt': 'cGVwcGVy',
                'usedCharacters': 'abcdefghijklmnopqrstuvwxyzABCDEFGHJKLMNPQRTUVWXYZ0123456789',
                'cDate': '2011-02-12T11:07:31',
                'mDate': '2013-07-12T14:46:11'
            },
            'some.domain': {
                'domain': 'some.domain',
                'length': 4,
                'iterations': 4097,
                'salt': 'cGVwcGVy',
                'usedCharacters': '6478593021',
                'cDate': '2013-06-17T04:03:41',
                'mDate': '2014-08-02T10:37:11'
            },
            'third.domain': {
                'domain': 'third.domain',
                'length': 10,
                'iterations': 4098,
                'salt': 'cGVwcGVy',
                'usedCharacters': 'aeiou',
                'cDate': '2013-06-17T04:03:41',
                'mDate': '2014-08-02T10:37:11'
            }
        }
        salt = os.urandom(32)
        crypter = Crypter(salt, 'xyz')
        return True, str(b64encode(b'\x00' + salt + crypter.encrypt(
            Packer.compress(json.dumps(remote_data).encode('utf-8')))), encoding='utf-8')
Пример #22
0
 def test_update_from_sync(self):
     settings = {
         'settings': {
             'unit.test': {
                 'domain': 'unit.test',
                 'length': 11,
                 'iterations': 5000,
                 'notes': 'Nice note!',
                 'salt': 'cGVwcGVy',
                 'usedCharacters': 'abcdefghijklmnopqrstuvwxyzABCDEFGHJKLMNPQRTUVWXYZ0123456789' +
                                   '#!"§$%&/()[]{}=-_+*<>;:.',
                 'cDate': '2011-02-12T11:07:31',
                 'mDate': '2011-02-12T11:07:32'
             },
             'some.domain': {
                 'domain': 'some.domain',
                 'length': 4,
                 'iterations': 4096,
                 'salt': 'cGVwcGVy',
                 'usedCharacters': '6478593021',
                 'cDate': '2013-06-17T04:03:41',
                 'mDate': '2014-08-02T10:37:12'
             }
         },
         'synced': []
     }
     salt = os.urandom(32)
     crypter = Crypter(salt, 'xyz')
     f = open(os.path.expanduser('~/.ctSESAM_test.pws'), 'bw')
     f.write(salt + struct.pack('!I', 0) + crypter.encrypt(
         Packer.compress(json.dumps(settings).encode('utf-8'))))
     f.close()
     self.manager.load_settings_from_file('xyz')
     self.manager.sync_manager = MockSyncManager()
     self.manager.update_from_sync('xyz')
     self.assertIn('unit.test', self.manager.get_domain_list())
     self.assertIn('some.domain', self.manager.get_domain_list())
     self.assertIn('third.domain', self.manager.get_domain_list())
     self.assertEqual(5001, self.manager.get_setting('unit.test').get_iterations())
     self.assertEqual(4096, self.manager.get_setting('some.domain').get_iterations())
     self.assertEqual(4098, self.manager.get_setting('third.domain').get_iterations())
    def save_settings_to_file(self, password):
        """
        This actually saves the settings to a file on the disk. The file is encrypted so you need to supply the
        password.

        :param password: masterpassword
        :type password: str
        """
        salt = os.urandom(32)
        crypter = Crypter(salt, password)
        file = open(self.settings_file, 'bw')
        encrypted_sync_settings = crypter.encrypt(self.sync_manager.get_binary_sync_settings())
        file.write(salt + struct.pack('!I', len(encrypted_sync_settings)) + encrypted_sync_settings +
                   crypter.encrypt(Packer.compress(json.dumps(self.get_settings_as_dict()))))
        file.close()
        try:
            import win32con
            import win32api
            win32api.SetFileAttributes(self.settings_file, win32con.FILE_ATTRIBUTE_HIDDEN)
        except ImportError:
            pass
    def load_settings_from_file(self, password, omit_sync_settings_questions=False):
        """
        This loads the saved settings. It is a good idea to call this method the minute you have a password.

        :param str password: masterpassword
        :param bool omit_sync_settings_questions: do not ask for questions? (Defalut: False)
        :type password: str
        """
        if os.path.isfile(self.settings_file):
            file = open(self.settings_file, 'br')
            data = file.read()
            crypter = Crypter(data[:32], password)
            sync_settings_len = struct.unpack('!I', data[32:36])[0]
            if sync_settings_len > 0:
                self.sync_manager.load_binary_sync_settings(crypter.decrypt(data[36:36+sync_settings_len]))
            saved_settings = json.loads(str(Packer.decompress(crypter.decrypt(data[36+sync_settings_len:])),
                                            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)
            file.close()
        else:
            if not omit_sync_settings_questions:
                self.sync_manager.ask_for_sync_settings()
Пример #25
0
    def load_binary_sync_settings(self, data):
        """
        loads sync settings

        :param bytes data: packed json data of sync settings
        """
        settings_dict = json.loads(str(Packer.decompress(data), encoding='utf-8'))
        if "server-address" in settings_dict and \
           "username" in settings_dict and \
           "password" in settings_dict and \
           "certificate" in settings_dict:
            self.server_address = settings_dict["server-address"]
            self.username = settings_dict["username"]
            self.password = settings_dict["password"]
            self.certificate = settings_dict["certificate"]
            if self.certificate_file:
                self.certificate_file.close()
            self.certificate_file = NamedTemporaryFile()
            self.certificate_file.write(self.certificate.encode('utf-8'))
            self.certificate_file.seek(0)
            self.create_sync()
        else:
            print("Sync settings konnten nicht geladen werden.")
Пример #26
0
 def test_decompress(self):
     self.assertEqual(
         b'Some packable information',
         Packer.decompress(b64decode("AAAAGXjaC87PTVUoSEzOTkzKSVXIzEvLL8pNLMnMzwMAedUJrg==")))
Пример #27
0
 def test_compress(self):
     packed_data = Packer.compress("Some packable information")
     self.assertEqual(b'AAAAGXjaC87PTVUoSEzOTkzKSVXIzEvLL8pNLMnMzwMAedUJrg==', b64encode(packed_data))
Пример #28
0
    def buildFloor(self):
        """
        Creates a Cell for each location on the floor and creates objects that will initially start
        on the Floor. Initial Point locations for the warehouse Floor are set here.

        Goes through every Point location within Floor and creates a new Cell for it. If there is
        an object that has a matching Point location as the new Cell, that object is added to the
        Cell as well

        Creates Picker, Packer, Robots, Chargers, as well as the DockArea, BeltArea, and ShelveAreas

        Current values are for a 10x10 floor layout

        Called during initialization
        """
        # Set Locations for objects and create instances
        picker_location = Point(1, 7)
        picker = Picker(picker_location)

        packer_location = Point(1, 4)
        packer = Packer(packer_location)

        shipping_dock = DockArea(
            [Point(0, 0), Point(1, 0),
             Point(0, 1), Point(1, 1)])
        shipping_dock_corner = Point(0, 1)

        chargers = [
            Charger(Point(2, 9)),
            Charger(Point(3, 9)),
            Charger(Point(4, 9)),
            Charger(Point(5, 9)),
            Charger(Point(6, 9))
        ]

        robots = [
            Robot('A', Point(2, 9)),
            Robot('B', Point(3, 9)),
            Robot('C', Point(4, 9)),
            Robot('D', Point(5, 9)),
            Robot('E', Point(6, 9))
        ]

        shelf_areas = [ShelfArea(Point(5, 1), 5), ShelfArea(Point(5, 5), 5)]

        belt_length = picker_location.y - shipping_dock_corner.y
        belt_areas = [
            BeltArea(self, Point(picker_location.x - 1, picker_location.y),
                     belt_length)
        ]

        # Once everything has been created, give them to Floor
        self.picker = picker
        self.packer = packer
        self.shipping_dock = shipping_dock
        self.shipping_dock_corner = shipping_dock_corner
        self.chargers = chargers
        self.robots = robots
        self.shelf_areas = shelf_areas
        self.belt_areas = belt_areas

        # For each Point location in the warehouse, create a new Cell and if there is an object
        # that has a matching Point location, add that object to the Cell
        for x in range(0, self.warehouse_width):
            for y in range(0, self.warehouse_depth):
                point = Point(x, y)
                # Create Cell for point location
                cell = Cell(point)

                # Check if Point location matches Picker location
                if picker.getPickLocation(
                ).x == point.x and picker.getPickLocation().y == point.y:
                    cell.setContents(self.picker)

                # Check if Point location matched Packer location
                if self.packer.getLocation(
                ).x == point.x and packer.getLocation().y == point.y:
                    cell.setContents(self.packer)

                # Check if Point location matched Dock Area location
                for p in self.shipping_dock.points:
                    if p.x == point.x and p.y == point.y:
                        cell.setContents(self.shipping_dock)

                # Check the Chargers to see if any match Point location
                for charger in self.chargers:
                    if charger.location.x == point.x and charger.location.y == point.y:
                        cell.setContents(charger)

                # Check the Robots to see if any match Point location
                for robot in self.robots:
                    if robot.location.x == point.x and robot.location.y == point.y:
                        cell.setContents(robot)
                        robot.setCell(cell)

                # Check the Shelf Areas for Shelves that match Point location
                # Cell are already created within Shelf Area so use those Cells if matching location
                for s in self.shelf_areas:
                    if s.hasWithin(point):
                        cell = s.getCell(point)
                        assert cell is not None

                # Check the Belt Areas for Belts that match Point location
                # Cell are already created within Belt Area so use those Cells if matching location
                for b in self.belt_areas:
                    if b.isWithin(point):
                        cell = b.getCell(point)
                        assert cell is not None

                # Adds to the dictionary as {Point: Cell}
                self.all_points.update({str(point): cell})
    def update_from_sync(self, password):
        """
        Call this method to pull settings from the sync server.

        :param password: the masterpassword
        :type password: str
        """
        pull_successful, data = self.sync_manager.pull()
        if not pull_successful:
            print("Sync failed: No connection to the server.")
            return False
        if not len(data) > 0:
            return False
        binary_data = b64decode(data)
        data_version = binary_data[:1]
        if data_version == b'\x00':
            encryption_salt = binary_data[1:33]
            encrypted_data = binary_data[33:]
            crypter = Crypter(encryption_salt, password)
            self.remote_data = json.loads(
                str(Packer.decompress(crypter.decrypt(encrypted_data)),
                    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
        else:
            print("Unknown data format version! Could not update.")