From b4f34a25e061d3bdf6e1b47ef62b962833175872 Mon Sep 17 00:00:00 2001 From: richard-dds Date: Tue, 4 Sep 2018 11:44:02 -0400 Subject: [PATCH 01/19] Add workspace members to seed script --- script/seed.py | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/script/seed.py b/script/seed.py index e69694a0..01050427 100644 --- a/script/seed.py +++ b/script/seed.py @@ -15,6 +15,29 @@ from atst.domain.exceptions import AlreadyExistsError from tests.factories import RequestFactory from atst.routes.dev import _DEV_USERS as DEV_USERS +WORKSPACE_USERS = [ + { + "first_name": "Danny", + "last_name": "Knight", + "email": "knight@mil.gov", + "workspace_role": "developer", + "dod_id": "0000000001" + }, + { + "first_name": "Mario", + "last_name": "Hudson", + "email": "hudson@mil.gov", + "workspace_role": "ccpo", + "dod_id": "0000000002" + }, + { + "first_name": "Louise", + "last_name": "Greer", + "email": "greer@mil.gov", + "workspace_role": "admin", + "dod_id": "0000000003" + }, +] def seed_db(): users = [] @@ -41,6 +64,9 @@ def seed_db(): requests.append(request) workspace = Workspaces.create(requests[0], name="{}'s workspace".format(user.first_name)) + for workspace_user in WORKSPACE_USERS: + Workspaces.create_member(user, workspace, workspace_user) + Projects.create( workspace=workspace, name="First Project", From ea3f1b926caf64fe23426a351938839c1a62cdb3 Mon Sep 17 00:00:00 2001 From: richard-dds Date: Wed, 5 Sep 2018 11:02:15 -0400 Subject: [PATCH 02/19] Display workspace members --- atst/models/workspace.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/atst/models/workspace.py b/atst/models/workspace.py index edeba529..ad5f2948 100644 --- a/atst/models/workspace.py +++ b/atst/models/workspace.py @@ -4,8 +4,8 @@ from sqlalchemy.orm import relationship from atst.models import Base from atst.models.types import Id from atst.models.mixins import TimestampsMixin -from atst.utils import first_or_none from atst.models.workspace_user import WorkspaceUser +from atst.utils import first_or_none class Workspace(Base, TimestampsMixin): From 398bdac871c0cff6a4feafb3f353961c48f74123 Mon Sep 17 00:00:00 2001 From: richard-dds Date: Wed, 5 Sep 2018 12:02:42 -0400 Subject: [PATCH 03/19] Add new VIEW_WORKSPACE_MEMBERS permission to owner and ccpo --- ...b_add_view_workspace_members_permission.py | 32 +++++++++++++++++++ atst/models/permissions.py | 1 + 2 files changed, 33 insertions(+) create mode 100644 alembic/versions/ad30159ef19b_add_view_workspace_members_permission.py diff --git a/alembic/versions/ad30159ef19b_add_view_workspace_members_permission.py b/alembic/versions/ad30159ef19b_add_view_workspace_members_permission.py new file mode 100644 index 00000000..ab45a6a2 --- /dev/null +++ b/alembic/versions/ad30159ef19b_add_view_workspace_members_permission.py @@ -0,0 +1,32 @@ +"""add view_workspace_members_permission + +Revision ID: ad30159ef19b +Revises: 2c2a2af465d3 +Create Date: 2018-09-05 11:17:17.204089 + +""" +from alembic import op +from sqlalchemy.orm.session import Session +from atst.models.role import Role +from atst.models.permissions import Permissions + + +# revision identifiers, used by Alembic. +revision = 'ad30159ef19b' +down_revision = '2c2a2af465d3' +branch_labels = None +depends_on = None + +def upgrade(): + + session = Session(bind=op.get_bind()) + + owner_role = session.query(Role).filter_by(name="owner").one() + owner_role.permissions.append(Permissions.VIEW_WORKSPACE_MEMBERS) + + ccpo_role = session.query(Role).filter_by(name="ccpo").one() + ccpo_role.permissions.append(Permissions.VIEW_WORKSPACE_MEMBERS) + + +def downgrade(): + pass diff --git a/atst/models/permissions.py b/atst/models/permissions.py index 9536348f..23adcf55 100644 --- a/atst/models/permissions.py +++ b/atst/models/permissions.py @@ -23,6 +23,7 @@ class Permissions(object): DEACTIVATE_WORKSPACE = "deactivate_workspace" VIEW_ATAT_PERMISSIONS = "view_atat_permissions" TRANSFER_OWNERSHIP_OF_WORKSPACE = "transfer_ownership_of_workspace" + VIEW_WORKSPACE_MEMBERS = "view_workspace_members" ADD_APPLICATION_IN_WORKSPACE = "add_application_in_workspace" DELETE_APPLICATION_IN_WORKSPACE = "delete_application_in_workspace" From 29e6d2934f696b3cf2b0e791e3c1909c152603c2 Mon Sep 17 00:00:00 2001 From: richard-dds Date: Wed, 5 Sep 2018 12:04:22 -0400 Subject: [PATCH 04/19] Check VIEW_WORKSPACE_MEMBERS permission --- atst/routes/workspaces.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/atst/routes/workspaces.py b/atst/routes/workspaces.py index 0e18ed63..190b5eff 100644 --- a/atst/routes/workspaces.py +++ b/atst/routes/workspaces.py @@ -63,8 +63,14 @@ def show_workspace(workspace_id): @bp.route("/workspaces//members") def workspace_members(workspace_id): - workspace = Workspaces.get(g.current_user, workspace_id) - return render_template("workspaces/members/index.html", workspace=workspace) + user = g.current_user + workspace = Workspaces.get(user, workspace_id) + if not Authorization.has_workspace_permission( + user, workspace, Permissions.VIEW_WORKSPACE_MEMBERS + ): + raise UnauthorizedError(user, "view workspace members") + + return render_template("workspace_members.html", workspace=workspace) @bp.route("/workspaces//reports") From 4fe758c4ff126ab1d21cb9b307726f97880b8e0d Mon Sep 17 00:00:00 2001 From: richard-dds Date: Wed, 5 Sep 2018 17:00:07 -0400 Subject: [PATCH 05/19] Fix migration path --- .../ad30159ef19b_add_view_workspace_members_permission.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/alembic/versions/ad30159ef19b_add_view_workspace_members_permission.py b/alembic/versions/ad30159ef19b_add_view_workspace_members_permission.py index ab45a6a2..13fce237 100644 --- a/alembic/versions/ad30159ef19b_add_view_workspace_members_permission.py +++ b/alembic/versions/ad30159ef19b_add_view_workspace_members_permission.py @@ -13,7 +13,7 @@ from atst.models.permissions import Permissions # revision identifiers, used by Alembic. revision = 'ad30159ef19b' -down_revision = '2c2a2af465d3' +down_revision = '06aa23166ca9' branch_labels = None depends_on = None From 19d88ce4f5eb6f0ea29f773f0a5d37c58ad2c77f Mon Sep 17 00:00:00 2001 From: richard-dds Date: Wed, 5 Sep 2018 20:34:54 -0400 Subject: [PATCH 06/19] Changes to mutable arrays need to be flagged --- ...b_add_view_workspace_members_permission.py | 22 ++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/alembic/versions/ad30159ef19b_add_view_workspace_members_permission.py b/alembic/versions/ad30159ef19b_add_view_workspace_members_permission.py index 13fce237..25b5a4f2 100644 --- a/alembic/versions/ad30159ef19b_add_view_workspace_members_permission.py +++ b/alembic/versions/ad30159ef19b_add_view_workspace_members_permission.py @@ -7,6 +7,8 @@ Create Date: 2018-09-05 11:17:17.204089 """ from alembic import op from sqlalchemy.orm.session import Session +from sqlalchemy.orm.attributes import flag_modified + from atst.models.role import Role from atst.models.permissions import Permissions @@ -27,6 +29,24 @@ def upgrade(): ccpo_role = session.query(Role).filter_by(name="ccpo").one() ccpo_role.permissions.append(Permissions.VIEW_WORKSPACE_MEMBERS) + flag_modified(owner_role, "permissions") + flag_modified(ccpo_role, "permissions") + + session.add_all((ccpo_role, owner_role)) + session.commit() + def downgrade(): - pass + session = Session(bind=op.get_bind()) + + owner_role = session.query(Role).filter_by(name="owner").one() + owner_role.permissions.append(Permissions.VIEW_WORKSPACE_MEMBERS) + + ccpo_role = session.query(Role).filter_by(name="ccpo").one() + ccpo_role.permissions.append(Permissions.VIEW_WORKSPACE_MEMBERS) + + flag_modified(owner_role, "permissions") + flag_modified(ccpo_role, "permissions") + + session.add_all((ccpo_role, owner_role)) + session.commit() From 361630e446dc79b0ded7e3ca47a4f308e010a174 Mon Sep 17 00:00:00 2001 From: richard-dds Date: Thu, 6 Sep 2018 10:16:48 -0400 Subject: [PATCH 07/19] Use helper methods for adding and removing permissions --- ...ef19b_add_view_workspace_members_permission.py | 15 ++++----------- atst/models/role.py | 13 +++++++++++++ 2 files changed, 17 insertions(+), 11 deletions(-) diff --git a/alembic/versions/ad30159ef19b_add_view_workspace_members_permission.py b/alembic/versions/ad30159ef19b_add_view_workspace_members_permission.py index 25b5a4f2..de5546c1 100644 --- a/alembic/versions/ad30159ef19b_add_view_workspace_members_permission.py +++ b/alembic/versions/ad30159ef19b_add_view_workspace_members_permission.py @@ -7,7 +7,6 @@ Create Date: 2018-09-05 11:17:17.204089 """ from alembic import op from sqlalchemy.orm.session import Session -from sqlalchemy.orm.attributes import flag_modified from atst.models.role import Role from atst.models.permissions import Permissions @@ -24,13 +23,10 @@ def upgrade(): session = Session(bind=op.get_bind()) owner_role = session.query(Role).filter_by(name="owner").one() - owner_role.permissions.append(Permissions.VIEW_WORKSPACE_MEMBERS) + owner_role.add_permission(Permissions.VIEW_WORKSPACE_MEMBERS) ccpo_role = session.query(Role).filter_by(name="ccpo").one() - ccpo_role.permissions.append(Permissions.VIEW_WORKSPACE_MEMBERS) - - flag_modified(owner_role, "permissions") - flag_modified(ccpo_role, "permissions") + ccpo_role.add_permission(Permissions.VIEW_WORKSPACE_MEMBERS) session.add_all((ccpo_role, owner_role)) session.commit() @@ -40,13 +36,10 @@ def downgrade(): session = Session(bind=op.get_bind()) owner_role = session.query(Role).filter_by(name="owner").one() - owner_role.permissions.append(Permissions.VIEW_WORKSPACE_MEMBERS) + owner_role.remove_permission(Permissions.VIEW_WORKSPACE_MEMBERS) ccpo_role = session.query(Role).filter_by(name="ccpo").one() - ccpo_role.permissions.append(Permissions.VIEW_WORKSPACE_MEMBERS) - - flag_modified(owner_role, "permissions") - flag_modified(ccpo_role, "permissions") + ccpo_role.remove_permission(Permissions.VIEW_WORKSPACE_MEMBERS) session.add_all((ccpo_role, owner_role)) session.commit() diff --git a/atst/models/role.py b/atst/models/role.py index 1205dedd..8833d3e3 100644 --- a/atst/models/role.py +++ b/atst/models/role.py @@ -1,5 +1,6 @@ from sqlalchemy import String, Column from sqlalchemy.dialects.postgresql import ARRAY +from sqlalchemy.orm.attributes import flag_modified from atst.models import Base from .types import Id @@ -12,3 +13,15 @@ class Role(Base): name = Column(String, index=True, unique=True) description = Column(String) permissions = Column(ARRAY(String), index=True, server_default="{}") + + def add_permission(self, permission): + perms_set = set(self.permissions) + perms_set.add(permission) + self.permissions = list(perms_set) + flag_modified(self, "permissions") + + def remove_permission(self, permission): + perms_set = set(self.permissions) + perms_set.discard(permission) + self.permissions = list(perms_set) + flag_modified(self, "permissions") From bdab58f1503e0a12dac8f1020e3b0838e2eb2b11 Mon Sep 17 00:00:00 2001 From: richard-dds Date: Thu, 6 Sep 2018 11:19:13 -0400 Subject: [PATCH 08/19] Add a new "view workspace" permission --- ...b_add_view_workspace_members_permission.py | 28 ++++++++++++------- atst/domain/workspaces.py | 2 +- atst/models/permissions.py | 1 + 3 files changed, 20 insertions(+), 11 deletions(-) diff --git a/alembic/versions/ad30159ef19b_add_view_workspace_members_permission.py b/alembic/versions/ad30159ef19b_add_view_workspace_members_permission.py index de5546c1..59f7c3dc 100644 --- a/alembic/versions/ad30159ef19b_add_view_workspace_members_permission.py +++ b/alembic/versions/ad30159ef19b_add_view_workspace_members_permission.py @@ -22,24 +22,32 @@ def upgrade(): session = Session(bind=op.get_bind()) - owner_role = session.query(Role).filter_by(name="owner").one() - owner_role.add_permission(Permissions.VIEW_WORKSPACE_MEMBERS) + all_roles_but_default = session.query(Role).filter(Role.name != "default").all() + for role in all_roles_but_default: + role.add_permission(Permissions.VIEW_WORKSPACE) + session.add(role) - ccpo_role = session.query(Role).filter_by(name="ccpo").one() - ccpo_role.add_permission(Permissions.VIEW_WORKSPACE_MEMBERS) + owner_and_ccpo = session.query(Role).filter(Role.name.in_(["owner", "ccpo"])).all() + for role in owner_and_ccpo: + role.add_permission(Permissions.VIEW_WORKSPACE_MEMBERS) + session.add(role) - session.add_all((ccpo_role, owner_role)) + session.flush() session.commit() def downgrade(): session = Session(bind=op.get_bind()) - owner_role = session.query(Role).filter_by(name="owner").one() - owner_role.remove_permission(Permissions.VIEW_WORKSPACE_MEMBERS) + all_roles_but_default = session.query(Role).filter(Role.name != "default").all() + for role in all_roles_but_default: + role.remove_permission(Permissions.VIEW_WORKSPACE) + session.add(role) - ccpo_role = session.query(Role).filter_by(name="ccpo").one() - ccpo_role.remove_permission(Permissions.VIEW_WORKSPACE_MEMBERS) + owner_and_ccpo = session.query(Role).filter(Role.name.in_(["owner", "ccpo"])).all() + for role in owner_and_ccpo: + role.remove_permission(Permissions.VIEW_WORKSPACE_MEMBERS) + session.add(role) - session.add_all((ccpo_role, owner_role)) + session.flush() session.commit() diff --git a/atst/domain/workspaces.py b/atst/domain/workspaces.py index c1af06ea..50c44695 100644 --- a/atst/domain/workspaces.py +++ b/atst/domain/workspaces.py @@ -30,7 +30,7 @@ class Workspaces(object): except NoResultFound: raise NotFoundError("workspace") - if not Authorization.is_in_workspace(user, workspace): + if not Authorization.has_workspace_permission(user, workspace, Permissions.VIEW_WORKSPACE): raise UnauthorizedError(user, "get workspace") return workspace diff --git a/atst/models/permissions.py b/atst/models/permissions.py index 23adcf55..c39d5b71 100644 --- a/atst/models/permissions.py +++ b/atst/models/permissions.py @@ -24,6 +24,7 @@ class Permissions(object): VIEW_ATAT_PERMISSIONS = "view_atat_permissions" TRANSFER_OWNERSHIP_OF_WORKSPACE = "transfer_ownership_of_workspace" VIEW_WORKSPACE_MEMBERS = "view_workspace_members" + VIEW_WORKSPACE = "view_workspace" ADD_APPLICATION_IN_WORKSPACE = "add_application_in_workspace" DELETE_APPLICATION_IN_WORKSPACE = "delete_application_in_workspace" From 549e4d626369a7142039a6b2dde7624c5b5c566d Mon Sep 17 00:00:00 2001 From: richard-dds Date: Thu, 6 Sep 2018 11:20:11 -0400 Subject: [PATCH 09/19] Use Workspaces.get_with_members --- atst/domain/workspaces.py | 9 +++++++++ atst/routes/workspaces.py | 8 +------- tests/domain/test_workspaces.py | 16 ++++++++++++++++ 3 files changed, 26 insertions(+), 7 deletions(-) diff --git a/atst/domain/workspaces.py b/atst/domain/workspaces.py index 50c44695..4adf0567 100644 --- a/atst/domain/workspaces.py +++ b/atst/domain/workspaces.py @@ -53,6 +53,15 @@ class Workspaces(object): return workspace + @classmethod + def get_with_members(cls, user, workspace_id): + workspace = Workspaces.get(user, workspace_id) + if not Authorization.has_workspace_permission( + user, workspace, Permissions.VIEW_WORKSPACE_MEMBERS + ): + raise UnauthorizedError(user, "view workspace members") + return workspace + @classmethod def get_many(cls, user): workspaces = ( diff --git a/atst/routes/workspaces.py b/atst/routes/workspaces.py index 190b5eff..647afda9 100644 --- a/atst/routes/workspaces.py +++ b/atst/routes/workspaces.py @@ -63,13 +63,7 @@ def show_workspace(workspace_id): @bp.route("/workspaces//members") def workspace_members(workspace_id): - user = g.current_user - workspace = Workspaces.get(user, workspace_id) - if not Authorization.has_workspace_permission( - user, workspace, Permissions.VIEW_WORKSPACE_MEMBERS - ): - raise UnauthorizedError(user, "view workspace members") - + workspace = Workspaces.get_with_members(g.current_user, workspace_id) return render_template("workspace_members.html", workspace=workspace) diff --git a/tests/domain/test_workspaces.py b/tests/domain/test_workspaces.py index 296c16d9..85d18735 100644 --- a/tests/domain/test_workspaces.py +++ b/tests/domain/test_workspaces.py @@ -155,3 +155,19 @@ def test_need_permission_to_update_workspace_user_role(): with pytest.raises(UnauthorizedError): Workspaces.update_member(random_user, workspace, member, role_name) + + +def test_owner_can_view_workspace_members(): + owner = UserFactory.create() + workspace = Workspaces.create(RequestFactory.create(creator=owner)) + workspace = Workspaces.get_with_members(owner, workspace.id) + + assert workspace + + +def test_ccpo_can_view_workspace_members(): + workspace = Workspaces.create(RequestFactory.create(creator=UserFactory.create())) + ccpo = UserFactory.from_atat_role("ccpo") + workspace = Workspaces.get_with_members(ccpo, workspace.id) + + assert workspace From b2717ca62cbf8821b79bb91c50292c9e9c0bf897 Mon Sep 17 00:00:00 2001 From: richard-dds Date: Thu, 6 Sep 2018 11:22:23 -0400 Subject: [PATCH 10/19] Add additional test --- tests/domain/test_workspaces.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tests/domain/test_workspaces.py b/tests/domain/test_workspaces.py index 85d18735..c95989d1 100644 --- a/tests/domain/test_workspaces.py +++ b/tests/domain/test_workspaces.py @@ -171,3 +171,11 @@ def test_ccpo_can_view_workspace_members(): workspace = Workspaces.get_with_members(ccpo, workspace.id) assert workspace + + +def test_random_user_cannot_view_workspace_members(): + workspace = Workspaces.create(RequestFactory.create(creator=UserFactory.create())) + developer = UserFactory.from_atat_role("developer") + + with pytest.raises(UnauthorizedError): + workspace = Workspaces.get_with_members(developer, workspace.id) From e7ae4cf80f5c3166f4d84da925168599258de948 Mon Sep 17 00:00:00 2001 From: richard-dds Date: Thu, 6 Sep 2018 11:22:45 -0400 Subject: [PATCH 11/19] Formatting --- atst/domain/workspaces.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/atst/domain/workspaces.py b/atst/domain/workspaces.py index 4adf0567..f3fc8c63 100644 --- a/atst/domain/workspaces.py +++ b/atst/domain/workspaces.py @@ -30,7 +30,9 @@ class Workspaces(object): except NoResultFound: raise NotFoundError("workspace") - if not Authorization.has_workspace_permission(user, workspace, Permissions.VIEW_WORKSPACE): + if not Authorization.has_workspace_permission( + user, workspace, Permissions.VIEW_WORKSPACE + ): raise UnauthorizedError(user, "get workspace") return workspace From 40c141f14621c4b65de75e70624acf2cbb915dc9 Mon Sep 17 00:00:00 2001 From: richard-dds Date: Thu, 6 Sep 2018 11:36:25 -0400 Subject: [PATCH 12/19] Remove random --- atst/models/workspace_user.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/atst/models/workspace_user.py b/atst/models/workspace_user.py index 1677a4bd..934c6f89 100644 --- a/atst/models/workspace_user.py +++ b/atst/models/workspace_user.py @@ -38,7 +38,7 @@ class WorkspaceUser(object): @property def status(self): - return "radical" + return "active" @property def has_environment_roles(self): From 6c0df3b0cb4125053c705485e5ed9be7ffb20b5b Mon Sep 17 00:00:00 2001 From: richard-dds Date: Thu, 6 Sep 2018 11:49:57 -0400 Subject: [PATCH 13/19] Use check_workspace_permission --- atst/domain/workspaces.py | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/atst/domain/workspaces.py b/atst/domain/workspaces.py index f3fc8c63..d7cf9f5b 100644 --- a/atst/domain/workspaces.py +++ b/atst/domain/workspaces.py @@ -30,10 +30,9 @@ class Workspaces(object): except NoResultFound: raise NotFoundError("workspace") - if not Authorization.has_workspace_permission( - user, workspace, Permissions.VIEW_WORKSPACE - ): - raise UnauthorizedError(user, "get workspace") + Authorization.check_workspace_permission( + user, workspace, Permissions.VIEW_WORKSPACE, "get workspace" + ) return workspace @@ -58,10 +57,9 @@ class Workspaces(object): @classmethod def get_with_members(cls, user, workspace_id): workspace = Workspaces.get(user, workspace_id) - if not Authorization.has_workspace_permission( - user, workspace, Permissions.VIEW_WORKSPACE_MEMBERS - ): - raise UnauthorizedError(user, "view workspace members") + Authorization.check_workspace_permission( + user, workspace, Permissions.VIEW_WORKSPACE_MEMBERS, "view workspace members" + ) return workspace @classmethod From d569e02a47da0ee30252a6ee2b28be23c1af5553 Mon Sep 17 00:00:00 2001 From: richard-dds Date: Thu, 6 Sep 2018 13:04:55 -0400 Subject: [PATCH 14/19] Formatting --- atst/domain/workspaces.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/atst/domain/workspaces.py b/atst/domain/workspaces.py index d7cf9f5b..87853c45 100644 --- a/atst/domain/workspaces.py +++ b/atst/domain/workspaces.py @@ -58,7 +58,10 @@ class Workspaces(object): def get_with_members(cls, user, workspace_id): workspace = Workspaces.get(user, workspace_id) Authorization.check_workspace_permission( - user, workspace, Permissions.VIEW_WORKSPACE_MEMBERS, "view workspace members" + user, + workspace, + Permissions.VIEW_WORKSPACE_MEMBERS, + "view workspace members", ) return workspace From 3e74ff9c05daab3c56a688cd0fcef9e5b9dcd25d Mon Sep 17 00:00:00 2001 From: richard-dds Date: Thu, 6 Sep 2018 14:11:09 -0400 Subject: [PATCH 15/19] Remove unused import --- atst/domain/workspaces.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/atst/domain/workspaces.py b/atst/domain/workspaces.py index 87853c45..2773567f 100644 --- a/atst/domain/workspaces.py +++ b/atst/domain/workspaces.py @@ -3,7 +3,7 @@ from sqlalchemy.orm.exc import NoResultFound from atst.database import db from atst.models.workspace import Workspace from atst.models.workspace_role import WorkspaceRole -from atst.domain.exceptions import NotFoundError, UnauthorizedError +from atst.domain.exceptions import NotFoundError from atst.domain.roles import Roles from atst.domain.authz import Authorization from atst.models.permissions import Permissions From eb200fbd675541b6242d98cdccb94d7ebd3fbf97 Mon Sep 17 00:00:00 2001 From: richard-dds Date: Thu, 6 Sep 2018 14:17:32 -0400 Subject: [PATCH 16/19] Create Workspaces._get --- atst/domain/workspaces.py | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/atst/domain/workspaces.py b/atst/domain/workspaces.py index 2773567f..b21c8ca0 100644 --- a/atst/domain/workspaces.py +++ b/atst/domain/workspaces.py @@ -25,11 +25,7 @@ class Workspaces(object): @classmethod def get(cls, user, workspace_id): - try: - workspace = db.session.query(Workspace).filter_by(id=workspace_id).one() - except NoResultFound: - raise NotFoundError("workspace") - + workspace = Workspaces._get(workspace_id) Authorization.check_workspace_permission( user, workspace, Permissions.VIEW_WORKSPACE, "get workspace" ) @@ -38,7 +34,7 @@ class Workspaces(object): @classmethod def get_for_update(cls, user, workspace_id): - workspace = Workspaces.get(user, workspace_id) + workspace = Workspaces._get(workspace_id) Authorization.check_workspace_permission( user, workspace, Permissions.ADD_APPLICATION_IN_WORKSPACE, "add project" ) @@ -56,13 +52,14 @@ class Workspaces(object): @classmethod def get_with_members(cls, user, workspace_id): - workspace = Workspaces.get(user, workspace_id) + workspace = Workspaces._get(workspace_id) Authorization.check_workspace_permission( user, workspace, Permissions.VIEW_WORKSPACE_MEMBERS, "view workspace members", ) + return workspace @classmethod @@ -112,3 +109,12 @@ class Workspaces(object): workspace_role = WorkspaceRole(user=user, role=role, workspace=workspace) db.session.add(workspace_role) return workspace_role + + @classmethod + def _get(cls, workspace_id): + try: + workspace = db.session.query(Workspace).filter_by(id=workspace_id).one() + except NoResultFound: + raise NotFoundError("workspace") + + return workspace From 674477042b2ac5130d58562fc6c7689cd870548e Mon Sep 17 00:00:00 2001 From: richard-dds Date: Thu, 6 Sep 2018 15:56:24 -0400 Subject: [PATCH 17/19] Fix migration path --- .../ad30159ef19b_add_view_workspace_members_permission.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/alembic/versions/ad30159ef19b_add_view_workspace_members_permission.py b/alembic/versions/ad30159ef19b_add_view_workspace_members_permission.py index 59f7c3dc..cc82c0bc 100644 --- a/alembic/versions/ad30159ef19b_add_view_workspace_members_permission.py +++ b/alembic/versions/ad30159ef19b_add_view_workspace_members_permission.py @@ -14,7 +14,7 @@ from atst.models.permissions import Permissions # revision identifiers, used by Alembic. revision = 'ad30159ef19b' -down_revision = '06aa23166ca9' +down_revision = 'c1d074288e99' branch_labels = None depends_on = None From 633957c61d8e395cd920febcb30a4b722159777d Mon Sep 17 00:00:00 2001 From: richard-dds Date: Thu, 6 Sep 2018 15:56:29 -0400 Subject: [PATCH 18/19] Template has moved --- atst/routes/workspaces.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/atst/routes/workspaces.py b/atst/routes/workspaces.py index 647afda9..ecd97bac 100644 --- a/atst/routes/workspaces.py +++ b/atst/routes/workspaces.py @@ -64,7 +64,7 @@ def show_workspace(workspace_id): @bp.route("/workspaces//members") def workspace_members(workspace_id): workspace = Workspaces.get_with_members(g.current_user, workspace_id) - return render_template("workspace_members.html", workspace=workspace) + return render_template("workspaces/members/index.html", workspace=workspace) @bp.route("/workspaces//reports") From 1620403cda0e55dc0c0a6b34b97ea914e80bc9a1 Mon Sep 17 00:00:00 2001 From: richard-dds Date: Thu, 6 Sep 2018 16:15:11 -0400 Subject: [PATCH 19/19] Add view_workspace_members permission to admin role --- .../ad30159ef19b_add_view_workspace_members_permission.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/alembic/versions/ad30159ef19b_add_view_workspace_members_permission.py b/alembic/versions/ad30159ef19b_add_view_workspace_members_permission.py index cc82c0bc..8a3ff320 100644 --- a/alembic/versions/ad30159ef19b_add_view_workspace_members_permission.py +++ b/alembic/versions/ad30159ef19b_add_view_workspace_members_permission.py @@ -27,7 +27,7 @@ def upgrade(): role.add_permission(Permissions.VIEW_WORKSPACE) session.add(role) - owner_and_ccpo = session.query(Role).filter(Role.name.in_(["owner", "ccpo"])).all() + owner_and_ccpo = session.query(Role).filter(Role.name.in_(["owner", "ccpo", "admin"])).all() for role in owner_and_ccpo: role.add_permission(Permissions.VIEW_WORKSPACE_MEMBERS) session.add(role)