diff --git a/src/sentry/api/endpoints/user_notification_settings_options_detail.py b/src/sentry/api/endpoints/user_notification_settings_options_detail.py index a35285814ba3f3..d74476ff438b5a 100644 --- a/src/sentry/api/endpoints/user_notification_settings_options_detail.py +++ b/src/sentry/api/endpoints/user_notification_settings_options_detail.py @@ -1,4 +1,5 @@ from rest_framework import status +from rest_framework.exceptions import NotFound from rest_framework.request import Request from rest_framework.response import Response @@ -19,13 +20,26 @@ class UserNotificationSettingsOptionsDetailEndpoint(UserEndpoint): # TODO(Steve): Make not private when we launch new system private = True - def delete(self, request: Request, user: User, notification_option_id: str) -> Response: + def convert_args( + self, + request: Request, + user_id: int | str | None = None, + *args, + notification_option_id: int, + **kwargs, + ): + args, kwargs = super().convert_args(request, user_id, *args, **kwargs) + user = kwargs["user"] try: - option = NotificationSettingOption.objects.get( - id=notification_option_id, - ) + option = NotificationSettingOption.objects.get(id=notification_option_id, user=user) except NotificationSettingOption.DoesNotExist: - return Response(status=status.HTTP_404_NOT_FOUND) + raise NotFound(detail="User notification setting does not exist") - option.delete() + kwargs["notification_setting_option"] = option + return args, kwargs + + def delete( + self, request: Request, user: User, notification_setting_option: NotificationSettingOption + ) -> Response: + notification_setting_option.delete() return Response(status=status.HTTP_204_NO_CONTENT) diff --git a/tests/sentry/api/endpoints/test_user_notification_settings_options_details.py b/tests/sentry/api/endpoints/test_user_notification_settings_options_details.py index 785336f1633f8c..ff9dc10158df1c 100644 --- a/tests/sentry/api/endpoints/test_user_notification_settings_options_details.py +++ b/tests/sentry/api/endpoints/test_user_notification_settings_options_details.py @@ -24,18 +24,20 @@ def setUp(self): super().setUp() self.login_as(self.user) - option = NotificationSettingOption.objects.create( + self.option = NotificationSettingOption.objects.create( user_id=self.user.id, scope_type=NotificationScopeEnum.ORGANIZATION.value, scope_identifier=self.organization.id, type=NotificationSettingEnum.ISSUE_ALERTS.value, value=NotificationSettingsOptionEnum.ALWAYS.value, ) + + def test_simple(self): self.get_success_response( "me", - option.id, + self.option.id, ) - assert not NotificationSettingOption.objects.filter(id=option.id).exists() + assert not NotificationSettingOption.objects.filter(id=self.option.id).exists() def test_invalid_option(self): self.get_error_response( @@ -43,3 +45,22 @@ def test_invalid_option(self): "123", status_code=status.HTTP_404_NOT_FOUND, ) + + def test_cannot_delete_other_users_setting(self): + victim_user = self.create_user() + victim_org = self.create_organization(owner=victim_user) + victim_option = NotificationSettingOption.objects.create( + user_id=victim_user.id, + scope_type=NotificationScopeEnum.ORGANIZATION.value, + scope_identifier=victim_org.id, + type=NotificationSettingEnum.ISSUE_ALERTS.value, + value=NotificationSettingsOptionEnum.ALWAYS.value, + ) + + response = self.get_error_response( + "me", + victim_option.id, + status_code=status.HTTP_404_NOT_FOUND, + ) + assert response.data["detail"] == "User notification setting does not exist" + assert NotificationSettingOption.objects.filter(id=victim_option.id).exists()