Allow messaging backends to be enabled/disabled per organization (#1151)

# What this PR does
Allows messaging backends to be enabled/disabled per organization when
getting a list of available personal notification channels.

## Checklist

- [x] Tests updated
- [ ] Documentation added (N/A)
- [x] `CHANGELOG.md` updated
This commit is contained in:
Vadim Stepanov 2023-01-18 15:52:25 +00:00 committed by GitHub
parent 1c799f7265
commit b8d78fd6bb
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 43 additions and 1 deletions

View file

@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## Unreleased
### Added
- Allow messaging backends to be enabled/disabled per organization ([#1151](https://github.com/grafana/oncall/pull/1151))
## v1.1.17 (2023-01-18) ## v1.1.17 (2023-01-18)
### Changed ### Changed

View file

@ -1,4 +1,5 @@
import json import json
from unittest.mock import patch
import pytest import pytest
from django.urls import reverse from django.urls import reverse
@ -8,6 +9,7 @@ from rest_framework.test import APIClient
from apps.api.permissions import LegacyAccessControlRole from apps.api.permissions import LegacyAccessControlRole
from apps.base.models import UserNotificationPolicy from apps.base.models import UserNotificationPolicy
from apps.base.tests.messaging_backend import TestOnlyBackend
DEFAULT_NOTIFICATION_CHANNEL = UserNotificationPolicy.NotificationChannel.SLACK DEFAULT_NOTIFICATION_CHANNEL = UserNotificationPolicy.NotificationChannel.SLACK
@ -463,3 +465,22 @@ def test_notification_policy_backends_enabled(
assert response.status_code == status.HTTP_200_OK assert response.status_code == status.HTTP_200_OK
options = [opt["display_name"] for opt in response.json()] options = [opt["display_name"] for opt in response.json()]
assert "Test Only Backend" in options assert "Test Only Backend" in options
@pytest.mark.django_db
def test_notification_policy_backends_disabled_for_organization(
user_notification_policy_internal_api_setup, settings, make_user_auth_headers
):
token, _, users = user_notification_policy_internal_api_setup
admin, _ = users
client = APIClient()
url = reverse("api-internal:notification_policy-notify-by-options")
with patch.object(TestOnlyBackend, "is_enabled_for_organization", return_value=False):
response = client.get(url, **make_user_auth_headers(admin, token))
assert response.status_code == status.HTTP_200_OK
options = [opt["display_name"] for opt in response.json()]
assert "Test Only Backend" not in options

View file

@ -176,7 +176,9 @@ class UserNotificationPolicyView(UpdateSerializerMixin, ModelViewSet):
built_in_backend_names = {b[0] for b in BUILT_IN_BACKENDS} built_in_backend_names = {b[0] for b in BUILT_IN_BACKENDS}
if notification_channel.name not in built_in_backend_names: if notification_channel.name not in built_in_backend_names:
extra_messaging_backend = get_messaging_backend_from_id(notification_channel.name) extra_messaging_backend = get_messaging_backend_from_id(notification_channel.name)
if extra_messaging_backend is None: if extra_messaging_backend is None or not extra_messaging_backend.is_enabled_for_organization(
request.auth.organization
):
continue continue
choices.append( choices.append(

View file

@ -38,6 +38,10 @@ class BaseMessagingBackend:
"""Remove backend link to user account.""" """Remove backend link to user account."""
return return
@staticmethod
def is_enabled_for_organization(organization):
return True
def serialize_user(self, user): def serialize_user(self, user):
"""Return a serialized backend user representation.""" """Return a serialized backend user representation."""
raise NotImplementedError("serialize_user method missing implementation") raise NotImplementedError("serialize_user method missing implementation")

View file

@ -4,6 +4,7 @@ from django.conf import settings
from fcm_django.models import FCMDevice from fcm_django.models import FCMDevice
from apps.base.messaging import BaseMessagingBackend from apps.base.messaging import BaseMessagingBackend
from apps.base.models import DynamicSetting
from apps.mobile_app.tasks import notify_user_async from apps.mobile_app.tasks import notify_user_async
@ -50,6 +51,14 @@ class MobileAppBackend(BaseMessagingBackend):
critical=critical, critical=critical,
) )
@staticmethod
def is_enabled_for_organization(organization):
mobile_app_settings, _ = DynamicSetting.objects.get_or_create(
name="mobile_app_settings", defaults={"json_value": {"org_ids": []}}
)
return organization.pk in mobile_app_settings.json_value["org_ids"]
class MobileAppCriticalBackend(MobileAppBackend): class MobileAppCriticalBackend(MobileAppBackend):
""" """