Skip to content

Commit 826273d

Browse files
M7mdiskbartaz
andauthored
refactor snap reports (#5578)
Co-authored-by: Bartek Szopka <83575+bartaz@users.noreply.github.com>
1 parent 14b3c44 commit 826273d

6 files changed

Lines changed: 44 additions & 49 deletions

File tree

.env

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,4 @@ ENVIRONMENT=devel
55
FLASK_DEBUG=true
66
DEVEL=True
77
SECRET_KEY=local_development_fake_key
8-
LP_API_USERNAME=test_lp_user
8+
LP_API_USERNAME=test_lp_user

konf/site.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,11 @@ env: &env
8686
key: dns-verification-salt
8787
name: snapcraft-io
8888

89+
- name: REPORT_SHEET_URL
90+
secretKeyRef:
91+
key: report-sheet-url
92+
name: snapcraft-io
93+
8994
memoryLimit: 256Mi
9095

9196
extraHosts:

static/js/public/snap-details/reportSnap.ts

Lines changed: 8 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -48,13 +48,6 @@ export default function initReportSnap(
4848
const modal = document.querySelector(modalSelector) as HTMLElement;
4949
const reportForm = modal.querySelector("form") as HTMLFormElement;
5050

51-
const honeypotField = reportForm.querySelector(
52-
"#report-snap-confirm",
53-
) as HTMLInputElement;
54-
const commentField = reportForm.querySelector(
55-
"#report-snap-comment",
56-
) as HTMLInputElement;
57-
5851
toggle.addEventListener("click", (event) => {
5952
event.preventDefault();
6053
toggleModal(modal);
@@ -75,30 +68,22 @@ export default function initReportSnap(
7568
"Submitting…",
7669
);
7770

78-
if (
79-
honeypotField.checked ||
80-
(commentField.value && commentField.value.includes("http"))
81-
) {
82-
showSuccess(modal);
83-
return;
84-
}
85-
8671
try {
8772
const resp = await fetch(formURL, {
8873
method: "POST",
8974
body: new FormData(reportForm),
90-
mode: "no-cors",
9175
});
9276

77+
if (!resp.ok) {
78+
showError(modal);
79+
return;
80+
}
81+
9382
if (reportForm.action.endsWith("/report")) {
9483
const data = await resp.json();
95-
if (data.url) {
96-
const formData = new FormData(reportForm);
97-
fetch(data.url, {
98-
method: "POST",
99-
body: formData,
100-
mode: "no-cors",
101-
});
84+
if (!data.ok) {
85+
showError(modal);
86+
return;
10287
}
10388
}
10489

templates/store/snap-details/_report_snap_modal.html

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,10 @@ <h2 class="p-modal__title" id="modal-title">Report {{snap_title}} for a Snap Sto
66
<button class="p-modal__close js-modal-close" aria-label="Close dialog">Close</button>
77
</header>
88

9-
{# report snap form submits to a Google Forms #}
10-
{# names of the inputs need to be consistend with the original form #}
9+
{# report snap form submits to the app endpoint #}
1110
<form id="report-snap-form" action="/report" method="POST">
1211
<input name="csrf_token" type="hidden" value="{{csrf_token()}}" />
13-
<input type="hidden" name="entry.718227286" value="{{package_name}}" />
12+
<input type="hidden" name="snap_name" value="{{package_name}}" />
1413
<div class="p-notification--negative">
1514
<div class="p-notification__content">
1615
<h5 class="p-notification__title">
@@ -41,18 +40,16 @@ <h5 class="p-notification__title">
4140
</div>
4241
</div>
4342
<label for="report-snap-reason">Choose a reason for reporting this snap</label>
44-
<select id="report-snap-reason" name="entry.340540050" required>
43+
<select id="report-snap-reason" name="reason" required>
4544
<option value="" selected>Select an option</option>
4645
<option value="Copyright or trademark violation">Copyright or trademark violation</option>
4746
<option value="Snap Store terms of service violation">Snap Store terms of service violation</option>
4847
</select>
4948
<label for="report-snap-comment">Please provide more detailed reason to your report</label>
50-
<textarea id="report-snap-comment" type="text" name="entry.1974584359" placeholder="Comment..." rows="5" maxlength="1000" required></textarea>
49+
<textarea id="report-snap-comment" type="text" name="comment" placeholder="Comment..." rows="5" maxlength="1000" required></textarea>
5150

5251
<label for="report-snap-email">Your email (optional)</label>
53-
<input id="report-snap-email" type="email" name="entry.1624813972" placeholder="email@example.com" />
54-
<label for="report-snap-confirm" style="position: absolute; top: -9999999px;">I agree</label>
55-
<input id="report-snap-confirm" type="checkbox" name="entry.13371337" style="position: absolute; top: -9999999px;" />
52+
<input id="report-snap-email" type="email" name="email" placeholder="email@example.com" />
5653
<p>In submitting this form, I confirm that I have read and agree to <a href="https://ubuntu.com/legal/data-privacy/contact">Canonical’s Privacy Notice</a> and <a href="https://ubuntu.com/legal/data-privacy">Privacy Policy</a>.</p>
5754
<div class="u-align--right">
5855
<button type="button" class="js-modal-close u-no-margin--bottom">Cancel</button>

webapp/config.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,3 +49,5 @@ class ConfigurationError(Exception):
4949
SEARCH_CUSTOM_ID = "009048213575199080868:i3zoqdwqk8o"
5050

5151
APP_NAME = "snapcraft"
52+
53+
REPORT_SHEET_URL = os.getenv("REPORT_SHEET_URL", "").strip()

webapp/store/snap_details_views.py

Lines changed: 23 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -535,24 +535,30 @@ def snap_distro_install(snap_name, distro):
535535

536536
@store.route("/report", methods=["POST"])
537537
def report_snap():
538-
form_url = "/".join(
539-
[
540-
"https://docs.google.com",
541-
"forms",
542-
"d",
543-
"e",
544-
"1FAIpQLSc5w1Ow6hRGs-VvBXmDtPOZaadYHEpsqCl2RbKEenluBvaw3Q",
545-
"formResponse",
546-
]
547-
)
538+
form_url = flask.current_app.config.get("REPORT_SHEET_URL")
539+
if not form_url:
540+
logger.warning("REPORT_SHEET_URL is not configured")
541+
return flask.jsonify({"error": "report_url_missing"}), 503
548542

549543
fields = flask.request.form
550544

551-
# If the honeypot is activated or a URL is included in the message,
552-
# say "OK" to avoid spam
553-
if (
554-
"entry.13371337" in fields and fields["entry.13371337"] == "on"
555-
) or "http" in fields["entry.1974584359"]:
556-
return "", 200
545+
payload = {
546+
"snap_name": fields.get("snap_name", ""),
547+
"reason": fields.get("reason", ""),
548+
"comment": fields.get("comment", ""),
549+
"email": fields.get("email", ""),
550+
}
557551

558-
return flask.jsonify({"url": form_url}), 200
552+
try:
553+
response = requests.post(form_url, data=payload)
554+
if not response.ok:
555+
logger.warning(
556+
"Report sheet webhook returned %s",
557+
response.status_code,
558+
)
559+
return flask.jsonify({"error": "report_failed"}), 502
560+
except requests.RequestException:
561+
logger.exception("Report sheet webhook request failed")
562+
return flask.jsonify({"error": "report_failed"}), 502
563+
564+
return flask.jsonify({"ok": True}), 200

0 commit comments

Comments
 (0)