This is an automated email from the ASF dual-hosted git repository.
sbp pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/tooling-trusted-releases.git
The following commit(s) were added to refs/heads/main by this push:
new 3cffe56 Avoid sending archive URL state through forms
3cffe56 is described below
commit 3cffe561607cf40143cb0b6a8497d8484ac30b72
Author: Sean B. Palmer <[email protected]>
AuthorDate: Tue Oct 28 20:44:46 2025 +0000
Avoid sending archive URL state through forms
---
Makefile | 2 +-
atr/forms.py | 4 +++
atr/get/vote.py | 9 +++---
atr/post/resolve.py | 38 ++++++++++++++------------
atr/shared/__init__.py | 4 +--
atr/templates/check-selected-release-info.html | 4 +--
scripts/build | 2 +-
7 files changed, 34 insertions(+), 29 deletions(-)
diff --git a/Makefile b/Makefile
index 3c31596..9f1802b 100644
--- a/Makefile
+++ b/Makefile
@@ -68,7 +68,7 @@ ipython:
uv run --frozen --with ipython ipython
run-alpine:
- docker run -p 8080:8080 -p 2222:2222 \
+ docker run --rm -p 8080:8080 -p 2222:2222 \
-v "$$PWD/state:/opt/atr/state" \
-v
"$$PWD/state/localhost.apache.org+3-key.pem:/opt/atr/state/key.pem" \
-v "$$PWD/state/localhost.apache.org+3.pem:/opt/atr/state/cert.pem" \
diff --git a/atr/forms.py b/atr/forms.py
index bd0f3fe..a58daa0 100644
--- a/atr/forms.py
+++ b/atr/forms.py
@@ -86,6 +86,10 @@ class Hidden(Typed):
submit = wtforms.SubmitField()
+class Submit(Typed):
+ submit = wtforms.SubmitField()
+
+
class Value(Typed):
value = wtforms.StringField(validators=[REQUIRED])
submit = wtforms.SubmitField()
diff --git a/atr/get/vote.py b/atr/get/vote.py
index 6a8304e..f2da908 100644
--- a/atr/get/vote.py
+++ b/atr/get/vote.py
@@ -83,12 +83,11 @@ async def selected(session: web.Committer | None,
project_name: str, version_nam
wagp = write.as_general_public()
archive_url = await wagp.cache.get_message_archive_url(task_mid)
- hidden_form = None
+ resolve_form = None
if can_resolve:
# Special form for the [ Resolve vote ] button, to make it POST
- hidden_form = await forms.Hidden.create_form()
- hidden_form.hidden_field.data = archive_url or ""
- hidden_form.submit.label.text = "Resolve vote"
+ resolve_form = await forms.Submit.create_form()
+ resolve_form.submit.label.text = "Resolve vote"
form = None
if can_vote:
@@ -116,7 +115,7 @@ async def selected(session: web.Committer | None,
project_name: str, version_nam
release,
task_mid=task_mid,
form=form,
- hidden_form=hidden_form,
+ resolve_form=resolve_form,
archive_url=archive_url,
vote_task=latest_vote_task,
can_vote=can_vote,
diff --git a/atr/post/resolve.py b/atr/post/resolve.py
index 1803de6..c85dcf8 100644
--- a/atr/post/resolve.py
+++ b/atr/post/resolve.py
@@ -16,11 +16,11 @@
# under the License.
-import asfquart.base as base
import quart
import werkzeug.wrappers.response as response
import atr.blueprints.post as post
+import atr.db.interaction as interaction
import atr.forms as forms
import atr.get as get
import atr.models.sql as sql
@@ -127,30 +127,32 @@ async def tabulated_selected_post(session: web.Committer,
project_name: str, ver
if release.vote_manual:
raise RuntimeError("This page is for tabulated votes only")
- hidden_form = await forms.Hidden.create_form()
+ submit_form = await forms.Submit.create_form()
details = None
committee = None
thread_id = None
archive_url = None
fetch_error = None
- if await hidden_form.validate_on_submit():
- # TODO: Just pass the thread_id itself instead?
- # TODO: The hidden field is user controlled data, so we should HMAC it
- # Ideally there would be a concept of authenticated hidden fields
- # Perhaps all hidden fields should be authenticated
- # We should also still validate all HMACed fields
- archive_url = hidden_form.hidden_field.data or ""
+ if await submit_form.validate_on_submit():
+ latest_vote_task = await interaction.release_latest_vote_task(release)
+ if latest_vote_task is not None:
+ task_mid = interaction.task_mid_get(latest_vote_task)
+ if task_mid:
+ async with storage.write(session) as write:
+ wagp = write.as_general_public()
+ archive_url = await
wagp.cache.get_message_archive_url(task_mid)
+
if archive_url:
- if not web.valid_url(archive_url, "lists.apache.org"):
- raise base.ASFQuartException("Invalid vote thread URL",
errorcode=400)
- thread_id = archive_url.split("/")[-1]
- if thread_id:
- try:
- committee = await tabulate.vote_committee(thread_id, release)
- except util.FetchError as e:
- fetch_error = f"Failed to fetch thread metadata: {e}"
+ thread_id = archive_url.split("/")[-1]
+ if thread_id:
+ try:
+ committee = await tabulate.vote_committee(thread_id,
release)
+ except util.FetchError as e:
+ fetch_error = f"Failed to fetch thread metadata: {e}"
+ else:
+ details = await tabulate.vote_details(committee,
thread_id, release)
else:
- details = await tabulate.vote_details(committee, thread_id,
release)
+ fetch_error = "The vote thread could not yet be found."
else:
fetch_error = "The vote thread could not yet be found."
resolve_form = await shared.resolve.ResolveVoteForm.create_form()
diff --git a/atr/shared/__init__.py b/atr/shared/__init__.py
index 14f86a5..0675e01 100644
--- a/atr/shared/__init__.py
+++ b/atr/shared/__init__.py
@@ -79,7 +79,7 @@ async def check(
release: sql.Release,
task_mid: str | None = None,
form: wtforms.Form | None = None,
- hidden_form: wtforms.Form | None = None,
+ resolve_form: wtforms.Form | None = None,
archive_url: str | None = None,
vote_task: sql.Task | None = None,
can_vote: bool = False,
@@ -159,7 +159,7 @@ async def check(
archive_url=archive_url,
vote_task_warnings=vote_task_warnings,
empty_form=empty_form,
- hidden_form=hidden_form,
+ resolve_form=resolve_form,
has_files=has_files,
strict_checking_errors=strict_checking_errors,
can_vote=can_vote,
diff --git a/atr/templates/check-selected-release-info.html
b/atr/templates/check-selected-release-info.html
index 09d1b6c..51e15db 100644
--- a/atr/templates/check-selected-release-info.html
+++ b/atr/templates/check-selected-release-info.html
@@ -80,11 +80,11 @@
{% if can_resolve and release.vote_manual %}
<a href="{{ as_url(get.resolve.manual_selected,
project_name=release.project.name, version_name=release.version) }}"
class="btn btn-success"><i class="bi bi-clipboard-check
me-1"></i> Resolve vote</a>
- {% elif can_resolve and hidden_form %}
+ {% elif can_resolve and resolve_form %}
<form action="{{ as_url(post.resolve.tabulated_selected_post,
project_name=release.project.name, version_name=release.version) }}"
method="post"
class="mb-0">
- {{ hidden_form.hidden_tag() }}
+ {{ resolve_form.hidden_tag() }}
<button type="submit" class="btn btn-success">
<i class="bi bi-clipboard-check me-1"></i> Resolve vote
</button>
diff --git a/scripts/build b/scripts/build
index 2761c5b..40f1347 100755
--- a/scripts/build
+++ b/scripts/build
@@ -4,4 +4,4 @@ set -eu
DOCKERFILE="${1:-Dockerfile.alpine}"
IMAGE="${2:-tooling-trusted-releases}"
-docker build -t "${IMAGE}" -f "${DOCKERFILE}" .
+docker build --no-cache -t "${IMAGE}" -f "${DOCKERFILE}" .
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]