def validate_request(self): if self.username is None: raise SvcException("invalid event request, username is missing") if self.text is None: raise SvcException("invalid event request, message text is missing") if self.timeout is None: raise SvcException("invalid event request, message timeout is missing") if not SvcUtils.validate_username(self.username): error_msg = SvcUtils.error_message( "invalid message request, recipient username is not valid", {"username": self.username} ) raise ValueError(error_msg) if len(self.text) > SvcConfig.message_length: error_msg = SvcUtils.error_message( "invalid message request, message length is greater than maximum ({0})".format( SvcConfig.message_length ), {"text": self.text}, ) raise ValueError(error_msg) if not type(self.timeout) == int: error_msg = SvcUtils.error_message( "invalid message request, message timeout is not valid", {"timeout": self.timeout} ) raise ValueError(error_msg) if self.timeout > SvcConfig.max_message_timeout or self.timeout < 1: error_msg = SvcUtils.error_message( "invalid message request, message timeout must be between 1 and ({0})".format( SvcConfig.max_message_timeout ), {"timeout": self.timeout}, ) raise ValueError(error_msg)
def validate_request(self): if self.username is None: raise SvcException('invalid event request, username is missing') if self.text is None: raise SvcException( 'invalid event request, message text is missing') if self.timeout is None: raise SvcException( 'invalid event request, message timeout is missing') if not SvcUtils.validate_username(self.username): error_msg = SvcUtils.error_message( 'invalid message request, recipient username is not valid', {'username': self.username}) raise ValueError(error_msg) if len(self.text) > SvcConfig.message_length: error_msg = SvcUtils.error_message( 'invalid message request, message length is greater than maximum ({0})' .format(SvcConfig.message_length), {'text': self.text}) raise ValueError(error_msg) if not type(self.timeout) == int: error_msg = SvcUtils.error_message( 'invalid message request, message timeout is not valid', {'timeout': self.timeout}) raise ValueError(error_msg) if self.timeout > SvcConfig.max_message_timeout or self.timeout < 1: error_msg = SvcUtils.error_message( 'invalid message request, message timeout must be between 1 and ({0})' .format(SvcConfig.max_message_timeout), {'timeout': self.timeout}) raise ValueError(error_msg)
def save_message(self, request): if request is None or request == '': raise SvcException('invalid message request, no valid request was submitted') request_dict = SvcUtils.deserialize_object(request) try: message_request_obj = SvcUtils.get_obj_from_dict(request_dict, 'MessageRequest') timeout = message_request_obj.timeout if 'timeout' in request_dict.keys() else None message_request = MessageRequest(message_request_obj.username, message_request_obj.text, timeout) except: raise SvcException(SvcUtils.error_message('invalid message request, request is not valid', {'request': request_dict})) # first, validate the request message_request.validate_request() # create message expiration timestamp message_expiration_utc = datetime.utcnow() + timedelta(seconds=message_request.timeout) # check if user already exists user_id = self.data_access.get_user_id_by_username(message_request.username) if user_id == 0: user_id = self.data_access.save_user(message_request.username) if user_id == 0: raise Exception(SvcUtils.error_message('could not create user', {'username': message_request.username})) message_id = self.data_access.save_message(user_id, message_request.text, message_expiration_utc) if message_id == 0: raise Exception(SvcUtils.error_message('could not create message', {'username': message_request.username, 'message': message_request.text})) return MessageId(message_id)
def validate_request(self): EventRequest.validate_request(self) if self.dstIp is not None: # first, validation IPv4 format if SvcUtils.regex_validate(SvcConfig.ipv4_validation_regex) is False: # second, if not IPv4 compliant, validate for IPv6 format if SvcUtils.regex_validate(SvcConfig.ipv6_validation_regex) is False: error_msg = SvcUtils.error_message('Invalid event request, destination IP is invalid', {'destination IP': self.dstIp}) raise ValueError(error_msg) if SvcUtils.regex_validate(SvcConfig.uri_validation_regex, self.externalUrl) is False: error_msg = SvcUtils.error_message('Invalid event request, external URL is invalid', {'external URL': self.externalUrl}) raise ValueError(error_msg)
def get_message_by_id(self, message_id): if message_id < 1: raise SvcException('invalid event request, message ID must be greater than 0') message = self.data_access.get_message_by_id(message_id) if message is None: raise KeyError(SvcUtils.error_message('message not found', {'id': message_id})) user = self.data_access.get_user_by_id(message.user_id) if user is None: raise Exception(SvcUtils.error_message('message not found', {'id': message_id})) return MessageDetailDto(user.username, message.text, message.expiration_date)
def get_messages_by_username(self, username): messages = [] statement = ''' SELECT msg.id, msg.[user_id], [text], expiration_date_utc, msg.created_date_utc FROM [message] msg WITH (NOLOCK) JOIN [user] usr WITH (NOLOCK) ON usr.[id] = msg.[user_id] WHERE usr.username = ?''' try: result = self.engine.execute(statement, username).fetchall() if result is not None: for row in result: messages.append( Message(id=row.id, user_id=row.user_id, text=row.text, expiration_date_utc=row.expiration_date_utc, created_date_utc=row.created_date_utc)) except Exception as ex: raise Exception( SvcUtils.error_message('message lookup failed', { 'id': username, 'error': ex.message })) return messages
def create_connection(self): try: connection = pyodbc.connect(self.connection_str) return connection except Exception as ex: raise Exception( SvcUtils.error_message('database connection failed', {'error': ex.message}))
def validate_request(self): if self.customerKey is None: raise Exception('Invalid event request, customer key is missing') if self.deviceId is None: raise Exception('Invalid event request, device ID is missing') if self.deviceVersion is None: raise Exception('Invalid event request, device version is missing') if self.dstUrl is None: raise Exception('Invalid event request, destination URL is missing') if self.eventTime is None: raise Exception('Invalid event request, event time (UTC) is missing') if SvcUtils.regex_validate(SvcConfig.uuid_validation_regex, self.customerKey) is False: error_msg = SvcUtils.error_message('Invalid event request, customer key is invalid', {'customer key': self.customerKey}) raise ValueError(error_msg) if SvcUtils.regex_validate(SvcConfig.uri_validation_regex, self.dstUrl) is False: error_msg = SvcUtils.error_message('Invalid event request, destination URL is invalid', {'destination URL': self.dstUrl}) raise ValueError(error_msg) if SvcUtils.validate_timestamp(self.eventTime)is False: error_msg = SvcUtils.error_message('Invalid event request, event time is invalid', {'event time': self.eventTime}) raise ValueError(error_msg)
def process_event(self, request): if request is None or request == '': raise SvcException('invalid event request, no valid request was submitted') request_dict = SvcUtils.deserialize_object(request) try: event_request_obj = SvcUtils.get_obj_from_dict(request_dict, 'EventRequest') if 'disableDstSafeguards' in request_dict.keys(): event_request = EventExtendedRequest(event_request_obj.customerKey, event_request_obj.deviceId, event_request_obj.deviceVersion, event_request_obj.dstUrl, event_request_obj.eventTime, event_request_obj.disableDstSafeguards, event_request_obj.dstIp, event_request_obj.eventSeverity, event_request_obj.eventType, event_request_obj.eventDescription, event_request_obj.fileName, event_request_obj.externalUrl, event_request_obj.src) else: event_request = EventRequest(event_request_obj.customerKey, event_request_obj.deviceId, event_request_obj.deviceVersion, event_request_obj.dstUrl, event_request_obj.eventTime) except: raise SvcException(SvcUtils.error_message('invalid event request, request is not valid', {'request': request_dict})) # validate request event_request.validate_request() # forward request to security platform if type(event_request) == EventRequest: request_body = Event(alert_time=datetime.utcnow(), device_id=event_request.device_id, device_version=event_request.device_version, dst_domain=SvcUtils.get_domain_from_url(event_request.dstUrl), dst_url=event_request.dst_url, event_time=event_request.event_time, protocol_version=SvcConfig.protocol_version, provider_name=SvcConfig.provider_name) else: request_body = EventExtended(alert_time=datetime.utcnow(), device_id=event_request.device_id, device_version=event_request.device_version, dst_domain=SvcUtils.get_domain_from_url(event_request.dstUrl), dst_url=event_request.dst_url, event_time=event_request.event_time, protocol_version=SvcConfig.protocol_version, provider_name=SvcConfig.provider_name, event_request.disable_dst_safeguards, event_request.dst_ip, event_request.event_severity, event_request.event_type, event_request.event_description, event_request.event_hash, event_request.file_name, event_request.file_hash, event_request.external_url, event_request.src) http_headers = {'Content-Type':'application/json'} url_params = {'customerKey': event_request.customerKey} http_response = requests.post(SvcConfig.sp_integration_url, headers=http_headers, params=url_params, data=request_body) # handle non-200 responses if http_response.status_code >= status.HTTP_300_MULTIPLE_CHOICES: if http_response.status_code == status.HTTP_403_FORBIDDEN: raise SvcException(http_response.content) if http_response.status_code == status.HTTP_403_FORBIDDEN: raise SvcException('unauthorized access attempt') elif http_response.status_code == status.HTTP_404_NOT_FOUND: raise KeyError(SvcUtils.error_message('security platform client not found', {'customer key': event_request.customerKey})) else: raise Exception()
def get_message_by_username(self, username): if username is None or username == '': raise SvcException('invalid event request, no username was submitted') messages = self.data_access.get_messages_by_username(username) if len(messages) == 0: raise KeyError(SvcUtils.error_message('message(s) not found for user', {'username': username})) messages_dto = [] for message in messages: messages_dto.append(MessageDto(message.id, message.text)) return messages_dto
def get_user_id_by_username(self, username): user_id = 0 statement = 'SELECT id FROM [user] WITH (NOLOCK) WHERE username = ?' try: result = self.engine.execute(statement, [username]).fetchone() if result is not None: user_id = result.id except Exception as ex: raise Exception( SvcUtils.error_message('user lookup failed', { 'username': username, 'error': ex.message })) return user_id
def get_user_by_id(self, user_id): user = None statement = 'SELECT id, username, created_date_utc FROM [user] WITH (NOLOCK) WHERE id = ?' try: result = self.engine.execute(statement, [user_id]).fetchone() if result is not None: user = User(id=result.id, username=result.username, created_date_utc=result.created_date_utc) except Exception as ex: raise Exception( SvcUtils.error_message('user lookup failed', { 'user ID': user_id, 'error': ex.message })) return user
def save_user(self, username): user_id = 0 statement = 'INSERT INTO [user](username) VALUES (?)' try: self.engine.execute(statement, [username]) result = self.engine.execute( 'SELECT CAST(@@IDENTITY AS BIGINT) AS [user_id]').fetchone() if result is not None: user_id = result.user_id except Exception as ex: raise Exception( SvcUtils.error_message('user insert failed', { 'username': username, 'error': ex.message })) return user_id
def get_message_by_id(self, message_id): message = None statement = 'SELECT id, [user_id], [text], expiration_date_utc, created_date_utc FROM [message] WITH (NOLOCK) WHERE [message].id = ?' try: result = self.engine.execute(statement, message_id).fetchone() if result is not None: message = Message( id=result.id, user_id=result.user_id, text=result.text, expiration_date_utc=result.expiration_date_utc, created_date_utc=result.created_date_utc) except Exception as ex: raise Exception( SvcUtils.error_message('message lookup failed', { 'id': message_id, 'error': ex.message })) return message
def save_message(self, user_id, message, expiration_date_utc): message_id = 0 statement = 'INSERT INTO [message]([user_id], [text], expiration_date_utc) VALUES (?, ?, ?)' try: self.engine.execute(statement, [user_id, message, expiration_date_utc]) result = self.engine.execute( 'SELECT CAST(@@IDENTITY AS BIGINT) AS message_id').fetchone() if result is not None: message_id = result.message_id except Exception as ex: raise Exception( SvcUtils.error_message( 'message insert failed', { 'user_id': user_id, 'message': message, 'expiration_date_utc': expiration_date_utc, 'error': ex.message })) return message_id