Applications users were invited to were not showing in the portfolios
sidebar
This commit is contained in:
parent
42900a20a6
commit
6487fe91ba
@ -2,6 +2,11 @@ from atst.database import db
|
|||||||
from atst.domain.common import Query
|
from atst.domain.common import Query
|
||||||
from atst.models.portfolio import Portfolio
|
from atst.models.portfolio import Portfolio
|
||||||
from atst.models.portfolio_role import PortfolioRole, Status as PortfolioRoleStatus
|
from atst.models.portfolio_role import PortfolioRole, Status as PortfolioRoleStatus
|
||||||
|
from atst.models.application_role import (
|
||||||
|
ApplicationRole,
|
||||||
|
Status as ApplicationRoleStatus,
|
||||||
|
)
|
||||||
|
from atst.models.application import Application
|
||||||
|
|
||||||
|
|
||||||
class PortfoliosQuery(Query):
|
class PortfoliosQuery(Query):
|
||||||
@ -9,7 +14,24 @@ class PortfoliosQuery(Query):
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_for_user(cls, user):
|
def get_for_user(cls, user):
|
||||||
return (
|
granted_applications = (
|
||||||
|
db.session.query(Application)
|
||||||
|
.join(ApplicationRole)
|
||||||
|
.filter(ApplicationRole.application_id == Application.id)
|
||||||
|
.filter(ApplicationRole.user_id == user.id)
|
||||||
|
.filter(ApplicationRole.status == ApplicationRoleStatus.ACTIVE)
|
||||||
|
.subquery()
|
||||||
|
)
|
||||||
|
|
||||||
|
application_portfolios = (
|
||||||
|
db.session.query(Portfolio)
|
||||||
|
.join(Application)
|
||||||
|
.filter(Portfolio.id == Application.portfolio_id)
|
||||||
|
.filter(Application.id == granted_applications.c.id)
|
||||||
|
.all()
|
||||||
|
)
|
||||||
|
|
||||||
|
portfolios = (
|
||||||
db.session.query(Portfolio)
|
db.session.query(Portfolio)
|
||||||
.join(PortfolioRole)
|
.join(PortfolioRole)
|
||||||
.filter(PortfolioRole.user == user)
|
.filter(PortfolioRole.user == user)
|
||||||
@ -17,6 +39,18 @@ class PortfoliosQuery(Query):
|
|||||||
.all()
|
.all()
|
||||||
)
|
)
|
||||||
|
|
||||||
|
portfolio_ids = []
|
||||||
|
|
||||||
|
[portfolio_ids.append(p.id) for p in portfolios]
|
||||||
|
[portfolio_ids.append(p.id) for p in application_portfolios]
|
||||||
|
|
||||||
|
return (
|
||||||
|
db.session.query(Portfolio)
|
||||||
|
.filter(Portfolio.id.in_(portfolio_ids))
|
||||||
|
.order_by(Portfolio.name.desc())
|
||||||
|
.all()
|
||||||
|
)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def create_portfolio_role(cls, user, portfolio, **kwargs):
|
def create_portfolio_role(cls, user, portfolio, **kwargs):
|
||||||
return PortfolioRole(user=user, portfolio=portfolio, **kwargs)
|
return PortfolioRole(user=user, portfolio=portfolio, **kwargs)
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
from datetime import date, timedelta
|
from datetime import date, timedelta
|
||||||
|
|
||||||
from flask import render_template, request as http_request, g, redirect, url_for
|
from flask import render_template, request as http_request, g
|
||||||
|
|
||||||
from . import portfolios_bp
|
from . import portfolios_bp
|
||||||
from atst.domain.reports import Reports
|
from atst.domain.reports import Reports
|
||||||
@ -19,14 +19,6 @@ def portfolios():
|
|||||||
return render_template("portfolios/blank_slate.html")
|
return render_template("portfolios/blank_slate.html")
|
||||||
|
|
||||||
|
|
||||||
@portfolios_bp.route("/portfolios/<portfolio_id>")
|
|
||||||
@user_can(Permissions.VIEW_PORTFOLIO, message="view portfolio")
|
|
||||||
def show_portfolio(portfolio_id):
|
|
||||||
return redirect(
|
|
||||||
url_for("applications.portfolio_applications", portfolio_id=portfolio_id)
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
@portfolios_bp.route("/portfolios/<portfolio_id>/reports")
|
@portfolios_bp.route("/portfolios/<portfolio_id>/reports")
|
||||||
@user_can(Permissions.VIEW_PORTFOLIO_REPORTS, message="view portfolio reports")
|
@user_can(Permissions.VIEW_PORTFOLIO_REPORTS, message="view portfolio reports")
|
||||||
def reports(portfolio_id):
|
def reports(portfolio_id):
|
||||||
|
@ -30,7 +30,7 @@ def accept_invitation(portfolio_token):
|
|||||||
)
|
)
|
||||||
|
|
||||||
return redirect(
|
return redirect(
|
||||||
url_for("portfolios.show_portfolio", portfolio_id=invite.portfolio.id)
|
url_for("applications.portfolio_applications", portfolio_id=invite.portfolio.id)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -145,7 +145,7 @@ MESSAGES = {
|
|||||||
"actions": """
|
"actions": """
|
||||||
{% from "components/icon.html" import Icon %}
|
{% from "components/icon.html" import Icon %}
|
||||||
<div class='alert__actions'>
|
<div class='alert__actions'>
|
||||||
<a href='{{ url_for("portfolios.show_portfolio", portfolio_id=portfolio.id) }}' class='icon-link'>
|
<a href='{{ url_for("applications.portfolio_applications", portfolio_id=portfolio.id) }}' class='icon-link'>
|
||||||
{{ Icon('shield') }}
|
{{ Icon('shield') }}
|
||||||
<span>{{ "flash.portfolio_home" | translate }}</span>
|
<span>{{ "flash.portfolio_home" | translate }}</span>
|
||||||
</a>
|
</a>
|
||||||
|
@ -21,7 +21,7 @@
|
|||||||
{% if portfolios %}
|
{% if portfolios %}
|
||||||
{% for other_portfolio in portfolios|sort(attribute='name') %}
|
{% for other_portfolio in portfolios|sort(attribute='name') %}
|
||||||
{{ SidenavItem(other_portfolio.name,
|
{{ SidenavItem(other_portfolio.name,
|
||||||
href=url_for("portfolios.show_portfolio", portfolio_id=other_portfolio.id),
|
href=url_for("applications.portfolio_applications", portfolio_id=other_portfolio.id),
|
||||||
active=(other_portfolio.id | string) == request.view_args.get('portfolio_id')
|
active=(other_portfolio.id | string) == request.view_args.get('portfolio_id')
|
||||||
) }}
|
) }}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
@ -34,7 +34,7 @@ def test_existing_member_accepts_valid_invite(client, user_session):
|
|||||||
# user is redirected to the portfolio view
|
# user is redirected to the portfolio view
|
||||||
assert response.status_code == 302
|
assert response.status_code == 302
|
||||||
assert (
|
assert (
|
||||||
url_for("portfolios.show_portfolio", portfolio_id=invite.portfolio.id)
|
url_for("applications.portfolio_applications", portfolio_id=invite.portfolio.id)
|
||||||
in response.headers["Location"]
|
in response.headers["Location"]
|
||||||
)
|
)
|
||||||
# the one-time use invite is no longer usable
|
# the one-time use invite is no longer usable
|
||||||
@ -77,7 +77,7 @@ def test_new_member_accepts_valid_invite(monkeypatch, client, user_session):
|
|||||||
# user is redirected to the portfolio view
|
# user is redirected to the portfolio view
|
||||||
assert response.status_code == 302
|
assert response.status_code == 302
|
||||||
assert (
|
assert (
|
||||||
url_for("portfolios.show_portfolio", portfolio_id=portfolio.id)
|
url_for("applications.portfolio_applications", portfolio_id=portfolio.id)
|
||||||
in response.headers["Location"]
|
in response.headers["Location"]
|
||||||
)
|
)
|
||||||
# the user has access to the portfolio
|
# the user has access to the portfolio
|
||||||
|
@ -466,19 +466,6 @@ def test_portfolios_revoke_invitation_access(post_url_assert_status):
|
|||||||
post_url_assert_status(user, url, status)
|
post_url_assert_status(user, url, status)
|
||||||
|
|
||||||
|
|
||||||
# portfolios.show_portfolio
|
|
||||||
def test_portfolios_show_portfolio_access(get_url_assert_status):
|
|
||||||
ccpo = user_with(PermissionSets.VIEW_PORTFOLIO)
|
|
||||||
owner = user_with()
|
|
||||||
rando = user_with()
|
|
||||||
portfolio = PortfolioFactory.create(owner=owner)
|
|
||||||
|
|
||||||
url = url_for("portfolios.show_portfolio", portfolio_id=portfolio.id)
|
|
||||||
get_url_assert_status(ccpo, url, 302)
|
|
||||||
get_url_assert_status(owner, url, 302)
|
|
||||||
get_url_assert_status(rando, url, 404)
|
|
||||||
|
|
||||||
|
|
||||||
# task_orders.so_review
|
# task_orders.so_review
|
||||||
def test_task_orders_so_review_access(get_url_assert_status):
|
def test_task_orders_so_review_access(get_url_assert_status):
|
||||||
ccpo = UserFactory.create_ccpo()
|
ccpo = UserFactory.create_ccpo()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user