diff --git a/atst/forms/portfolio_member.py b/atst/forms/portfolio_member.py index bee61c09..10009759 100644 --- a/atst/forms/portfolio_member.py +++ b/atst/forms/portfolio_member.py @@ -1,6 +1,6 @@ -from wtforms.fields import StringField, FormField, FieldList from wtforms.fields.html5 import EmailField, TelField from wtforms.validators import Required, Email, Length, Optional +from wtforms.fields import StringField, FormField, FieldList, HiddenField from atst.domain.permission_sets import PermissionSets from .forms import BaseForm @@ -11,6 +11,7 @@ from atst.utils.localization import translate class PermissionsForm(BaseForm): member = StringField() + user_id = HiddenField() perms_app_mgmt = SelectField( None, choices=[ diff --git a/atst/routes/portfolios/index.py b/atst/routes/portfolios/index.py index 78f0ba68..541a8194 100644 --- a/atst/routes/portfolios/index.py +++ b/atst/routes/portfolios/index.py @@ -2,9 +2,12 @@ from datetime import date, timedelta from flask import render_template, request as http_request, g, redirect, url_for +from atst.utils.flash import formatted_flash as flash + from . import portfolios_bp from atst.domain.reports import Reports from atst.domain.portfolios import Portfolios +from atst.domain.portfolio_roles import PortfolioRoles from atst.domain.audit_log import AuditLog from atst.domain.common import Paginator from atst.forms.portfolio import PortfolioForm @@ -34,6 +37,7 @@ def permission_str(member, edit_perm_set, view_perm_set): def serialize_member_form_data(member): return { "member": member.user.full_name, + "user_id": member.user_id, "perms_app_mgmt": permission_str( member, PermissionSets.EDIT_PORTFOLIO_APPLICATION_MANAGEMENT, @@ -86,6 +90,33 @@ def portfolio_admin(portfolio_id): return render_admin_page(portfolio) +@portfolios_bp.route("/portfolios//admin", methods=["POST"]) +@user_can(Permissions.EDIT_PORTFOLIO_USERS, message="view portfolio admin page") +def edit_portfolio_members(portfolio_id): + portfolio = Portfolios.get_for_update(portfolio_id) + member_perms_form = member_forms.MembersPermissionsForm(http_request.form) + + if member_perms_form.validate(): + for subform in member_perms_form.members_permissions: + new_perm_set = subform.data["permission_sets"] + user_id = subform.user_id.data + portfolio_role = PortfolioRoles.get(portfolio.id, user_id) + PortfolioRoles.update(portfolio_role, new_perm_set) + + flash("update_portfolio_members", portfolio=portfolio) + + return redirect( + url_for( + "portfolios.portfolio_admin", + portfolio_id=portfolio.id, + fragment="portfolio-members", + _anchor="portfolio-members", + ) + ) + else: + return render_admin_page(portfolio) + + @portfolios_bp.route("/portfolios//edit", methods=["POST"]) @user_can(Permissions.EDIT_PORTFOLIO_NAME, message="edit portfolio") def edit_portfolio(portfolio_id): diff --git a/atst/utils/flash.py b/atst/utils/flash.py index a6f6f5ba..89f81132 100644 --- a/atst/utils/flash.py +++ b/atst/utils/flash.py @@ -21,6 +21,13 @@ MESSAGES = { """, "category": "success", }, + "update_portfolio_members": { + "title_template": "Success!", + "message_template": """ +

You have successfully updated access permissions for members of {{ portfolio.name }}.

+ """, + "category": "success", + }, "new_portfolio_member": { "title_template": "Success!", "message_template": """ diff --git a/templates/fragments/admin/members_edit.html b/templates/fragments/admin/members_edit.html index c64dafcb..0d873622 100644 --- a/templates/fragments/admin/members_edit.html +++ b/templates/fragments/admin/members_edit.html @@ -16,5 +16,6 @@ + {{ subform.user_id() }} {% endfor %} diff --git a/templates/fragments/admin/portfolio_members.html b/templates/fragments/admin/portfolio_members.html index 63e44680..08e856e0 100644 --- a/templates/fragments/admin/portfolio_members.html +++ b/templates/fragments/admin/portfolio_members.html @@ -6,18 +6,20 @@ {% if g.matchesPath("portfolio-members") %} {% include "fragments/flash.html" %} {% endif %} -
-
-
-
{{ "portfolios.admin.portfolio_members_title" | translate }}
-
- {{ "portfolios.admin.portfolio_members_subheading" | translate }} -
+ + {{ member_perms_form.csrf_token }} + +
+
+
{{ "portfolios.admin.portfolio_members_title" | translate }}
+
+ {{ "portfolios.admin.portfolio_members_subheading" | translate }}
- - {{ Icon('info') }} - {{ "portfolios.admin.settings_info" | translate }} - +
+ + {{ Icon('info') }} + {{ "portfolios.admin.settings_info" | translate }} +
{% if not portfolio.members %} diff --git a/tests/routes/portfolios/test_admin.py b/tests/routes/portfolios/test_admin.py index 7f141fe8..522dcb0c 100644 --- a/tests/routes/portfolios/test_admin.py +++ b/tests/routes/portfolios/test_admin.py @@ -26,3 +26,107 @@ def test_member_table_access(client, user_session): user_session(rando) view_resp = client.get(url) assert "