diff --git a/tests/unit/accounts/test_models.py b/tests/unit/accounts/test_models.py index 7008049950f5..02889c6eede2 100644 --- a/tests/unit/accounts/test_models.py +++ b/tests/unit/accounts/test_models.py @@ -18,6 +18,7 @@ from pyramid.authorization import Authenticated from warehouse.accounts.models import Email, RecoveryCode, User, UserFactory, WebAuthn +from warehouse.authnz import Permissions from warehouse.utils.security_policy import principals_for from ...common.db.accounts import ( @@ -164,8 +165,20 @@ def test_has_no_burned_recovery_codes(self, db_session): def test_acl(self, db_session): user = DBUserFactory.create() assert user.__acl__() == [ - ("Allow", "group:admins", "admin"), - ("Allow", "group:moderators", "moderator"), + ( + "Allow", + "group:admins", + ( + Permissions.AdminUsersRead, + Permissions.AdminUsersWrite, + Permissions.AdminDashboardSidebarRead, + ), + ), + ( + "Allow", + "group:moderators", + (Permissions.AdminUsersRead, Permissions.AdminDashboardSidebarRead), + ), ] @pytest.mark.parametrize( diff --git a/tests/unit/organizations/test_models.py b/tests/unit/organizations/test_models.py index 4d51ae1256ce..1c6eadab406f 100644 --- a/tests/unit/organizations/test_models.py +++ b/tests/unit/organizations/test_models.py @@ -17,6 +17,7 @@ from pyramid.httpexceptions import HTTPPermanentRedirect from pyramid.location import lineage +from warehouse.authnz import Permissions from warehouse.organizations.models import ( OrganizationFactory, OrganizationRoleType, @@ -115,8 +116,15 @@ def test_acl(self, db_session): acls.extend(acl) assert acls == [ - (Allow, "group:admins", "admin"), - (Allow, "group:moderators", "moderator"), + ( + Allow, + "group:admins", + ( + Permissions.AdminOrganizationsRead, + Permissions.AdminOrganizationsWrite, + ), + ), + (Allow, "group:moderators", Permissions.AdminOrganizationsRead), ] + sorted( [ ( @@ -299,8 +307,15 @@ def test_acl(self, db_session): acls.extend(acl) assert acls == [ - (Allow, "group:admins", "admin"), - (Allow, "group:moderators", "moderator"), + ( + Allow, + "group:admins", + ( + Permissions.AdminOrganizationsRead, + Permissions.AdminOrganizationsWrite, + ), + ), + (Allow, "group:moderators", Permissions.AdminOrganizationsRead), ] + sorted( [ ( diff --git a/tests/unit/packaging/test_models.py b/tests/unit/packaging/test_models.py index 92e41fc807ce..c40d7b18033a 100644 --- a/tests/unit/packaging/test_models.py +++ b/tests/unit/packaging/test_models.py @@ -18,6 +18,7 @@ from pyramid.authorization import Allow from pyramid.location import lineage +from warehouse.authnz import Permissions from warehouse.organizations.models import TeamProjectRoleType from warehouse.packaging.models import File, ProjectFactory, ReleaseURL @@ -158,8 +159,33 @@ def test_acl(self, db_session): acls.extend(acl) assert acls == [ - (Allow, "group:admins", "admin"), - (Allow, "group:moderators", "moderator"), + ( + Allow, + "group:admins", + ( + Permissions.AdminDashboardSidebarRead, + Permissions.AdminObservationsRead, + Permissions.AdminObservationsWrite, + Permissions.AdminProhibitedProjectsWrite, + Permissions.AdminProjectsDelete, + Permissions.AdminProjectsRead, + Permissions.AdminProjectsWrite, + Permissions.AdminRoleAdd, + Permissions.AdminRoleDelete, + ), + ), + ( + Allow, + "group:moderators", + ( + Permissions.AdminDashboardSidebarRead, + Permissions.AdminObservationsRead, + Permissions.AdminObservationsWrite, + Permissions.AdminProjectsRead, + Permissions.AdminRoleAdd, + Permissions.AdminRoleDelete, + ), + ), ] + sorted( [(Allow, f"oidc:{publisher.id}", ["upload"])], key=lambda x: x[1] ) + sorted( @@ -415,8 +441,33 @@ def test_acl(self, db_session): acls.extend(acl) assert acls == [ - (Allow, "group:admins", "admin"), - (Allow, "group:moderators", "moderator"), + ( + Allow, + "group:admins", + ( + Permissions.AdminDashboardSidebarRead, + Permissions.AdminObservationsRead, + Permissions.AdminObservationsWrite, + Permissions.AdminProhibitedProjectsWrite, + Permissions.AdminProjectsDelete, + Permissions.AdminProjectsRead, + Permissions.AdminProjectsWrite, + Permissions.AdminRoleAdd, + Permissions.AdminRoleDelete, + ), + ), + ( + Allow, + "group:moderators", + ( + Permissions.AdminDashboardSidebarRead, + Permissions.AdminObservationsRead, + Permissions.AdminObservationsWrite, + Permissions.AdminProjectsRead, + Permissions.AdminRoleAdd, + Permissions.AdminRoleDelete, + ), + ), ] + sorted( [ (Allow, f"user:{owner1.user.id}", ["manage:project", "upload"]), diff --git a/tests/unit/test_config.py b/tests/unit/test_config.py index 82ab1f3c9fb9..eb34e58e8234 100644 --- a/tests/unit/test_config.py +++ b/tests/unit/test_config.py @@ -24,6 +24,7 @@ from pyramid.tweens import EXCVIEW from warehouse import config +from warehouse.authnz import Permissions from warehouse.utils.wsgi import ProxyFixer, VhmRootRemover @@ -453,11 +454,69 @@ def test_root_factory_access_control_list(): acl = config.RootFactory.__acl__ assert acl == [ - (Allow, "group:admins", "admin"), - (Allow, "group:admins", "admin_dashboard_access"), - (Allow, "group:moderators", "moderator"), - (Allow, "group:moderators", "admin_dashboard_access"), - (Allow, "group:psf_staff", "psf_staff"), - (Allow, "group:psf_staff", "admin_dashboard_access"), + ( + Allow, + "group:admins", + ( + Permissions.AdminBannerRead, + Permissions.AdminBannerWrite, + Permissions.AdminDashboardRead, + Permissions.AdminDashboardSidebarRead, + Permissions.AdminEmailsRead, + Permissions.AdminEmailsWrite, + Permissions.AdminFlagsRead, + Permissions.AdminFlagsWrite, + Permissions.AdminIpAddressesRead, + Permissions.AdminJournalRead, + Permissions.AdminMacaroonsRead, + Permissions.AdminMacaroonsWrite, + Permissions.AdminObservationsRead, + Permissions.AdminObservationsWrite, + Permissions.AdminOrganizationsRead, + Permissions.AdminOrganizationsWrite, + Permissions.AdminProhibitedProjectsRead, + Permissions.AdminProhibitedProjectsWrite, + Permissions.AdminProjectsDelete, + Permissions.AdminProjectsRead, + Permissions.AdminProjectsWrite, + Permissions.AdminRoleAdd, + Permissions.AdminRoleDelete, + Permissions.AdminSponsorsRead, + Permissions.AdminUsersRead, + Permissions.AdminUsersWrite, + ), + ), + ( + Allow, + "group:moderators", + ( + Permissions.AdminBannerRead, + Permissions.AdminDashboardRead, + Permissions.AdminDashboardSidebarRead, + Permissions.AdminEmailsRead, + Permissions.AdminFlagsRead, + Permissions.AdminJournalRead, + Permissions.AdminObservationsRead, + Permissions.AdminObservationsWrite, + Permissions.AdminOrganizationsRead, + Permissions.AdminProhibitedProjectsRead, + Permissions.AdminProjectsRead, + Permissions.AdminRoleAdd, + Permissions.AdminRoleDelete, + Permissions.AdminSponsorsRead, + Permissions.AdminUsersRead, + ), + ), + ( + Allow, + "group:psf_staff", + ( + Permissions.AdminBannerRead, + Permissions.AdminBannerWrite, + Permissions.AdminDashboardRead, + Permissions.AdminSponsorsRead, + Permissions.AdminSponsorsWrite, + ), + ), (Allow, Authenticated, "manage:user"), ] diff --git a/warehouse/accounts/models.py b/warehouse/accounts/models.py index 95ec80b5441c..ffec187b5ee2 100644 --- a/warehouse/accounts/models.py +++ b/warehouse/accounts/models.py @@ -35,6 +35,7 @@ from sqlalchemy.orm import Mapped, mapped_column from warehouse import db +from warehouse.authnz import Permissions from warehouse.events.models import HasEvents from warehouse.observations.models import HasObserversMixin from warehouse.sitemap.models import SitemapMixin @@ -253,9 +254,25 @@ def __principals__(self) -> list[str]: return principals def __acl__(self): + # TODO: This ACL is duplicating permissions set in RootFactory.__acl__ + # If nothing else, setting the ACL on the model is more restrictive + # than RootFactory.__acl__, which is why we duplicate + # AdminDashboardSidebarRead here, otherwise the sidebar is not displayed. return [ - (Allow, "group:admins", "admin"), - (Allow, "group:moderators", "moderator"), + ( + Allow, + "group:admins", + ( + Permissions.AdminUsersRead, + Permissions.AdminUsersWrite, + Permissions.AdminDashboardSidebarRead, + ), + ), + ( + Allow, + "group:moderators", + (Permissions.AdminUsersRead, Permissions.AdminDashboardSidebarRead), + ), ] def __lt__(self, other): diff --git a/warehouse/admin/templates/admin/banners/edit.html b/warehouse/admin/templates/admin/banners/edit.html index f685c8aa5d69..bcb98b4cd996 100644 --- a/warehouse/admin/templates/admin/banners/edit.html +++ b/warehouse/admin/templates/admin/banners/edit.html @@ -82,12 +82,12 @@

Create banner

- + {% if banner %} Preview Saved - {% endif %} diff --git a/warehouse/admin/templates/admin/banners/list.html b/warehouse/admin/templates/admin/banners/list.html index f7c95bd4c32c..308568b0ffad 100644 --- a/warehouse/admin/templates/admin/banners/list.html +++ b/warehouse/admin/templates/admin/banners/list.html @@ -22,7 +22,7 @@ {% block content %}
- {% if request.has_permission('psf_staff') %} + {% if request.has_permission(Permissions.AdminBannerWrite) %} diff --git a/warehouse/admin/templates/admin/base.html b/warehouse/admin/templates/admin/base.html index abda52950949..0948ecd8fbef 100644 --- a/warehouse/admin/templates/admin/base.html +++ b/warehouse/admin/templates/admin/base.html @@ -111,7 +111,8 @@
+{% endif %}
diff --git a/warehouse/admin/templates/admin/flags/index.html b/warehouse/admin/templates/admin/flags/index.html index 7903f217bb53..021fe1717a1a 100644 --- a/warehouse/admin/templates/admin/flags/index.html +++ b/warehouse/admin/templates/admin/flags/index.html @@ -46,10 +46,10 @@

Edit Flags

{{ flag.id }} - + {{ flag.notify }} - - + + {% endfor %} diff --git a/warehouse/admin/templates/admin/macaroons/detail.html b/warehouse/admin/templates/admin/macaroons/detail.html index 5229d18ece83..7db4d2eff0f4 100644 --- a/warehouse/admin/templates/admin/macaroons/detail.html +++ b/warehouse/admin/templates/admin/macaroons/detail.html @@ -70,7 +70,7 @@
diff --git a/warehouse/admin/templates/admin/projects/detail.html b/warehouse/admin/templates/admin/projects/detail.html index c2a261cf91e6..7a1d93c02bc7 100644 --- a/warehouse/admin/templates/admin/projects/detail.html +++ b/warehouse/admin/templates/admin/projects/detail.html @@ -15,24 +15,6 @@ {% import "admin/utils/pagination.html" as pagination %} -{% macro render_field(label, field, input_id, placeholder=None, class=None) %} -
- - -
- {{ field(id=input_id, class=class, placeholder=placeholder)}} - - {% if field.errors %} -
- {% for error in field.errors %} -
{{ error }}
- {% endfor %} -
- {% endif %} -
-
-{% endmacro %} - {% block title %}{{ project.name }}{% endblock %} {% block breadcrumb %} @@ -133,7 +115,7 @@
{{ role.user.username }} {{ role.role_name }} - diff --git a/warehouse/admin/templates/admin/sponsors/edit.html b/warehouse/admin/templates/admin/sponsors/edit.html index 6fde6a01e018..91aa5bf01680 100644 --- a/warehouse/admin/templates/admin/sponsors/edit.html +++ b/warehouse/admin/templates/admin/sponsors/edit.html @@ -96,11 +96,11 @@

Create sponsor

{{ render_field("Sidebar", form.sidebar, "sponsor-sidebar") }}
- + {% if sponsor %}
-
diff --git a/warehouse/admin/templates/admin/sponsors/list.html b/warehouse/admin/templates/admin/sponsors/list.html index bd7e8387db26..7b97a9d8c772 100644 --- a/warehouse/admin/templates/admin/sponsors/list.html +++ b/warehouse/admin/templates/admin/sponsors/list.html @@ -22,7 +22,7 @@ {% block content %}
- {% if request.has_permission('psf_staff') %} + {% if request.has_permission(Permissions.AdminSponsorsWrite) %} diff --git a/warehouse/admin/templates/admin/users/detail.html b/warehouse/admin/templates/admin/users/detail.html index 5abd826b7c14..ff78af50c6a6 100644 --- a/warehouse/admin/templates/admin/users/detail.html +++ b/warehouse/admin/templates/admin/users/detail.html @@ -15,12 +15,14 @@ {% import "admin/utils/pagination.html" as pagination %} +{% set perms_admin_users_write = request.has_permission(Permissions.AdminUsersWrite) %} + {% macro render_field(label, field, input_id, placeholder=None, class=None) %}
- {{ field(id=input_id, class=class, placeholder=placeholder, disabled=(not request.has_permission('admin')))}} + {{ field(id=input_id, class=class, placeholder=placeholder, disabled=(not perms_admin_users_write))}} {% if field.errors %}
@@ -35,7 +37,7 @@ {% macro render_checkbox(label, field, input_id, class=None) %}
- {{ field(id=input_id, class=class, disabled=(not request.has_permission('admin')))}} + {{ field(id=input_id, class=class, disabled=(not perms_admin_users_write))}}
{% endmacro %} @@ -101,13 +103,13 @@

Actions

- - -