This is an automated email from the ASF dual-hosted git repository.

tn 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 1a6f9f8  Refactor is_admin function to user module, use 
is_committee_member instead of is_project_lead
1a6f9f8 is described below

commit 1a6f9f80ac48dfdfe210bcfb089c512b7a35d006
Author: Thomas Neidhart <[email protected]>
AuthorDate: Fri Mar 28 07:41:29 2025 +0100

    Refactor is_admin function to user module, use is_committee_member instead 
of is_project_lead
---
 atr/blueprints/admin/__init__.py |  4 ++--
 atr/db/service.py                |  6 ------
 atr/routes/projects.py           |  9 +++------
 atr/server.py                    |  7 +++----
 atr/templates/project-view.html  |  6 +++---
 atr/user.py                      | 15 +++++++++++++++
 atr/util.py                      | 13 -------------
 7 files changed, 26 insertions(+), 34 deletions(-)

diff --git a/atr/blueprints/admin/__init__.py b/atr/blueprints/admin/__init__.py
index 6b4371c..f3a992e 100644
--- a/atr/blueprints/admin/__init__.py
+++ b/atr/blueprints/admin/__init__.py
@@ -24,7 +24,7 @@ import asfquart.base as base
 import asfquart.session as session
 import quart
 
-import atr.util as util
+import atr.user as user
 
 BLUEPRINT: Final = quart.Blueprint("admin", __name__, url_prefix="/admin", 
template_folder="templates")
 
@@ -37,7 +37,7 @@ async def before_request_func() -> None:
         if web_session is None:
             raise base.ASFQuartException("Not authenticated", errorcode=401)
 
-        if web_session.uid not in util.get_admin_users():
+        if web_session.uid not in user.get_admin_users():
             raise base.ASFQuartException("You are not authorized to access the 
admin interface", errorcode=403)
 
     await check_logged_in()
diff --git a/atr/db/service.py b/atr/db/service.py
index ee031c8..61f9d22 100644
--- a/atr/db/service.py
+++ b/atr/db/service.py
@@ -26,12 +26,6 @@ import atr.db as db
 import atr.db.models as models
 
 
-def is_project_lead(project: models.Project, user_id: str) -> bool:
-    if project.committee is None:
-        raise RuntimeError(f"Committee for project {project.name} not set")
-    return user_id in project.committee.committee_members
-
-
 async def get_committee_by_name(
     name: str, session: sqlalchemy.ext.asyncio.AsyncSession | None = None
 ) -> models.Committee | None:
diff --git a/atr/routes/projects.py b/atr/routes/projects.py
index 7357f1b..af4207c 100644
--- a/atr/routes/projects.py
+++ b/atr/routes/projects.py
@@ -26,8 +26,8 @@ import wtforms
 
 import atr.db as db
 import atr.db.models as models
-import atr.db.service as service
 import atr.routes as routes
+import atr.user as user
 import atr.util as util
 
 
@@ -86,10 +86,7 @@ async def vote_policy_add(session: routes.CommitterSession, 
project_name: str) -
             base.ASFQuartException(f"Project {project_name} not found", 
errorcode=404)
         )
 
-        if project.committee is None:
-            base.ASFQuartException(f"Committee for project {project_name} not 
found", errorcode=404)
-
-        if not (service.is_project_lead(project, uid) or util.is_admin(uid)):
+        if not (user.is_committee_member(project.committee, uid) or 
user.is_admin(uid)):
             raise base.ASFQuartException(
                 f"You must be a committee member of {project.display_name} to 
submit a voting policy", errorcode=403
             )
@@ -122,7 +119,7 @@ async def vote_policy_edit(session: 
routes.CommitterSession, project_name: str)
         if project.vote_policy is None:
             base.ASFQuartException(f"Vote Policy for project {project_name} 
does not exist", errorcode=404)
 
-        if not (service.is_project_lead(project, uid) or util.is_admin(uid)):
+        if not (user.is_committee_member(project.committee, uid) or 
user.is_admin(uid)):
             raise base.ASFQuartException(
                 f"You must be a committee member of {project.display_name} to 
submit a voting policy", errorcode=403
             )
diff --git a/atr/server.py b/atr/server.py
index f5b6a82..cac3c7f 100644
--- a/atr/server.py
+++ b/atr/server.py
@@ -38,6 +38,7 @@ import atr.db as db
 import atr.manager as manager
 import atr.preload as preload
 import atr.ssh as ssh
+import atr.user as user
 import atr.util as util
 
 # TODO: Technically this is a global variable
@@ -132,17 +133,15 @@ def app_setup_context(app: base.QuartApp) -> None:
 
     @app.context_processor
     async def app_wide() -> dict[str, Any]:
-        import atr.db.service as service
         import atr.metadata as metadata
         import atr.routes.modules as modules
-        import atr.util as util
 
         return {
             "as_url": util.as_url,
             "commit": metadata.commit,
             "current_user": await asfquart.session.read(),
-            "is_admin_fn": util.is_admin,
-            "is_project_lead_fn": service.is_project_lead,
+            "is_admin_fn": user.is_admin,
+            "is_committee_member_fn": user.is_committee_member,
             "routes": modules,
             "version": metadata.version,
         }
diff --git a/atr/templates/project-view.html b/atr/templates/project-view.html
index 2a6216b..0b4ab6a 100644
--- a/atr/templates/project-view.html
+++ b/atr/templates/project-view.html
@@ -21,7 +21,7 @@
   </div>
 
   {% set is_admin = is_admin_fn(current_user.uid) %}
-  {% set is_project_lead = is_project_lead_fn(project, current_user.uid) %}
+  {% set is_committee_member = is_committee_member_fn(project.committee, 
current_user.uid) %}
 
   <div class="card mb-4">
     <div class="card-header bg-light">
@@ -110,12 +110,12 @@
     <div class="card-header bg-light d-flex justify-content-between 
align-items-center">
       <h3 class="mb-0">Voting Policy</h3>
       {% if not project.is_retired %}
-        {% if project.vote_policy and (is_project_lead or is_admin) %}
+        {% if project.vote_policy and (is_committee_member or is_admin) %}
           <div>
             <a class="btn btn-primary btn-sm"
                href="{{ as_url(routes.projects.vote_policy_edit, 
project_name=project.name) }}"><i class="fa-solid fa-pen-to-square"></i></a>
           </div>
-        {% elif (is_project_lead or is_admin) %}
+        {% elif (is_committee_member or is_admin) %}
           <div>
             <a class="btn btn-primary btn-sm"
                href="{{ as_url(routes.projects.vote_policy_add, 
project_name=project.name) }}"><i class="fa-solid fa-plus"></i></a>
diff --git a/atr/user.py b/atr/user.py
index f2872ac..9ff79a1 100644
--- a/atr/user.py
+++ b/atr/user.py
@@ -17,6 +17,9 @@
 
 """user.py"""
 
+import functools
+
+import atr.config as config
 import atr.db as db
 import atr.db.models as models
 import atr.util as util
@@ -32,6 +35,18 @@ async def candidate_drafts(uid: str, user_projects: 
list[models.Project] | None
     return user_candidate_drafts
 
 
[email protected]
+def get_admin_users() -> set[str]:
+    return set(config.get().ADMIN_USERS)
+
+
+def is_admin(user_id: str | None) -> bool:
+    """Check whether a user is an admin."""
+    if user_id is None:
+        return False
+    return user_id in get_admin_users()
+
+
 def is_committer(committee: models.Committee | None, uid: str) -> bool:
     if committee is None:
         return False
diff --git a/atr/util.py b/atr/util.py
index 378d3c5..dbbe814 100644
--- a/atr/util.py
+++ b/atr/util.py
@@ -16,7 +16,6 @@
 # under the License.
 
 import dataclasses
-import functools
 import hashlib
 import pathlib
 from collections.abc import Callable, Mapping, Sequence
@@ -111,11 +110,6 @@ async def file_sha3(path: str) -> str:
     return sha3.hexdigest()
 
 
[email protected]
-def get_admin_users() -> set[str]:
-    return set(config.get().ADMIN_USERS)
-
-
 def get_phase_dir() -> pathlib.Path:
     return pathlib.Path(config.get().PHASE_STORAGE_DIR)
 
@@ -136,13 +130,6 @@ def get_release_dir() -> pathlib.Path:
     return pathlib.Path(config.get().PHASE_STORAGE_DIR) / "release"
 
 
-def is_admin(user_id: str | None) -> bool:
-    """Check whether a user is an admin."""
-    if user_id is None:
-        return False
-    return user_id in get_admin_users()
-
-
 async def paths_recursive(base_path: pathlib.Path, sort: bool = True) -> 
list[pathlib.Path]:
     """List all paths recursively in alphabetical order from a given base 
path."""
     paths: list[pathlib.Path] = []


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to