From a9e78c8e8e9d89dc4879ad14606200cd968e78d3 Mon Sep 17 00:00:00 2001 From: U039b Date: Sat, 21 Sep 2024 13:09:01 +0200 Subject: [PATCH] Handle Threatr inconsistent configuration --- colander/core/threatr.py | 19 ++++++-- colander/core/views/investigate_views.py | 11 +++-- .../templates/pages/investigate/base.html | 48 ++++++++++--------- 3 files changed, 47 insertions(+), 31 deletions(-) diff --git a/colander/core/threatr.py b/colander/core/threatr.py index 505cb9a..201588d 100644 --- a/colander/core/threatr.py +++ b/colander/core/threatr.py @@ -15,18 +15,23 @@ class ThreatrClient: def __init__(self): self.api_key = '' self.types = [] - self.supported_types = [] + self.supported_types = {} self.__load_credentials() + self.__correctly_configured, self.__error_message = self.is_correctly_configured() def is_correctly_configured(self): + if not self.api_key: + return False, 'No Threatr API key found, check the documentation.' try: response = requests.head(f'{self.url}/api/schema/', headers=self.__get_headers(), timeout=10) return response.status_code == 200 except requests.exceptions.RequestException as e: logger.error(e) - return False + return False, 'Unable to retrieve the API schema (https:///api/schema/)' def is_online(self): + if not self.__correctly_configured: + return False try: requests.head(f'{self.url}/api/schema/', headers=self.__get_headers(), timeout=10) return True @@ -47,13 +52,16 @@ def __load_credentials(self): credentials = BackendCredentials.objects.filter(backend=ThreatrClient.backend_identifier) if credentials: credentials = credentials.first() - self.api_key = credentials.credentials.get('api_key') + self.api_key = credentials.credentials.get('api_key', '') def get_types(self): """ Get all the types defined in Threatr models. :return: all the types defined in Threatr models """ + if not self.__correctly_configured: + self.types = [] + return self.types if self.types: return self.types response = requests.get(f'{self.url}/api/types/', headers=self.__get_headers()) @@ -83,6 +91,9 @@ def get_supported_types(self): :return: the entity types supported by the modules available on Threatr """ + if not self.__correctly_configured: + self.supported_types = {} + return self.supported_types if self.supported_types: return self.supported_types response = requests.get(f'{self.url}/api/types/supported/', headers=self.__get_headers()) @@ -109,6 +120,8 @@ def send_request(self, data) -> (list, bool): :param data: the data to be sent :return: the query results and a boolean telling if the client has to wait and come back later """ + if not self.__correctly_configured: + return [], False if not data: return [], False response = requests.post(f'{self.url}/api/request/', headers=self.__get_headers(), json=data) diff --git a/colander/core/views/investigate_views.py b/colander/core/views/investigate_views.py index 92811c1..64c194d 100644 --- a/colander/core/views/investigate_views.py +++ b/colander/core/views/investigate_views.py @@ -26,7 +26,6 @@ def get_threatr_types(api_key): @login_required @csrf_exempt def investigate_search_view(request): - form = InvestigateSearchForm() threatr_client = ThreatrClient() threatr_results = {} wait = False @@ -35,14 +34,15 @@ def investigate_search_view(request): ordering = {} request_data = {} - if not threatr_client.is_correctly_configured(): - messages.error(request, 'Threatr is not correctly configured. Unable to retrieve the API schema (/api/schema/)', extra_tags='danger') - logger.error(f'Threatr is not correctly configured. {THREAT_BACKEND_IDENTIFIER}') + correctly_configured, message = threatr_client.is_correctly_configured() + if not correctly_configured: + messages.error(request, message, extra_tags='danger') + logger.error(f'Threatr is not correctly configured. {THREAT_BACKEND_IDENTIFIER}. {message}') return render( request, 'pages/investigate/base.html', { - 'form': form, + 'form': None, 'request_data': request_data, 'results': threatr_results, 'mermaid': mermaid, @@ -52,6 +52,7 @@ def investigate_search_view(request): ) types = threatr_client.get_supported_types() + form = InvestigateSearchForm() if request.GET.keys(): entities = {} diff --git a/colander/templates/pages/investigate/base.html b/colander/templates/pages/investigate/base.html index 0e41017..4249f5f 100644 --- a/colander/templates/pages/investigate/base.html +++ b/colander/templates/pages/investigate/base.html @@ -7,34 +7,36 @@ {% block content %} {% block inner-content %} -
-
-
-
-
-
- {% include "helpers/dynamic_type_selector.html" %} -
-
-
-
- - + {% if form %} +
+
+
+
+ +
+ {% include "helpers/dynamic_type_selector.html" %} +
+
+
+
+ + +
+ {{ form.force_update|as_crispy_field }}
- {{ form.force_update|as_crispy_field }}
-
- + +
-
+ {% endif %}
{# Wait for the threatr request to complete #} {% if wait %}