0
0
Fork 0
mirror of https://github.com/healthchecks/healthchecks.git synced 2025-04-03 04:15:29 +00:00

Rename "phone" -> "recipient" in Signal add/edit forms

(since this field can now be a phone number *or* a username)
This commit is contained in:
Pēteris Caune 2024-12-28 11:21:34 +02:00
parent b22f359595
commit a05fb5cece
No known key found for this signature in database
GPG key ID: E28D7679E9A9EDE2
7 changed files with 33 additions and 34 deletions

View file

@ -284,15 +284,14 @@ class PhoneUpDownForm(PhoneNumberForm):
class SignalRecipientForm(forms.Form):
error_css_class = "has-error"
label = forms.CharField(max_length=100, required=False)
phone = forms.CharField()
recipient = forms.CharField()
def clean_phone(self) -> str:
v = self.cleaned_data["phone"]
def clean_recipient(self) -> str:
v = self.cleaned_data["recipient"]
stripped = v.encode("ascii", "ignore").decode("ascii")
assert isinstance(stripped, str)
stripped = stripped.replace(" ", "").replace("-", "")
if "." in stripped:
# Assume it is a username
if not re.match(r"^\w{3,48}\.\d{2,10}$", stripped):
@ -321,7 +320,7 @@ class SignalForm(SignalRecipientForm):
def get_json(self) -> str:
return json.dumps(
{
"value": self.cleaned_data["phone"],
"value": self.cleaned_data["recipient"],
"up": self.cleaned_data["up"],
"down": self.cleaned_data["down"],
}

View file

@ -22,7 +22,7 @@ class AddSignalTestCase(BaseTestCase):
def test_it_creates_channel(self) -> None:
form = {
"label": "My Phone",
"phone": "+1234567890",
"recipient": "+1234567890",
"down": "true",
"up": "true",
}
@ -45,7 +45,7 @@ class AddSignalTestCase(BaseTestCase):
def test_it_handles_username(self) -> None:
form = {
"label": "My Phone",
"phone": "foobar.123",
"recipient": "foobar.123",
"down": "true",
"up": "true",
}
@ -71,7 +71,7 @@ class AddSignalTestCase(BaseTestCase):
self.assertEqual(r.status_code, 403)
def test_it_handles_down_false_up_true(self) -> None:
form = {"phone": "+1234567890", "up": True}
form = {"recipient": "+1234567890", "up": True}
self.client.login(username="alice@example.org", password="password")
self.client.post(self.url, form)
@ -81,7 +81,7 @@ class AddSignalTestCase(BaseTestCase):
self.assertTrue(c.phone.notify_up)
def test_it_rejects_unchecked_up_and_down(self) -> None:
form = {"phone": "+1234567890"}
form = {"recipient": "+1234567890"}
self.client.login(username="alice@example.org", password="password")
r = self.client.post(self.url, form)
@ -90,17 +90,17 @@ class AddSignalTestCase(BaseTestCase):
def test_it_rejects_bad_phone(self) -> None:
for v in ["not a phone number", False, 15, "+123456789A"]:
self.client.login(username="alice@example.org", password="password")
r = self.client.post(self.url, {"phone": v})
r = self.client.post(self.url, {"recipient": v})
self.assertContains(r, "Invalid phone number format.")
def test_it_rejects_bad_username(self) -> None:
for v in ["a.123", "foobar.0"]:
self.client.login(username="alice@example.org", password="password")
r = self.client.post(self.url, {"phone": v})
r = self.client.post(self.url, {"recipient": v})
self.assertContains(r, "Invalid username format.")
def test_it_strips_invisible_formatting_characters(self) -> None:
form = {"phone": "\u202c+1234567890\u202c", "down": True}
form = {"recipient": "\u202c+1234567890\u202c", "down": True}
self.client.login(username="alice@example.org", password="password")
r = self.client.post(self.url, form)
@ -110,7 +110,7 @@ class AddSignalTestCase(BaseTestCase):
self.assertEqual(c.phone.value, "+1234567890")
def test_it_strips_hyphens(self) -> None:
form = {"phone": "+123-4567890", "down": True}
form = {"recipient": "+123-4567890", "down": True}
self.client.login(username="alice@example.org", password="password")
r = self.client.post(self.url, form)
@ -120,7 +120,7 @@ class AddSignalTestCase(BaseTestCase):
self.assertEqual(c.phone.value, "+1234567890")
def test_it_strips_spaces(self) -> None:
form = {"phone": " +123 45 678 90 ", "down": True}
form = {"recipient": " +123 45 678 90 ", "down": True}
self.client.login(username="alice@example.org", password="password")
r = self.client.post(self.url, form)

View file

@ -32,7 +32,7 @@ class EditSignalTestCase(BaseTestCase):
def test_it_updates_channel(self) -> None:
form = {
"label": "My Phone",
"phone": "+1234567890",
"recipient": "+1234567890",
"down": "true",
"up": "false",
}
@ -53,7 +53,7 @@ class EditSignalTestCase(BaseTestCase):
def test_it_handles_username(self) -> None:
form = {
"label": "My Phone",
"phone": "foobar.123",
"recipient": "foobar.123",
"down": "true",
"up": "false",
}

View file

@ -19,7 +19,7 @@ class VerifySignalNumberTestCase(BaseTestCase):
@patch("hc.front.views.Signal")
def test_it_works(self, mock_signal: Mock) -> None:
self.client.login(username="alice@example.org", password="password")
r = self.client.post(self.url, {"phone": "+1234567890"})
r = self.client.post(self.url, {"recipient": "+1234567890"})
self.assertContains(r, "All good, the message was sent")
@patch("hc.front.views.Signal")
@ -27,7 +27,7 @@ class VerifySignalNumberTestCase(BaseTestCase):
mock_signal.send.side_effect = TransportError("CAPTCHA proof required")
self.client.login(username="alice@example.org", password="password")
r = self.client.post(self.url, {"phone": "+1234567890"})
r = self.client.post(self.url, {"recipient": "+1234567890"})
self.assertContains(r, "We hit a Signal rate-limit")
@patch("hc.front.views.Signal")
@ -35,7 +35,7 @@ class VerifySignalNumberTestCase(BaseTestCase):
mock_signal.send.side_effect = TransportError("Recipient not found")
self.client.login(username="alice@example.org", password="password")
r = self.client.post(self.url, {"phone": "+1234567890"})
r = self.client.post(self.url, {"recipient": "+1234567890"})
self.assertContains(r, "Recipient not found")
@patch("hc.front.views.Signal")
@ -43,13 +43,13 @@ class VerifySignalNumberTestCase(BaseTestCase):
mock_signal.send.side_effect = TransportError("signal-cli call failed (123)")
self.client.login(username="alice@example.org", password="password")
r = self.client.post(self.url, {"phone": "+1234567890"})
r = self.client.post(self.url, {"recipient": "+1234567890"})
self.assertContains(r, "signal-cli call failed")
@patch("hc.front.views.Signal")
def test_it_handles_invalid_phone_number(self, mock_signal: Mock) -> None:
self.client.login(username="alice@example.org", password="password")
r = self.client.post(self.url, {"phone": "+123"})
r = self.client.post(self.url, {"recipient": "+123"})
self.assertContains(r, "Invalid phone number")
def test_it_requires_post(self) -> None:
@ -58,14 +58,14 @@ class VerifySignalNumberTestCase(BaseTestCase):
self.assertEqual(r.status_code, 405)
def test_it_requires_authenticated_user(self) -> None:
r = self.client.post(self.url, {"phone": "+1234567890"})
r = self.client.post(self.url, {"recipient": "+1234567890"})
self.assertRedirects(r, "/accounts/login/?next=" + self.url)
def test_it_obeys_per_account_rate_limit(self) -> None:
TokenBucket.objects.create(value=f"signal-verify-{self.alice.id}", tokens=0)
self.client.login(username="alice@example.org", password="password")
r = self.client.post(self.url, {"phone": "+1234567890"})
r = self.client.post(self.url, {"recipient": "+1234567890"})
self.assertContains(r, "Verification rate limit exceeded")
@override_settings(SECRET_KEY="test-secret")
@ -76,5 +76,5 @@ class VerifySignalNumberTestCase(BaseTestCase):
obj.save()
self.client.login(username="alice@example.org", password="password")
r = self.client.post(self.url, {"phone": "+123456789"})
r = self.client.post(self.url, {"recipient": "+123456789"})
self.assertContains(r, "Verification rate limit exceeded")

View file

@ -2285,7 +2285,7 @@ def signal_form(request: HttpRequest, channel: Channel) -> HttpResponse:
form = forms.SignalForm(
{
"label": channel.name,
"phone": channel.phone.value,
"recipient": channel.phone.value,
"up": channel.phone.notify_up,
"down": channel.phone.notify_down,
}
@ -2697,13 +2697,13 @@ def verify_signal_number(request: AuthenticatedHttpRequest) -> HttpResponse:
if not form.is_valid():
return render_result("Invalid phone number")
phone = form.cleaned_data["phone"]
recipient = form.cleaned_data["recipient"]
# Enforce per-recipient rate limit (6 messages per minute)
if not TokenBucket.authorize_signal(phone):
if not TokenBucket.authorize_signal(recipient):
return render_result("Verification rate limit exceeded")
try:
Signal.send(phone, f"Test message from {settings.SITE_NAME}")
Signal.send(recipient, f"Test message from {settings.SITE_NAME}")
except TransportError as e:
return render_result(e.message)

View file

@ -15,7 +15,7 @@ $(function () {
url: url,
type: "post",
headers: { "X-CSRFToken": token },
data: { phone: $("#id_number").val() },
data: { recipient: $("#id_number").val() },
success: function (data) {
$("#verify-result").html(data);
$("#submit-btn").attr("disabled", data.indexOf("alert-success") == -1);

View file

@ -45,7 +45,7 @@ Signal Settings - {% site_name %}
</div>
</div>
<div class="form-group {{ form.phone.css_classes }}">
<div class="form-group {{ form.recipient.css_classes }}">
<label for="id_number" class="col-sm-2 control-label">Phone or Username</label>
<div class="col-sm-6">
<div class="input-group">
@ -53,9 +53,9 @@ Signal Settings - {% site_name %}
id="id_number"
type="text"
class="form-control"
name="phone"
name="recipient"
placeholder="+1234567890 or xyz.123"
value="{{ form.phone.value|default:"" }}">
value="{{ form.recipient.value|default:"" }}">
<span class="input-group-btn">
<button
@ -69,9 +69,9 @@ Signal Settings - {% site_name %}
</span>
</div>
{% if form.phone.errors %}
{% if form.recipient.errors %}
<div class="help-block">
{{ form.phone.errors|join:"" }}
{{ form.recipient.errors|join:"" }}
</div>
{% else %}
<span class="help-block">