0
0
Fork 0
mirror of https://github.com/healthchecks/healthchecks.git synced 2025-04-06 21:58:48 +00:00

Fix a crash when adding an integration for an empty Trello account

This commit is contained in:
Pēteris Caune 2021-01-28 12:57:08 +02:00
parent b9997137a6
commit ae976a38b6
No known key found for this signature in database
GPG key ID: E28D7679E9A9EDE2
7 changed files with 65 additions and 22 deletions

View file

@ -15,6 +15,7 @@ All notable changes to this project will be documented in this file.
## Bug Fixes ## Bug Fixes
- Fix unwanted HTML escaping in SMS and WhatsApp notifications - Fix unwanted HTML escaping in SMS and WhatsApp notifications
- Fix a crash when adding an integration for an empty Trello account
## v1.18.0 - 2020-12-09 ## v1.18.0 - 2020-12-09

View file

@ -280,3 +280,13 @@ class AddZulipForm(forms.Form):
def get_value(self): def get_value(self):
return json.dumps(dict(self.cleaned_data), sort_keys=True) return json.dumps(dict(self.cleaned_data), sort_keys=True)
class AddTrelloForm(forms.Form):
token = forms.RegexField(regex=r"^[0-9a-fA-F]{64}$")
board_name = forms.CharField(max_length=100)
list_name = forms.CharField(max_length=100)
list_id = forms.RegexField(regex=r"^[0-9a-fA-F]{16,32}$")
def get_value(self):
return json.dumps(dict(self.cleaned_data), sort_keys=True)

View file

@ -18,14 +18,10 @@ class AddTrelloTestCase(BaseTestCase):
def test_it_works(self): def test_it_works(self):
form = { form = {
"settings": json.dumps( "token": "0" * 64,
{ "board_name": "My Board",
"token": "fake-token", "list_name": "My List",
"board_name": "My Board", "list_id": "1" * 32,
"list_name": "My List",
"list_id": "fake-list-id",
}
)
} }
self.client.login(username="alice@example.org", password="password") self.client.login(username="alice@example.org", password="password")
@ -34,7 +30,7 @@ class AddTrelloTestCase(BaseTestCase):
c = Channel.objects.get() c = Channel.objects.get()
self.assertEqual(c.kind, "trello") self.assertEqual(c.kind, "trello")
self.assertEqual(c.trello_token, "fake-token") self.assertEqual(c.trello_token, "0" * 64)
self.assertEqual(c.project, self.project) self.assertEqual(c.project, self.project)
@override_settings(TRELLO_APP_KEY=None) @override_settings(TRELLO_APP_KEY=None)
@ -50,3 +46,16 @@ class AddTrelloTestCase(BaseTestCase):
self.client.login(username="bob@example.org", password="password") self.client.login(username="bob@example.org", password="password")
r = self.client.get(self.url) r = self.client.get(self.url)
self.assertEqual(r.status_code, 403) self.assertEqual(r.status_code, 403)
def test_it_requires_board_name(self):
self.client.login(username="alice@example.org", password="password")
form = {
"token": "0" * 64,
"board_name": "",
"list_name": "My List",
"list_id": "1" * 32,
}
r = self.client.post(self.url, form)
self.assertEqual(r.status_code, 400)

View file

@ -24,3 +24,12 @@ class AddTrelloTestCase(BaseTestCase):
self.client.login(username="alice@example.org", password="password") self.client.login(username="alice@example.org", password="password")
r = self.client.get(self.url) r = self.client.get(self.url)
self.assertEqual(r.status_code, 404) self.assertEqual(r.status_code, 404)
@patch("hc.front.views.requests.get")
def test_it_handles_no_lists(self, mock_get):
mock_get.return_value.json.return_value = []
self.client.login(username="alice@example.org", password="password")
r = self.client.post(self.url)
self.assertNotContains(r, "Please select the Trello list")
self.assertContains(r, "Could not find any boards with lists")

View file

@ -1661,8 +1661,12 @@ def add_signal(request, code):
def add_trello(request, code): def add_trello(request, code):
project = _get_rw_project_for_user(request, code) project = _get_rw_project_for_user(request, code)
if request.method == "POST": if request.method == "POST":
form = forms.AddTrelloForm(request.POST)
if not form.is_valid():
return HttpResponseBadRequest()
channel = Channel(project=project, kind="trello") channel = Channel(project=project, kind="trello")
channel.value = request.POST["settings"] channel.value = form.get_value()
channel.save() channel.save()
channel.assign_all_checks() channel.assign_all_checks()
@ -1753,14 +1757,17 @@ def trello_settings(request):
{ {
"key": settings.TRELLO_APP_KEY, "key": settings.TRELLO_APP_KEY,
"token": token, "token": token,
"filter": "open",
"fields": "id,name", "fields": "id,name",
"lists": "open", "lists": "open",
"list_fields": "id,name", "list_fields": "id,name",
} }
) )
r = requests.get(url) boards = requests.get(url).json()
ctx = {"token": token, "data": r.json()} num_lists = sum(len(board["lists"]) for board in boards)
ctx = {"token": token, "boards": boards, "num_lists": num_lists}
return render(request, "integrations/trello_settings.html", ctx) return render(request, "integrations/trello_settings.html", ctx)

View file

@ -1,12 +1,9 @@
$(function() { $(function() {
function updateSettings() { function updateSettings() {
var opt = $('#list-selector').find(":selected"); var opt = $('#list-selector').find(":selected");
$("#settings").val(JSON.stringify({ $("#board-name").val(opt.data("boardName"));
"token": $("#settings").data("token"), $("#list-name").val(opt.data("listName"));
"list_id": opt.data("listId"), $("#list-id").val(opt.data("listId"));
"board_name": opt.data("boardName"),
"list_name": opt.data("listName")
}));
} }
var tokenMatch = window.location.hash.match(/token=(\w+)/); var tokenMatch = window.location.hash.match(/token=(\w+)/);

View file

@ -1,15 +1,19 @@
<p class="text-success">Authentication successful!</p> {% if num_lists %}
<p class="alert alert-success">Authentication successful!</p>
<p>Please select the Trello list to post notifications to:</p> <p>Please select the Trello list to post notifications to:</p>
<form method="post" class="form-horizontal"> <form method="post" class="form-horizontal">
{% csrf_token %} {% csrf_token %}
<input type="hidden" id="settings" name="settings" data-token="{{ token }}"/> <input type="hidden" name="token" value="{{ token }}" />
<input id="board-name" type="hidden" name="board_name" value="" />
<input id="list-name" type="hidden" name="list_name" value="" />
<input id="list-id" type="hidden" name="list_id" value="" />
<div class="form-group {{ form.value.css_classes }}"> <div class="form-group {{ form.value.css_classes }}">
<label for="list-selector" class="col-sm-3 control-label">Post Notifications to</label> <label for="list-selector" class="col-sm-3 control-label">Post Notifications to</label>
<div class="col-sm-3"> <div class="col-sm-3">
<select id="list-selector" name="board_list_id" class="form-control"> <select id="list-selector" name="board_list_id" class="form-control">
{% for board in data %} {% for board in boards %}
<optgroup label="{{ board.name }}"> <optgroup label="{{ board.name }}">
{% for list in board.lists %} {% for list in board.lists %}
<option <option
@ -34,4 +38,10 @@
<button type="submit" class="btn btn-primary">Save Integration</button> <button type="submit" class="btn btn-primary">Save Integration</button>
</div> </div>
</div> </div>
</form> </form>
{% else %}
<p class="alert alert-warning">
Could not find any boards with lists in your Trello account.
Are you logged in the correct Trello account?
</p>
{% endif %}