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]