This is an automated email from the ASF dual-hosted git repository.
sbp pushed a commit to branch sbp
in repository https://gitbox.apache.org/repos/asf/tooling-trusted-releases.git
The following commit(s) were added to refs/heads/sbp by this push:
new 02787d1f Move key association management to the storage interface
02787d1f is described below
commit 02787d1fe2ee9e08696dc0abd383e95a91b89ed1
Author: Sean B. Palmer <[email protected]>
AuthorDate: Thu Apr 2 19:57:51 2026 +0100
Move key association management to the storage interface
---
atr/post/keys.py | 38 +++++++++----------------------
atr/storage/writers/keys.py | 54 +++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 64 insertions(+), 28 deletions(-)
diff --git a/atr/post/keys.py b/atr/post/keys.py
index 69b3ece3..16c4c8e3 100644
--- a/atr/post/keys.py
+++ b/atr/post/keys.py
@@ -107,34 +107,16 @@ async def details(
key_fingerprint = str(fingerprint).lower()
try:
- async with db.session() as data:
- key = await data.public_signing_key(fingerprint=key_fingerprint,
_committees=True).get()
- if not key:
- await quart.flash("OpenPGP key not found", "error")
- return await session.redirect(get.keys.keys)
-
- if not (key.apache_uid and session.uid and (key.apache_uid.lower()
== session.uid.lower())):
- await quart.flash("You are not authorized to modify this key",
"error")
- return await session.redirect(get.keys.keys)
-
- selected_committee_keys = update_form.selected_committees
- old_committee_keys = {c.key for c in key.committees}
-
- new_committees = await
data.committee(name_in=selected_committee_keys).all()
- key.committees = list(new_committees)
- data.add(key)
- await data.commit()
-
- affected_committee_keys =
old_committee_keys.union(set(selected_committee_keys))
- if affected_committee_keys:
- async with storage.write() as write:
- for affected_committee_key in affected_committee_keys:
- wacm =
write.as_committee_member_outcome(affected_committee_key).result_or_none()
- if wacm is None:
- continue
- await wacm.keys.autogenerate_keys_file()
-
- await quart.flash("Key committee associations updated
successfully.", "success")
+ async with storage.write() as write:
+ wafc = write.as_foundation_committer()
+ await wafc.keys.update_committee_associations(
+ key_fingerprint,
+ update_form.selected_committees,
+ )
+
+ await quart.flash("Key committee associations updated successfully.",
"success")
+ except storage.AccessError as e:
+ await quart.flash(str(e), "error")
except Exception as e:
log.exception("Error updating key committee associations:")
await quart.flash(f"An unexpected error occurred: {e!s}", "error")
diff --git a/atr/storage/writers/keys.py b/atr/storage/writers/keys.py
index 3a29ae1a..cebad86c 100644
--- a/atr/storage/writers/keys.py
+++ b/atr/storage/writers/keys.py
@@ -211,6 +211,60 @@ class FoundationCommitter(GeneralPublic):
except Exception as e:
return outcome.Error(e)
+ async def update_committee_associations(
+ self,
+ fingerprint: str,
+ selected_committee_keys: list[str],
+ ) -> set[str]:
+ via = sql.validate_instrumented_attribute
+
+ key = await self.__data.public_signing_key(
+ fingerprint=fingerprint,
+ apache_uid=self.__asf_uid,
+ _committees=True,
+ ).get()
+ if not key:
+ raise storage.AccessError("Key not found or not owned by you")
+
+ old_committee_keys = {c.key for c in key.committees}
+ new_committee_keys = set(selected_committee_keys)
+ to_add = new_committee_keys - old_committee_keys
+ to_remove = old_committee_keys - new_committee_keys
+ affected = to_add | to_remove
+
+ if not affected:
+ return affected
+
+ for committee_key in sorted(to_add):
+ self.__write.as_committee_participant(committee_key)
+
+ await self.__data.begin_immediate()
+
+ if to_add:
+ link_values = [{"committee_key": ck, "key_fingerprint":
fingerprint} for ck in to_add]
+ await self.__data.execute(
+ sqlite.insert(sql.KeyLink)
+ .values(link_values)
+ .on_conflict_do_nothing(index_elements=["committee_key",
"key_fingerprint"])
+ )
+
+ if to_remove:
+ await self.__data.execute(
+ sqlmodel.delete(sql.KeyLink).where(
+ via(sql.KeyLink.key_fingerprint) == fingerprint,
+ via(sql.KeyLink.committee_key).in_(to_remove),
+ )
+ )
+
+ await self.__data.commit()
+
+ for committee_key in sorted(affected):
+ wacp =
self.__write.as_committee_participant_outcome(committee_key).result_or_none()
+ if wacp is not None:
+ await wacp.keys.autogenerate_keys_file()
+
+ return affected
+
def __block_model(self, key_block: str, ldap_data: dict[str, str]) ->
types.Key:
# This cache is only held for the session
if key_block in self.__key_block_models_cache:
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]