Prohibit creating & updating past overrides (#1474)

# What this PR does
Prohibits creating & updating overrides in the past when using the web
UI.

## Which issue(s) this PR fixes
https://github.com/grafana/oncall/issues/1221

## Checklist

- [x] Tests updated
- [x] `CHANGELOG.md` updated
This commit is contained in:
Vadim Stepanov 2023-03-07 15:54:20 +00:00 committed by GitHub
parent 3921a62780
commit 98ccd3eca5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 36 additions and 2 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/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## Unreleased
### Fixed
- Prohibit creating & updating past overrides ([1474](https://github.com/grafana/oncall/pull/1474))
## v1.1.33 (2023-03-07)
### Fixed

View file

@ -1,3 +1,4 @@
from django.utils import timezone
from rest_framework import serializers
from apps.schedules.models import CustomOnCallShift, OnCallScheduleWeb
@ -93,10 +94,13 @@ class OnCallShiftSerializer(EagerLoadingMixin, serializers.ModelSerializer):
result.append(users_dict)
return result
def _validate_shift_end(self, start, end):
def _validate_shift_end(self, start, end, event_type):
if end <= start:
raise serializers.ValidationError({"shift_end": ["Incorrect shift end date"]})
if event_type == CustomOnCallShift.TYPE_OVERRIDE and timezone.now() > end:
raise serializers.ValidationError({"shift_end": ["Cannot create or update an override in the past"]})
def _validate_frequency(self, frequency, event_type, rolling_users, interval, by_day, until):
if frequency is None:
if rolling_users and len(rolling_users) > 1:
@ -157,7 +161,7 @@ class OnCallShiftSerializer(EagerLoadingMixin, serializers.ModelSerializer):
# convert shift_end into internal value and validate
raw_shift_end = self.initial_data["shift_end"]
shift_end = serializers.DateTimeField().to_internal_value(raw_shift_end)
self._validate_shift_end(validated_data["start"], shift_end)
self._validate_shift_end(validated_data["start"], shift_end, event_type)
validated_data["duration"] = shift_end - validated_data["start"]
if validated_data.get("schedule"):

View file

@ -921,6 +921,30 @@ def test_create_on_call_shift_override_invalid_data(on_call_shift_internal_api_s
assert response.data["frequency"][0] == "Cannot set 'frequency' for shifts with type 'override'"
@pytest.mark.django_db
def test_create_on_call_shift_override_in_past(on_call_shift_internal_api_setup, make_user_auth_headers):
token, user1, _, _, schedule = on_call_shift_internal_api_setup
client = APIClient()
url = reverse("api-internal:oncall_shifts-list")
start_date = timezone.now().replace(microsecond=0, tzinfo=None) - timezone.timedelta(hours=2)
data = {
"title": "Test Shift Override",
"type": CustomOnCallShift.TYPE_OVERRIDE,
"schedule": schedule.public_primary_key,
"priority_level": 0,
"shift_start": start_date.strftime("%Y-%m-%dT%H:%M:%SZ"),
"shift_end": (start_date + timezone.timedelta(hours=1)).strftime("%Y-%m-%dT%H:%M:%SZ"),
"rotation_start": start_date.strftime("%Y-%m-%dT%H:%M:%SZ"),
"rolling_users": [[user1.public_primary_key]],
}
response = client.post(url, data, format="json", **make_user_auth_headers(user1, token))
assert response.status_code == status.HTTP_400_BAD_REQUEST
assert response.data["shift_end"][0] == "Cannot create or update an override in the past"
@pytest.mark.django_db
@pytest.mark.parametrize(
"role,expected_status",