From 50a532ddbb2242f4bbcfc384713b2c4c833e19fe Mon Sep 17 00:00:00 2001 From: George Drummond Date: Thu, 11 Apr 2019 10:03:21 -0400 Subject: [PATCH 1/4] ApplicationRoles seed and domain --- atst/domain/application_roles.py | 15 +++++++++++++++ script/seed_sample.py | 15 ++++++++++++++- tests/domain/test_application_roles.py | 18 ++++++++++++++++++ 3 files changed, 47 insertions(+), 1 deletion(-) create mode 100644 atst/domain/application_roles.py create mode 100644 tests/domain/test_application_roles.py diff --git a/atst/domain/application_roles.py b/atst/domain/application_roles.py new file mode 100644 index 00000000..41a75c0f --- /dev/null +++ b/atst/domain/application_roles.py @@ -0,0 +1,15 @@ +from atst.database import db +from atst.models.application_role import ApplicationRole + + +class ApplicationRoles(object): + @classmethod + def create(cls, user, application, permission_sets): + application_role = ApplicationRole(user=user, application_id=application.id) + + application_role.permission_sets = permission_sets + + db.session.add(application_role) + db.session.commit() + + return application_role diff --git a/script/seed_sample.py b/script/seed_sample.py index df5c0af5..5b175cb1 100644 --- a/script/seed_sample.py +++ b/script/seed_sample.py @@ -13,6 +13,7 @@ from atst.domain.users import Users from atst.domain.portfolios import Portfolios from atst.domain.applications import Applications from atst.domain.portfolio_roles import PortfolioRoles +from atst.domain.application_roles import ApplicationRoles from atst.models.invitation import Status as InvitationStatus from atst.domain.exceptions import AlreadyExistsError from tests.factories import ( @@ -27,6 +28,7 @@ from atst.routes.dev import _DEV_USERS as DEV_USERS from atst.domain.csp.reports import MockReportingProvider from atst.models.application import Application from atst.domain.environments import Environments +from atst.domain.permission_sets import PermissionSets PORTFOLIO_USERS = [ @@ -115,14 +117,25 @@ def create_task_order(portfolio, start, end, clin_01=None, clin_03=None): def add_applications_to_portfolio(portfolio, applications): + application_permission_sets = PermissionSets.get_many( + [PermissionSets.EDIT_APPLICATION_TEAM] + ) + for application in applications: - Applications.create( + application = Applications.create( portfolio=portfolio, name=application["name"], description=application["description"], environment_names=application["environments"], ) + for user in get_users(): + ApplicationRoles.create( + user=user, + application=application, + permission_sets=application_permission_sets, + ) + def create_demo_portfolio(name, data): try: diff --git a/tests/domain/test_application_roles.py b/tests/domain/test_application_roles.py new file mode 100644 index 00000000..02378521 --- /dev/null +++ b/tests/domain/test_application_roles.py @@ -0,0 +1,18 @@ +from atst.domain.application_roles import ApplicationRoles +from atst.domain.permission_sets import PermissionSets +from tests.factories import UserFactory, ApplicationFactory + + +def test_create_application_role(): + application = ApplicationFactory.create() + user = UserFactory.create() + + permission_sets = PermissionSets.get_many([PermissionSets.EDIT_APPLICATION_TEAM]) + + application_role = ApplicationRoles.create( + application=application, user=user, permission_sets=permission_sets + ) + + assert application_role.permission_sets == permission_sets + assert application_role.application == application + assert application_role.user == user From 265833f3fcc55538e289b8f4bdac1a864430974b Mon Sep 17 00:00:00 2001 From: dandds Date: Thu, 11 Apr 2019 11:32:17 -0400 Subject: [PATCH 2/4] ApplicationRoles.create should accept permission set names --- atst/domain/application_roles.py | 11 +++++++++-- tests/domain/test_application_roles.py | 10 ++++++---- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/atst/domain/application_roles.py b/atst/domain/application_roles.py index 41a75c0f..0177374a 100644 --- a/atst/domain/application_roles.py +++ b/atst/domain/application_roles.py @@ -1,13 +1,20 @@ from atst.database import db from atst.models.application_role import ApplicationRole +from atst.domain.permission_sets import PermissionSets class ApplicationRoles(object): @classmethod - def create(cls, user, application, permission_sets): + def _permission_sets_for_names(cls, set_names): + return PermissionSets.get_many(set_names) + + @classmethod + def create(cls, user, application, permission_set_names): application_role = ApplicationRole(user=user, application_id=application.id) - application_role.permission_sets = permission_sets + application_role.permission_sets = ApplicationRoles._permission_sets_for_names( + permission_set_names + ) db.session.add(application_role) db.session.commit() diff --git a/tests/domain/test_application_roles.py b/tests/domain/test_application_roles.py index 02378521..ceac10e1 100644 --- a/tests/domain/test_application_roles.py +++ b/tests/domain/test_application_roles.py @@ -7,12 +7,14 @@ def test_create_application_role(): application = ApplicationFactory.create() user = UserFactory.create() - permission_sets = PermissionSets.get_many([PermissionSets.EDIT_APPLICATION_TEAM]) - application_role = ApplicationRoles.create( - application=application, user=user, permission_sets=permission_sets + application=application, + user=user, + permission_set_names=[PermissionSets.EDIT_APPLICATION_TEAM], ) - assert application_role.permission_sets == permission_sets + assert application_role.permission_sets == PermissionSets.get_many( + [PermissionSets.EDIT_APPLICATION_TEAM] + ) assert application_role.application == application assert application_role.user == user From e556ded6ddda41931f8ca2de7c9ec808f436d077 Mon Sep 17 00:00:00 2001 From: George Drummond Date: Thu, 11 Apr 2019 14:16:56 -0400 Subject: [PATCH 3/4] Fix script to reflect changes in ApplicationRoles.create --- script/seed_sample.py | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/script/seed_sample.py b/script/seed_sample.py index 5b175cb1..8ec3574c 100644 --- a/script/seed_sample.py +++ b/script/seed_sample.py @@ -117,10 +117,6 @@ def create_task_order(portfolio, start, end, clin_01=None, clin_03=None): def add_applications_to_portfolio(portfolio, applications): - application_permission_sets = PermissionSets.get_many( - [PermissionSets.EDIT_APPLICATION_TEAM] - ) - for application in applications: application = Applications.create( portfolio=portfolio, @@ -133,7 +129,7 @@ def add_applications_to_portfolio(portfolio, applications): ApplicationRoles.create( user=user, application=application, - permission_sets=application_permission_sets, + permission_set_names=[PermissionSets.EDIT_APPLICATION_TEAM], ) From 9084dce762fe545b4326a9c907f8d9d82155b5bb Mon Sep 17 00:00:00 2001 From: dandds Date: Thu, 11 Apr 2019 15:38:27 -0400 Subject: [PATCH 4/4] build out seed sample script - semi-random data for applications and environments - added users to applications and environments - updated CSPRole enum with current CSP roles --- atst/models/environment_role.py | 5 +- script/seed_sample.py | 181 +++++++++++++++++++++++++------- 2 files changed, 146 insertions(+), 40 deletions(-) diff --git a/atst/models/environment_role.py b/atst/models/environment_role.py index d4bf6d1c..37207e59 100644 --- a/atst/models/environment_role.py +++ b/atst/models/environment_role.py @@ -7,7 +7,10 @@ from atst.models import Base, types, mixins class CSPRole(Enum): - NONSENSE_ROLE = "nonsense_role" + BASIC_ACCESS = "Basic Access" + NETWORK_ADMIN = "Network Admin" + BUSINESS_READ = "Business Read-only" + TECHNICAL_READ = "Technical Read-only" class EnvironmentRole(Base, mixins.TimestampsMixin, mixins.AuditableMixin): diff --git a/script/seed_sample.py b/script/seed_sample.py index 8ec3574c..247fa47c 100644 --- a/script/seed_sample.py +++ b/script/seed_sample.py @@ -1,34 +1,36 @@ # Add root application dir to the python path import os import sys -from datetime import datetime, timedelta, date +from datetime import timedelta, date import random +from faker import Faker parent_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), "..")) sys.path.append(parent_dir) -from atst.database import db from atst.app import make_config, make_app -from atst.domain.users import Users -from atst.domain.portfolios import Portfolios -from atst.domain.applications import Applications -from atst.domain.portfolio_roles import PortfolioRoles +from atst.database import db from atst.domain.application_roles import ApplicationRoles -from atst.models.invitation import Status as InvitationStatus -from atst.domain.exceptions import AlreadyExistsError +from atst.domain.applications import Applications +from atst.domain.csp.reports import MockReportingProvider +from atst.domain.environments import Environments +from atst.domain.exceptions import AlreadyExistsError, NotFoundError +from atst.domain.permission_sets import PermissionSets, APPLICATION_PERMISSION_SETS +from atst.domain.portfolio_roles import PortfolioRoles +from atst.domain.environment_roles import EnvironmentRoles +from atst.domain.portfolios import Portfolios +from atst.domain.users import Users +from atst.models.application import Application +from atst.models.environment_role import CSPRole +from atst.routes.dev import _DEV_USERS as DEV_USERS + from tests.factories import ( - InvitationFactory, TaskOrderFactory, - random_future_date, - random_past_date, random_task_order_number, random_service_branch, ) -from atst.routes.dev import _DEV_USERS as DEV_USERS -from atst.domain.csp.reports import MockReportingProvider -from atst.models.application import Application -from atst.domain.environments import Environments -from atst.domain.permission_sets import PermissionSets + +fake = Faker() PORTFOLIO_USERS = [ @@ -36,7 +38,6 @@ PORTFOLIO_USERS = [ "first_name": "Danny", "last_name": "Knight", "email": "knight@mil.gov", - "portfolio_role": "developer", "dod_id": "0000000001", "permission_sets": PortfolioRoles.DEFAULT_PORTFOLIO_PERMISSION_SETS, }, @@ -44,7 +45,6 @@ PORTFOLIO_USERS = [ "first_name": "Mario", "last_name": "Hudson", "email": "hudson@mil.gov", - "portfolio_role": "billing_auditor", "dod_id": "0000000002", "permission_sets": PortfolioRoles.DEFAULT_PORTFOLIO_PERMISSION_SETS, }, @@ -52,13 +52,89 @@ PORTFOLIO_USERS = [ "first_name": "Louise", "last_name": "Greer", "email": "greer@mil.gov", - "portfolio_role": "admin", "dod_id": "0000000003", "permission_sets": PortfolioRoles.DEFAULT_PORTFOLIO_PERMISSION_SETS, }, ] +APPLICATION_USERS = [ + { + "first_name": "Jean Luc", + "last_name": "Picard", + "email": "picard@mil.gov", + "dod_id": "0000000004", + "permission_sets": random.sample( + APPLICATION_PERMISSION_SETS, k=random.randint(1, 4) + ), + }, + { + "first_name": "()", + "last_name": "Spock", + "email": "spock@mil.gov", + "dod_id": "0000000005", + "permission_sets": random.sample( + APPLICATION_PERMISSION_SETS, k=random.randint(1, 4) + ), + }, + { + "first_name": "William", + "last_name": "Shatner", + "email": "shatner@mil.gov", + "dod_id": "0000000006", + "permission_sets": random.sample( + APPLICATION_PERMISSION_SETS, k=random.randint(1, 4) + ), + }, + { + "first_name": "Nyota", + "last_name": "Uhura", + "email": "uhura@mil.gov", + "dod_id": "0000000007", + "permission_sets": random.sample( + APPLICATION_PERMISSION_SETS, k=random.randint(1, 4) + ), + }, + { + "first_name": "Kathryn", + "last_name": "Janeway", + "email": "janeway@mil.gov", + "dod_id": "0000000008", + "permission_sets": random.sample( + APPLICATION_PERMISSION_SETS, k=random.randint(1, 4) + ), + }, +] + + +SHIP_NAMES = [ + "Millenium Falcon", + "Star Destroyer", + "Attack Cruiser", + "Sith Infiltrator", + "Death Star", + "Lambda Shuttle", + "Corellian Corvette", +] + + +SOFTWARE_WORDS = [ + "Enterprise", + "Scalable", + "Solution", + "Blockchain", + "Cloud", + "Micro", + "Macro", + "Software", + "Global", + "Team", +] + + +ENVIRONMENT_NAMES = ["production", "staging", "test", "uat", "dev", "qa"] + + def get_users(): users = [] for dev_user in DEV_USERS.values(): @@ -72,8 +148,8 @@ def get_users(): def add_members_to_portfolio(portfolio): - for portfolio_role in PORTFOLIO_USERS: - ws_role = Portfolios.create_member(portfolio, portfolio_role) + for user_data in PORTFOLIO_USERS: + ws_role = Portfolios.create_member(portfolio, user_data) db.session.refresh(ws_role) PortfolioRoles.enable(ws_role) @@ -116,22 +192,53 @@ def create_task_order(portfolio, start, end, clin_01=None, clin_03=None): db.session.commit() -def add_applications_to_portfolio(portfolio, applications): - for application in applications: +def random_applications(): + return [ + { + "name": fake.sentence(nb_words=3, ext_word_list=SOFTWARE_WORDS)[0:-1], + "description": fake.bs(), + "environments": random.sample(ENVIRONMENT_NAMES, k=random.randint(1, 4)), + } + for n in range(random.randint(1, 4)) + ] + + +def add_applications_to_portfolio(portfolio): + applications = random_applications() + for application_data in applications: application = Applications.create( portfolio=portfolio, - name=application["name"], - description=application["description"], - environment_names=application["environments"], + name=application_data["name"], + description=application_data["description"], + environment_names=application_data["environments"], ) - for user in get_users(): + users = random.sample(APPLICATION_USERS, k=random.randint(1, 5)) + for user_data in users: + try: + user = Users.get_by_dod_id(user_data["dod_id"]) + except NotFoundError: + user = Users.create( + user_data["dod_id"], + None, + first_name=user_data["first_name"], + last_name=user_data["last_name"], + ) + ApplicationRoles.create( user=user, application=application, permission_set_names=[PermissionSets.EDIT_APPLICATION_TEAM], ) + user_environments = random.sample( + application.environments, + k=random.randint(1, len(application.environments)), + ) + for env in user_environments: + role = random.choice([e.value for e in CSPRole]) + EnvironmentRoles.create(user=user, environment=env, role=role) + def create_demo_portfolio(name, data): try: @@ -165,13 +272,6 @@ def create_demo_portfolio(name, data): def seed_db(): get_users() amanda = Users.get_by_dod_id("2345678901") - application_info = [ - { - "name": "First Application", - "description": "This is our first application", - "environments": ["dev", "staging", "prod"], - } - ] # Create Portfolios for Amanda with mocked reporting data create_demo_portfolio("A-Wing", MockReportingProvider.REPORT_FIXTURE_MAP["A-Wing"]) @@ -182,23 +282,26 @@ def seed_db(): ) add_task_orders_to_portfolio(tie_interceptor) add_members_to_portfolio(tie_interceptor) - add_applications_to_portfolio(tie_interceptor, application_info) + add_applications_to_portfolio(tie_interceptor) tie_fighter = Portfolios.create( amanda, name="TIE Fighter", defense_component=random_service_branch() ) add_task_orders_to_portfolio(tie_fighter) add_members_to_portfolio(tie_fighter) - add_applications_to_portfolio(tie_fighter, application_info) + add_applications_to_portfolio(tie_fighter) - # create a portfolio 'Y-Wing' for each user + # create a portfolio for each user + ships = SHIP_NAMES.copy() for user in get_users(): + ship = random.choice(ships) + ships.remove(ship) portfolio = Portfolios.create( - user, name="Y-Wing", defense_component=random_service_branch() + user, name=ship, defense_component=random_service_branch() ) add_task_orders_to_portfolio(portfolio) add_members_to_portfolio(portfolio) - add_applications_to_portfolio(portfolio, application_info) + add_applications_to_portfolio(portfolio) if __name__ == "__main__":