diff --git a/atst/domain/permission_sets.py b/atst/domain/permission_sets.py index b162a15c..3de4492e 100644 --- a/atst/domain/permission_sets.py +++ b/atst/domain/permission_sets.py @@ -5,6 +5,32 @@ from atst.models import PermissionSet, Permissions from .exceptions import NotFoundError +class PermissionSets(object): + VIEW_PORTFOLIO = "view_portfolio" + VIEW_PORTFOLIO_APPLICATION_MANAGEMENT = "view_portfolio_application_management" + VIEW_PORTFOLIO_FUNDING = "view_portfolio_funding" + VIEW_PORTFOLIO_REPORTS = "view_portfolio_reports" + VIEW_PORTFOLIO_ADMIN = "view_portfolio_admin" + EDIT_PORTFOLIO_APPLICATION_MANAGEMENT = "edit_portfolio_application_management" + EDIT_PORTFOLIO_FUNDING = "edit_portfolio_funding" + EDIT_PORTFOLIO_REPORTS = "edit_portfolio_reports" + EDIT_PORTFOLIO_ADMIN = "edit_portfolio_admin" + PORTFOLIO_POC = "portfolio_poc" + + @classmethod + def get(cls, perms_set_name): + try: + role = db.session.query(PermissionSet).filter_by(name=perms_set_name).one() + except NoResultFound: + raise NotFoundError("permission_set") + + return role + + @classmethod + def get_all(cls): + return db.session.query(PermissionSet).all() + + ATAT_ROLES = [ { "name": "ccpo", @@ -57,13 +83,13 @@ ATAT_ROLES = [ _VIEW_PORTFOLIO_PERMISSION_SETS = [ { - "name": "view_portfolio", + "name": PermissionSets.VIEW_PORTFOLIO, "description": "View basic portfolio info", "display_name": "View Portfolio", "permissions": [Permissions.VIEW_PORTFOLIO], }, { - "name": "view_portfolio_application_management", + "name": PermissionSets.VIEW_PORTFOLIO_APPLICATION_MANAGEMENT, "description": "View applications and related resources", "display_name": "Application Management", "permissions": [ @@ -73,7 +99,7 @@ _VIEW_PORTFOLIO_PERMISSION_SETS = [ ], }, { - "name": "view_portfolio_funding", + "name": PermissionSets.VIEW_PORTFOLIO_FUNDING, "description": "View a portfolio's task orders", "display_name": "Funding", "permissions": [ @@ -82,13 +108,13 @@ _VIEW_PORTFOLIO_PERMISSION_SETS = [ ], }, { - "name": "view_portfolio_reports", + "name": PermissionSets.VIEW_PORTFOLIO_REPORTS, "description": "View a portfolio's reports", "display_name": "Reporting", "permissions": [Permissions.VIEW_PORTFOLIO_REPORTS], }, { - "name": "view_portfolio_admin", + "name": PermissionSets.VIEW_PORTFOLIO_ADMIN, "description": "View a portfolio's admin options", "display_name": "Portfolio Administration", "permissions": [ @@ -103,7 +129,7 @@ _VIEW_PORTFOLIO_PERMISSION_SETS = [ _EDIT_PORTFOLIO_PERMISSION_SETS = [ { - "name": "edit_portfolio_application_management", + "name": PermissionSets.EDIT_PORTFOLIO_APPLICATION_MANAGEMENT, "description": "Edit applications and related resources", "display_name": "Application Management", "permissions": [ @@ -116,7 +142,7 @@ _EDIT_PORTFOLIO_PERMISSION_SETS = [ ], }, { - "name": "edit_portfolio_funding", + "name": PermissionSets.EDIT_PORTFOLIO_FUNDING, "description": "Edit a portfolio's task orders and add new ones", "display_name": "Funding", "permissions": [ @@ -125,13 +151,13 @@ _EDIT_PORTFOLIO_PERMISSION_SETS = [ ], }, { - "name": "edit_portfolio_reports", + "name": PermissionSets.EDIT_PORTFOLIO_REPORTS, "description": "Edit a portfolio's reports (no-op)", "display_name": "Reporting", "permissions": [], }, { - "name": "edit_portfolio_admin", + "name": PermissionSets.EDIT_PORTFOLIO_ADMIN, "description": "Edit a portfolio's admin options", "display_name": "Portfolio Administration", "permissions": [ @@ -157,18 +183,3 @@ PORTFOLIO_PERMISSION_SETS = ( } ] ) - - -class PermissionSets(object): - @classmethod - def get(cls, perms_set_name): - try: - role = db.session.query(PermissionSet).filter_by(name=perms_set_name).one() - except NoResultFound: - raise NotFoundError("permission_set") - - return role - - @classmethod - def get_all(cls): - return db.session.query(PermissionSet).all() diff --git a/atst/domain/portfolio_roles.py b/atst/domain/portfolio_roles.py index 19e5125b..204ef80f 100644 --- a/atst/domain/portfolio_roles.py +++ b/atst/domain/portfolio_roles.py @@ -97,10 +97,10 @@ class PortfolioRoles(object): return new_portfolio_role _DEFAULT_PORTFOLIO_PERMS_SETS = { - "view_portfolio_application_management", - "view_portfolio_funding", - "view_portfolio_reports", - "view_portfolio_admin", + PermissionSets.VIEW_PORTFOLIO_APPLICATION_MANAGEMENT, + PermissionSets.VIEW_PORTFOLIO_FUNDING, + PermissionSets.VIEW_PORTFOLIO_REPORTS, + PermissionSets.VIEW_PORTFOLIO_ADMIN, } @classmethod diff --git a/atst/domain/task_orders.py b/atst/domain/task_orders.py index 3f3a5b51..3055f31d 100644 --- a/atst/domain/task_orders.py +++ b/atst/domain/task_orders.py @@ -7,6 +7,7 @@ from atst.models.permissions import Permissions from atst.models.dd_254 import DD254 from atst.domain.portfolios import Portfolios from atst.domain.authz import Authorization +from atst.domain.permission_sets import PermissionSets from .exceptions import NotFoundError @@ -174,8 +175,7 @@ class TaskOrders(object): portfolio, { **officer_data, - "portfolio_role": "officer", - "permission_sets": ["edit_portfolio_funding"], + "permission_sets": [PermissionSets.EDIT_PORTFOLIO_FUNDING], }, ) portfolio_user = member.user diff --git a/atst/forms/portfolio_member.py b/atst/forms/portfolio_member.py index f75c2869..36e0d3cd 100644 --- a/atst/forms/portfolio_member.py +++ b/atst/forms/portfolio_member.py @@ -2,6 +2,7 @@ from wtforms.fields import StringField from wtforms.fields.html5 import EmailField from wtforms.validators import Required, Email, Length +from atst.domain.permission_sets import PermissionSets from .forms import BaseForm from atst.forms.validators import IsNumber from atst.forms.fields import SelectField @@ -12,29 +13,29 @@ class PermissionsForm(BaseForm): perms_app_mgmt = SelectField( None, choices=[ - ("view_portfolio_application_management", "View Only"), - ("edit_portfolio_application_management", "Edit Access"), + (PermissionSets.VIEW_PORTFOLIO_APPLICATION_MANAGEMENT, "View Only"), + (PermissionSets.EDIT_PORTFOLIO_APPLICATION_MANAGEMENT, "Edit Access"), ], ) perms_funding = SelectField( None, choices=[ - ("view_portfolio_funding", "View Only"), - ("edit_portfolio_funding", "Edit Access"), + (PermissionSets.VIEW_PORTFOLIO_FUNDING, "View Only"), + (PermissionSets.EDIT_PORTFOLIO_FUNDING, "Edit Access"), ], ) perms_reporting = SelectField( None, choices=[ - ("view_portfolio_reports", "View Only"), - ("edit_portfolio_reports", "Edit Access"), + (PermissionSets.VIEW_PORTFOLIO_REPORTS, "View Only"), + (PermissionSets.EDIT_PORTFOLIO_REPORTS, "Edit Access"), ], ) perms_portfolio_mgmt = SelectField( None, choices=[ - ("view_portfolio_admin", "View Only"), - ("edit_portfolio_admin", "Edit Access"), + (PermissionSets.VIEW_PORTFOLIO_ADMIN, "View Only"), + (PermissionSets.EDIT_PORTFOLIO_ADMIN, "Edit Access"), ], ) diff --git a/atst/models/portfolio.py b/atst/models/portfolio.py index 0b133ae1..599de3e6 100644 --- a/atst/models/portfolio.py +++ b/atst/models/portfolio.py @@ -4,6 +4,7 @@ from itertools import chain from atst.models import Base, mixins, types from atst.models.portfolio_role import PortfolioRole, Status as PortfolioRoleStatus +from atst.domain.permission_sets import PermissionSets from atst.utils import first_or_none from atst.database import db @@ -23,7 +24,7 @@ class Portfolio(Base, mixins.TimestampsMixin, mixins.AuditableMixin): @property def owner(self): def _is_portfolio_owner(portfolio_role): - return "portfolio_poc" in [ + return PermissionSets.PORTFOLIO_POC in [ perms_set.name for perms_set in portfolio_role.permission_sets ] diff --git a/tests/domain/test_authz.py b/tests/domain/test_authz.py index c240e523..fdf72fdd 100644 --- a/tests/domain/test_authz.py +++ b/tests/domain/test_authz.py @@ -45,8 +45,8 @@ def test_check_is_ko_or_cor(task_order, invalid_user): def test_has_portfolio_permission(): - role_one = PermissionSets.get("view_portfolio_funding") - role_two = PermissionSets.get("view_portfolio_reports") + role_one = PermissionSets.get(PermissionSets.VIEW_PORTFOLIO_FUNDING) + role_two = PermissionSets.get(PermissionSets.VIEW_PORTFOLIO_REPORTS) port_role = PortfolioRoleFactory.create(permission_sets=[role_one, role_two]) different_user = UserFactory.create() assert Authorization.has_portfolio_permission( diff --git a/tests/domain/test_portfolio_roles.py b/tests/domain/test_portfolio_roles.py index e7108c2e..8ffbed81 100644 --- a/tests/domain/test_portfolio_roles.py +++ b/tests/domain/test_portfolio_roles.py @@ -14,17 +14,17 @@ from tests.factories import ( def test_add_portfolio_role_with_permission_sets(): portfolio = PortfolioFactory.create() new_user = UserFactory.create() - permission_sets = ["edit_portfolio_application_management"] + permission_sets = [PermissionSets.EDIT_PORTFOLIO_APPLICATION_MANAGEMENT] port_role = PortfolioRoles.add( new_user, portfolio.id, permission_sets=permission_sets ) assert len(port_role.permission_sets) == 5 expected_names = [ - "edit_portfolio_application_management", - "view_portfolio_application_management", - "view_portfolio_funding", - "view_portfolio_reports", - "view_portfolio_admin", + PermissionSets.EDIT_PORTFOLIO_APPLICATION_MANAGEMENT, + PermissionSets.VIEW_PORTFOLIO_APPLICATION_MANAGEMENT, + PermissionSets.VIEW_PORTFOLIO_FUNDING, + PermissionSets.VIEW_PORTFOLIO_REPORTS, + PermissionSets.VIEW_PORTFOLIO_ADMIN, ] actual_names = [prms.name for prms in port_role.permission_sets] assert expected_names == expected_names diff --git a/tests/domain/test_portfolios.py b/tests/domain/test_portfolios.py index fe2b7672..9140d82d 100644 --- a/tests/domain/test_portfolios.py +++ b/tests/domain/test_portfolios.py @@ -114,7 +114,7 @@ def test_update_portfolio_role_role(portfolio, portfolio_owner): } PortfolioRoleFactory._meta.sqlalchemy_session_persistence = "flush" member = PortfolioRoleFactory.create(portfolio=portfolio) - permission_sets = ["edit_portfolio_funding"] + permission_sets = [PermissionSets.EDIT_PORTFOLIO_FUNDING] updated_member = Portfolios.update_member( portfolio_owner, portfolio, member, permission_sets=permission_sets diff --git a/tests/models/test_portfolio_role.py b/tests/models/test_portfolio_role.py index 0a484624..7c67fe5d 100644 --- a/tests/models/test_portfolio_role.py +++ b/tests/models/test_portfolio_role.py @@ -285,8 +285,8 @@ def test_can_list_all_environments(): def test_can_list_all_permissions(): - role_one = PermissionSets.get("view_portfolio_funding") - role_two = PermissionSets.get("view_portfolio_reports") + role_one = PermissionSets.get(PermissionSets.VIEW_PORTFOLIO_FUNDING) + role_two = PermissionSets.get(PermissionSets.VIEW_PORTFOLIO_REPORTS) port_role = PortfolioRoleFactory.create(permission_sets=[role_one, role_two]) expected_perms = role_one.permissions + role_two.permissions assert expected_perms == expected_perms diff --git a/tests/routes/portfolios/test_invitations.py b/tests/routes/portfolios/test_invitations.py index e6ea7a95..7719a380 100644 --- a/tests/routes/portfolios/test_invitations.py +++ b/tests/routes/portfolios/test_invitations.py @@ -12,6 +12,7 @@ from atst.domain.portfolios import Portfolios from atst.models.portfolio_role import Status as PortfolioRoleStatus from atst.models.invitation import Status as InvitationStatus from atst.domain.users import Users +from atst.domain.permission_sets import PermissionSets def test_existing_member_accepts_valid_invite(client, user_session): @@ -48,10 +49,10 @@ def test_new_member_accepts_valid_invite(monkeypatch, client, user_session): response = client.post( url_for("portfolios.create_member", portfolio_id=portfolio.id), data={ - "perms_app_mgmt": "view_portfolio_application_management", - "perms_funding": "view_portfolio_funding", - "perms_reporting": "view_portfolio_reports", - "perms_portfolio_mgmt": "view_portfolio_admin", + "perms_app_mgmt": PermissionSets.VIEW_PORTFOLIO_APPLICATION_MANAGEMENT, + "perms_funding": PermissionSets.VIEW_PORTFOLIO_FUNDING, + "perms_reporting": PermissionSets.VIEW_PORTFOLIO_REPORTS, + "perms_portfolio_mgmt": PermissionSets.VIEW_PORTFOLIO_ADMIN, **user_info, }, ) diff --git a/tests/routes/portfolios/test_members.py b/tests/routes/portfolios/test_members.py index 06957f18..910042b5 100644 --- a/tests/routes/portfolios/test_members.py +++ b/tests/routes/portfolios/test_members.py @@ -18,10 +18,10 @@ from atst.models.portfolio_role import Status as PortfolioRoleStatus from atst.models.invitation import Status as InvitationStatus _DEFAULT_PERMS_FORM_DATA = { - "perms_app_mgmt": "view_portfolio_application_management", - "perms_funding": "view_portfolio_funding", - "perms_reporting": "view_portfolio_reports", - "perms_portfolio_mgmt": "view_portfolio_admin", + "perms_app_mgmt": PermissionSets.VIEW_PORTFOLIO_APPLICATION_MANAGEMENT, + "perms_funding": PermissionSets.VIEW_PORTFOLIO_FUNDING, + "perms_reporting": PermissionSets.VIEW_PORTFOLIO_REPORTS, + "perms_portfolio_mgmt": PermissionSets.VIEW_PORTFOLIO_ADMIN, } @@ -135,11 +135,14 @@ def test_update_member_portfolio_role(client, user_session): url_for( "portfolios.update_member", portfolio_id=portfolio.id, member_id=user.id ), - data={**_DEFAULT_PERMS_FORM_DATA, "perms_funding": "edit_portfolio_funding"}, + data={ + **_DEFAULT_PERMS_FORM_DATA, + "perms_funding": PermissionSets.EDIT_PORTFOLIO_FUNDING, + }, follow_redirects=True, ) assert response.status_code == 200 - edit_funding = PermissionSets.get("edit_portfolio_funding") + edit_funding = PermissionSets.get(PermissionSets.EDIT_PORTFOLIO_FUNDING) assert edit_funding in member.permission_sets diff --git a/tests/routes/portfolios/test_task_orders.py b/tests/routes/portfolios/test_task_orders.py index b694e2a3..4af42ce1 100644 --- a/tests/routes/portfolios/test_task_orders.py +++ b/tests/routes/portfolios/test_task_orders.py @@ -234,8 +234,8 @@ def test_ko_can_view_task_order(client, user_session, portfolio, user): user=user, status=PortfolioStatus.ACTIVE, permission_sets=[ - PermissionSets.get("view_portfolio"), - PermissionSets.get("view_portfolio_funding"), + PermissionSets.get(PermissionSets.VIEW_PORTFOLIO), + PermissionSets.get(PermissionSets.VIEW_PORTFOLIO_FUNDING), ], ) task_order = TaskOrderFactory.create(portfolio=portfolio, contracting_officer=user) @@ -301,8 +301,8 @@ def test_ko_can_view_ko_review_page(client, user_session): user=ko, status=PortfolioStatus.ACTIVE, permission_sets=[ - PermissionSets.get("view_portfolio"), - PermissionSets.get("view_portfolio_funding"), + PermissionSets.get(PermissionSets.VIEW_PORTFOLIO), + PermissionSets.get(PermissionSets.VIEW_PORTFOLIO_FUNDING), ], ) PortfolioRoleFactory.create( @@ -310,8 +310,8 @@ def test_ko_can_view_ko_review_page(client, user_session): user=cor, status=PortfolioStatus.ACTIVE, permission_sets=[ - PermissionSets.get("view_portfolio"), - PermissionSets.get("view_portfolio_funding"), + PermissionSets.get(PermissionSets.VIEW_PORTFOLIO), + PermissionSets.get(PermissionSets.VIEW_PORTFOLIO_FUNDING), ], ) task_order = TaskOrderFactory.create( @@ -378,8 +378,8 @@ def test_cor_redirected_to_build_page(client, user_session, portfolio): user=cor, status=PortfolioStatus.ACTIVE, permission_sets=[ - PermissionSets.get("view_portfolio"), - PermissionSets.get("view_portfolio_funding"), + PermissionSets.get(PermissionSets.VIEW_PORTFOLIO), + PermissionSets.get(PermissionSets.VIEW_PORTFOLIO_FUNDING), ], ) task_order = TaskOrderFactory.create( @@ -400,8 +400,8 @@ def test_submit_completed_ko_review_page_as_cor( user=user, status=PortfolioStatus.ACTIVE, permission_sets=[ - PermissionSets.get("view_portfolio"), - PermissionSets.get("view_portfolio_funding"), + PermissionSets.get(PermissionSets.VIEW_PORTFOLIO), + PermissionSets.get(PermissionSets.VIEW_PORTFOLIO_FUNDING), ], ) @@ -448,8 +448,8 @@ def test_submit_completed_ko_review_page_as_ko( user=ko, status=PortfolioStatus.ACTIVE, permission_sets=[ - PermissionSets.get("view_portfolio"), - PermissionSets.get("view_portfolio_funding"), + PermissionSets.get(PermissionSets.VIEW_PORTFOLIO), + PermissionSets.get(PermissionSets.VIEW_PORTFOLIO_FUNDING), ], ) @@ -492,8 +492,8 @@ def test_so_review_page(app, client, user_session, portfolio): user=so, status=PortfolioStatus.ACTIVE, permission_sets=[ - PermissionSets.get("view_portfolio"), - PermissionSets.get("view_portfolio_funding"), + PermissionSets.get(PermissionSets.VIEW_PORTFOLIO), + PermissionSets.get(PermissionSets.VIEW_PORTFOLIO_FUNDING), ], ) task_order = TaskOrderFactory.create(portfolio=portfolio, security_officer=so) @@ -533,8 +533,8 @@ def test_submit_so_review(app, client, user_session, portfolio): user=so, status=PortfolioStatus.ACTIVE, permission_sets=[ - PermissionSets.get("view_portfolio"), - PermissionSets.get("view_portfolio_funding"), + PermissionSets.get(PermissionSets.VIEW_PORTFOLIO), + PermissionSets.get(PermissionSets.VIEW_PORTFOLIO_FUNDING), ], ) task_order = TaskOrderFactory.create(portfolio=portfolio, security_officer=so)