Fix teams filter related issue setting maintenance mode (#1885)

Related to https://github.com/grafana/support-escalations/issues/5862
This commit is contained in:
Matias Bordese 2023-05-05 15:09:25 -03:00 committed by GitHub
parent bb3521b879
commit b62687295d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 110 additions and 6 deletions

View file

@ -19,6 +19,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Fixed
- Fix issue with how OnCall determines if a cloud Grafana Instance supports RBAC by @joeyorlando ([#1880](https://github.com/grafana/oncall/pull/1880))
- Fix issue trying to set maintenance mode for integrations belonging to non-current team
## v1.2.19 (2023-05-04)

View file

@ -46,6 +46,64 @@ def test_start_maintenance_integration(
assert alert_receive_channel.maintenance_author is not None
@pytest.mark.django_db
def test_start_maintenance_integration_user_team(
maintenance_internal_api_setup, mock_start_disable_maintenance_task, make_user_auth_headers, make_team
):
token, organization, user, alert_receive_channel = maintenance_internal_api_setup
another_team = make_team(organization)
user.current_team = another_team
user.save()
client = APIClient()
url = reverse("api-internal:start_maintenance")
data = {
"mode": AlertReceiveChannel.MAINTENANCE,
"duration": AlertReceiveChannel.DURATION_ONE_HOUR.total_seconds(),
"type": "alert_receive_channel",
"alert_receive_channel_id": alert_receive_channel.public_primary_key,
}
response = client.post(url, data=data, format="json", **make_user_auth_headers(user, token))
alert_receive_channel.refresh_from_db()
assert response.status_code == status.HTTP_200_OK
assert alert_receive_channel.maintenance_mode == AlertReceiveChannel.MAINTENANCE
assert alert_receive_channel.maintenance_duration == AlertReceiveChannel.DURATION_ONE_HOUR
assert alert_receive_channel.maintenance_uuid is not None
assert alert_receive_channel.maintenance_started_at is not None
assert alert_receive_channel.maintenance_author is not None
@pytest.mark.django_db
def test_start_maintenance_integration_different_team(
maintenance_internal_api_setup, mock_start_disable_maintenance_task, make_user_auth_headers, make_team
):
token, organization, user, alert_receive_channel = maintenance_internal_api_setup
another_team = make_team(organization)
other_team = make_team(organization)
user.current_team = another_team
user.save()
# integration belongs to non-general team, != user current team
alert_receive_channel.team = other_team
alert_receive_channel.save()
client = APIClient()
url = reverse("api-internal:start_maintenance")
data = {
"mode": AlertReceiveChannel.MAINTENANCE,
"duration": AlertReceiveChannel.DURATION_ONE_HOUR.total_seconds(),
"type": "alert_receive_channel",
"alert_receive_channel_id": alert_receive_channel.public_primary_key,
}
response = client.post(url, data=data, format="json", **make_user_auth_headers(user, token))
assert response.status_code == status.HTTP_400_BAD_REQUEST
alert_receive_channel.refresh_from_db()
assert alert_receive_channel.maintenance_mode is None
@pytest.mark.django_db
def test_stop_maintenance_integration(
maintenance_internal_api_setup,
@ -159,6 +217,46 @@ def test_maintenances_list(
assert response.json() == expected_payload
@pytest.mark.django_db
def test_maintenances_list_include_all_user_teams(
maintenance_internal_api_setup,
mock_start_disable_maintenance_task,
make_user_auth_headers,
make_team,
):
token, organization, user, alert_receive_channel = maintenance_internal_api_setup
another_team = make_team(organization)
other_team = make_team(organization)
# setup user teams
user.teams.add(another_team)
user.teams.add(other_team)
user.current_team = other_team
user.save()
# integration belongs to non-general team, != user current team
alert_receive_channel.team = another_team
alert_receive_channel.save()
client = APIClient()
mode = AlertReceiveChannel.MAINTENANCE
duration = AlertReceiveChannel.DURATION_ONE_HOUR.seconds
alert_receive_channel.start_maintenance(mode, duration, user)
url = reverse("api-internal:maintenance")
response = client.get(url, format="json", **make_user_auth_headers(user, token))
expected_payload = [
{
"alert_receive_channel_id": alert_receive_channel.public_primary_key,
"type": "alert_receive_channel",
"maintenance_mode": 1,
"maintenance_till_timestamp": alert_receive_channel.till_maintenance_timestamp,
"started_at_timestamp": alert_receive_channel.started_at_timestamp,
},
]
assert response.status_code == status.HTTP_200_OK
assert response.json() == expected_payload
@pytest.mark.django_db
def test_empty_maintenances_list(
maintenance_internal_api_setup, mock_start_disable_maintenance_task, make_user_auth_headers

View file

@ -9,6 +9,7 @@ from apps.alerts.models.maintainable_object import MaintainableObject
from apps.api.permissions import RBACPermission
from apps.auth_token.auth import PluginAuthentication
from common.api_helpers.exceptions import BadRequest
from common.api_helpers.mixins import TeamFilteringMixin
from common.exceptions import MaintenanceCouldNotBeStartedError
@ -26,8 +27,9 @@ class GetObjectMixin:
instance = AlertReceiveChannel.objects.get(
public_primary_key=pk,
organization=organization,
team=request.user.current_team,
)
if instance.team is not None and instance.team not in self.request.user.teams.all():
raise BadRequest(detail={"alert_receive_channel_id": ["unknown id"]})
except AlertReceiveChannel.DoesNotExist:
raise BadRequest(detail={"alert_receive_channel_id": ["unknown id"]})
else:
@ -38,7 +40,7 @@ class GetObjectMixin:
return instance
class MaintenanceAPIView(APIView):
class MaintenanceAPIView(APIView, TeamFilteringMixin):
"""Deprecated. Maintenance management is now performed on integrations page (alert_receive_channel/ endpoint))"""
authentication_classes = (PluginAuthentication,)
@ -51,12 +53,15 @@ class MaintenanceAPIView(APIView):
def get(self, request):
organization = self.request.auth.organization
team = self.request.user.current_team
response = []
integrations_under_maintenance = AlertReceiveChannel.objects.filter(
maintenance_mode__isnull=False, organization=organization, team=team
).order_by("maintenance_started_at")
integrations_under_maintenance = (
AlertReceiveChannel.objects.filter(
maintenance_mode__isnull=False, organization=organization, *self.available_teams_lookup_args
)
.distinct()
.order_by("maintenance_started_at")
)
if organization.maintenance_mode is not None:
response.append(