Skip to content

Commit d604fa1

Browse files
authored
Fix action/webhook API not accepting empty/null user (#3094)
# What this PR does Fix update calls made by terraform when user field is empty or not present. Should have been part of: #3053 ## Which issue(s) this PR fixes grafana/terraform-provider-grafana#1025 ## Checklist - [x] Unit, integration, and e2e (if applicable) tests updated - [x] Documentation added (or `pr:no public docs` PR label added if not required) - [x] `CHANGELOG.md` updated (or `pr:no changelog` PR label added if not required)
1 parent d9c3d08 commit d604fa1

File tree

4 files changed

+40
-12
lines changed

4 files changed

+40
-12
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
99

1010
### Fixed
1111

12+
- Accept empty and null user when updating webhook via API @mderynck ([#3094](https://github.com/grafana/oncall/pull/3094)))
1213
- Fix slack notification for a shift which end is affected by a taken swap ([#3092](https://github.com/grafana/oncall/pull/3092))
1314

1415
## v1.3.40 (2023-08-28)

engine/apps/public_api/serializers/action.py

+1-2
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ class Meta:
4848

4949

5050
class ActionUpdateSerializer(ActionCreateSerializer):
51-
user = serializers.CharField(required=False, source="username")
51+
user = serializers.CharField(required=False, source="username", allow_null=True, allow_blank=True)
5252
trigger_type = WebhookTriggerTypeField(required=False)
5353
forward_whole_payload = serializers.BooleanField(required=False, source="forward_all")
5454

@@ -63,7 +63,6 @@ class Meta(ActionCreateSerializer.Meta):
6363
"headers": {"required": False, "allow_null": True, "allow_blank": True},
6464
"url": {"required": False, "allow_null": False, "allow_blank": False},
6565
"data": {"required": False, "allow_null": True, "allow_blank": True},
66-
"forward_whole_payload": {"required": False, "allow_null": False},
6766
"http_method": {"required": False, "allow_null": False, "allow_blank": False},
6867
"integration_filter": {"required": False, "allow_null": True},
6968
}

engine/apps/public_api/tests/test_custom_actions.py

+37-8
Original file line numberDiff line numberDiff line change
@@ -354,28 +354,59 @@ def test_create_custom_action_valid_after_render_use_all_data(make_organization_
354354

355355

356356
@pytest.mark.django_db
357+
@pytest.mark.django_db
358+
@pytest.mark.parametrize(
359+
"data",
360+
[
361+
(
362+
{
363+
"name": "RENAMED",
364+
"url": "https://example.com",
365+
}
366+
),
367+
(
368+
{
369+
"name": "RENAMED 1",
370+
"url": "https://example.com",
371+
"user": None,
372+
"password": None,
373+
"data": None,
374+
"authorization_header": None,
375+
"forward_whole_payload": True,
376+
}
377+
),
378+
(
379+
{
380+
"name": "RENAMED 2",
381+
"url": "https://example.com",
382+
"user": "",
383+
"password": "",
384+
"data": "",
385+
"authorization_header": "",
386+
"forward_whole_payload": True,
387+
}
388+
),
389+
],
390+
)
357391
def test_update_custom_action(
358392
make_organization_and_user_with_token,
359393
make_custom_webhook,
394+
data,
360395
):
361396
organization, user, token = make_organization_and_user_with_token()
362397
client = APIClient()
363398

364399
custom_action = make_custom_webhook(organization=organization)
365400

366401
url = reverse("api-public:actions-detail", kwargs={"pk": custom_action.public_primary_key})
367-
368-
data = {
369-
"name": "RENAMED",
370-
}
371-
372402
assert custom_action.name != data["name"]
373403

374404
response = client.put(url, data=data, format="json", HTTP_AUTHORIZATION=f"{token}")
405+
custom_action.refresh_from_db()
375406

376407
expected_result = {
377408
"id": custom_action.public_primary_key,
378-
"name": data["name"],
409+
"name": custom_action.name,
379410
"team_id": None,
380411
"url": custom_action.url,
381412
"data": custom_action.data,
@@ -392,8 +423,6 @@ def test_update_custom_action(
392423
}
393424

394425
assert response.status_code == status.HTTP_200_OK
395-
custom_action.refresh_from_db()
396-
assert custom_action.name == expected_result["name"]
397426
assert response.data == expected_result
398427

399428

engine/apps/public_api/views/action.py

+1-2
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
from rest_framework.permissions import IsAuthenticated
33
from rest_framework.viewsets import ModelViewSet
44

5-
from apps.api.serializers.webhook import WebhookSerializer
65
from apps.auth_token.auth import ApiTokenAuthentication
76
from apps.public_api.serializers.action import ActionCreateSerializer, ActionUpdateSerializer
87
from apps.public_api.throttlers.user_throttle import UserThrottle
@@ -19,7 +18,7 @@ class ActionView(RateLimitHeadersMixin, PublicPrimaryKeyMixin, UpdateSerializerM
1918
pagination_class = FiftyPageSizePaginator
2019
throttle_classes = [UserThrottle]
2120

22-
model = WebhookSerializer
21+
model = Webhook
2322
serializer_class = ActionCreateSerializer
2423
update_serializer_class = ActionUpdateSerializer
2524

0 commit comments

Comments
 (0)