Skip to content

Commit

Permalink
Fix MultipleObjectsReturned error on webhook endpoints (#1996)
Browse files Browse the repository at this point in the history
# What this PR does
Sometimes `CustomButtonView` returns HTTP 500 with the following error:

```
apps.alerts.models.custom_button.CustomButton.MultipleObjectsReturned: get() returned more than one CustomButton -- it returned 3!
```

This PR fixes it by adding `.distinct()` to the `CustomButton` queryset
when retrieving an instance + does the same for `WebhooksView`.

## Which issue(s) this PR fixes
Related to grafana/oncall-private#1828

## 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)
  • Loading branch information
vstpme authored May 23, 2023
1 parent c921674 commit 06bd045
Show file tree
Hide file tree
Showing 4 changed files with 11 additions and 2 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Fixed

- Improve plugin authentication by @vadimkerr ([#1995](https://github.com/grafana/oncall/pull/1995))
- Fix MultipleObjectsReturned error on webhook endpoints by @vadimkerr ([#1996](https://github.com/grafana/oncall/pull/1996))

## v1.2.27 (2023-05-23)

Expand Down
6 changes: 5 additions & 1 deletion engine/apps/api/views/custom_button.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,11 @@ def get_object_from_organization(self):
pk = self.kwargs["pk"]
organization = self.request.auth.organization
try:
obj = organization.custom_buttons.filter(*self.available_teams_lookup_args).get(public_primary_key=pk)
obj = (
organization.custom_buttons.filter(*self.available_teams_lookup_args)
.distinct()
.get(public_primary_key=pk)
)
except ObjectDoesNotExist:
raise NotFound

Expand Down
2 changes: 1 addition & 1 deletion engine/apps/api/views/webhooks.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ def get_object_from_organization(self):
pk = self.kwargs["pk"]
organization = self.request.auth.organization
try:
obj = organization.webhooks.filter(*self.available_teams_lookup_args).get(public_primary_key=pk)
obj = organization.webhooks.filter(*self.available_teams_lookup_args).distinct().get(public_primary_key=pk)
except ObjectDoesNotExist:
raise NotFound

Expand Down
4 changes: 4 additions & 0 deletions engine/common/api_helpers/mixins.py
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,10 @@ class TeamFilteringMixin:

@property
def available_teams_lookup_args(self):
"""
This property returns a list of Q objects that are used to filter instances by teams available to the user.
NOTE: use .distinct() after filtering by available teams as it may return duplicate instances.
"""
available_teams_lookup_args = []
if not self.request.user.role == LegacyAccessControlRole.ADMIN:
available_teams_lookup_args = [
Expand Down

0 comments on commit 06bd045

Please sign in to comment.