From 1b84ac901842c707768d804881ade54317d23563 Mon Sep 17 00:00:00 2001 From: Philipp Kilian Date: Tue, 28 May 2024 11:12:48 +0200 Subject: [PATCH] api: check meeting id length and reorder __init__ functions --- b3lb/rest/b3lb/constants.py | 1 + b3lb/rest/classes/api.py | 103 +++++++++++++++++++----------------- b3lb/rest/models.py | 7 ++- 3 files changed, 58 insertions(+), 53 deletions(-) diff --git a/b3lb/rest/b3lb/constants.py b/b3lb/rest/b3lb/constants.py index 287b2a9..44b6c95 100644 --- a/b3lb/rest/b3lb/constants.py +++ b/b3lb/rest/b3lb/constants.py @@ -24,6 +24,7 @@ RETURN_STRING_GET_RECORDING_TEXT_TRACKS_NOTHING_FOUND_JSON = '{"response":{"returncode":"FAILED","messageKey":"noRecordings","message":"No recording found"}}' RETURN_STRING_GET_RECORDING_NO_RECORDINGS = '\r\nSUCCESS\r\n\r\nnoRecordings\r\nThere are no recordings for the meeting(s).\r\n' RETURN_STRING_MISSING_MEETING_ID = '\r\nFAILED\r\nmissingParamMeetingID\r\nYou must specify a meeting ID for the meeting.\r\n' +RETURN_STRING_MISSING_MEETING_ID_TO_LONG = '\r\nFAILED\r\nMeeting id must be between 2 and 100 characters\r\n' RETURN_STRING_MISSING_RECORD_ID = '\r\nFAILED\r\nmissingParamRecordID\r\nYou must specify one or more a record IDs.\r\n' RETURN_STRING_MISSING_RECORD_PUBLISH = '\r\nFAILED\r\nmissingParamPublish\r\nYou must specify one a publish value true or false.\r\n' RETURN_STRING_RECORD_PUBLISHED = '\r\nSUCCESS\r\n{}\r\n' diff --git a/b3lb/rest/classes/api.py b/b3lb/rest/classes/api.py index a6c8479..a68c317 100644 --- a/b3lb/rest/classes/api.py +++ b/b3lb/rest/classes/api.py @@ -34,7 +34,7 @@ from rest.b3lb.metrics import incr_metric, update_create_metrics from rest.b3lb.parameters import ALLOW_START_STOP_RECORDING, AUTO_START_RECORDING, BLOCK, LOGO, OVERRIDE, PARAMETERS_CREATE, PARAMETERS_JOIN, RECORD, SET, USERDATA_BBB_CUSTOM_STYLE_URL from rest.b3lb.utils import get_checksum -from rest.models import is_meeting_name_length_fine, ClusterGroupRelation, Meeting, Metric, Node, Parameter, Record, RecordSet, Secret, SecretMeetingList, SecretMetricsList, Stats +from rest.models import check_str_length, ClusterGroupRelation, Meeting, Metric, Node, Parameter, Record, RecordSet, Secret, SecretMeetingList, SecretMetricsList, Stats from typing import Any, Dict, List, Literal, Union from uuid import UUID from urllib.parse import urlencode @@ -49,6 +49,7 @@ class ClientB3lbRequest: request: HttpRequest parameters: Dict[str, Any] meeting_id: str + meeting_name: str body: Union[str, bytes] endpoint: str checksum: str @@ -60,6 +61,40 @@ class ClientB3lbRequest: ENDPOINTS_PASS_THROUGH: List[str] ENDPOINTS: Dict[str, Any] + ## INIT ## + def __init__(self, request: HttpRequest, endpoint: str): + self.has_assets = False + self.request = request + self.endpoint = endpoint + self.parameters = {} + self.body = request.body + for parameter in request.GET.keys(): + self.parameters[parameter] = request.GET.get(parameter) + + self.meeting_id = self.parameters.get("meetingID", "") + self.meeting_name = self.parameters.get("name", "") + self.checksum = self.parameters.pop("checksum", "") + self.stats_token = self.request.headers.get("Authorization", "") + + self.secret = None + self.node = None + self.state = self.parameters.get("state", "") + self.ENDPOINTS_PASS_THROUGH = ["end", "insertDocument", "setConfigXML", "getMeetingInfo"] + self.ENDPOINTS = { + "": self.version, + "create": self.create, + "join": self.join, + "isMeetingRunning": self.is_meeting_running, + "getMeetings": self.get_meetings, + "getRecordingTextTracks": self.get_recording_text_tracks, + "getRecordings": self.get_recordings, + "deleteRecordings": self.delete_recordings, + "publishRecordings": self.publish_recordings, + "updateRecordings": self.update_recordings, + "b3lb_metrics": self.metrics, + "b3lb_stats": self.stats + } + #### Class functions async def _check_post_headers(self) -> Dict[str, Any]: if not self.has_assets: @@ -81,7 +116,10 @@ async def create(self) -> HttpResponse: if not self.meeting_id: return HttpResponse(cst.RETURN_STRING_MISSING_MEETING_ID, content_type=cst.CONTENT_TYPE) - if not is_meeting_name_length_fine(self.parameters.get("name", "")): + if not check_str_length(self.meeting_id, cst.MEETING_ID_LENGTH): + return HttpResponse(cst.RETURN_STRING_MISSING_MEETING_ID_TO_LONG, content_type=cst.CONTENT_TYPE) + + if not check_str_length(self.meeting_name, cst.MEETING_NAME_LENGTH): return HttpResponse(cst.RETURN_STRING_WRONG_MEETING_NAME_LENGTH, content_type=cst.CONTENT_TYPE) if not await self.is_meeting(): @@ -449,7 +487,7 @@ def is_node_free(self) -> bool: ## Getter Routines ## def get_meeting_defaults(self) -> Dict[str, Any]: - return {"id": self.meeting_id, "secret": self.secret, "node": self.node, "room_name": self.parameters.get("name", "Unknown"), "end_callback_url": self.parameters.get("meta_endCallbackUrl", "")} + return {"id": self.meeting_id, "secret": self.secret, "node": self.node, "room_name": self.meeting_name, "end_callback_url": self.parameters.get("meta_endCallbackUrl", "")} def get_node_endpoint_url(self) -> str: parameter_str = "" @@ -540,39 +578,6 @@ async def set_secret_by_slug_and_slug_id(self, slug: str, sub_id: int): except ObjectDoesNotExist: pass - ## INIT ## - def __init__(self, request: HttpRequest, endpoint: str): - self.has_assets = False - self.request = request - self.endpoint = endpoint - self.parameters = {} - self.body = request.body - for parameter in request.GET.keys(): - self.parameters[parameter] = request.GET.get(parameter) - - self.meeting_id = self.parameters.get("meetingID", "") - self.checksum = self.parameters.pop("checksum", "") - self.stats_token = self.request.headers.get("Authorization", "") - - self.secret = None - self.node = None - self.state = self.parameters.get("state", "") - self.ENDPOINTS_PASS_THROUGH = ["end", "insertDocument", "setConfigXML", "getMeetingInfo"] - self.ENDPOINTS = { - "": self.version, - "create": self.create, - "join": self.join, - "isMeetingRunning": self.is_meeting_running, - "getMeetings": self.get_meetings, - "getRecordingTextTracks": self.get_recording_text_tracks, - "getRecordings": self.get_recordings, - "deleteRecordings": self.delete_recordings, - "publishRecordings": self.publish_recordings, - "updateRecordings": self.update_recordings, - "b3lb_metrics": self.metrics, - "b3lb_stats": self.stats - } - class NodeB3lbRequest: """ @@ -587,6 +592,19 @@ class NodeB3lbRequest: nonce: str recording_marks: str + def __init__(self, request: HttpRequest, backend: str, endpoint: str): + self.request = request + self.meeting = None + self.backend = backend + self.endpoint = endpoint + self.meeting_id = self.request.GET.get("meetingID", "") + self.nonce = self.request.GET.get("nonce", "") + self.recording_marks = self.request.GET.get("recordingmarks", "false") + self.BACKENDS = { + "meeting/end": {"methods": ["GET"], "function": self.end_meeting}, + "record/upload": {"methods": ["POST"], "function": self.upload_record} + } + def is_allowed_endpoint(self) -> bool: if self.full_endpoint() in self.BACKENDS: return True @@ -697,16 +715,3 @@ async def upload_record(self) -> HttpResponse: await sync_to_async(record_set.save)() return HttpResponse(status=204) - - def __init__(self, request: HttpRequest, backend: str, endpoint: str): - self.request = request - self.meeting = None - self.backend = backend - self.endpoint = endpoint - self.meeting_id = self.request.GET.get("meetingID", "") - self.nonce = self.request.GET.get("nonce", "") - self.recording_marks = self.request.GET.get("recordingmarks", "false") - self.BACKENDS = { - "meeting/end": {"methods": ["GET"], "function": self.end_meeting}, - "record/upload": {"methods": ["POST"], "function": self.upload_record} - } diff --git a/b3lb/rest/models.py b/b3lb/rest/models.py index 21f8854..94ccccf 100644 --- a/b3lb/rest/models.py +++ b/b3lb/rest/models.py @@ -46,6 +46,9 @@ # # FUNCTIONS # +def check_str_length(value: str, max_length: int) -> bool: + return 2 <= len(value) < max_length + def get_nonce(): return get_random_string(cst.NONCE_LENGTH, cst.NONCE_CHAR_POOL) @@ -65,10 +68,6 @@ def get_storage(): return used_storage -def is_meeting_name_length_fine(name: str) -> bool: - return 2 <= len(name) < cst.MEETING_NAME_LENGTH - - # # ADMIN ACTIONS #