apply access decorator to routes

This commit is contained in:
dandds
2019-03-20 10:47:13 -04:00
parent 0ea21fbb9b
commit de7c69bde7
25 changed files with 198 additions and 59 deletions

View File

@@ -22,7 +22,7 @@ def developer():
return UserFactory.create()
@pytest.mark.auth
@pytest.mark.skip(reason="redo as a route access test")
def test_non_admin_cannot_view_audit_log(developer):
with pytest.raises(UnauthorizedError):
AuditLog.get_all_events(developer)
@@ -64,7 +64,7 @@ def test_ws_owner_can_view_ws_audit_log():
assert len(events) > 0
@pytest.mark.auth
@pytest.mark.skip(reason="redo as a route access test")
def test_other_users_cannot_view_portfolio_audit_log():
with pytest.raises(UnauthorizedError):
portfolio = PortfolioFactory.create()

View File

@@ -46,19 +46,18 @@ def test_portfolio_has_timestamps(portfolio):
assert portfolio.time_created == portfolio.time_updated
@pytest.mark.auth
@pytest.mark.skip(reason="redo as a route access test")
def test_portfolios_get_ensures_user_is_in_portfolio(portfolio, portfolio_owner):
outside_user = UserFactory.create()
with pytest.raises(UnauthorizedError):
Portfolios.get(outside_user, portfolio.id)
@pytest.mark.auth
def test_get_for_update_applications_allows_owner(portfolio, portfolio_owner):
Portfolios.get_for_update_applications(portfolio_owner, portfolio.id)
@pytest.mark.auth
@pytest.mark.skip(reason="redo as a route access test")
def test_get_for_update_applications_blocks_developer(portfolio):
developer = UserFactory.create()
PortfolioRoles.add(developer, portfolio.id)
@@ -97,7 +96,7 @@ def test_can_add_existing_user_to_portfolio(portfolio, portfolio_owner):
assert not new_member.user.provisional
@pytest.mark.auth
@pytest.mark.skip(reason="redo as a route access test")
def test_need_permission_to_create_portfolio_role(portfolio, portfolio_owner):
random_user = UserFactory.create()
@@ -131,7 +130,7 @@ def test_update_portfolio_role_role(portfolio, portfolio_owner):
assert updated_member.portfolio == portfolio
@pytest.mark.auth
@pytest.mark.skip(reason="redo as a route access test")
def test_need_permission_to_update_portfolio_role_role(portfolio, portfolio_owner):
random_user = UserFactory.create()
user_data = {
@@ -159,7 +158,7 @@ def test_ccpo_can_view_portfolio_members(portfolio, portfolio_owner):
assert Portfolios.get_with_members(ccpo, portfolio.id)
@pytest.mark.auth
@pytest.mark.skip(reason="redo as a route access test")
def test_random_user_cannot_view_portfolio_members(portfolio):
developer = UserFactory.create()
@@ -288,7 +287,7 @@ def test_for_user_returns_all_portfolios_for_ccpo(portfolio, portfolio_owner):
assert len(sams_portfolios) == 2
@pytest.mark.auth
@pytest.mark.skip(reason="redo as a route access test")
def test_get_for_update_information(portfolio, portfolio_owner):
owner_ws = Portfolios.get_for_update_information(portfolio_owner, portfolio.id)
assert portfolio == owner_ws

View File

@@ -95,7 +95,7 @@ def test_add_officer_who_is_already_portfolio_member():
assert member.user == owner
@pytest.mark.auth
@pytest.mark.skip(reason="redo as route access test")
def test_task_order_access():
creator = UserFactory.create()
member = UserFactory.create()

View File

@@ -175,7 +175,6 @@ def test_user_with_permission_can_update_application(client, user_session):
assert application.description == "A very cool application."
@pytest.mark.auth
def test_user_without_permission_cannot_update_application(client, user_session):
dev = UserFactory.create()
owner = UserFactory.create()

View File

@@ -95,7 +95,6 @@ def test_member_accepts_invalid_invite(client, user_session):
assert response.status_code == 404
@pytest.mark.auth
def test_user_who_has_not_accepted_portfolio_invite_cannot_view(client, user_session):
user = UserFactory.create()
portfolio = PortfolioFactory.create()

View File

@@ -60,7 +60,6 @@ def test_user_with_permission_has_add_member_link(client, user_session):
)
@pytest.mark.auth
def test_user_without_permission_has_no_add_member_link(client, user_session):
user = UserFactory.create()
portfolio = PortfolioFactory.create()
@@ -73,7 +72,6 @@ def test_user_without_permission_has_no_add_member_link(client, user_session):
)
@pytest.mark.auth
def test_permissions_for_view_member(client, user_session):
user = UserFactory.create()
portfolio = PortfolioFactory.create()

View File

@@ -371,27 +371,6 @@ def test_mo_redirected_to_build_page(client, user_session, portfolio):
assert response.status_code == 200
def test_cor_redirected_to_build_page(client, user_session, portfolio):
cor = UserFactory.create()
PortfolioRoleFactory.create(
portfolio=portfolio,
user=cor,
status=PortfolioStatus.ACTIVE,
permission_sets=[
PermissionSets.get(PermissionSets.VIEW_PORTFOLIO),
PermissionSets.get(PermissionSets.VIEW_PORTFOLIO_FUNDING),
],
)
task_order = TaskOrderFactory.create(
portfolio=portfolio, contracting_officer_representative=cor
)
user_session(cor)
response = client.get(
url_for("task_orders.new", screen=1, task_order_id=task_order.id)
)
assert response.status_code == 200
def test_submit_completed_ko_review_page_as_cor(
client, user_session, pdf_upload, portfolio, user
):
@@ -620,6 +599,7 @@ def test_resend_invite_when_officer_type_missing(
assert len(queue.get_queue()) == queue_length
@pytest.mark.skip(reason="KO should not be able to resend invites")
def test_resend_invite_when_ko(app, client, user_session, portfolio, user):
queue_length = len(queue.get_queue())

View File

@@ -63,7 +63,6 @@ class TestDownloadCSPEstimate:
)
assert response.status_code == 404
@pytest.mark.auth
def test_download_with_wrong_user(self, client, user_session):
other_user = UserFactory.create()
user_session(other_user)

View File

@@ -2,11 +2,17 @@ import pytest
from flask import url_for
from atst.domain.task_orders import TaskOrders
from atst.domain.permission_sets import PermissionSets
from atst.models.attachment import Attachment
from atst.routes.task_orders.new import ShowTaskOrderWorkflow, UpdateTaskOrderWorkflow
from atst.utils.localization import translate
from tests.factories import UserFactory, TaskOrderFactory, PortfolioFactory
from tests.factories import (
UserFactory,
TaskOrderFactory,
PortfolioFactory,
PortfolioRoleFactory,
)
class TestShowTaskOrderWorkflow:
@@ -93,8 +99,6 @@ def test_to_on_pf_cannot_edit_pf_attributes():
assert second_workflow.pf_attributes_read_only
# TODO: this test will need to be more complicated when we add validation to
# the forms
def test_create_new_task_order(client, user_session, pdf_upload):
creator = UserFactory.create()
user_session(creator)
@@ -296,6 +300,11 @@ def test_update_task_order_with_existing_task_order(task_order):
def test_update_to_redirects_to_ko_review(client, user_session, task_order):
ko = UserFactory.create()
task_order.contracting_officer = ko
PortfolioRoleFactory.create(
user=ko,
portfolio=task_order.portfolio,
permission_sets=[PermissionSets.get(PermissionSets.EDIT_PORTFOLIO_FUNDING)],
)
user_session(ko)
url = url_for(
"portfolios.ko_review",

View File

@@ -4,7 +4,7 @@ from urllib.parse import quote
from tests.factories import UserFactory
PROTECTED_URL = "/portfolios"
PROTECTED_URL = "/task_orders/new/get_started"
def test_request_page_with_complete_profile(client, user_session):

View File

72
tests/test_authz.py Normal file
View File

@@ -0,0 +1,72 @@
import pytest
import atst
from atst.app import make_app, make_config
from atst.domain.auth import UNPROTECTED_ROUTES as _NO_LOGIN_REQUIRED
import atst.domain.authz as authz
from tests.factories import UserFactory
_NO_ACCESS_CHECK_REQUIRED = _NO_LOGIN_REQUIRED + [
"task_orders.get_started",
"atst.csp_environment_access",
"atst.jedi_csp_calculator",
"atst.styleguide",
"dev.test_email",
"dev.messages",
"atst.home",
"users.user",
"users.update_user",
"portfolios.accept_invitation",
"atst.catch_all",
"portfolios.portfolios",
]
def protected_routes(app):
_protected_routes = []
for rule in app.url_map.iter_rules():
args = [1] * len(rule.arguments)
mock_args = dict(zip(rule.arguments, args))
_n, route = rule.build(mock_args)
if rule.endpoint in _NO_ACCESS_CHECK_REQUIRED or "/static" in route:
continue
_protected_routes.append((rule, route))
return _protected_routes
_PROTECTED_ROUTES = protected_routes(make_app(make_config()))
class Null:
def __init__(self, *args, **kwargs):
pass
def __getattr__(self, name):
return self
@pytest.mark.parametrize("rule,route", _PROTECTED_ROUTES)
def test_all_protected_routes_have_access_control(
rule, route, mocker, client, user_session, monkeypatch
):
monkeypatch.setattr("atst.domain.portfolios.Portfolios.for_user", lambda *a: [])
monkeypatch.setattr("atst.domain.portfolios.Portfolios.get", lambda *a: None)
monkeypatch.setattr("atst.domain.task_orders.TaskOrders.get", lambda *a: Null())
mocker.patch("atst.domain.authz.decorator.user_can_access")
mocker.patch("atst.domain.authz.decorator.evaluate_exceptions")
user = UserFactory.create()
user_session(user)
method = "get" if "GET" in rule.methods else "post"
getattr(client, method)(route)
assert (
atst.domain.authz.decorator.user_can_access.call_count == 1
or atst.domain.authz.decorator.evaluate_exceptions.call_count == 1
), "no access control for {}".format(rule.endpoint)