This is an automated email from the ASF dual-hosted git repository. wave pushed a commit to branch remove-hardcoded-tooling-users in repository https://gitbox.apache.org/repos/asf/tooling-trusted-releases.git
commit d4c44183910193b3879eb7daece10f3692a6b173 Author: Dave Fisher <[email protected]> AuthorDate: Mon Mar 2 14:46:51 2026 -0800 Remove hardcoded tooling users --- atr/config.py | 1 + atr/datasources/apache.py | 16 ++++++++++++---- atr/ldap.py | 34 ++++++++++++++++++++++++++++++++++ 3 files changed, 47 insertions(+), 4 deletions(-) diff --git a/atr/config.py b/atr/config.py index c42763dd..114bbbc7 100644 --- a/atr/config.py +++ b/atr/config.py @@ -126,6 +126,7 @@ class AppConfig: SESSION_COOKIE_NAME = "__Host-session" ADMIN_USERS_ADDITIONAL = decouple.config("ADMIN_USERS_ADDITIONAL", default="", cast=str) + TOOLING_USERS_ADDITIONAL = decouple.config("TOOLING_USERS_ADDITIONAL", default="", cast=str) class DebugConfig(AppConfig): diff --git a/atr/datasources/apache.py b/atr/datasources/apache.py index 0db6c0e8..a6faf5f3 100644 --- a/atr/datasources/apache.py +++ b/atr/datasources/apache.py @@ -27,7 +27,9 @@ if TYPE_CHECKING: import sqlmodel +import atr.config as config import atr.db as db +import atr.ldap as ldap import atr.log as log import atr.models.helpers as helpers import atr.models.schema as schema @@ -504,11 +506,17 @@ async def _update_tooling(data: db.Session) -> tuple[int, int]: else: updated_count += 1 + additional = config.get().TOOLING_USERS_ADDITIONAL + if additional: + extra = list(additional.split(",")) + else: + extra = list() + # Update Tooling PMC data - # Could put this in the "if not tooling_committee" block, perhaps - tooling_committee.committee_members = ["wave", "sbp", "arm", "akm"] - tooling_committee.committers = ["wave", "sbp", "arm", "akm"] - tooling_committee.release_managers = ["wave"] + tooling_users = await ldap.fetch_tooling_users(extra) + tooling_committee.committee_members = tooling_users + tooling_committee.committers = tooling_users + tooling_committee.release_managers = tooling_users tooling_committee.is_podling = False return added_count, updated_count diff --git a/atr/ldap.py b/atr/ldap.py index 54ed3d5a..98f0bf14 100644 --- a/atr/ldap.py +++ b/atr/ldap.py @@ -161,6 +161,40 @@ async def fetch_admin_users() -> frozenset[str]: return await asyncio.to_thread(_query_ldap) +async def fetch_tooling_users(extra: list[str]) -> list[str]: + import atr.log as log + + credentials = get_bind_credentials() + if credentials is None: + log.warning("LDAP bind DN or password not configured, returning empty admin set") + return extra + + bind_dn, bind_password = credentials + + def _query_ldap() -> list[str]: + users: list[str] = list() + with Search(bind_dn, bind_password) as ldap_search: + for base in (LDAP_TOOLING_BASE): + try: + result = ldap_search.search(ldap_base=base, ldap_scope="BASE") + if (not result) or (len(result) != 1): + continue + members = result[0].get("member", []) + if not isinstance(members, list): + continue + for member_dn in members: + parsed = parse_dn(member_dn) + uids = parsed.get("uid", []) + if uids: + users.add(uids[0]) + except Exception as e: + log.warning(f"Failed to query LDAP group {base}: {e}") + return users + + tooling = await asyncio.to_thread(_query_ldap) + return tooling | extra + + def get_bind_credentials() -> tuple[str, str] | None: import atr.config as config --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
