def test_disable_portfolio_role(): portfolio_role = PortfolioRoleFactory.create( status=PortfolioRoleStatus.ACTIVE) assert portfolio_role.status == PortfolioRoleStatus.ACTIVE PortfolioRoles.disable(portfolio_role=portfolio_role) assert portfolio_role.status == PortfolioRoleStatus.DISABLED
def remove_member(portfolio_id, portfolio_role_id): portfolio_role = PortfolioRoles.get_by_id(portfolio_role_id) if g.current_user.id == portfolio_role.user_id: raise UnauthorizedError(g.current_user, "you cant remove yourself from the portfolio") portfolio = Portfolios.get(user=g.current_user, portfolio_id=portfolio_id) if portfolio_role.user_id == portfolio.owner.id: raise UnauthorizedError( g.current_user, "you can't delete the portfolios PPoC from the portfolio") if (portfolio_role.latest_invitation and portfolio_role.status == PortfolioRoleStatus.PENDING): PortfolioInvitations.revoke(portfolio_role.latest_invitation.token) else: PortfolioRoles.disable(portfolio_role=portfolio_role) flash("portfolio_member_removed", member_name=portfolio_role.full_name) return redirect( url_for( "portfolios.admin", portfolio_id=portfolio_id, _anchor="portfolio-members", fragment="portfolio-members", ))
def test_remove_portfolio_member_ppoc(client, user_session): portfolio = PortfolioFactory.create() user = UserFactory.create() PortfolioRoleFactory.create( portfolio=portfolio, user=user, permission_sets=[ PermissionSets.get(PermissionSets.EDIT_PORTFOLIO_ADMIN) ], ) ppoc_port_role = PortfolioRoles.get(portfolio_id=portfolio.id, user_id=portfolio.owner.id) user_session(user) response = client.post( url_for( "portfolios.remove_member", portfolio_id=portfolio.id, portfolio_role_id=ppoc_port_role.id, ), follow_redirects=False, ) assert response.status_code == 404 assert (PortfolioRoles.get( portfolio_id=portfolio.id, user_id=portfolio.owner.id).status == PortfolioRoleStatus.ACTIVE)
def remove_member(portfolio_id, portfolio_role_id): portfolio_role = PortfolioRoles.get_by_id(portfolio_role_id) if g.current_user.id == portfolio_role.user_id: raise UnauthorizedError( g.current_user, "you cant remove yourself from the portfolio" ) portfolio = Portfolios.get(user=g.current_user, portfolio_id=portfolio_id) if portfolio_role.user_id == portfolio.owner.id: raise UnauthorizedError( g.current_user, "you can't delete the portfolios PPoC from the portfolio" ) # TODO: should this cascade and disable any application and environment # roles they might have? PortfolioRoles.disable(portfolio_role=portfolio_role) flash("portfolio_member_removed", member_name=portfolio_role.full_name) return redirect( url_for( "portfolios.admin", portfolio_id=portfolio_id, _anchor="portfolio-members", fragment="portfolio-members", ) )
def test_has_portfolio_role_history(session): owner = UserFactory.create() user = UserFactory.create() portfolio = PortfolioFactory.create(owner=owner) # in order to get the history, we don't want the PortfolioRoleFactory # to commit after create() # PortfolioRoleFactory._meta.sqlalchemy_session_persistence = "flush" portfolio_role = PortfolioRoleFactory.create( portfolio=portfolio, user=user, permission_sets=[] ) PortfolioRoles.update( portfolio_role, PortfolioRoles.DEFAULT_PORTFOLIO_PERMISSION_SETS ) changed_event = ( session.query(AuditEvent) .filter( AuditEvent.resource_id == portfolio_role.id, AuditEvent.action == "update" ) .one() ) old_state, new_state = changed_event.changed_state["permission_sets"] assert old_state == [] assert set(new_state) == PortfolioRoles.DEFAULT_PORTFOLIO_PERMISSION_SETS
def test_revoke_ppoc_permissions(): portfolio = PortfolioFactory.create() portfolio_role = PortfolioRoles.get(portfolio_id=portfolio.id, user_id=portfolio.owner.id) assert Permissions.EDIT_PORTFOLIO_POC in portfolio_role.permissions PortfolioRoles.revoke_ppoc_permissions(portfolio_role=portfolio_role) assert Permissions.EDIT_PORTFOLIO_POC not in portfolio_role.permissions
def add_members_to_portfolio(portfolio): for user_data in PORTFOLIO_USERS: invite = Portfolios.invite(portfolio, portfolio.owner, {"user_data": user_data}) profile = { k: user_data[k] for k in user_data if k not in ["dod_id", "permission_sets"] } user = Users.get_or_create_by_dod_id(user_data["dod_id"], **profile) PortfolioRoles.enable(invite.role, user) db.session.commit()
def delete(cls, portfolio): if len(portfolio.applications) != 0: raise PortfolioDeletionApplicationsExistError() for portfolio_role in portfolio.roles: PortfolioRoles.disable(portfolio_role=portfolio_role, commit=False) portfolio.deleted = True db.session.add(portfolio) db.session.commit() return portfolio
def test_make_ppoc(): portfolio = PortfolioFactory.create() original_owner = portfolio.owner new_owner = UserFactory.create() new_owner_role = PortfolioRoles.add(user=new_owner, portfolio_id=portfolio.id) PortfolioRoles.make_ppoc(portfolio_role=new_owner_role) assert portfolio.owner is new_owner assert Permissions.EDIT_PORTFOLIO_POC in new_owner_role.permissions assert (Permissions.EDIT_PORTFOLIO_POC not in PortfolioRoles.get(portfolio_id=portfolio.id, user_id=original_owner.id).permissions)
def test_user_can_access(): ccpo = UserFactory.create_ccpo() edit_admin = UserFactory.create() view_admin = UserFactory.create() portfolio = PortfolioFactory.create(owner=edit_admin) # factory gives view perms by default view_admin_pr = PortfolioRoleFactory.create(user=view_admin, portfolio=portfolio) # check a site-wide permission assert user_can_access(ccpo, Permissions.VIEW_AUDIT_LOG) with pytest.raises(UnauthorizedError): user_can_access(edit_admin, Permissions.VIEW_AUDIT_LOG) with pytest.raises(UnauthorizedError): user_can_access(view_admin, Permissions.VIEW_AUDIT_LOG) # check a portfolio view permission assert user_can_access(ccpo, Permissions.VIEW_PORTFOLIO, portfolio=portfolio) assert user_can_access(edit_admin, Permissions.VIEW_PORTFOLIO, portfolio=portfolio) assert user_can_access(view_admin, Permissions.VIEW_PORTFOLIO, portfolio=portfolio) # check a portfolio edit permission assert user_can_access(ccpo, Permissions.EDIT_PORTFOLIO_NAME, portfolio=portfolio) assert user_can_access(edit_admin, Permissions.EDIT_PORTFOLIO_NAME, portfolio=portfolio) with pytest.raises(UnauthorizedError): user_can_access(view_admin, Permissions.EDIT_PORTFOLIO_NAME, portfolio=portfolio) # check when portfolio_role is disabled PortfolioRoles.disable(portfolio_role=view_admin_pr) with pytest.raises(UnauthorizedError): user_can_access(view_admin, Permissions.EDIT_PORTFOLIO_NAME, portfolio=portfolio)
def test_cannot_update_portfolio_ppoc_perms(client, user_session): portfolio = PortfolioFactory.create() ppoc = portfolio.owner ppoc_pf_role = PortfolioRoles.get(portfolio_id=portfolio.id, user_id=ppoc.id) user = UserFactory.create() PortfolioRoleFactory.create(portfolio=portfolio, user=user) user_session(user) assert ppoc_pf_role.has_permission_set(PermissionSets.PORTFOLIO_POC) member_perms_data = { "members_permissions-0-member_id": ppoc_pf_role.id, "members_permissions-0-perms_app_mgmt": "view_portfolio_application_management", "members_permissions-0-perms_funding": "view_portfolio_funding", "members_permissions-0-perms_reporting": "view_portfolio_reports", "members_permissions-0-perms_portfolio_mgmt": "view_portfolio_admin", } response = client.post( url_for("portfolios.edit_members", portfolio_id=portfolio.id), data=member_perms_data, follow_redirects=True, ) assert response.status_code == 404 assert ppoc_pf_role.has_permission_set(PermissionSets.PORTFOLIO_POC)
def test_remove_portfolio_member(client, user_session): portfolio = PortfolioFactory.create() user = UserFactory.create() member = PortfolioRoleFactory.create(portfolio=portfolio, user=user) user_session(portfolio.owner) response = client.post( url_for( "portfolios.remove_member", portfolio_id=portfolio.id, portfolio_role_id=member.id, ), follow_redirects=False, ) assert response.status_code == 302 assert response.headers["Location"] == url_for( "portfolios.admin", portfolio_id=portfolio.id, _anchor="portfolio-members", fragment="portfolio-members", _external=True, ) assert (PortfolioRoles.get( portfolio_id=portfolio.id, user_id=user.id).status == PortfolioRoleStatus.DISABLED)
def test_event_details(): owner = UserFactory.create() user = UserFactory.create() portfolio = PortfolioFactory.create(owner=owner) portfolio_role = PortfolioRoles.add(user, portfolio.id) assert portfolio_role.event_details["updated_user_name"] == user.displayname assert portfolio_role.event_details["updated_user_id"] == str(user.id)
def update_ppoc(portfolio_id): role_id = http_request.form.get("role_id") portfolio = Portfolios.get(g.current_user, portfolio_id) new_ppoc_role = PortfolioRoles.get_by_id(role_id) PortfolioRoles.make_ppoc(portfolio_role=new_ppoc_role) flash("primary_point_of_contact_changed", ppoc_name=new_ppoc_role.full_name) return redirect( url_for( "portfolios.admin", portfolio_id=portfolio.id, fragment="primary-point-of-contact", _anchor="primary-point-of-contact", ))
def test_remove_portfolio_member_self(client, user_session): portfolio = PortfolioFactory.create() portfolio_role = PortfolioRoles.get(portfolio_id=portfolio.id, user_id=portfolio.owner.id) user_session(portfolio.owner) response = client.post( url_for( "portfolios.remove_member", portfolio_id=portfolio.id, portfolio_role_id=portfolio_role.id, ), follow_redirects=False, ) assert response.status_code == 404 assert (PortfolioRoles.get( portfolio_id=portfolio.id, user_id=portfolio.owner.id).status == PortfolioRoleStatus.ACTIVE)
def test_has_no_portfolio_role_history(session): owner = UserFactory.create() user = UserFactory.create() portfolio = PortfolioFactory.create(owner=owner) portfolio_role = PortfolioRoles.add(user, portfolio.id) create_event = (session.query(AuditEvent).filter( AuditEvent.resource_id == portfolio_role.id, AuditEvent.action == "create").one()) assert not create_event.changed_state
def invite(cls, portfolio, inviter, member_data): permission_sets = PortfolioRoles._permission_sets_for_names( member_data.get("permission_sets", [])) role = PortfolioRole(portfolio=portfolio, permission_sets=permission_sets) invitation = PortfolioInvitations.create( inviter=inviter, role=role, member_data=member_data["user_data"]) PortfoliosQuery.add_and_commit(role) return invitation
def edit_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: member_id = subform.member_id.data member = PortfolioRoles.get_by_id(member_id) if member is not portfolio.owner_role: new_perm_set = subform.data["permission_sets"] PortfolioRoles.update(member, new_perm_set) flash("update_portfolio_members", portfolio=portfolio) return redirect( url_for( "portfolios.admin", portfolio_id=portfolio_id, fragment="portfolio-members", _anchor="portfolio-members", ) ) else: return render_admin_page(portfolio)
def test_add_portfolio_role_with_permission_sets(): portfolio = PortfolioFactory.create() new_user = UserFactory.create() permission_sets = [PermissionSets.EDIT_PORTFOLIO_APPLICATION_MANAGEMENT] port_role = PortfolioRoles.add(new_user, portfolio.id, permission_sets=permission_sets) assert len(port_role.permission_sets) == 6 expected_names = [ PermissionSets.EDIT_PORTFOLIO_APPLICATION_MANAGEMENT, PermissionSets.VIEW_PORTFOLIO_APPLICATION_MANAGEMENT, PermissionSets.VIEW_PORTFOLIO_FUNDING, PermissionSets.VIEW_PORTFOLIO_REPORTS, PermissionSets.VIEW_PORTFOLIO_ADMIN, PermissionSets.VIEW_PORTFOLIO, ] actual_names = [prms.name for prms in port_role.permission_sets] assert expected_names == expected_names
def update_member(cls, member, permission_sets): return PortfolioRoles.update(member, permission_sets)
def add_member(cls, portfolio, member, permission_sets=None): portfolio_role = PortfolioRoles.add(member, portfolio.id, permission_sets) return portfolio_role