Standardize token
argument in routes.
- `token` becomes `portfolio_token` in routes. - Find relevant portfolio from token in `before_request` hook, like other routes.
This commit is contained in:
parent
42b912d4cb
commit
3c1f4ac6df
@ -3,11 +3,6 @@ from functools import wraps
|
|||||||
from flask import g, current_app as app, request
|
from flask import g, current_app as app, request
|
||||||
|
|
||||||
from . import user_can_access
|
from . import user_can_access
|
||||||
from atst.domain.portfolios import Portfolios
|
|
||||||
from atst.domain.task_orders import TaskOrders
|
|
||||||
from atst.domain.applications import Applications
|
|
||||||
from atst.domain.environments import Environments
|
|
||||||
from atst.domain.invitations import PortfolioInvitations
|
|
||||||
from atst.domain.exceptions import UnauthorizedError
|
from atst.domain.exceptions import UnauthorizedError
|
||||||
|
|
||||||
|
|
||||||
@ -18,14 +13,6 @@ def check_access(permission, message, override, *args, **kwargs):
|
|||||||
"application": g.application,
|
"application": g.application,
|
||||||
}
|
}
|
||||||
|
|
||||||
# TODO: We should change the `token` arg in routes to be either
|
|
||||||
# `portfolio_token` or `application_token` and have
|
|
||||||
# atst.utils.context_processors.assign_resources take care of
|
|
||||||
# this.
|
|
||||||
if "token" in kwargs:
|
|
||||||
invite = PortfolioInvitations._get(kwargs["token"])
|
|
||||||
access_args["portfolio"] = invite.role.portfolio
|
|
||||||
|
|
||||||
if override is not None and override(g.current_user, **access_args, **kwargs):
|
if override is not None and override(g.current_user, **access_args, **kwargs):
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
@ -19,9 +19,9 @@ def send_invite_email(owner_name, token, new_member_email):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@portfolios_bp.route("/portfolios/invitations/<token>", methods=["GET"])
|
@portfolios_bp.route("/portfolios/invitations/<portfolio_token>", methods=["GET"])
|
||||||
def accept_invitation(token):
|
def accept_invitation(portfolio_token):
|
||||||
invite = PortfolioInvitations.accept(g.current_user, token)
|
invite = PortfolioInvitations.accept(g.current_user, portfolio_token)
|
||||||
|
|
||||||
for task_order in invite.portfolio.task_orders:
|
for task_order in invite.portfolio.task_orders:
|
||||||
if g.current_user in task_order.officers:
|
if g.current_user in task_order.officers:
|
||||||
@ -35,11 +35,11 @@ def accept_invitation(token):
|
|||||||
|
|
||||||
|
|
||||||
@portfolios_bp.route(
|
@portfolios_bp.route(
|
||||||
"/portfolios/<portfolio_id>/invitations/<token>/revoke", methods=["POST"]
|
"/portfolios/<portfolio_id>/invitations/<portfolio_token>/revoke", methods=["POST"]
|
||||||
)
|
)
|
||||||
@user_can(Permissions.EDIT_PORTFOLIO_USERS, message="revoke invitation")
|
@user_can(Permissions.EDIT_PORTFOLIO_USERS, message="revoke invitation")
|
||||||
def revoke_invitation(portfolio_id, token):
|
def revoke_invitation(portfolio_id, portfolio_token):
|
||||||
PortfolioInvitations.revoke(token)
|
PortfolioInvitations.revoke(portfolio_token)
|
||||||
|
|
||||||
return redirect(
|
return redirect(
|
||||||
url_for(
|
url_for(
|
||||||
@ -52,11 +52,11 @@ def revoke_invitation(portfolio_id, token):
|
|||||||
|
|
||||||
|
|
||||||
@portfolios_bp.route(
|
@portfolios_bp.route(
|
||||||
"/portfolios/<portfolio_id>/invitations/<token>/resend", methods=["POST"]
|
"/portfolios/<portfolio_id>/invitations/<portfolio_token>/resend", methods=["POST"]
|
||||||
)
|
)
|
||||||
@user_can(Permissions.EDIT_PORTFOLIO_USERS, message="resend invitation")
|
@user_can(Permissions.EDIT_PORTFOLIO_USERS, message="resend invitation")
|
||||||
def resend_invitation(portfolio_id, token):
|
def resend_invitation(portfolio_id, portfolio_token):
|
||||||
invite = PortfolioInvitations.resend(g.current_user, token)
|
invite = PortfolioInvitations.resend(g.current_user, portfolio_token)
|
||||||
send_invite_email(g.current_user.full_name, invite.token, invite.email)
|
send_invite_email(g.current_user.full_name, invite.token, invite.email)
|
||||||
flash("resend_portfolio_invitation", user_name=invite.user_name)
|
flash("resend_portfolio_invitation", user_name=invite.user_name)
|
||||||
return redirect(
|
return redirect(
|
||||||
|
@ -5,7 +5,14 @@ from sqlalchemy.orm.exc import NoResultFound
|
|||||||
|
|
||||||
from atst.database import db
|
from atst.database import db
|
||||||
from atst.domain.authz import Authorization
|
from atst.domain.authz import Authorization
|
||||||
from atst.models import Application, Environment, Portfolio, TaskOrder
|
from atst.models import (
|
||||||
|
Application,
|
||||||
|
Environment,
|
||||||
|
Portfolio,
|
||||||
|
PortfolioInvitation,
|
||||||
|
PortfolioRole,
|
||||||
|
TaskOrder,
|
||||||
|
)
|
||||||
from atst.models.permissions import Permissions
|
from atst.models.permissions import Permissions
|
||||||
from atst.domain.portfolios.scopes import ScopedPortfolio
|
from atst.domain.portfolios.scopes import ScopedPortfolio
|
||||||
|
|
||||||
@ -13,7 +20,18 @@ from atst.domain.portfolios.scopes import ScopedPortfolio
|
|||||||
def get_resources_from_context(view_args):
|
def get_resources_from_context(view_args):
|
||||||
query = None
|
query = None
|
||||||
|
|
||||||
if "portfolio_id" in view_args:
|
if "portfolio_token" in view_args:
|
||||||
|
query = (
|
||||||
|
db.session.query(Portfolio)
|
||||||
|
.join(PortfolioRole, PortfolioRole.portfolio_id == Portfolio.id)
|
||||||
|
.join(
|
||||||
|
PortfolioInvitation,
|
||||||
|
PortfolioInvitation.portfolio_role_id == PortfolioRole.id,
|
||||||
|
)
|
||||||
|
.filter(PortfolioInvitation.token == view_args["portfolio_token"])
|
||||||
|
)
|
||||||
|
|
||||||
|
elif "portfolio_id" in view_args:
|
||||||
query = db.session.query(Portfolio).filter(
|
query = db.session.query(Portfolio).filter(
|
||||||
Portfolio.id == view_args["portfolio_id"]
|
Portfolio.id == view_args["portfolio_id"]
|
||||||
)
|
)
|
||||||
|
@ -5,6 +5,6 @@
|
|||||||
Join this JEDI Cloud Portfolio
|
Join this JEDI Cloud Portfolio
|
||||||
{{ owner }} has invited you to join a JEDI Cloud Portfolio. Login now to view or use your JEDI Cloud resources.
|
{{ owner }} has invited you to join a JEDI Cloud Portfolio. Login now to view or use your JEDI Cloud resources.
|
||||||
|
|
||||||
{{ url_for("portfolios.accept_invitation", token=token, _external=True) }}
|
{{ url_for("portfolios.accept_invitation", portfolio_token=token, _external=True) }}
|
||||||
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
@ -27,7 +27,9 @@ def test_existing_member_accepts_valid_invite(client, user_session):
|
|||||||
assert len(Portfolios.for_user(user)) == 0
|
assert len(Portfolios.for_user(user)) == 0
|
||||||
|
|
||||||
user_session(user)
|
user_session(user)
|
||||||
response = client.get(url_for("portfolios.accept_invitation", token=invite.token))
|
response = client.get(
|
||||||
|
url_for("portfolios.accept_invitation", portfolio_token=invite.token)
|
||||||
|
)
|
||||||
|
|
||||||
# user is redirected to the portfolio view
|
# user is redirected to the portfolio view
|
||||||
assert response.status_code == 302
|
assert response.status_code == 302
|
||||||
@ -68,7 +70,9 @@ def test_new_member_accepts_valid_invite(monkeypatch, client, user_session):
|
|||||||
"atst.domain.auth.should_redirect_to_user_profile", lambda *args: False
|
"atst.domain.auth.should_redirect_to_user_profile", lambda *args: False
|
||||||
)
|
)
|
||||||
user_session(user)
|
user_session(user)
|
||||||
response = client.get(url_for("portfolios.accept_invitation", token=token))
|
response = client.get(
|
||||||
|
url_for("portfolios.accept_invitation", portfolio_token=token)
|
||||||
|
)
|
||||||
|
|
||||||
# user is redirected to the portfolio view
|
# user is redirected to the portfolio view
|
||||||
assert response.status_code == 302
|
assert response.status_code == 302
|
||||||
@ -90,7 +94,9 @@ def test_member_accepts_invalid_invite(client, user_session):
|
|||||||
user_id=user.id, role=ws_role, status=InvitationStatus.REJECTED_WRONG_USER
|
user_id=user.id, role=ws_role, status=InvitationStatus.REJECTED_WRONG_USER
|
||||||
)
|
)
|
||||||
user_session(user)
|
user_session(user)
|
||||||
response = client.get(url_for("portfolios.accept_invitation", token=invite.token))
|
response = client.get(
|
||||||
|
url_for("portfolios.accept_invitation", portfolio_token=invite.token)
|
||||||
|
)
|
||||||
|
|
||||||
assert response.status_code == 404
|
assert response.status_code == 404
|
||||||
|
|
||||||
@ -121,7 +127,9 @@ def test_user_accepts_invite_with_wrong_dod_id(client, user_session):
|
|||||||
)
|
)
|
||||||
invite = PortfolioInvitationFactory.create(user_id=user.id, role=ws_role)
|
invite = PortfolioInvitationFactory.create(user_id=user.id, role=ws_role)
|
||||||
user_session(different_user)
|
user_session(different_user)
|
||||||
response = client.get(url_for("portfolios.accept_invitation", token=invite.token))
|
response = client.get(
|
||||||
|
url_for("portfolios.accept_invitation", portfolio_token=invite.token)
|
||||||
|
)
|
||||||
|
|
||||||
assert response.status_code == 404
|
assert response.status_code == 404
|
||||||
|
|
||||||
@ -139,7 +147,9 @@ def test_user_accepts_expired_invite(client, user_session):
|
|||||||
expiration_time=datetime.datetime.now() - datetime.timedelta(seconds=1),
|
expiration_time=datetime.datetime.now() - datetime.timedelta(seconds=1),
|
||||||
)
|
)
|
||||||
user_session(user)
|
user_session(user)
|
||||||
response = client.get(url_for("portfolios.accept_invitation", token=invite.token))
|
response = client.get(
|
||||||
|
url_for("portfolios.accept_invitation", portfolio_token=invite.token)
|
||||||
|
)
|
||||||
|
|
||||||
assert response.status_code == 404
|
assert response.status_code == 404
|
||||||
|
|
||||||
@ -161,7 +171,7 @@ def test_revoke_invitation(client, user_session):
|
|||||||
url_for(
|
url_for(
|
||||||
"portfolios.revoke_invitation",
|
"portfolios.revoke_invitation",
|
||||||
portfolio_id=portfolio.id,
|
portfolio_id=portfolio.id,
|
||||||
token=invite.token,
|
portfolio_token=invite.token,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -187,7 +197,7 @@ def test_user_can_only_revoke_invites_in_their_portfolio(client, user_session):
|
|||||||
url_for(
|
url_for(
|
||||||
"portfolios.revoke_invitation",
|
"portfolios.revoke_invitation",
|
||||||
portfolio_id=portfolio.id,
|
portfolio_id=portfolio.id,
|
||||||
token=invite.token,
|
portfolio_token=invite.token,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -213,7 +223,7 @@ def test_user_can_only_resend_invites_in_their_portfolio(client, user_session, q
|
|||||||
url_for(
|
url_for(
|
||||||
"portfolios.resend_invitation",
|
"portfolios.resend_invitation",
|
||||||
portfolio_id=portfolio.id,
|
portfolio_id=portfolio.id,
|
||||||
token=invite.token,
|
portfolio_token=invite.token,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -235,7 +245,7 @@ def test_resend_invitation_sends_email(client, user_session, queue):
|
|||||||
url_for(
|
url_for(
|
||||||
"portfolios.resend_invitation",
|
"portfolios.resend_invitation",
|
||||||
portfolio_id=portfolio.id,
|
portfolio_id=portfolio.id,
|
||||||
token=invite.token,
|
portfolio_token=invite.token,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -261,7 +271,7 @@ def test_existing_member_invite_resent_to_email_submitted_in_form(
|
|||||||
url_for(
|
url_for(
|
||||||
"portfolios.resend_invitation",
|
"portfolios.resend_invitation",
|
||||||
portfolio_id=portfolio.id,
|
portfolio_id=portfolio.id,
|
||||||
token=invite.token,
|
portfolio_token=invite.token,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -295,7 +305,9 @@ def test_contracting_officer_accepts_invite(monkeypatch, client, user_session):
|
|||||||
"atst.domain.auth.should_redirect_to_user_profile", lambda *args: False
|
"atst.domain.auth.should_redirect_to_user_profile", lambda *args: False
|
||||||
)
|
)
|
||||||
user_session(user)
|
user_session(user)
|
||||||
response = client.get(url_for("portfolios.accept_invitation", token=token))
|
response = client.get(
|
||||||
|
url_for("portfolios.accept_invitation", portfolio_token=token)
|
||||||
|
)
|
||||||
|
|
||||||
# user is redirected to the task order review page
|
# user is redirected to the task order review page
|
||||||
assert response.status_code == 302
|
assert response.status_code == 302
|
||||||
@ -329,7 +341,9 @@ def test_cor_accepts_invite(monkeypatch, client, user_session):
|
|||||||
"atst.domain.auth.should_redirect_to_user_profile", lambda *args: False
|
"atst.domain.auth.should_redirect_to_user_profile", lambda *args: False
|
||||||
)
|
)
|
||||||
user_session(user)
|
user_session(user)
|
||||||
response = client.get(url_for("portfolios.accept_invitation", token=token))
|
response = client.get(
|
||||||
|
url_for("portfolios.accept_invitation", portfolio_token=token)
|
||||||
|
)
|
||||||
|
|
||||||
# user is redirected to the task order review page
|
# user is redirected to the task order review page
|
||||||
assert response.status_code == 302
|
assert response.status_code == 302
|
||||||
@ -363,7 +377,9 @@ def test_so_accepts_invite(monkeypatch, client, user_session):
|
|||||||
"atst.domain.auth.should_redirect_to_user_profile", lambda *args: False
|
"atst.domain.auth.should_redirect_to_user_profile", lambda *args: False
|
||||||
)
|
)
|
||||||
user_session(user)
|
user_session(user)
|
||||||
response = client.get(url_for("portfolios.accept_invitation", token=token))
|
response = client.get(
|
||||||
|
url_for("portfolios.accept_invitation", portfolio_token=token)
|
||||||
|
)
|
||||||
|
|
||||||
# user is redirected to the task order review page
|
# user is redirected to the task order review page
|
||||||
assert response.status_code == 302
|
assert response.status_code == 302
|
||||||
|
@ -411,7 +411,9 @@ def test_portfolios_resend_invitation_access(post_url_assert_status):
|
|||||||
invite = PortfolioInvitationFactory.create(user=UserFactory.create(), role=prr)
|
invite = PortfolioInvitationFactory.create(user=UserFactory.create(), role=prr)
|
||||||
|
|
||||||
url = url_for(
|
url = url_for(
|
||||||
"portfolios.resend_invitation", portfolio_id=portfolio.id, token=invite.token
|
"portfolios.resend_invitation",
|
||||||
|
portfolio_id=portfolio.id,
|
||||||
|
portfolio_token=invite.token,
|
||||||
)
|
)
|
||||||
post_url_assert_status(ccpo, url, 302)
|
post_url_assert_status(ccpo, url, 302)
|
||||||
post_url_assert_status(owner, url, 302)
|
post_url_assert_status(owner, url, 302)
|
||||||
@ -459,7 +461,7 @@ def test_portfolios_revoke_invitation_access(post_url_assert_status):
|
|||||||
url = url_for(
|
url = url_for(
|
||||||
"portfolios.revoke_invitation",
|
"portfolios.revoke_invitation",
|
||||||
portfolio_id=portfolio.id,
|
portfolio_id=portfolio.id,
|
||||||
token=invite.token,
|
portfolio_token=invite.token,
|
||||||
)
|
)
|
||||||
post_url_assert_status(user, url, status)
|
post_url_assert_status(user, url, status)
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user