diff --git a/moesifdjango/block_response_buffer.py b/moesifdjango/block_response_buffer.py index aacee9c..9155078 100644 --- a/moesifdjango/block_response_buffer.py +++ b/moesifdjango/block_response_buffer.py @@ -7,12 +7,12 @@ def __init__(self): self.rule_type = None self.blocked = False - def update(self, block, updated_gr_status, updated_gr_headers, updated_gr_body): + def update(self, block, updated_gr_status, updated_gr_headers, updated_gr_body, rule_id): if not self.rule_type: self.rule_type = 'regex' if block and not self.blocked: self.blocked = True gov_rule_response = GovernanceRuleBlockResponse() - gov_rule_response.update_response(updated_gr_status, updated_gr_headers, updated_gr_body, block) + gov_rule_response.update_response(updated_gr_status, updated_gr_headers, updated_gr_body, block, rule_id) self.responses.append(gov_rule_response) diff --git a/moesifdjango/event_mapper.py b/moesifdjango/event_mapper.py index 9104a84..faf8e0f 100644 --- a/moesifdjango/event_mapper.py +++ b/moesifdjango/event_mapper.py @@ -26,7 +26,7 @@ def to_response(self, rsp_time, status_code, rsp_headers, rsp_body, transfer_enc transfer_encoding=transfer_encoding) @classmethod - def to_event(cls, event_req, event_rsp, user_id, company_id, session_token, metadata): + def to_event(cls, event_req, event_rsp, user_id, company_id, session_token, metadata, blocked_by=None): # Prepare Event Model return EventModel(request=event_req, response=event_rsp, @@ -34,4 +34,5 @@ def to_event(cls, event_req, event_rsp, user_id, company_id, session_token, meta company_id=company_id, session_token=session_token, metadata=metadata, - direction="Incoming") + direction="Incoming", + blocked_by=blocked_by) diff --git a/moesifdjango/governance_rule_response.py b/moesifdjango/governance_rule_response.py index 9163aff..6f9e76d 100644 --- a/moesifdjango/governance_rule_response.py +++ b/moesifdjango/governance_rule_response.py @@ -1,13 +1,15 @@ class GovernanceRuleBlockResponse: - # TODO Create a empty init, and add function def __init__(self): self.block_response_status = None self.block_response_headers = None self.block_response_body = None self.blocked = False + self.blocked_by = None # holds blocked by rule_id - def update_response(self, gr_status, gr_headers, gr_body, block): + def update_response(self, gr_status, gr_headers, gr_body, block, rule_id): self.block_response_status = gr_status self.block_response_headers = gr_headers self.block_response_body = gr_body self.blocked = block + self.blocked_by = rule_id + diff --git a/moesifdjango/middleware.py b/moesifdjango/middleware.py index 0d80675..0c9ef35 100644 --- a/moesifdjango/middleware.py +++ b/moesifdjango/middleware.py @@ -279,7 +279,7 @@ def __call__(self, request): rsp_body_transfer_encoding) # Prepare Event Model event_model = self.event_mapper.to_event(event_req, event_rsp, user_id, company_id, session_token, - metadata) + metadata, updated_Response.blocked_by) # Mask Event Model event_model = self.logger_helper.mask_event(event_model, self.middleware_settings, self.DEBUG) diff --git a/moesifdjango/moesif_gov.py b/moesifdjango/moesif_gov.py index 20f943e..5f84bbe 100644 --- a/moesifdjango/moesif_gov.py +++ b/moesifdjango/moesif_gov.py @@ -359,7 +359,7 @@ def block_request_based_on_entity_governance_rule(self, governance_rule, rule_and_values) block = governance_rule.get('block', False) - response_buffer.update(block, updated_gr_status, updated_gr_headers, updated_gr_body) + response_buffer.update(block, updated_gr_status, updated_gr_headers, updated_gr_body, rule_id) if DEBUG: print("[moesif] request matched with rule_id [{}]".format(rule_id)) @@ -392,8 +392,7 @@ def get_rules_id_if_governance_rule_matched(self, regex_governance_rules, event, return matched_rules_id - def block_request_based_on_governance_rule_regex_config(self, event, ready_for_body_request, regex_governance_rules, - DEBUG): + def block_request_based_on_governance_rule_regex_config(self, event, ready_for_body_request, regex_governance_rules, DEBUG): """ Check if need to block request based on the governance rule regex config associated with the request :param event: @@ -404,35 +403,29 @@ def block_request_based_on_governance_rule_regex_config(self, event, ready_for_b """ response_buffer = BlockResponseBufferList() - matched_rules_id = self.get_rules_id_if_governance_rule_matched(regex_governance_rules, event, - ready_for_body_request) - - if not matched_rules_id: - if DEBUG: - print('[moesif] no regex rule matched with the request') - else: - for rule_id in matched_rules_id: - governance_rule = regex_governance_rules.get(rule_id) - if not governance_rule: - if DEBUG: - print( - '[moesif] Skipped blocking request as rule {} is not found'.format(rule_id)) - continue - - if 'response' not in governance_rule \ - or 'status' not in governance_rule['response'] \ - or 'headers' not in governance_rule['response']: - if DEBUG: - print( - '[moesif] Skipped blocking request as response is not set for the governance rule with regex config') + matched_rules_id = self.get_rules_id_if_governance_rule_matched(regex_governance_rules, event, ready_for_body_request) + for rule_id in matched_rules_id: + governance_rule = regex_governance_rules.get(rule_id) + if not governance_rule: + if DEBUG: + print( + '[moesif] Skipped blocking request as rule {} is not found'.format(rule_id)) continue - block = governance_rule.get('block', False) - gr_status, gr_header, gr_body = self.fetch_governance_rule_response_details(governance_rule) - - response_buffer.update(block, gr_status, gr_header, gr_body) + if 'response' not in governance_rule \ + or 'status' not in governance_rule['response'] \ + or 'headers' not in governance_rule['response']: if DEBUG: - print('[moesif] request matched with regex rule with rule_id {}'.format(rule_id)) + print('[moesif] Skipped blocking request as response is not set for the governance rule with regex config') + continue + + block = governance_rule.get('block', False) + gr_status, gr_header, gr_body = self.fetch_governance_rule_response_details(governance_rule) + + response_buffer.update(block, gr_status, gr_header, gr_body, rule_id) + if DEBUG: + print('[moesif] request matched with regex rule with rule_id {}'.format(rule_id)) + return response_buffer # TODO can deal with request.body in one place @@ -481,7 +474,7 @@ def prepare_request_config_based_on_regex_config(cls, event: EventModel, ready_f def generate_blocking_response(self, response_buffers): """ - rearrange matching rules' response, merge all of the headers, and ordered by the rules type priority + rearrange matching rules' response, merge all the headers, and ordered by the rules type priority updated response_body and response_status with the highest priority blocked rule :param response_buffers: @@ -493,6 +486,8 @@ def generate_blocking_response(self, response_buffers): updated_body = None updated_status = None updated_headers = {} + blocked_by = None + blocked = False for rule_type in REVERSED_PRIORITY_RULES_ORDER: if rule_type in response_buffers: @@ -503,10 +498,12 @@ def generate_blocking_response(self, response_buffers): if response.blocked: updated_body = response.block_response_body updated_status = response.block_response_status + blocked_by = response.blocked_by + blocked = response.blocked updated_headers.update(response.block_response_headers) gov_rule_response = GovernanceRuleBlockResponse() - gov_rule_response.update_response(updated_status, updated_headers, updated_body, True) + gov_rule_response.update_response(updated_status, updated_headers, updated_body, blocked, blocked_by) return gov_rule_response @classmethod diff --git a/requirements.txt b/requirements.txt index e2dcc15..51aa279 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,7 +3,7 @@ jsonpickle==0.7.1 python-dateutil==2.5.3 nose==1.3.7 isodatetimehandler==1.0.2 -moesifapi==1.4.0 +moesifapi==1.4.1 celery>=3.1.25 moesifpythonrequest==0.3.0 apscheduler==3.6.1 diff --git a/setup.py b/setup.py index 32ee81c..776813f 100644 --- a/setup.py +++ b/setup.py @@ -82,7 +82,7 @@ # your project is installed. For an analysis of "install_requires" vs pip's # requirements files see: # https://packaging.python.org/en/latest/requirements.html - install_requires=['requests', 'jsonpickle', 'python-dateutil', 'isodatetimehandler', 'moesifapi>=1.4.0', + install_requires=['requests', 'jsonpickle', 'python-dateutil', 'isodatetimehandler', 'moesifapi>=1.4.1', 'moesifpythonrequest>=0.3.0', 'apscheduler', 'nose'], # List additional groups of dependencies here (e.g. development