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: