Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(contact_form): Enable selection of issue type and enable Jira integration #4605

Merged
merged 9 commits into from
Oct 22, 2024
27 changes: 26 additions & 1 deletion cl/simple_pages/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,18 @@


class ContactForm(forms.Form):
REMOVAL_REQUEST = "removal"
RECAP_BUG = "recap"
SUPPORT_REQUEST = "support"

ISSUE_TYPE_CHOICES = [
(REMOVAL_REQUEST, "Case Removal Request"),
(RECAP_BUG, "RECAP Extension Bug"),
(SUPPORT_REQUEST, "Support"),
]

VALID_ISSUE_TYPES = [REMOVAL_REQUEST, RECAP_BUG, SUPPORT_REQUEST]

name = forms.CharField(
widget=forms.TextInput(attrs={"class": "form-control"})
)
Expand All @@ -14,6 +26,11 @@ class ContactForm(forms.Form):
widget=forms.TextInput(attrs={"class": "form-control"})
)

issue_type = forms.ChoiceField(
choices=ISSUE_TYPE_CHOICES,
widget=forms.Select(attrs={"class": "form-control"}),
)

# This is actually the "Subject" field, but we call it the phone_number
# field to defeat spam.
phone_number = forms.CharField(
Expand Down Expand Up @@ -41,11 +58,19 @@ def clean(self) -> Dict[str, Any] | None:
r"remov(e|al)|take down",
re.I,
)
if re.search(regex, subject) and "http" not in message.lower():
is_removal_request = (
re.search(regex, subject)
or cleaned_data.get("issue_type", "") == self.REMOVAL_REQUEST
)
if is_removal_request and "http" not in message.lower():
msg = (
"This appears to be a removal request, but you did not "
"include a link. You must include a link for a request to be "
"valid."
)
self.add_error("message", msg)
return cleaned_data

def get_issue_type_display(self) -> str:
value = self.cleaned_data.get("issue_type", "")
return dict(self.ISSUE_TYPE_CHOICES).get(value, "Unidentified Type")
12 changes: 12 additions & 0 deletions cl/simple_pages/templates/contact_form.html
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,18 @@ <h1 class="text-center v-offset-below-2">Contact Us</h1>
{% endif %}
</div>

<div class="form-group">
<label for="id_issue_type">Issue Type</label>
{{ form.issue_type }}
{% if form.issue_type.errors %}
<p class="help-block">
{% for error in form.issue_type.errors %}
{{ error|escape }}
{% endfor %}
</p>
{% endif %}
</div>

{# We use the phone_number field as the subject field to defeat spam #}
<div class="form-group">
<label for="id_phone_number">Subject</label>
Expand Down
1 change: 1 addition & 0 deletions cl/simple_pages/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ class ContactTest(SimpleUserDataMixin, TestCase):
test_msg = {
"name": "pandora",
"phone_number": "asdf",
"issue_type": "support",
"message": "123456789012345678901",
"email": "pandora@box.com",
"hcaptcha": "xxx",
Expand Down
12 changes: 10 additions & 2 deletions cl/simple_pages/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -378,24 +378,32 @@ async def contact(
logger.info("Detected spam message. Not sending email.")
return HttpResponseRedirect(reverse("contact_thanks"))

issue_type_label = form.get_issue_type_display()

default_from = settings.DEFAULT_FROM_EMAIL
message = EmailMessage(
subject="[CourtListener] Contact: "
"{phone_number}".format(**cd),
body="Subject: {phone_number}\n"
"From: {name} ({email})\n\n\n"
"From: {name}\n"
"User Email: <{email}>\n"
"Issue Type: {issue_type_label}\n\n"
"{message}\n\n"
"Browser: {browser}".format(
browser=request.META.get("HTTP_USER_AGENT", "Unknown"),
issue_type_label=issue_type_label,
**cd,
),
to=["info@free.law"],
to=["support@freelawproject.atlassian.net"],
reply_to=[cd.get("email", default_from) or default_from],
)
await sync_to_async(message.send)()
return HttpResponseRedirect(reverse("contact_thanks"))
else:
# the form is loading for the first time
issue_type = request.GET.get("issue_type")
if issue_type and issue_type.lower() in ContactForm.VALID_ISSUE_TYPES:
initial["issue_type"] = issue_type.lower()
user = await request.auser() # type: ignore[attr-defined]
if isinstance(user, User):
initial["email"] = user.email
Expand Down