From 5a5fb6ea8e0737127ea0ee5a5784559bceac10cc Mon Sep 17 00:00:00 2001 From: Michael Derynck Date: Wed, 23 Aug 2023 13:39:02 -0600 Subject: [PATCH] Status to not access grafana headers from mobile request (#2870) # What this PR does When accessing the status endpoint using a mobile authentication token do not use headers that would only be available if the request came from Grafana. ## Which issue(s) this PR fixes ## Checklist - [x] Unit, integration, and e2e (if applicable) tests updated - [x] Documentation added (or `pr:no public docs` PR label added if not required) - [x] `CHANGELOG.md` updated (or `pr:no changelog` PR label added if not required) --- engine/apps/grafana_plugin/tests/test_status.py | 5 +---- engine/apps/grafana_plugin/views/status.py | 10 +++++----- engine/common/api_helpers/mixins.py | 14 ++++++++++++-- 3 files changed, 18 insertions(+), 11 deletions(-) diff --git a/engine/apps/grafana_plugin/tests/test_status.py b/engine/apps/grafana_plugin/tests/test_status.py index 966d3708..24374f56 100644 --- a/engine/apps/grafana_plugin/tests/test_status.py +++ b/engine/apps/grafana_plugin/tests/test_status.py @@ -84,8 +84,5 @@ def test_status_mobile_app_auth_token( response = client.post(url) assert response.status_code == status.HTTP_403_FORBIDDEN - auth_headers = make_user_auth_headers( - user, - auth_token, - ) + auth_headers = {"HTTP_AUTHORIZATION": f"{auth_token}"} _check_status_response(auth_headers, client) diff --git a/engine/apps/grafana_plugin/views/status.py b/engine/apps/grafana_plugin/views/status.py index 7e32de30..9b5d3a21 100644 --- a/engine/apps/grafana_plugin/views/status.py +++ b/engine/apps/grafana_plugin/views/status.py @@ -31,16 +31,14 @@ class StatusView(GrafanaHeadersMixin, APIView): } ) - stack_id = self.instance_context["stack_id"] - org_id = self.instance_context["org_id"] - + organization = request.auth.organization is_installed = False token_ok = False allow_signup = True api_url = settings.BASE_URL # Check if organization is in OnCall database - if organization := Organization.objects.get(stack_id=stack_id, org_id=org_id): + if organization: is_installed = True token_ok = organization.api_token_status == Organization.API_TOKEN_STATUS_OK if organization.is_moved: @@ -64,7 +62,9 @@ class StatusView(GrafanaHeadersMixin, APIView): "is_installed": is_installed, "token_ok": token_ok, "allow_signup": allow_signup, - "is_user_anonymous": self.grafana_context.get("IsAnonymous", request.user is None), + "is_user_anonymous": self.grafana_context["IsAnonymous"] + if self.grafana_context + else request.user is None, "license": settings.LICENSE, "version": settings.VERSION, "recaptcha_site_key": settings.RECAPTCHA_V3_SITE_KEY, diff --git a/engine/common/api_helpers/mixins.py b/engine/common/api_helpers/mixins.py index bcdd20c8..c873c0d7 100644 --- a/engine/common/api_helpers/mixins.py +++ b/engine/common/api_helpers/mixins.py @@ -26,6 +26,10 @@ from common.api_helpers.exceptions import BadRequest from common.jinja_templater import apply_jinja_template from common.jinja_templater.apply_jinja_template import JinjaTemplateError, JinjaTemplateWarning +X_INSTANCE_CONTEXT = "X-Instance-Context" + +X_GRAFANA_CONTEXT = "X-Grafana-Context" + class UpdateSerializerMixin: serializer_class = None @@ -366,10 +370,16 @@ class GrafanaHeadersMixin: @cached_property def grafana_context(self) -> GrafanaContext: - grafana_context: GrafanaContext = json.loads(self.request.headers["X-Grafana-Context"]) + if X_GRAFANA_CONTEXT in self.request.headers: + grafana_context: GrafanaContext = json.loads(self.request.headers[X_GRAFANA_CONTEXT]) + else: + grafana_context = None return grafana_context @cached_property def instance_context(self) -> InstanceContext: - instance_context: InstanceContext = json.loads(self.request.headers["X-Instance-Context"]) + if X_INSTANCE_CONTEXT in self.request.headers: + instance_context: InstanceContext = json.loads(self.request.headers[X_INSTANCE_CONTEXT]) + else: + instance_context = None return instance_context