From 0da0f6a0ae39d8f80b33b1ed5c987140768766b0 Mon Sep 17 00:00:00 2001 From: dandds Date: Wed, 1 May 2019 15:30:42 -0400 Subject: [PATCH] WIP: use team form for application team page --- atst/domain/environment_roles.py | 14 ++++- atst/forms/team.py | 3 +- atst/models/application.py | 1 + atst/routes/applications/team.py | 43 +++++++++++++-- .../add_new_application_member.html | 20 +++---- .../applications/read_only_team.html | 46 ++++++++++++++++ templates/portfolios/applications/team.html | 52 +++---------------- tests/domain/test_environment_roles.py | 16 ++++++ 8 files changed, 134 insertions(+), 61 deletions(-) create mode 100644 templates/fragments/applications/read_only_team.html create mode 100644 tests/domain/test_environment_roles.py diff --git a/atst/domain/environment_roles.py b/atst/domain/environment_roles.py index 99728467..bb8fdb85 100644 --- a/atst/domain/environment_roles.py +++ b/atst/domain/environment_roles.py @@ -1,7 +1,7 @@ from flask import current_app as app from atst.database import db -from atst.models import EnvironmentRole +from atst.models import EnvironmentRole, Application, Environment class EnvironmentRoles(object): @@ -35,3 +35,15 @@ class EnvironmentRoles(object): return True else: return False + + @classmethod + def get_for_application_and_user(cls, user_id, application_id): + return ( + db.session.query(EnvironmentRole) + .join(Environment) + .join(Application, Environment.application_id == Application.id) + .filter(EnvironmentRole.user_id == user_id) + .filter(Application.id == application_id) + .filter(EnvironmentRole.environment_id == Environment.id) + .all() + ) diff --git a/atst/forms/team.py b/atst/forms/team.py index ccc49e35..f9661f72 100644 --- a/atst/forms/team.py +++ b/atst/forms/team.py @@ -1,5 +1,5 @@ from flask_wtf import FlaskForm -from wtforms.fields import FormField, FieldList, HiddenField +from wtforms.fields import FormField, FieldList, HiddenField, StringField from .application_member import EnvironmentForm from .forms import BaseForm @@ -43,6 +43,7 @@ class PermissionsForm(FlaskForm): class MemberForm(FlaskForm): user_id = HiddenField() + user_name = StringField() environment_roles = FieldList(FormField(EnvironmentForm)) permission_sets = FormField(PermissionsForm) diff --git a/atst/models/application.py b/atst/models/application.py index 9edb5166..ef783ff6 100644 --- a/atst/models/application.py +++ b/atst/models/application.py @@ -28,6 +28,7 @@ class Application( back_populates="application", primaryjoin="and_(Environment.application_id==Application.id, Environment.deleted==False)", ) + # TODO: filter condition on this relationship? roles = relationship("ApplicationRole") @property diff --git a/atst/routes/applications/team.py b/atst/routes/applications/team.py index 57994a3c..8bee43ec 100644 --- a/atst/routes/applications/team.py +++ b/atst/routes/applications/team.py @@ -2,12 +2,14 @@ from flask import render_template, request as http_request, g, url_for, redirect from . import applications_bp -from atst.domain.environments import Environments from atst.domain.applications import Applications +from atst.domain.environments import Environments +from atst.domain.environment_roles import EnvironmentRoles from atst.domain.authz.decorator import user_can_access_decorator as user_can from atst.domain.permission_sets import PermissionSets from atst.domain.exceptions import AlreadyExistsError from atst.forms.application_member import NewForm as NewMemberForm +from atst.forms.team import TeamForm from atst.models import Permissions from atst.services.invitation import Invitation as InvitationService from atst.utils.flash import formatted_flash as flash @@ -27,8 +29,10 @@ def team(application_id): application = Applications.get(resource_id=application_id) environment_users = {} + team_data = [] for member in application.members: user_id = member.user.id + user_name = member.user.full_name environment_users[user_id] = { "permissions": { "delete_access": permission_str( @@ -45,18 +49,51 @@ def team(application_id): user=member.user, application=application ), } + permission_sets = { + "perms_env_mgmt": PermissionSets.EDIT_APPLICATION_ENVIRONMENTS + if member.has_permission_set(PermissionSets.EDIT_APPLICATION_ENVIRONMENTS) + else "", + "perms_team_mgmt": PermissionSets.EDIT_APPLICATION_TEAM + if member.has_permission_set(PermissionSets.EDIT_APPLICATION_TEAM) + else "", + "perms_del_env": PermissionSets.DELETE_APPLICATION_ENVIRONMENTS + if member.has_permission_set(PermissionSets.DELETE_APPLICATION_ENVIRONMENTS) + else "", + } + roles = EnvironmentRoles.get_for_application_and_user( + member.user.id, application.id + ) + environment_roles = [ + { + "environment_id": str(role.environment.id), + "environment_name": role.environment.name, + "role": role.role, + } + for role in roles + ] + team_data.append( + { + "user_id": str(user_id), + "user_name": user_name, + "permission_sets": permission_sets, + "environment_roles": environment_roles, + } + ) + + team_form = TeamForm(data={"members": team_data}) env_roles = [ {"environment_id": e.id, "environment_name": e.name} for e in application.environments ] - member_form = NewMemberForm(data={"environment_roles": env_roles}) + new_member_form = NewMemberForm(data={"environment_roles": env_roles}) return render_template( "portfolios/applications/team.html", application=application, environment_users=environment_users, - member_form=member_form, + team_form=team_form, + new_member_form=new_member_form, ) diff --git a/templates/fragments/applications/add_new_application_member.html b/templates/fragments/applications/add_new_application_member.html index 99f8f99a..3294b21c 100644 --- a/templates/fragments/applications/add_new_application_member.html +++ b/templates/fragments/applications/add_new_application_member.html @@ -9,23 +9,23 @@
- {{ TextInput(member_form.user_data.first_name, validation='requiredField') }} + {{ TextInput(new_member_form.user_data.first_name, validation='requiredField') }}
- {{ TextInput(member_form.user_data.last_name, validation='requiredField') }} + {{ TextInput(new_member_form.user_data.last_name, validation='requiredField') }}
- {{ TextInput(member_form.user_data.email, validation='email') }} + {{ TextInput(new_member_form.user_data.email, validation='email') }}
- {{ TextInput(member_form.user_data.phone_number, validation='usPhone', optional=True) }} + {{ TextInput(new_member_form.user_data.phone_number, validation='usPhone', optional=True) }}
- {{ TextInput(member_form.user_data.dod_id, validation='dodId') }} + {{ TextInput(new_member_form.user_data.dod_id, validation='dodId') }}
@@ -61,7 +61,7 @@
- {% for environment_data in member_form.environment_roles %} + {% for environment_data in new_member_form.environment_roles %} @@ -86,9 +86,9 @@ {% endfor %}

{{ "portfolios.applications.members.new.manage_perms" | translate({"application_name": application.name}) }}

- {{ CheckboxInput(member_form.permission_sets.perms_team_mgmt, classes="input__inline-fields") }} - {% call CheckboxInput(member_form.permission_sets.perms_env_mgmt, classes="input__inline-fields") %} - {% set field=member_form.permission_sets.perms_del_env %} + {{ CheckboxInput(new_member_form.permission_sets.perms_team_mgmt, classes="input__inline-fields") }} + {% call CheckboxInput(new_member_form.permission_sets.perms_env_mgmt, classes="input__inline-fields") %} + {% set field=new_member_form.permission_sets.perms_del_env %} {{ value }} + {% endmacro %} + + +
  • +
    +
    {{ user.full_name }}
    + {{ PermissionField(user_permissions["delete_access"]) }} + {{ PermissionField(user_permissions["environment_management"]) }} + {{ PermissionField(user_permissions["team_management"]) }} + +
    + {% call ToggleSection(section_name="environments") %} +
      + {% for environment in user_info["environments"] %} +
    • + {{ environment.name }} +
    • + {% endfor %} +
    + {% endcall %} +
  • +
    +{% endfor %} diff --git a/templates/portfolios/applications/team.html b/templates/portfolios/applications/team.html index e02a5459..c5e94b0a 100644 --- a/templates/portfolios/applications/team.html +++ b/templates/portfolios/applications/team.html @@ -61,52 +61,12 @@
      - {% for member in application.members %} - {% set user = member.user %} - {% set user_info = environment_users[user.id] %} - {% set user_permissions = user_info["permissions"] %} - - {% macro PermissionField(value) %} -
      {{ value }}
      - {% endmacro %} - - -
    • -
      -
      {{ user.full_name }}
      - {{ PermissionField(user_permissions["delete_access"]) }} - {{ PermissionField(user_permissions["environment_management"]) }} - {{ PermissionField(user_permissions["team_management"]) }} - -
      - {% call ToggleSection(section_name="environments") %} -
        - {% for environment in user_info["environments"] %} -
      • - {{ environment.name }} -
      • - {% endfor %} -
      - {% endcall %} -
    • -
      - {% endfor %} + {% if user_can(permissions.EDIT_APPLICATION_MEMBER) %} + {# edit version goes here #} + {% include "fragments/applications/read_only_team.html" %} + {% elif user_can(permissions.VIEW_APPLICATION_MEMBER) %} + {% include "fragments/applications/read_only_team.html" %} + {% endif %}
    diff --git a/tests/domain/test_environment_roles.py b/tests/domain/test_environment_roles.py new file mode 100644 index 00000000..de42d70e --- /dev/null +++ b/tests/domain/test_environment_roles.py @@ -0,0 +1,16 @@ +from atst.domain.environment_roles import EnvironmentRoles + +from tests.factories import * + + +def test_get_for_application_and_user(): + user = UserFactory.create() + application = ApplicationFactory.create() + env1 = EnvironmentFactory.create(application=application) + EnvironmentFactory.create(application=application) + EnvironmentRoleFactory.create(user=user, environment=env1) + + roles = EnvironmentRoles.get_for_application_and_user(user.id, application.id) + assert len(roles) == 1 + assert roles[0].environment == env1 + assert roles[0].user == user