diff --git a/CHANGELOG.md b/CHANGELOG.md index ede47cad..d123b651 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,6 +26,10 @@ endpoint currently) @mderynck ([#3189](https://github.com/grafana/oncall/pull/31 - Add ability for webhook presets to mask sensitive headers @mderynck ([#3189](https://github.com/grafana/oncall/pull/3189)) +### Changed + +- Use instance ID for cloud Grafana service token auth @mderynck ([#3435](https://github.com/grafana/oncall/pull/3435)) + ### Fixed - Fixed issue that blocked saving webhooks with presets if the preset is controlling the URL @mderynck diff --git a/engine/apps/auth_token/auth.py b/engine/apps/auth_token/auth.py index 8982fe21..6d6907c6 100644 --- a/engine/apps/auth_token/auth.py +++ b/engine/apps/auth_token/auth.py @@ -266,8 +266,7 @@ class UserScheduleExportAuthentication(BaseAuthentication): return auth_token.user, auth_token -X_GRAFANA_ORG_SLUG = "X-Grafana-Org-Slug" -X_GRAFANA_INSTANCE_SLUG = "X-Grafana-Instance-Slug" +X_GRAFANA_INSTANCE_ID = "X-Grafana-Instance-ID" GRAFANA_SA_PREFIX = "glsa_" @@ -290,17 +289,15 @@ class GrafanaServiceAccountAuthentication(BaseAuthentication): return self.authenticate_credentials(organization, auth) def get_organization(self, request): - org_slug = SELF_HOSTED_SETTINGS["ORG_SLUG"] - instance_slug = SELF_HOSTED_SETTINGS["STACK_SLUG"] if settings.LICENSE == settings.CLOUD_LICENSE_NAME: - org_slug = request.headers.get(X_GRAFANA_ORG_SLUG) - if not org_slug: - raise exceptions.AuthenticationFailed(f"Missing {X_GRAFANA_ORG_SLUG}") - instance_slug = request.headers.get(X_GRAFANA_INSTANCE_SLUG) - if not instance_slug: - raise exceptions.AuthenticationFailed(f"Missing {X_GRAFANA_INSTANCE_SLUG}") - - return Organization.objects.filter(org_slug=org_slug, stack_slug=instance_slug).first() + instance_id = request.headers.get(X_GRAFANA_INSTANCE_ID) + if not instance_id: + raise exceptions.AuthenticationFailed(f"Missing {X_GRAFANA_INSTANCE_ID}") + return Organization.objects.filter(stack_id=instance_id).first() + else: + org_slug = SELF_HOSTED_SETTINGS["ORG_SLUG"] + instance_slug = SELF_HOSTED_SETTINGS["STACK_SLUG"] + return Organization.objects.filter(org_slug=org_slug, stack_slug=instance_slug).first() def authenticate_credentials(self, organization, token): permissions = get_service_account_token_permissions(organization, token) diff --git a/engine/apps/auth_token/tests/test_grafana_auth.py b/engine/apps/auth_token/tests/test_grafana_auth.py index b1fdc800..5b78636c 100644 --- a/engine/apps/auth_token/tests/test_grafana_auth.py +++ b/engine/apps/auth_token/tests/test_grafana_auth.py @@ -5,12 +5,7 @@ import pytest from rest_framework import exceptions from rest_framework.test import APIRequestFactory -from apps.auth_token.auth import ( - GRAFANA_SA_PREFIX, - X_GRAFANA_INSTANCE_SLUG, - X_GRAFANA_ORG_SLUG, - GrafanaServiceAccountAuthentication, -) +from apps.auth_token.auth import GRAFANA_SA_PREFIX, X_GRAFANA_INSTANCE_ID, GrafanaServiceAccountAuthentication from settings.base import CLOUD_LICENSE_NAME, OPEN_SOURCE_LICENSE_NAME, SELF_HOSTED_SETTINGS @@ -24,7 +19,10 @@ def test_grafana_authentication_oss_inputs(make_organization, settings): headers, token = check_common_inputs() organization = make_organization( - stack_slug=SELF_HOSTED_SETTINGS["STACK_SLUG"], org_slug=SELF_HOSTED_SETTINGS["ORG_SLUG"] + stack_id=SELF_HOSTED_SETTINGS["STACK_ID"], + org_id=SELF_HOSTED_SETTINGS["ORG_ID"], + stack_slug=SELF_HOSTED_SETTINGS["STACK_SLUG"], + org_slug=SELF_HOSTED_SETTINGS["ORG_SLUG"], ) request = APIRequestFactory().get("/", **headers) with patch( @@ -40,15 +38,13 @@ def test_grafana_authentication_cloud_inputs(make_organization, settings): settings.LICENSE = CLOUD_LICENSE_NAME headers, token = check_common_inputs() - test_org_slug = "test_org_123" - test_stack_slug = "test_stack_123" - headers[f"HTTP_{X_GRAFANA_ORG_SLUG}"] = test_org_slug - headers[f"HTTP_{X_GRAFANA_INSTANCE_SLUG}"] = test_stack_slug + test_instance_id = "123" + headers[f"HTTP_{X_GRAFANA_INSTANCE_ID}"] = test_instance_id request = APIRequestFactory().get("/", **headers) with pytest.raises(exceptions.AuthenticationFailed): GrafanaServiceAccountAuthentication().authenticate(request) - organization = make_organization(stack_slug=test_stack_slug, org_slug=test_org_slug) + organization = make_organization(stack_id=test_instance_id) with patch( "apps.auth_token.auth.GrafanaServiceAccountAuthentication.authenticate_credentials", wraps=fake_authenticate_credentials,