Example #1
0
def create_or_update_new_application_step_1(portfolio_id=None,
                                            application_id=None):
    form = get_new_application_form({**http_request.form},
                                    NameAndDescriptionForm, application_id)

    if form.validate():
        application = None
        if application_id:
            application = Applications.get(application_id)
            application = Applications.update(application, form.data)
            flash("application_updated", application_name=application.name)
        else:
            portfolio = Portfolios.get_for_update(portfolio_id)
            application = Applications.create(g.current_user, portfolio,
                                              **form.data)
            flash("application_created", application_name=application.name)
        return redirect(
            url_for(
                "applications.update_new_application_step_2",
                application_id=application.id,
            ))
    else:
        return (
            render_new_application_form(
                "applications/new/step_1.html",
                NameAndDescriptionForm,
                portfolio_id,
                application_id,
                form,
            ),
            400,
        )
Example #2
0
def handle_create_member(application_id, form_data):
    application = Applications.get(application_id)
    form = NewMemberForm(form_data)

    if form.validate():
        try:
            invite = Applications.invite(
                application=application,
                inviter=g.current_user,
                user_data=form.user_data.data,
                permission_sets_names=form.data["permission_sets"],
                environment_roles_data=form.environment_roles.data,
            )

            send_application_invitation(
                invitee_email=invite.email,
                inviter_name=g.current_user.full_name,
                token=invite.token,
            )

            flash("new_application_member", user_name=invite.first_name)

        except AlreadyExistsError:
            return render_template(
                "error.html",
                message="There was an error processing your request.")
    else:
        pass
Example #3
0
def test_create_does_not_duplicate_names_within_portfolio():
    portfolio = PortfolioFactory.create()
    name = "An Awesome Application"

    assert Applications.create(portfolio.owner, portfolio, name, "")
    with pytest.raises(AlreadyExistsError):
        Applications.create(portfolio.owner, portfolio, name, "")
Example #4
0
def test_can_only_update_name_and_description():
    owner = UserFactory.create()
    portfolio = PortfolioFactory.create(
        owner=owner,
        applications=[{
            "name": "Application 1",
            "description": "a application",
            "environments": [{
                "name": "dev"
            }],
        }],
    )
    application = Applications.get(portfolio.applications[0].id)
    env_name = application.environments[0].name
    Applications.update(
        application,
        {
            "name": "New Name",
            "description": "a new application",
            "environment_name": "prod",
        },
    )

    assert application.name == "New Name"
    assert application.description == "a new application"
    assert len(application.environments) == 1
    assert application.environments[0].name == env_name
Example #5
0
def test_get_portfolio_events_includes_app_and_env_events():
    owner = UserFactory.create()
    # add portfolio level events
    portfolio = PortfolioFactory.create(owner=owner)
    portfolio_events = AuditLog.get_portfolio_events(portfolio)

    # add application level events
    application = ApplicationFactory.create(portfolio=portfolio)
    Applications.update(application, {"name": "Star Cruiser"})
    app_role = ApplicationRoleFactory.create(application=application)
    app_invite = ApplicationInvitationFactory.create(role=app_role)
    portfolio_and_app_events = AuditLog.get_portfolio_events(portfolio)
    assert len(portfolio_events) < len(portfolio_and_app_events)

    # add environment level events
    env = EnvironmentFactory.create(application=application)
    env_role = EnvironmentRoleFactory.create(environment=env, application_role=app_role)
    portfolio_app_and_env_events = AuditLog.get_portfolio_events(portfolio)
    assert len(portfolio_and_app_events) < len(portfolio_app_and_env_events)

    resource_types = [event.resource_type for event in portfolio_app_and_env_events]
    assert "application" in resource_types
    assert "application_role" in resource_types
    assert "application_invitation" in resource_types
    assert "environment" in resource_types
    assert "environment_role" in resource_types
Example #6
0
def test_get_application():
    app = ApplicationFactory.create()
    assert Applications.get(app.id) == app
    assert Applications.get(app.id, portfolio_id=app.portfolio_id) == app
    with pytest.raises(NotFoundError):
        # make the uuid a string like you'd get from a route
        rando_id = str(uuid4())
        Applications.get(app.id, portfolio_id=rando_id)
Example #7
0
def test_update_does_not_duplicate_names_within_portfolio():
    portfolio = PortfolioFactory.create()
    name = "An Awesome Application"
    application = ApplicationFactory.create(portfolio=portfolio, name=name)
    dupe_application = ApplicationFactory.create(portfolio=portfolio)

    with pytest.raises(AlreadyExistsError):
        Applications.update(dupe_application, {"name": name})
Example #8
0
def delete(application_id):
    application = Applications.get(application_id)
    Applications.delete(application)

    flash("application_deleted", application_name=application.name)

    return redirect(
        url_for("applications.portfolio_applications",
                portfolio_id=application.portfolio_id))
Example #9
0
def test_scoped_portfolio_returns_all_applications_for_portfolio_owner(
        portfolio, portfolio_owner):
    for _ in range(5):
        Applications.create(
            portfolio.owner,
            portfolio,
            "My Application",
            "My application",
            ["dev", "staging", "prod"],
        )

    scoped_portfolio = Portfolios.get(portfolio_owner, portfolio.id)

    assert len(scoped_portfolio.applications) == 5
    assert len(scoped_portfolio.applications[0].environments) == 3
Example #10
0
def update(application_id):
    application = Applications.get(application_id)
    form = NameAndDescriptionForm(http_request.form)
    if form.validate():
        application_data = form.data
        Applications.update(application, application_data)

        return redirect(
            url_for(
                "applications.portfolio_applications",
                portfolio_id=application.portfolio_id,
            ))
    else:
        return render_settings_page(application=application,
                                    application_form=form)
Example #11
0
def handle_update_member(application_id, application_role_id, form_data):
    app_role = ApplicationRoles.get_by_id(application_role_id)
    application = Applications.get(application_id)
    existing_env_roles_data = filter_env_roles_form_data(
        app_role, application.environments)
    form = UpdateMemberForm(formdata=form_data,
                            environment_roles=existing_env_roles_data)

    if form.validate():
        try:
            ApplicationRoles.update_permission_sets(
                app_role, form.data["permission_sets"])

            for env_role in form.environment_roles:
                environment = Environments.get(env_role.environment_id.data)
                new_role = None if env_role.disabled.data else env_role.data[
                    "role"]
                Environments.update_env_role(environment, app_role, new_role)

            flash("application_member_updated", user_name=app_role.user_name)

        except GeneralCSPException as exc:
            log_error(exc)
            flash(
                "application_member_update_error",
                user_name=app_role.user_name,
            )
    else:
        pass
Example #12
0
def test_invite():
    application = ApplicationFactory.create()
    env1 = EnvironmentFactory.create(application=application)
    env2 = EnvironmentFactory.create(application=application)
    user_data = UserFactory.dictionary()
    permission_sets_names = [PermissionSets.EDIT_APPLICATION_TEAM]

    invitation = Applications.invite(
        application=application,
        inviter=application.portfolio.owner,
        user_data=user_data,
        permission_sets_names=permission_sets_names,
        environment_roles_data=[
            {
                "environment_id": env1.id,
                "role": CSPRole.BASIC_ACCESS.value
            },
            {
                "environment_id": env2.id,
                "role": None
            },
        ],
    )

    member_role = invitation.role
    assert invitation.dod_id == user_data["dod_id"]
    # view application AND edit application team
    assert len(member_role.permission_sets) == 2

    env_roles = member_role.environment_roles
    assert len(env_roles) == 1
    assert env_roles[0].environment == env1
Example #13
0
def test_for_user():
    user = UserFactory.create()
    portfolio = PortfolioFactory.create()
    for _x in range(4):
        ApplicationFactory.create(portfolio=portfolio)

    ApplicationRoleFactory.create(
        application=portfolio.applications[0],
        user=user,
        status=ApplicationRoleStatus.ACTIVE,
    )
    ApplicationRoleFactory.create(
        application=portfolio.applications[1],
        user=user,
        status=ApplicationRoleStatus.ACTIVE,
    )
    ApplicationRoleFactory.create(
        application=portfolio.applications[2],
        user=user,
        status=ApplicationRoleStatus.PENDING,
    )

    assert len(portfolio.applications) == 4
    user_applications = Applications.for_user(user, portfolio)
    assert len(user_applications) == 2
Example #14
0
def settings(application_id):
    application = Applications.get(application_id)

    return render_settings_page(
        application=application,
        active_toggler=http_request.args.get("active_toggler"),
        active_toggler_section=http_request.args.get("active_toggler_section"),
    )
Example #15
0
    def applications(self):
        can_view_all_applications = Authorization.has_portfolio_permission(
            self.user, self.resource, Permissions.VIEW_APPLICATION)

        if can_view_all_applications:
            return self.resource.applications
        else:
            return Applications.for_user(self.user, self.resource)
Example #16
0
def test_scoped_portfolio_for_admin_missing_view_apps_perms(
        portfolio_owner, portfolio):
    Applications.create(
        portfolio.owner,
        portfolio,
        "My Application 2",
        "My application 2",
        ["dev", "staging", "prod"],
    )
    restricted_admin = UserFactory.create()
    PortfolioRoleFactory.create(
        portfolio=portfolio,
        user=restricted_admin,
        permission_sets=[PermissionSets.get(PermissionSets.VIEW_PORTFOLIO)],
    )
    scoped_portfolio = Portfolios.get(restricted_admin, portfolio.id)
    assert scoped_portfolio.id == portfolio.id
    assert len(portfolio.applications) == 1
    assert len(scoped_portfolio.applications) == 0
Example #17
0
def test_create_application_with_multiple_environments():
    portfolio = PortfolioFactory.create()
    application = Applications.create(portfolio.owner, portfolio,
                                      "My Test Application", "Test",
                                      ["dev", "prod"])

    assert application.portfolio == portfolio
    assert application.name == "My Test Application"
    assert application.description == "Test"
    assert sorted(e.name for e in application.environments) == ["dev", "prod"]
Example #18
0
def test_delete_application(session):
    app = ApplicationFactory.create()
    app_role = ApplicationRoleFactory.create(user=UserFactory.create(),
                                             application=app)
    env1 = EnvironmentFactory.create(application=app)
    env2 = EnvironmentFactory.create(application=app)
    assert not app.deleted
    assert not env1.deleted
    assert not env2.deleted
    assert not app_role.deleted

    Applications.delete(app)

    assert app.deleted
    assert env1.deleted
    assert env2.deleted
    assert app_role.deleted

    # changes are flushed
    assert not session.dirty
Example #19
0
def test_scoped_portfolio_returns_all_applications_for_portfolio_admin(
        portfolio, portfolio_owner):
    for _ in range(5):
        Applications.create(
            portfolio.owner,
            portfolio,
            "My Application",
            "My application",
            ["dev", "staging", "prod"],
        )

    admin = UserFactory.create()
    perm_sets = get_all_portfolio_permission_sets()
    PortfolioRoleFactory.create(user=admin,
                                portfolio=portfolio,
                                permission_sets=perm_sets)
    scoped_portfolio = Portfolios.get(admin, portfolio.id)

    assert len(scoped_portfolio.applications) == 5
    assert len(scoped_portfolio.applications[0].environments) == 3
Example #20
0
def handle_update_application(form, application_id=None, portfolio_id=None):
    if form.validate():
        application = None

        try:
            if application_id:
                application = Applications.get(application_id)
                application = Applications.update(application, form.data)
                flash("application_updated", application_name=application.name)
            else:
                portfolio = Portfolios.get_for_update(portfolio_id)
                application = Applications.create(g.current_user, portfolio,
                                                  **form.data)
                flash("application_created", application_name=application.name)

            return application

        except AlreadyExistsError:
            flash("application_name_error", name=form.data["name"])
            return False
Example #21
0
def test_invite_to_nonexistent_environment():
    application = ApplicationFactory.create()
    env1 = EnvironmentFactory.create(application=application)
    user_data = UserFactory.dictionary()

    with pytest.raises(NotFoundError):
        Applications.invite(
            application=application,
            inviter=application.portfolio.owner,
            user_data=user_data,
            environment_roles_data=[
                {
                    "environment_id": env1.id,
                    "role": CSPRole.BASIC_ACCESS.value
                },
                {
                    "environment_id": uuid4(),
                    "role": CSPRole.BASIC_ACCESS.value
                },
            ],
        )
Example #22
0
def test_get_application_events():
    # add in some portfolio level events
    portfolio = PortfolioFactory.create()
    Portfolios.update(portfolio, {"name": "New Name"})
    # add app level events
    application = ApplicationFactory.create(portfolio=portfolio)
    Applications.update(application, {"name": "Star Cruiser"})
    app_role = ApplicationRoleFactory.create(application=application)
    app_invite = ApplicationInvitationFactory.create(role=app_role)
    env = EnvironmentFactory.create(application=application)
    env_role = EnvironmentRoleFactory.create(environment=env, application_role=app_role)
    # add rando app
    rando_app = ApplicationFactory.create(portfolio=portfolio)

    events = AuditLog.get_application_events(application)
    for event in events:
        assert event.application_id == application.id
        assert not event.application_id == rando_app.id

    resource_types = [event.resource_type for event in events]
    assert "portfolio" not in resource_types
Example #23
0
def view_new_application_step_3(application_id):
    application = Applications.get(application_id)
    members = get_members_data(application)
    new_member_form = get_new_member_form(application)

    return render_template(
        "applications/new/step_3.html",
        application_id=application_id,
        application=application,
        members=members,
        new_member_form=new_member_form,
    )
Example #24
0
def update_new_application_step_2(application_id):
    form = get_new_application_form({**http_request.form}, EnvironmentsForm,
                                    application_id)
    if form.validate():
        application = Applications.get(application_id)
        application = Applications.update(application, form.data)
        flash("application_environments_updated")
        return redirect(
            url_for(
                "applications.update_new_application_step_3",
                application_id=application_id,
            ))
    else:
        return (
            render_new_application_form(
                "applications/new/step_2.html",
                EnvironmentsForm,
                application_id=application_id,
                form=form,
            ),
            400,
        )
Example #25
0
def view_new_application_step_2(application_id):
    application = Applications.get(application_id)
    render_args = {
        "form":
        EnvironmentsForm(
            data={
                "environment_names":
                [environment.name for environment in application.environments]
            }),
        "application":
        application,
    }

    return render_template("applications/new/step_2.html", **render_args)
Example #26
0
def render_new_application_form(template,
                                form_class,
                                portfolio_id=None,
                                application_id=None,
                                form=None):
    render_args = {"application_id": application_id}
    if application_id:
        application = Applications.get(application_id)
        render_args["form"] = form or form_class(obj=application)
        render_args["application"] = application
    else:
        render_args["form"] = form or form_class()

    return render_template(template, **render_args)
Example #27
0
def test_portfolio_owner_can_view_environments():
    owner = UserFactory.create()
    portfolio = PortfolioFactory.create(
        owner=owner,
        applications=[{
            "environments": [{
                "name": "dev"
            }, {
                "name": "prod"
            }]
        }],
    )
    application = Applications.get(portfolio.applications[0].id)

    assert len(application.environments) == 2
Example #28
0
def update(application_id):
    application = Applications.get(application_id)
    form = NameAndDescriptionForm(http_request.form)
    updated_application = handle_update_application(form, application_id)

    if updated_application:
        return redirect(
            url_for(
                "applications.portfolio_applications",
                portfolio_id=application.portfolio_id,
            ))
    else:
        return (
            render_settings_page(application=application, show_flash=True),
            400,
        )
Example #29
0
def new_environment(application_id):
    application = Applications.get(application_id)
    env_form = EditEnvironmentForm(formdata=http_request.form)
    environment = handle_update_environment(form=env_form,
                                            application=application)

    if environment:
        return redirect(
            url_for(
                "applications.settings",
                application_id=application.id,
                fragment="application-environments",
                _anchor="application-environments",
            ))
    else:
        return (render_settings_page(application=application,
                                     show_flash=True), 400)
Example #30
0
def test_application_settings(client, user_session):
    portfolio = PortfolioFactory.create()
    application = Applications.create(
        portfolio.owner,
        portfolio,
        "Snazzy Application",
        "A new application for me and my friends",
        {"env1", "env2"},
    )
    user_session(portfolio.owner)
    response = client.get(
        url_for("applications.settings", application_id=application.id))
    assert response.status_code == 200
    # the assertion below is a quick check to prevent regressions -- this ensures that
    # the correct URL for creating a member for an application is _somewhere_ in
    # the settings page.
    assert (url_for("applications.create_member",
                    application_id=application.id) in response.data.decode())