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 f78c1cd Make the form to add an SSH key more type safe
f78c1cd is described below
commit f78c1cdb009b3712be4cfe8c5d326be0b8c1b92e
Author: Sean B. Palmer <[email protected]>
AuthorDate: Tue Nov 11 20:05:06 2025 +0000
Make the form to add an SSH key more type safe
---
atr/get/keys.py | 27 +++++++++++++++++++++++++--
atr/post/keys.py | 17 +++++++++++++++--
atr/shared/keys.py | 46 +++++-----------------------------------------
playwright/test.py | 2 +-
4 files changed, 46 insertions(+), 46 deletions(-)
diff --git a/atr/get/keys.py b/atr/get/keys.py
index f69c46f..8826785 100644
--- a/atr/get/keys.py
+++ b/atr/get/keys.py
@@ -146,9 +146,32 @@ async def keys(session: web.Committer) -> str:
@get.committer("/keys/ssh/add")
-async def ssh_add(session: web.Committer) -> web.WerkzeugResponse | str:
+async def ssh_add(session: web.Committer) -> str:
"""Add a new SSH key to the user's account."""
- return await shared.keys.ssh_add(session)
+ page = htm.Block()
+ page.p[htm.a(".atr-back-link", href=util.as_url(keys))["← Back to Manage
keys"]]
+ page.h1["Add your SSH key"]
+ page.p["Add your SSH public key to use for rsync authentication."]
+ page.div[
+ htm.p[
+ "Welcome, ",
+ htm.strong[session.uid],
+ "! You are authenticated as an ASF committer.",
+ ]
+ ]
+
+ form.render_block(
+ page,
+ model_cls=shared.keys.AddSSHKeyForm,
+ action=util.as_url(post.keys.ssh_add),
+ submit_label="Add SSH key",
+ )
+
+ return await template.blank(
+ "Add your SSH key",
+ content=page.collect(),
+ description="Add your SSH public key to your account.",
+ )
@get.committer("/keys/upload")
diff --git a/atr/post/keys.py b/atr/post/keys.py
index 28b221f..fea0d3f 100644
--- a/atr/post/keys.py
+++ b/atr/post/keys.py
@@ -166,9 +166,22 @@ async def import_selected_revision(
@post.committer("/keys/ssh/add")
-async def ssh_add(session: web.Committer) -> web.WerkzeugResponse | str:
[email protected](shared.keys.AddSSHKeyForm)
+async def ssh_add(session: web.Committer, add_ssh_key_form:
shared.keys.AddSSHKeyForm) -> web.WerkzeugResponse:
"""Add a new SSH key to the user's account."""
- return await shared.keys.ssh_add(session)
+ try:
+ async with storage.write(session) as write:
+ wafc = write.as_foundation_committer()
+ fingerprint = await wafc.ssh.add_key(add_ssh_key_form.key,
session.uid)
+
+ await quart.flash(f"SSH key added successfully: {fingerprint}",
"success")
+ except util.SshFingerprintError as e:
+ await quart.flash(str(e), "error")
+ except Exception as e:
+ log.exception("Error adding SSH key:")
+ await quart.flash(f"An unexpected error occurred: {e!s}", "error")
+
+ return await session.redirect(get.keys.keys)
@post.committer("/keys/upload")
diff --git a/atr/shared/keys.py b/atr/shared/keys.py
index 4ec8484..20747af 100644
--- a/atr/shared/keys.py
+++ b/atr/shared/keys.py
@@ -66,18 +66,14 @@ class AddOpenPGPKeyForm(form.Form):
return self
-class AddSSHKeyForm(forms.Typed):
- key = forms.textarea(
+class AddSSHKeyForm(form.Form):
+ key: str = form.label(
"SSH public key",
- placeholder="Paste your SSH public key here (in the format used in
authorized_keys files)",
- description=(
- "Your SSH public key should be in the standard format, starting
with a key type"
- ' (like "ssh-rsa" or "ssh-ed25519") followed by the key data.'
- ),
+ "Your SSH public key should be in the standard format, starting with a
key type"
+ ' (like "ssh-rsa" or "ssh-ed25519") followed by the key data.',
+ widget=form.Widget.TEXTAREA,
)
- submit = forms.submit("Add SSH key")
-
class DeleteOpenPGPKeyForm(form.Form):
variant: DELETE_OPENPGP_KEY = form.value(DELETE_OPENPGP_KEY)
@@ -218,38 +214,6 @@ async def details(session: web.Committer, fingerprint:
str) -> str | web.Werkzeu
)
-async def ssh_add(session: web.Committer) -> web.WerkzeugResponse | str:
- """Add a new SSH key to the user's account."""
- # TODO: Make an auth.require wrapper that gives the session automatically
- # And the form if it's a POST handler? Might be hard to type
- # But we can use variants of the function
- # GET, POST, GET_POST are all we need
- # We could even include auth in the function names
- form = await AddSSHKeyForm.create_form()
- fingerprint = None
- if await form.validate_on_submit():
- key: str = util.unwrap(form.key.data)
- try:
- async with storage.write(session) as write:
- wafc = write.as_foundation_committer()
- fingerprint = await wafc.ssh.add_key(key, session.uid)
- except util.SshFingerprintError as e:
- if isinstance(form.key.errors, list):
- form.key.errors.append(str(e))
- else:
- form.key.errors = [str(e)]
- else:
- success_message = f"SSH key added successfully: {fingerprint}"
- return await session.redirect(get.keys.keys,
success=success_message)
-
- return await template.render(
- "keys-ssh-add.html",
- asf_id=session.uid,
- form=form,
- fingerprint=fingerprint,
- )
-
-
async def upload(session: web.Committer) -> str:
"""Upload a KEYS file containing multiple OpenPGP keys."""
async with storage.write() as write:
diff --git a/playwright/test.py b/playwright/test.py
index e9e49d0..b1bfa29 100755
--- a/playwright/test.py
+++ b/playwright/test.py
@@ -1020,7 +1020,7 @@ def test_ssh_01_add_key(page: sync_api.Page, credentials:
Credentials) -> None:
page.locator('textarea[name="key"]').fill(public_key_content)
logging.info("Submitting the Add SSH key form")
- page.locator('input[type="submit"][value="Add SSH key"]').click()
+ page.get_by_role("button", name="Add SSH key").click()
logging.info("Waiting for navigation back to /keys page")
wait_for_path(page, "/keys")
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]