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-release.git
The following commit(s) were added to refs/heads/main by this push:
new 41a1861 Improve the fix for getting user committees from ASFQuart
properly
41a1861 is described below
commit 41a18614c4474383c59c89af4b6e81b47c5a8d85
Author: Sean B. Palmer <[email protected]>
AuthorDate: Fri Sep 19 15:22:14 2025 +0100
Improve the fix for getting user committees from ASFQuart properly
---
atr/blueprints/admin/admin.py | 6 ++++--
atr/log.py | 2 +-
atr/principal.py | 17 ++++++-----------
atr/routes/root.py | 2 +-
atr/storage/writers/keys.py | 21 +++++++++++++--------
5 files changed, 25 insertions(+), 23 deletions(-)
diff --git a/atr/blueprints/admin/admin.py b/atr/blueprints/admin/admin.py
index a687a01..df3d3d6 100644
--- a/atr/blueprints/admin/admin.py
+++ b/atr/blueprints/admin/admin.py
@@ -126,9 +126,9 @@ async def admin_browse_as() -> str | response.Response:
ldap_projects_data = await apache.get_ldap_projects_data()
committee_data = await apache.get_active_committee_data()
ldap_data = ldap_params.results_list[0]
- log.info("Current session data: %s", current_session)
+ log.info("Current ASFQuart session data: %s", current_session)
new_session_data = _session_data(ldap_data, new_uid, current_session,
ldap_projects_data, committee_data)
- log.info("New session data: %s", new_session_data)
+ log.info("New Quart cookie (not ASFQuart session) data: %s",
new_session_data)
session.write(new_session_data)
await quart.flash(
@@ -881,6 +881,8 @@ def _session_data(
"isMember": is_member,
"isChair": is_chair,
"isRoot": is_root,
+ # WARNING: ASFQuart session.ClientSession uses "committees"
+ # But this is cookie, not ClientSession, data, and requires "pmcs"
"pmcs": sorted(list(committees)),
"projects": sorted(list(projects)),
"mfa": current_session.mfa,
diff --git a/atr/log.py b/atr/log.py
index fe88ad4..2088320 100644
--- a/atr/log.py
+++ b/atr/log.py
@@ -116,7 +116,7 @@ def _caller_logger(depth: int = 1) -> logging.Logger:
def _event(level: int, msg: str, *args: Any, stacklevel: int = 3, **kwargs:
Any) -> None:
- logger = _caller_logger(depth=2)
+ logger = _caller_logger(depth=3)
# Stack level 1 is *here*, 2 is the caller, 3 is the caller of the caller
# I.e. _event (1), log.* (2), actual caller (3)
logger.log(level, msg, *args, stacklevel=stacklevel, **kwargs)
diff --git a/atr/principal.py b/atr/principal.py
index 8437567..af35fb0 100644
--- a/atr/principal.py
+++ b/atr/principal.py
@@ -250,18 +250,13 @@ class AuthoriserASFQuart:
async def cache_refresh(self, asf_uid: str, asfquart_session:
session.ClientSession) -> None:
if not self.__cache.outdated():
return
+ if not isinstance(asfquart_session, session.ClientSession):
+ # Defense in depth runtime check, already validated by the type
checker
+ raise AuthenticationError("ASFQuart session is not a
ClientSession")
# We do not check that the ASF UID is the same as the one in the
session
# It is the caller's responsibility to ensure this
- self.__cache.member_of[asf_uid] =
frozenset(asfquart_session.get("committees", []))
-
- # TODO: The code previously used "pmcs" above, which was incorrect
- # The following is a defense in depth check until the reason for this
is investigated
- # If there is no evidence to the contrary, we can assume that it was a
simple typo
- if ("pmcs" in asfquart_session) and ("committees" not in
asfquart_session):
- asfquart_session["committees"] = asfquart_session["pmcs"]
- # End of defense in depth check
-
- self.__cache.participant_of[asf_uid] =
frozenset(asfquart_session.get("projects", []))
+ self.__cache.member_of[asf_uid] =
frozenset(asfquart_session.committees)
+ self.__cache.participant_of[asf_uid] =
frozenset(asfquart_session.projects)
self.__cache.last_refreshed = int(time.time())
@@ -324,7 +319,7 @@ class Authorisation(AsyncObject):
if asfquart_session is None:
raise AuthenticationError("No ASFQuart session found")
self.__authoriser = authoriser_asfquart
- self.__asf_uid = asfquart_session.get("uid")
+ self.__asf_uid = asfquart_session.uid
if not isinstance(self.__asf_uid, str | None):
raise AuthenticationError("ASFQuart session has no uid")
self.__authenticated = True
diff --git a/atr/routes/root.py b/atr/routes/root.py
index 6cdc4af..40e3a2d 100644
--- a/atr/routes/root.py
+++ b/atr/routes/root.py
@@ -75,7 +75,7 @@ async def index(session: route.CommitterSession | None) ->
response.Response | s
"""Show public info or an entry portal for participants."""
session_data = await asfquart.session.read()
if session_data:
- uid = session_data.get("uid")
+ uid = session_data.uid
if not uid:
return await template.render("index-public.html")
diff --git a/atr/storage/writers/keys.py b/atr/storage/writers/keys.py
index 2fea75a..aee319c 100644
--- a/atr/storage/writers/keys.py
+++ b/atr/storage/writers/keys.py
@@ -500,14 +500,19 @@ class CommitteeParticipant(FoundationCommitter):
committee = await self.committee()
key_values = [key.key_model.model_dump(exclude={"committees"}) for key
in key_list]
- key_insert_result = await self.__data.execute(
- sqlite.insert(sql.PublicSigningKey)
- .values(key_values)
- .on_conflict_do_nothing(index_elements=["fingerprint"])
- .returning(via(sql.PublicSigningKey.fingerprint))
- )
- key_inserts = {row.fingerprint for row in key_insert_result}
- log.info(f"Inserted {len(key_inserts)} keys")
+ if key_values:
+ key_insert_result = await self.__data.execute(
+ sqlite.insert(sql.PublicSigningKey)
+ .values(key_values)
+ .on_conflict_do_nothing(index_elements=["fingerprint"])
+ .returning(via(sql.PublicSigningKey.fingerprint))
+ )
+ key_inserts = {row.fingerprint for row in key_insert_result}
+ log.info(f"Inserted {len(key_inserts)} keys")
+ else:
+ # TODO: Warn the user about any keys that were already inserted
+ key_inserts = set()
+ log.info("Inserted 0 keys (no keys to insert)")
def replace_with_inserted(key: types.Key) -> types.Key:
if key.key_model.fingerprint in key_inserts:
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]