From d61f414754e6cc9565629a2e92bb624c78c32028 Mon Sep 17 00:00:00 2001 From: Simon Briere Date: Fri, 10 May 2024 10:24:54 -0400 Subject: [PATCH] Allowed devices to list the assets for a specific session --- .../DBManagerTeraDeviceAccess.py | 4 +- .../API/device/DeviceQueryAssets.py | 16 +++++-- .../python/opentera/db/models/TeraAsset.py | 12 +++++ .../python/opentera/db/models/TeraSession.py | 6 +-- .../API/device/test_DeviceQueryAssets.py | 45 +++++++++++++++++++ .../API/service/test_ServiceQueryAssets.py | 2 +- .../API/user/test_UserQueryAssets.py | 3 +- 7 files changed, 78 insertions(+), 10 deletions(-) diff --git a/teraserver/python/modules/DatabaseModule/DBManagerTeraDeviceAccess.py b/teraserver/python/modules/DatabaseModule/DBManagerTeraDeviceAccess.py index 43b4c3584..ca6cf0fca 100644 --- a/teraserver/python/modules/DatabaseModule/DBManagerTeraDeviceAccess.py +++ b/teraserver/python/modules/DatabaseModule/DBManagerTeraDeviceAccess.py @@ -78,13 +78,15 @@ def get_accessible_session_types_ids(self): types.append(my_type.id_session_type) return types - def get_accessible_assets(self, id_asset: int = None, uuid_asset: str = None): + def get_accessible_assets(self, id_asset: int = None, uuid_asset: str = None, session_id: int = None): from opentera.db.models.TeraAsset import TeraAsset query = TeraAsset.query.filter(TeraAsset.id_device == self.device.id_device) if id_asset: query = query.filter(TeraAsset.id_asset == id_asset) elif uuid_asset: query = query.filter(TeraAsset.asset_uuid == uuid_asset) + elif session_id: + query = query.filter(TeraAsset.id_session == session_id) return query.all() diff --git a/teraserver/python/modules/FlaskModule/API/device/DeviceQueryAssets.py b/teraserver/python/modules/FlaskModule/API/device/DeviceQueryAssets.py index c8854e34a..c2ebb674d 100644 --- a/teraserver/python/modules/FlaskModule/API/device/DeviceQueryAssets.py +++ b/teraserver/python/modules/FlaskModule/API/device/DeviceQueryAssets.py @@ -1,9 +1,9 @@ -from flask import session, request +from flask import request from flask_restx import Resource, inputs +from flask_babel import gettext from modules.LoginModule.LoginModule import LoginModule, current_device from modules.DatabaseModule.DBManager import DBManager from modules.FlaskModule.FlaskModule import device_api_ns as api -from opentera.db.models.TeraDevice import TeraDevice from opentera.db.models.TeraAsset import TeraAsset from opentera.redis.RedisVars import RedisVars @@ -11,6 +11,7 @@ get_parser = api.parser() get_parser.add_argument('asset_uuid', type=str, help='Asset UUID to query', default=None) get_parser.add_argument('id_asset', type=int, help='Asset ID to query', default=None) +get_parser.add_argument('id_session', type=int, help='Session ID to query assets for', default=None) get_parser.add_argument('with_urls', type=inputs.boolean, help='Also include assets infos and download-upload url') get_parser.add_argument('with_only_token', type=inputs.boolean, help='Only includes the access token. ' 'Will ignore with_urls if specified.') @@ -24,7 +25,7 @@ def __init__(self, _api, *args, **kwargs): self.module = kwargs.get('flaskModule', None) self.test = kwargs.get('test', False) - @api.doc(description='Get device assets based on the ID or, if no parameters, get all assets', + @api.doc(description='Get device assets based specified session or asset ID or, if no parameters, get all assets', responses={200: 'Success', 403: 'Device doesn\'t have access to the specified asset'}) @api.expect(get_parser) @@ -32,7 +33,13 @@ def __init__(self, _api, *args, **kwargs): def get(self): args = get_parser.parse_args() device_access = DBManager.deviceAccess(current_device) - assets = device_access.get_accessible_assets(id_asset=args['id_asset'], uuid_asset=args['asset_uuid']) + + if args['id_session']: + if args['id_session'] not in device_access.get_accessible_sessions_ids(): + return gettext('No access to session'), 403 + + assets = device_access.get_accessible_assets(id_asset=args['id_asset'], uuid_asset=args['asset_uuid'], + session_id=args['id_session']) # Create response servername = self.module.config.server_config['hostname'] @@ -44,6 +51,7 @@ def get(self): if 'X_EXTERNALPORT' in request.headers: port = request.headers['X_EXTERNALPORT'] services_infos = [] + if (args['with_urls'] or args['with_only_token']) and assets: services_infos = {service.service_uuid: service.service_clientendpoint for service in device_access.get_accessible_services()} diff --git a/teraserver/python/opentera/db/models/TeraAsset.py b/teraserver/python/opentera/db/models/TeraAsset.py index 758314f74..42808edf9 100644 --- a/teraserver/python/opentera/db/models/TeraAsset.py +++ b/teraserver/python/opentera/db/models/TeraAsset.py @@ -108,6 +108,18 @@ def create_defaults(test=False): new_asset.id_service = 1 TeraAsset.insert(new_asset) + device_session = TeraSession.get_session_by_name('Séance #9') + for i in range(3): + new_asset = TeraAsset() + new_asset.asset_name = "Device Asset" + new_asset.asset_session = device_session + new_asset.asset_device = asset_device + new_asset.asset_uuid = str(uuid.uuid4()) + new_asset.asset_service_uuid = '00000000-0000-0000-0000-000000000001' + new_asset.asset_type = 'video/mpeg' + new_asset.id_service = 1 + TeraAsset.insert(new_asset) + @staticmethod def get_asset_by_id(asset_id: int, with_deleted: bool = False): return TeraAsset.query.filter_by(id_asset=asset_id).execution_options(include_deleted=with_deleted).first() diff --git a/teraserver/python/opentera/db/models/TeraSession.py b/teraserver/python/opentera/db/models/TeraSession.py index a3b28fdd4..9d002f203 100644 --- a/teraserver/python/opentera/db/models/TeraSession.py +++ b/teraserver/python/opentera/db/models/TeraSession.py @@ -179,7 +179,7 @@ def create_defaults(test=False): base_session.session_creator_device = TeraDevice.get_device_by_id(1) ses_type = random.randint(1, 3) base_session.session_session_type = TeraSessionType.get_session_type_by_id(ses_type) - base_session.session_name = "Séance #" + str(i + 1) + base_session.session_name = "Séance #" + str(i + 1 + 8) base_session.session_start_datetime = datetime.now() - timedelta(days=i) base_session.session_duration = random.randint(60, 4800) # ses_status = random.randint(0, 4) @@ -199,7 +199,7 @@ def create_defaults(test=False): base_session.session_creator_participant = TeraParticipant.get_participant_by_id(1) ses_type = random.randint(1, 3) base_session.session_session_type = TeraSessionType.get_session_type_by_id(ses_type) - base_session.session_name = "Séance #" + str(i + 1) + base_session.session_name = "Séance #" + str(i + 1 + 16) base_session.session_start_datetime = datetime.now() - timedelta(days=i) base_session.session_duration = random.randint(60, 4800) # ses_status = random.randint(0, 4) @@ -227,7 +227,7 @@ def create_defaults(test=False): base_session.session_creator_service = session_service ses_type = random.randint(1, 3) base_session.session_session_type = TeraSessionType.get_session_type_by_id(ses_type) - base_session.session_name = "Séance #" + str(i + 1) + base_session.session_name = "Séance #" + str(i + 1 + 24) base_session.session_start_datetime = datetime.now() - timedelta(days=i) base_session.session_duration = random.randint(60, 4800) # ses_status = random.randint(0, 4) diff --git a/teraserver/python/tests/modules/FlaskModule/API/device/test_DeviceQueryAssets.py b/teraserver/python/tests/modules/FlaskModule/API/device/test_DeviceQueryAssets.py index 1e5a5eb87..429b303f3 100644 --- a/teraserver/python/tests/modules/FlaskModule/API/device/test_DeviceQueryAssets.py +++ b/teraserver/python/tests/modules/FlaskModule/API/device/test_DeviceQueryAssets.py @@ -2,6 +2,7 @@ from BaseDeviceAPITest import BaseDeviceAPITest from opentera.db.models.TeraDevice import TeraDevice from opentera.db.models.TeraAsset import TeraAsset +from opentera.db.models.TeraSession import TeraSession class DeviceQueryAssetsTest(BaseDeviceAPITest): @@ -164,6 +165,50 @@ def test_get_endpoint_with_token_auth_with_forbidden_uuid_asset(self): params=params) self.assertEqual(401, response.status_code) + def test_get_endpoint_with_token_auth_with_forbidden_id_session(self): + with self._flask_app.app_context(): + devices: List[TeraDevice] = TeraDevice.query.all() + + for device in devices: + for session in TeraSession.query.all(): + params = { + 'id_session': session.id_session, + 'with_urls': True + } + + if device.device_token: + if device.device_enabled: + if session.id_creator_device != device.id_device: + response = self._get_with_device_token_auth(self.test_client, token=device.device_token, + params=params) + self.assertEqual(403, response.status_code) + + def test_get_endpoint_with_token_auth_with_session_id(self): + with self._flask_app.app_context(): + devices: List[TeraDevice] = TeraDevice.query.all() + + for device in devices: + for session in TeraSession.query.all(): + params = { + 'id_session': session.id_session, + 'with_urls': True + } + + if device.device_token: + if device.device_enabled: + if session.id_creator_device == device.id_device: + response = self._get_with_device_token_auth(self.test_client, token=device.device_token, + params=params) + self.assertEqual(200, response.status_code) + + assets_ids = [asset.id_asset for asset in + TeraAsset.get_assets_for_session(session.id_session)] + for asset_json in response.json: + self.assertTrue(asset_json['id_asset'] in assets_ids) + self._checkJson(asset_json, minimal=False) + assets_ids.remove(asset_json['id_asset']) + self.assertFalse(assets_ids) + def test_get_endpoint_with_token_auth_with_token_only(self): with self._flask_app.app_context(): devices: List[TeraDevice] = TeraDevice.query.all() diff --git a/teraserver/python/tests/modules/FlaskModule/API/service/test_ServiceQueryAssets.py b/teraserver/python/tests/modules/FlaskModule/API/service/test_ServiceQueryAssets.py index f737457bf..45367e339 100644 --- a/teraserver/python/tests/modules/FlaskModule/API/service/test_ServiceQueryAssets.py +++ b/teraserver/python/tests/modules/FlaskModule/API/service/test_ServiceQueryAssets.py @@ -162,7 +162,7 @@ def test_get_endpoint_query_asset(self): def test_get_endpoint_query_asset_no_access(self): with self._flask_app.app_context(): - params = {'id_asset': 5, 'with_urls': True} + params = {'id_asset': 15, 'with_urls': True} response = self._get_with_service_token_auth(client=self.test_client, token=self.service_token, params=params, endpoint=self.test_endpoint) self.assertEqual(response.status_code, 200) diff --git a/teraserver/python/tests/modules/FlaskModule/API/user/test_UserQueryAssets.py b/teraserver/python/tests/modules/FlaskModule/API/user/test_UserQueryAssets.py index b548d9007..8f16ce9b7 100644 --- a/teraserver/python/tests/modules/FlaskModule/API/user/test_UserQueryAssets.py +++ b/teraserver/python/tests/modules/FlaskModule/API/user/test_UserQueryAssets.py @@ -1,4 +1,5 @@ from BaseUserAPITest import BaseUserAPITest +from opentera.db.models.TeraAsset import TeraAsset class UserQueryAssetsTest(BaseUserAPITest): @@ -72,7 +73,7 @@ def test_query_device_assets_as_admin(self): response = self._get_with_user_http_auth(self.test_client, username='admin', password='admin', params=params) self.assertEqual(200, response.status_code) - self.assertEqual(len(response.json), 1) + self.assertEqual(len(response.json), len(TeraAsset.get_assets_for_device(1))) for data_item in response.json: self._checkJson(json_data=data_item)