From ae5949aa7e281696d3776d0253334cb976569e60 Mon Sep 17 00:00:00 2001 From: Vadim Stepanov Date: Mon, 23 Jan 2023 11:17:57 +0000 Subject: [PATCH] Allow viewers fetch cloud connection status (#1181) # What this PR does Fixes the issue when users with the viewer role can't fetch the cloud connection status, which makes the plugin fail to load for viewers. This PR makes the cloud connection endpoint use `OTHER_SETTINGS_READ` for fetching the cloud connection status instead of `OTHER_SETTINGS_WRITE`. ## Checklist - [x] Tests updated - [x] `CHANGELOG.md` updated --- CHANGELOG.md | 4 ++ .../apps/oss_installation/tests/__init__.py | 0 .../apps/oss_installation/tests/test_views.py | 41 +++++++++++++++++++ engine/apps/oss_installation/urls.py | 2 + .../views/cloud_connection.py | 2 +- engine/engine/urls.py | 2 +- 6 files changed, 49 insertions(+), 2 deletions(-) create mode 100644 engine/apps/oss_installation/tests/__init__.py create mode 100644 engine/apps/oss_installation/tests/test_views.py diff --git a/CHANGELOG.md b/CHANGELOG.md index a5b62652..97e96543 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Add Slack slash command allowing to trigger a direct page via a manually created alert group +### Changed + +- Allow users with `viewer` role to fetch cloud connection status using the internal API ([#1181](https://github.com/grafana/oncall/pull/1181)) + ### Fixed - Removed duplicate API call, in the UI on plugin initial load, to `GET /api/internal/v1/alert_receive_channels` diff --git a/engine/apps/oss_installation/tests/__init__.py b/engine/apps/oss_installation/tests/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/engine/apps/oss_installation/tests/test_views.py b/engine/apps/oss_installation/tests/test_views.py new file mode 100644 index 00000000..3eaad082 --- /dev/null +++ b/engine/apps/oss_installation/tests/test_views.py @@ -0,0 +1,41 @@ +import pytest +from django.urls import reverse +from rest_framework import status +from rest_framework.test import APIClient + +from apps.api.permissions import LegacyAccessControlRole +from apps.oss_installation.models import CloudConnector + + +@pytest.mark.django_db +def test_cloud_connection_viewer_can_read( + make_organization_and_user_with_plugin_token, + make_user_auth_headers, +): + organization, user, token = make_organization_and_user_with_plugin_token(role=LegacyAccessControlRole.VIEWER) + + # create cloud connection + CloudConnector.objects.create(cloud_url="test") + + client = APIClient() + url = reverse("oss_installation:cloud-connection-status") + + response = client.get(url, **make_user_auth_headers(user, token)) + assert response.status_code == status.HTTP_200_OK + + +@pytest.mark.django_db +def test_cloud_connection_viewer_cant_delete( + make_organization_and_user_with_plugin_token, + make_user_auth_headers, +): + organization, user, token = make_organization_and_user_with_plugin_token(role=LegacyAccessControlRole.VIEWER) + + # create cloud connection + CloudConnector.objects.create(cloud_url="test") + + client = APIClient() + url = reverse("oss_installation:cloud-connection-status") + response = client.delete(url, **make_user_auth_headers(user, token)) + + assert response.status_code == status.HTTP_403_FORBIDDEN diff --git a/engine/apps/oss_installation/urls.py b/engine/apps/oss_installation/urls.py index ddf04020..3856b887 100644 --- a/engine/apps/oss_installation/urls.py +++ b/engine/apps/oss_installation/urls.py @@ -4,6 +4,8 @@ from common.api_helpers.optional_slash_router import OptionalSlashRouter, option from .views import CloudConnectionView, CloudHeartbeatView, CloudUsersView, CloudUserView +app_name = "oss_installation" + router = OptionalSlashRouter() router.register("cloud_users", CloudUserView, basename="cloud-users") diff --git a/engine/apps/oss_installation/views/cloud_connection.py b/engine/apps/oss_installation/views/cloud_connection.py index de73343c..004837df 100644 --- a/engine/apps/oss_installation/views/cloud_connection.py +++ b/engine/apps/oss_installation/views/cloud_connection.py @@ -15,7 +15,7 @@ class CloudConnectionView(APIView): authentication_classes = (PluginAuthentication,) permission_classes = (IsAuthenticated, RBACPermission) rbac_permissions = { - "get": [RBACPermission.Permissions.OTHER_SETTINGS_WRITE], + "get": [RBACPermission.Permissions.OTHER_SETTINGS_READ], "delete": [RBACPermission.Permissions.OTHER_SETTINGS_WRITE], } diff --git a/engine/engine/urls.py b/engine/engine/urls.py index 77d0f80f..2ae1f2ef 100644 --- a/engine/engine/urls.py +++ b/engine/engine/urls.py @@ -60,7 +60,7 @@ if settings.FEATURE_MOBILE_APP_INTEGRATION_ENABLED: if settings.OSS_INSTALLATION: urlpatterns += [ - path("api/internal/v1/", include("apps.oss_installation.urls")), + path("api/internal/v1/", include("apps.oss_installation.urls", namespace="oss_installation")), ] if settings.DEBUG: