def test_get_encrypted_field(self):
     fields = [
         EncryptedDeviceField('test_name', 'integer', 123),
         EncryptedDeviceField('test2', 'string', 'something')
     ]
     device = Device('test', [], fields, 'type')
     self.assertEqual(device.get_encrypted_field('test_name'), 123)
 def test_update_from_json_with_encrypted_fields(self):
     plaintext_fields = [
         DeviceField('test_name', 'integer', 123),
         DeviceField('test2', 'string', 'something')
     ]
     encrypted_fields = [
         EncryptedDeviceField('test3', 'boolean', True),
         EncryptedDeviceField('test4', 'string', 'something else')
     ]
     new_encrypted_fields = [
         EncryptedDeviceField('new_test3', 'boolean', True),
         EncryptedDeviceField('new_test4', 'string', 'something else')
     ]
     encrypted_field_json1 = new_encrypted_fields[0].as_json()
     encrypted_field_json2 = new_encrypted_fields[1].as_json()
     encrypted_field_json1['value'] = True
     encrypted_field_json2['value'] = 'something_else'
     device = Device('test',
                     plaintext_fields,
                     encrypted_fields,
                     'type',
                     description='desc')
     device.update_from_json(
         {'fields': [encrypted_field_json1, encrypted_field_json2]})
     self.assertEqual(device.name, 'test')
     self.assertEqual(device.type, 'type')
     self.assertEqual(device.description, 'desc')
     self.assertSetEqual({field.name
                          for field in device.plaintext_fields}, set())
     print({field.name for field in device.encrypted_fields})
     self.assertSetEqual({field.name
                          for field in device.encrypted_fields},
                         {'new_test3', 'new_test4'})
 def test_update_from_json_with_plaintext_fields(self):
     plaintext_fields = [
         DeviceField('test_name', 'integer', 123),
         DeviceField('test2', 'string', 'something')
     ]
     encrypted_fields = [
         EncryptedDeviceField('test3', 'boolean', True),
         EncryptedDeviceField('test4', 'string', 'something else')
     ]
     new_plaintext_fields = [
         DeviceField('new_test_name', 'integer', 451),
         DeviceField('new_test2', 'string', 'changed')
     ]
     device = Device('test',
                     plaintext_fields,
                     encrypted_fields,
                     'type',
                     description='desc')
     device.update_from_json(
         {'fields': [field.as_json() for field in new_plaintext_fields]})
     self.assertEqual(device.name, 'test')
     self.assertEqual(device.type, 'type')
     self.assertEqual(device.description, 'desc')
     self.assertSetEqual({field.name
                          for field in device.plaintext_fields},
                         {'new_test_name', 'new_test2'})
     print({field.name for field in device.encrypted_fields})
     self.assertSetEqual({field.name
                          for field in device.encrypted_fields}, set())
 def test_get_encrypted_field_dne(self):
     fields = [
         EncryptedDeviceField('test_name', 'integer', 123),
         EncryptedDeviceField('test2', 'string', 'something')
     ]
     device = Device('test', [], fields, 'type')
     with self.assertRaises(UnknownDeviceField):
         device.get_encrypted_field('invalid')
Example #5
0
 def setUp(self):
     self.device1 = Device('test1', [], [], 'type1')
     self.device2 = Device('test2', [], [], 'type1')
     self.device3 = Device('test3', [], [], 'type2')
     self.device4 = Device('test4', [], [], 'type2')
     self.all_devices = [
         self.device1, self.device2, self.device3, self.device4
     ]
Example #6
0
 def test_update_from_json_type_only(self):
     plaintext_fields = [DeviceField('test_name', 'integer', 123), DeviceField('test2', 'string', 'something')]
     encrypted_fields = [EncryptedDeviceField('test3', 'boolean', True),
                         EncryptedDeviceField('test4', 'string', 'something else')]
     device = Device('test', plaintext_fields, encrypted_fields, 'type', description='desc')
     device.update_from_json({'type': 'new_type'})
     self.assertConstructionIsCorrect(device, 'test', plaintext_fields, encrypted_fields, 'new_type',
                                      description='desc')
 def test_get_plaintext_fields_plaintext_only(self):
     fields = [
         DeviceField('test_name', 'integer', 123),
         DeviceField('test2', 'string', 'something')
     ]
     device = Device('test', fields, [], 'type')
     self.assertDictEqual(device.get_plaintext_fields(), {
         'test_name': 123,
         'test2': 'something'
     })
Example #8
0
    def setUp(self):
        self.test_app_name = 'TestApp'
        self.device1 = Device('test', [], [], 'type1')
        plaintext_fields = [DeviceField('test_name', 'integer', 123), DeviceField('test2', 'string', 'something')]
        encrypted_fields = [EncryptedDeviceField('test3', 'boolean', True),
                            EncryptedDeviceField('test4', 'string', 'something else')]
        self.device2 = Device('test2', plaintext_fields, encrypted_fields, 'type2')
        self.db_app = App(name=self.test_app_name, devices=[self.device1, self.device2])

        device_db.session.add(self.db_app)
        device_db.session.commit()
Example #9
0
 def test_update_device_app_dne(self):
     device1 = Device('test', [], [], 'type')
     device2 = Device('test2', [], [], 'type')
     device_db.session.add(device2)
     device_db.session.add(device1)
     device_db.session.commit()
     data = {'id': device1.id, 'name': 'renamed', 'app_name': 'Invalid'}
     self.post_with_status_check('/api/devices',
                                 headers=self.headers,
                                 data=json.dumps(data),
                                 status_code=INVALID_INPUT_ERROR,
                                 content_type='application/json')
Example #10
0
 def test_as_json(self):
     plaintext_fields = [DeviceField('test_name', 'integer', 123), DeviceField('test2', 'string', 'something')]
     encrypted_fields = [EncryptedDeviceField('test3', 'boolean', True),
                         EncryptedDeviceField('test4', 'string', 'something else')]
     device = Device('test', plaintext_fields, encrypted_fields, 'type', description='desc')
     device_json = device.as_json()
     self.assertEqual(device_json['name'], 'test')
     self.assertEqual(device_json['type'], 'type')
     self.assertEqual(device_json['description'], 'desc')
     plaintext_fields.extend(encrypted_fields)
     for field in plaintext_fields:
         self.assertIn(field.as_json(), device_json['fields'])
Example #11
0
    def setUp(self):
        self.app_name = 'TestApp'
        self.app = server.flaskserver.app.test_client(self)
        self.app.testing = True

        self.context = server.flaskserver.app.test_request_context()
        self.context.push()

        self.device1 = Device('test1', [], [], 'type1')
        self.device2 = Device('test2', [], [], 'type1')
        self.device3 = Device('test3', [], [], 'type2')
        self.device4 = Device('test4', [], [], 'type2')
Example #12
0
    def test_update_device_fields(self):
        device1 = Device('test', [], [], 'type')
        device2 = Device('test2', [], [], 'type')
        app = App(name=self.test_app_name, devices=[device1, device2])
        device_db.session.add(app)
        device_db.session.commit()

        fields_json = [{
            'name': 'test_name',
            'type': 'integer',
            'encrypted': False
        }, {
            'name': 'test2',
            'type': 'string',
            'encrypted': False
        }]
        core.config.config.app_apis = {
            self.test_app_name: {
                'devices': {
                    'test_type': {
                        'fields': fields_json
                    }
                }
            }
        }

        fields_json = [{
            'name': 'test_name',
            'value': 123
        }, {
            'name': 'test2',
            'value': 'something'
        }]

        data = {
            'id': device1.id,
            'name': 'renamed',
            'app_name': self.test_app_name,
            'type': 'test_type',
            'fields': fields_json
        }
        self.post_with_status_check('/api/devices',
                                    headers=self.headers,
                                    data=json.dumps(data),
                                    status_code=SUCCESS,
                                    content_type='application/json')

        self.assertEqual(device1.name, 'renamed')
        self.assertEqual(
            device1.get_plaintext_fields(),
            {field['name']: field['value']
             for field in fields_json})
Example #13
0
 def test_delete_device(self):
     device1 = Device('test', [], [], 'type')
     device2 = Device('test2', [], [], 'type')
     device_db.session.add(device2)
     device_db.session.add(device1)
     device_db.session.commit()
     device1_id = device1.id
     self.delete_with_status_check('/api/devices/{}'.format(device1_id),
                                   headers=self.headers,
                                   status_code=SUCCESS)
     self.assertIsNone(
         device_db.session.query(Device).filter(
             Device.id == device1_id).first())
Example #14
0
 def test_read_device(self):
     device1 = Device('test', [], [], 'type')
     device2 = Device('test2', [], [], 'type')
     device_db.session.add(device2)
     device_db.session.add(device1)
     device_db.session.commit()
     response = self.get_with_status_check('/api/devices/{}'.format(
         device1.id),
                                           headers=self.headers,
                                           status_code=SUCCESS)
     expected_device1 = device1.as_json()
     expected_device1['app_name'] = ''
     self.assertEqual(response, expected_device1)
 def test_get_plaintext_fields_with_encrypted(self):
     encrypted_fields = [
         EncryptedDeviceField('test_name', 'integer', 123),
         EncryptedDeviceField('test2', 'string', 'something')
     ]
     plaintext_fields = [
         DeviceField('test3', 'boolean', True),
         DeviceField('test4', 'string', 'something else')
     ]
     device = Device('test', plaintext_fields, encrypted_fields, 'type')
     self.assertDictEqual(device.get_plaintext_fields(), {
         'test3': True,
         'test4': 'something else'
     })
 def test_init_with_plaintext(self):
     fields = [
         DeviceField('test_name', 'integer', 123),
         DeviceField('test2', 'string', 'something')
     ]
     device = Device('test', fields, [], 'type')
     self.assertConstructionIsCorrect(device, 'test', fields, [], 'type')
 def test_init_with_encrypted(self):
     fields = [
         EncryptedDeviceField('test_name', 'integer', 123),
         EncryptedDeviceField('test2', 'string', 'something')
     ]
     device = Device('test', [], fields, 'type')
     self.assertConstructionIsCorrect(device, 'test', [], fields, 'type')
Example #18
0
    def test_from_json(self):
        plaintext_fields = [DeviceField('test_name', 'integer', 123), DeviceField('test2', 'string', 'something')]
        encrypted_field1 = EncryptedDeviceField('test3', 'boolean', True)
        encrypted_field2 = EncryptedDeviceField('test4', 'string', 'something else')
        encrypted_fields = [encrypted_field1, encrypted_field2]

        encrypted_field_json1 = encrypted_field1.as_json()
        encrypted_field_json2 = encrypted_field2.as_json()
        encrypted_field_json1_with_value = dict(encrypted_field_json1)
        encrypted_field_json2_with_value = dict(encrypted_field_json2)
        encrypted_field_json1_with_value['value'] = True
        encrypted_field_json2_with_value['value'] = 'something_else'

        fields_json = [field.as_json() for field in plaintext_fields]
        fields_json.extend([encrypted_field_json1_with_value, encrypted_field_json2_with_value])

        device = Device.from_json({'name': 'test', 'fields': fields_json, 'type': 'something', 'description': 'desc'})

        expected_plaintext_fields_as_json = [field.as_json() for field in plaintext_fields]
        expected_encrypted_fields_as_json = [field.as_json() for field in encrypted_fields]

        self.assertEqual(device.name, 'test')
        self.assertEqual(device.type, 'something')
        self.assertEqual(device.description, 'desc')
        for field in device.plaintext_fields:
            self.assertIn(field.as_json(), expected_plaintext_fields_as_json)
        for field in device.encrypted_fields:
            self.assertIn(field.as_json(), expected_encrypted_fields_as_json)
Example #19
0
    def __func():
        data = request.get_json()
        filename = data[
            'filename'] if 'filename' in data else core.config.paths.default_appdevice_export_path
        try:
            with open(filename, 'r') as devices_file:
                read_file = devices_file.read()
                read_file = read_file.replace('\n', '')
                apps = json.loads(read_file)
        except (OSError, IOError) as e:
            current_app.logger.error(
                'Error importing devices from {0}: {1}'.format(filename, e))
            return {"error": "Error reading file."}, IO_ERROR
        for app in apps:
            for device in apps[app]:
                if device_db.session.query(Device).filter(
                        Device.name == device['name']).first() is not None:
                    current_app.logger.error('Could not import device {0}. '
                                             'Device already exists.'.format(
                                                 device['name']))
                    continue
                fields = {
                    field['name']: field['value']
                    for field in device['fields']
                }
                device_type = device['type']
                try:
                    device_api = get_app_device_api(app, device_type)
                    device_fields_api = device_api['fields']
                    validate_device_fields(device_fields_api, fields,
                                           device_type, app)
                except UnknownDevice:
                    current_app.logger.error(
                        'Cannot import device for app {0}, type {1}. '
                        'Type does not exist'.format(app, device_type))
                    continue
                except InvalidArgument as e:
                    current_app.logger.error(
                        'Cannot import device for app {0}, type {1}. '
                        'Invalid input'.format(app, device_type,
                                               format_exception_message(e)))
                    continue
                else:
                    fields = device['fields']
                    add_configuration_keys_to_device_json(
                        fields, device_fields_api)
                    app = device_db.session.query(App).filter(
                        App.name == app).first()
                    if app is None:
                        current_app.logger.error(
                            'SEVERE: App defined in api does not have corresponding entry in database. '
                            'Cannot import device')
                        continue
                    device_obj = Device.from_json(device)
                    app.add_device(device_obj)
                    device_db.session.add(device_obj)
                    device_db.session.commit()

        current_app.logger.debug('Imported devices from {0}'.format(filename))
        return {}, SUCCESS
Example #20
0
    def test_update_device_invalid_fields(self):
        device1 = Device('test', [], [], 'type')
        device2 = Device('test2', [], [], 'type')
        app = App(name=self.test_app_name, devices=[device1, device2])
        device_db.session.add(app)
        device_db.session.commit()

        fields_json = [{
            'name': 'test_name',
            'type': 'integer',
            'encrypted': False
        }, {
            'name': 'test2',
            'type': 'string',
            'encrypted': False
        }]
        core.config.config.app_apis = {
            self.test_app_name: {
                'devices': {
                    'test_type': {
                        'fields': fields_json
                    }
                }
            }
        }

        fields_json = [{
            'name': 'test_name',
            'value': 'invalid'
        }, {
            'name': 'test2',
            'value': 'something'
        }]

        data = {
            'id': device1.id,
            'name': 'renamed',
            'app_name': self.test_app_name,
            'type': 'test_type',
            'fields': fields_json
        }
        self.post_with_status_check('/api/devices',
                                    headers=self.headers,
                                    data=json.dumps(data),
                                    status_code=INVALID_INPUT_ERROR,
                                    content_type='application/json')
Example #21
0
class TestAppDatabase(unittest.TestCase):
    def setUp(self):
        self.device1 = Device('test1', [], [], 'type1')
        self.device2 = Device('test2', [], [], 'type1')
        self.device3 = Device('test3', [], [], 'type2')
        self.device4 = Device('test4', [], [], 'type2')
        self.all_devices = [
            self.device1, self.device2, self.device3, self.device4
        ]

    def assertConstructionIsCorrect(self, app, name, devices):
        self.assertEqual(app.name, name)
        self.assertSetEqual({device.name for device in app.devices}, devices)

    def test_init_name_only(self):
        app = App('test')
        self.assertConstructionIsCorrect(app, 'test', set())

    def test_init_with_devices(self):
        app = App('test', devices=self.all_devices)
        self.assertConstructionIsCorrect(app, 'test',
                                         {'test1', 'test2', 'test3', 'test4'})

    def test_get_device(self):
        app = App('test', devices=self.all_devices)
        self.assertEqual(
            app.get_device('test2').as_json(), self.device2.as_json())

    def test_get_device_invalid(self):
        app = App('test', devices=self.all_devices)
        self.assertIsNone(app.get_device('invalid'))

    def test_as_json(self):
        app = App('test', devices=self.all_devices)
        app_json = app.as_json(with_devices=True)
        self.assertEqual(app_json['name'], 'test')
        expected_devices_json = [device.as_json() for device in app.devices]
        for device in app_json['devices']:
            self.assertIn(device, expected_devices_json)

    def test_add_device(self):
        app = App('test', devices=[self.device1, self.device2, self.device3])
        app.add_device(self.device4)
        self.assertSetEqual({device.name
                             for device in app.devices},
                            {'test1', 'test2', 'test3', 'test4'})

    def test_add_device_already_exists(self):
        app = App('test', devices=[self.device1, self.device2, self.device3])
        app.add_device(self.device3)
        self.assertSetEqual({device.name
                             for device in app.devices},
                            {'test1', 'test2', 'test3'})
 def test_init_with_both_plaintext_and_encrypted(self):
     plaintext_fields = [
         DeviceField('test_name', 'integer', 123),
         DeviceField('test2', 'string', 'something')
     ]
     encrypted_fields = [
         EncryptedDeviceField('test3', 'boolean', True),
         EncryptedDeviceField('test4', 'string', 'something else')
     ]
     device = Device('test', plaintext_fields, encrypted_fields, 'type')
     self.assertConstructionIsCorrect(device, 'test', plaintext_fields,
                                      encrypted_fields, 'type')
Example #23
0
    def __func():
        add_device_json = request.get_json()
        if device_db.session.query(Device).filter(
                Device.name == add_device_json['name']).first() is not None:
            current_app.logger.error('Could not create device {0}. '
                                     'Device already exists.'.format(
                                         add_device_json['name']))
            return {"error": "Device already exists."}, OBJECT_EXISTS_ERROR

        fields = {
            field['name']: field['value']
            for field in add_device_json['fields']
        }
        app = add_device_json['app_name']
        device_type = add_device_json['type']
        try:
            device_api = get_app_device_api(app, device_type)
            device_fields_api = device_api['fields']
            validate_device_fields(device_fields_api, fields, device_type, app)
        except UnknownApp:
            current_app.logger.error(
                'Cannot create device for app {0}, type {1}. '
                'App does not exist'.format(app, device_type))
            return {'error': 'Unknown app'}, INVALID_INPUT_ERROR
        except UnknownDevice:
            current_app.logger.error(
                'Cannot create device for app {0}, type {1}. '
                'Type does not exist'.format(app, device_type))
            return {'error': 'Unknown device type'}, INVALID_INPUT_ERROR
        except InvalidArgument as e:
            current_app.logger.error(
                'Cannot create device for app {0}, type {1}. '
                'Invalid input'.format(app, device_type,
                                       format_exception_message(e)))
            return {'error': 'Invalid device fields'}, INVALID_INPUT_ERROR
        else:
            fields = add_device_json['fields']
            add_configuration_keys_to_device_json(fields, device_fields_api)
            app = device_db.session.query(App).filter(App.name == app).first()
            if app is None:
                current_app.logger.error(
                    'SEVERE: App defined in api does not have corresponding entry in database. '
                    'Cannot add device')
                return {'error': 'Unknown app'}, INVALID_INPUT_ERROR
            device = Device.from_json(add_device_json)
            app.add_device(device)
            device_db.session.add(device)
            device_db.session.commit()
            device_json = get_device_json_with_app_name(device)
            # remove_configuration_keys_from_device_json(device_json)
            return device_json, OBJECT_CREATED
Example #24
0
 def test_create_device_device_already_exists(self):
     device1 = Device('test', [], [], 'type', description='description')
     device_db.session.add(device1)
     device_db.session.commit()
     device_json = {
         'app_name': 'test',
         'name': 'test',
         'type': 'some_type',
         'fields': []
     }
     self.put_with_status_check('/api/devices',
                                headers=self.headers,
                                data=json.dumps(device_json),
                                status_code=OBJECT_EXISTS_ERROR,
                                content_type='application/json')
Example #25
0
    def test_construct_fields_from_json(self):
        plaintext_fields = [DeviceField('test_name', 'integer', 123), DeviceField('test2', 'string', 'something')]
        encrypted_field1 = EncryptedDeviceField('test3', 'boolean', True)
        encrypted_field2 = EncryptedDeviceField('test4', 'string', 'something else')

        encrypted_field_json1 = encrypted_field1.as_json()
        encrypted_field_json2 = encrypted_field2.as_json()
        encrypted_field_json1['value'] = True
        encrypted_field_json2['value'] = 'something_else'
        fields_json = [field.as_json() for field in plaintext_fields]
        fields_json.extend([encrypted_field_json1, encrypted_field_json2])

        plaintext_fields, encrypted_fields = Device._construct_fields_from_json(fields_json)
        self.assertSetEqual({field.name for field in plaintext_fields}, {'test_name', 'test2'})
        self.assertSetEqual({field.name for field in encrypted_fields}, {'test3', 'test4'})
Example #26
0
 def test_read_all_devices(self):
     device1 = Device('test', [], [], 'type')
     device2 = Device('test2', [], [], 'type')
     app = App(name=self.test_app_name, devices=[device1, device2])
     device_db.session.add(app)
     device_db.session.commit()
     response = self.get_with_status_check('/api/devices',
                                           headers=self.headers,
                                           status_code=SUCCESS)
     expected_device1 = device1.as_json()
     expected_device1['app_name'] = 'TestApp'
     expected_device2 = device2.as_json()
     expected_device2['app_name'] = 'TestApp'
     self.assertIn(expected_device1, response)
     self.assertIn(expected_device2, response)
Example #27
0
class TestAppBase(TestCase):
    def setUp(self):
        self.test_app_name = 'TestApp'
        self.device1 = Device('test', [], [], 'type1')
        plaintext_fields = [
            DeviceField('test_name', 'integer', 123),
            DeviceField('test2', 'string', 'something')
        ]
        encrypted_fields = [
            EncryptedDeviceField('test3', 'boolean', True),
            EncryptedDeviceField('test4', 'string', 'something else')
        ]
        self.device2 = Device('test2', plaintext_fields, encrypted_fields,
                              'type2')
        self.db_app = App(name=self.test_app_name,
                          devices=[self.device1, self.device2])

        device_db.session.add(self.db_app)
        device_db.session.commit()

    def tearDown(self):
        device_db.session.rollback()
        for device in device_db.session.query(Device).all():
            device_db.session.delete(device)
        for field in device_db.session.query(DeviceField).all():
            device_db.session.delete(field)
        for field in device_db.session.query(EncryptedDeviceField).all():
            device_db.session.delete(field)
        app = device_db.session.query(App).filter(
            App.name == self.test_app_name).first()
        if app is not None:
            device_db.session.delete(app)
        device_db.session.commit()

    def test_app_is_tagged(self):
        self.assertTrue(getattr(AppBase, '_is_walkoff_app', False))

    def test_init(self):
        app = AppBase(self.test_app_name, 'test')
        self.assertEqual(app.app, self.db_app)
        self.assertEqual(app.device, self.device1)
        self.assertDictEqual(app.device_fields, {})
        self.assertEqual(app.device_type, 'type1')
        self.assertEqual(app.device_id, 'test')

    def test_init_with_fields(self):
        app = AppBase(self.test_app_name, 'test2')
        self.assertEqual(app.app, self.db_app)
        self.assertEqual(app.device, self.device2)
        self.assertDictEqual(app.device_fields,
                             self.device2.get_plaintext_fields())
        self.assertEqual(app.device_type, 'type2')
        self.assertEqual(app.device_id, 'test2')

    def test_init_with_invalid_app(self):
        app = AppBase('Invalid', 'test2')
        self.assertIsNone(app.app)
        self.assertIsNone(app.device)
        self.assertDictEqual(app.device_fields, {})
        self.assertEqual(app.device_type, None)
        self.assertEqual(app.device_id, 'test2')

    def test_init_with_invalid_device(self):
        app = AppBase(self.test_app_name, 'invalid')
        self.assertEqual(app.app, self.db_app)
        self.assertIsNone(app.device)
        self.assertDictEqual(app.device_fields, {})
        self.assertEqual(app.device_type, None)
        self.assertEqual(app.device_id, 'invalid')

    def test_get_all_devices(self):
        app = AppBase(self.test_app_name, 'test2')
        devices = app.get_all_devices()
        self.assertIn(self.device1, devices)
        self.assertIn(self.device2, devices)

    def test_get_all_devices_invalid_app(self):
        app = AppBase('Invalid', 'test2')
        self.assertListEqual(app.get_all_devices(), [])
 def test_get_plaintext_fields_no_fields(self):
     device = Device('test', [], [], 'type')
     self.assertDictEqual(device.get_plaintext_fields(), {})
 def test_init_name_only(self):
     device = Device('test', [], [], 'type')
     self.assertConstructionIsCorrect(device, 'test', [], [], 'type')
 def test_init_with_description(self):
     device = Device('test', [], [], 'type', description='desc')
     self.assertConstructionIsCorrect(device,
                                      'test', [], [],
                                      'type',
                                      description='desc')