A `before_request` hook queries the database for portfolios, requests, and task orders based on the route arguments. The resources are added as attributes on `g`. The portfolio context processor and the access decorator now rely on those resources being available on `g`. WIP: find major resources in before_request hook, apply to g WIP: use g.portfolio for portfolio context processor WIP: the access decorator should rely on the resources being available on g
95 lines
2.9 KiB
Python
95 lines
2.9 KiB
Python
from operator import attrgetter
|
|
|
|
from flask import g
|
|
from sqlalchemy.orm.exc import NoResultFound
|
|
|
|
from atst.database import db
|
|
from atst.domain.authz import Authorization
|
|
from atst.models import Application, Environment, Portfolio, TaskOrder
|
|
from atst.models.permissions import Permissions
|
|
from atst.domain.portfolios.scopes import ScopedPortfolio
|
|
|
|
|
|
def get_resources_from_context(view_args):
|
|
query = None
|
|
|
|
if "portfolio_id" in view_args:
|
|
query = db.session.query(Portfolio).filter(
|
|
Portfolio.id == view_args["portfolio_id"]
|
|
)
|
|
|
|
elif "application_id" in view_args:
|
|
query = (
|
|
db.session.query(Portfolio, Application)
|
|
.join(Application, Application.portfolio_id == Portfolio.id)
|
|
.filter(Application.id == view_args["application_id"])
|
|
)
|
|
|
|
elif "environment_id" in view_args:
|
|
query = (
|
|
db.session.query(Portfolio, Application)
|
|
.join(Application, Application.portfolio_id == Portfolio.id)
|
|
.join(Environment, Environment.application_id == Application.id)
|
|
.filter(Environment.id == view_args["environment_id"])
|
|
)
|
|
|
|
elif "task_order_id" in view_args:
|
|
query = (
|
|
db.session.query(Portfolio, TaskOrder)
|
|
.join(TaskOrder, TaskOrder.portfolio_id == Portfolio.id)
|
|
.filter(TaskOrder.id == view_args["task_order_id"])
|
|
)
|
|
|
|
if query:
|
|
try:
|
|
return query.only_return_tuples(True).one()
|
|
except NoResultFound:
|
|
raise NotFoundError("portfolio")
|
|
|
|
|
|
def assign_resources(view_args):
|
|
g.portfolio = None
|
|
g.application = None
|
|
g.task_order = None
|
|
|
|
resources = get_resources_from_context(view_args)
|
|
if resources:
|
|
for resource in resources:
|
|
if isinstance(resource, Portfolio):
|
|
g.portfolio = ScopedPortfolio(g.current_user, resource)
|
|
elif isinstance(resource, Application):
|
|
g.application = resource
|
|
elif isinstance(resource, TaskOrder):
|
|
g.task_order = resource
|
|
|
|
|
|
def portfolio():
|
|
def user_can(permission):
|
|
if g.portfolio:
|
|
return Authorization.has_portfolio_permission(
|
|
g.current_user, g.portfolio, permission
|
|
)
|
|
return False
|
|
|
|
if not g.portfolio is None:
|
|
active_task_orders = [
|
|
task_order for task_order in g.portfolio.task_orders if task_order.is_active
|
|
]
|
|
funding_end_date = (
|
|
sorted(active_task_orders, key=attrgetter("end_date"))[-1].end_date
|
|
if active_task_orders
|
|
else None
|
|
)
|
|
funded = len(active_task_orders) > 1
|
|
else:
|
|
funding_end_date = None
|
|
funded = None
|
|
|
|
return {
|
|
"portfolio": g.portfolio,
|
|
"permissions": Permissions,
|
|
"user_can": user_can,
|
|
"funding_end_date": funding_end_date,
|
|
"funded": funded,
|
|
}
|