You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tooling.apache.org by sb...@apache.org on 2026/05/06 15:18:28 UTC
(tooling-trusted-releases) branch altera updated: Warn when OpenPGP keys are uploaded for a different or unknown user
This is an automated email from the ASF dual-hosted git repository.
sbp pushed a commit to branch altera
in repository https://gitbox.apache.org/repos/asf/tooling-trusted-releases.git
The following commit(s) were added to refs/heads/altera by this push:
new 7ea3170c Warn when OpenPGP keys are uploaded for a different or unknown user
7ea3170c is described below
commit 7ea3170ca3ff1f1627caea495990743b5eac0e5c
Author: Sean B. Palmer <se...@miscoranda.com>
AuthorDate: Wed May 6 16:17:35 2026 +0100
Warn when OpenPGP keys are uploaded for a different or unknown user
---
atr/post/keys.py | 30 ++++++++++++++++++++
tests/unit/test_keys_post.py | 66 ++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 96 insertions(+)
diff --git a/atr/post/keys.py b/atr/post/keys.py
index 439c6894..25f583a4 100644
--- a/atr/post/keys.py
+++ b/atr/post/keys.py
@@ -85,6 +85,7 @@ async def add(
await quart.flash(str(p), "warning")
else:
await quart.flash(f"OpenPGP key {fingerprint_upper} added successfully.", "success")
+ await _flash_openpgp_key_uid_warning(key.key_model, session.asf_uid)
except web.FlashError as e:
log.warning(f"FlashError adding OpenPGP key: {e}")
@@ -300,6 +301,35 @@ async def _fetch_keys_from_url(keys_url: str) -> str:
raise base.ASFQuartException(f"Network error while fetching keys: {e}", errorcode=503)
+async def _flash_openpgp_key_uid_warning(key_model: sql.PublicSigningKey, current_asf_uid: str) -> None:
+ warning = _openpgp_key_uid_warning(key_model, current_asf_uid)
+ if warning is not None:
+ await quart.flash(str(warning), "warning")
+
+
+def _openpgp_key_uid_warning(key_model: sql.PublicSigningKey, current_asf_uid: str) -> htm.Element | None:
+ fingerprint_upper = key_model.fingerprint.upper()
+ if key_model.apache_uid is None:
+ details_url = util.as_url(get.keys.details, fingerprint=key_model.fingerprint)
+ return htm.p[
+ f"OpenPGP key {fingerprint_upper} was uploaded and associated, but ATR could not determine an ASF UID "
+ "from the key user IDs. ",
+ htm.a(href=details_url)["Review key details"],
+ ".",
+ ]
+
+ if key_model.apache_uid.lower() != current_asf_uid.lower():
+ details_url = util.as_url(get.keys.details, fingerprint=key_model.fingerprint)
+ return htm.p[
+ f"OpenPGP key {fingerprint_upper} was uploaded and associated, but it appears to belong to ASF UID "
+ f"{key_model.apache_uid}, not {current_asf_uid}. ",
+ htm.a(href=details_url)["Review key details"],
+ ".",
+ ]
+
+ return None
+
+
async def _process_keys(keys_text: str, selected_committee: str) -> str:
"""Process keys text and associate with committee."""
async with storage.write() as write:
diff --git a/tests/unit/test_keys_post.py b/tests/unit/test_keys_post.py
new file mode 100644
index 00000000..cd5c2054
--- /dev/null
+++ b/tests/unit/test_keys_post.py
@@ -0,0 +1,66 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+import datetime
+
+import pytest
+
+import atr.models.sql as sql
+import atr.post.keys as keys
+
+
+def test_openpgp_key_uid_warning_allows_matching_asf_uid() -> None:
+ warning = keys._openpgp_key_uid_warning(_public_key(apache_uid="alice"), "Alice")
+
+ assert warning is None
+
+
+def test_openpgp_key_uid_warning_flags_missing_asf_uid(monkeypatch: pytest.MonkeyPatch) -> None:
+ monkeypatch.setattr(keys.util, "as_url", lambda *_args, **_kwargs: "/keys/details/fp")
+
+ warning = keys._openpgp_key_uid_warning(_public_key(apache_uid=None), "alice")
+
+ assert warning is not None
+ warning_html = str(warning)
+ assert "could not determine an ASF UID" in warning_html
+ assert "/keys/details/fp" in warning_html
+
+
+def test_openpgp_key_uid_warning_flags_other_asf_uid(monkeypatch: pytest.MonkeyPatch) -> None:
+ monkeypatch.setattr(keys.util, "as_url", lambda *_args, **_kwargs: "/keys/details/fp")
+
+ warning = keys._openpgp_key_uid_warning(_public_key(apache_uid="bob"), "alice")
+
+ assert warning is not None
+ warning_html = str(warning)
+ assert "appears to belong to ASF UID bob, not alice" in warning_html
+ assert "/keys/details/fp" in warning_html
+
+
+def _public_key(apache_uid: str | None) -> sql.PublicSigningKey:
+ return sql.PublicSigningKey(
+ fingerprint="fp",
+ algorithm=1,
+ length=4096,
+ created=datetime.datetime.now(datetime.UTC),
+ latest_self_signature=None,
+ expires=None,
+ primary_declared_uid="Alice <al...@example.org>",
+ secondary_declared_uids=[],
+ apache_uid=apache_uid,
+ ascii_armored_key="-----BEGIN PGP PUBLIC KEY BLOCK-----\nbody\n-----END PGP PUBLIC KEY BLOCK-----\n",
+ )
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@tooling.apache.org
For additional commands, e-mail: commits-help@tooling.apache.org