apply auth requirement to virtually all endpoints
This commit is contained in:
parent
ed1e8bffd1
commit
2d5651a21d
@ -1,5 +1,5 @@
|
|||||||
from functools import wraps
|
from functools import wraps
|
||||||
from flask import g, request, redirect, url_for, session
|
from flask import g, redirect, url_for, session
|
||||||
|
|
||||||
from atst.domain.users import Users
|
from atst.domain.users import Users
|
||||||
|
|
||||||
|
@ -4,9 +4,11 @@ from flask import request as http_request
|
|||||||
from . import requests_bp
|
from . import requests_bp
|
||||||
from atst.domain.requests import Requests
|
from atst.domain.requests import Requests
|
||||||
from atst.forms.financial import FinancialForm
|
from atst.forms.financial import FinancialForm
|
||||||
|
from atst.domain.auth import login_required
|
||||||
|
|
||||||
|
|
||||||
@requests_bp.route("/requests/verify/<string:request_id>", methods=["GET"])
|
@requests_bp.route("/requests/verify/<string:request_id>", methods=["GET"])
|
||||||
|
@login_required
|
||||||
def financial_verification(request_id=None):
|
def financial_verification(request_id=None):
|
||||||
request = Requests.get(request_id)
|
request = Requests.get(request_id)
|
||||||
form = FinancialForm(data=request.body.get("financial_verification"))
|
form = FinancialForm(data=request.body.get("financial_verification"))
|
||||||
@ -16,6 +18,7 @@ def financial_verification(request_id=None):
|
|||||||
|
|
||||||
|
|
||||||
@requests_bp.route("/requests/verify/<string:request_id>", methods=["POST"])
|
@requests_bp.route("/requests/verify/<string:request_id>", methods=["POST"])
|
||||||
|
@login_required
|
||||||
def update_financial_verification(request_id):
|
def update_financial_verification(request_id):
|
||||||
post_data = http_request.form
|
post_data = http_request.form
|
||||||
existing_request = Requests.get(request_id)
|
existing_request = Requests.get(request_id)
|
||||||
@ -40,5 +43,6 @@ def update_financial_verification(request_id):
|
|||||||
|
|
||||||
|
|
||||||
@requests_bp.route("/requests/financial_verification_submitted")
|
@requests_bp.route("/requests/financial_verification_submitted")
|
||||||
|
@login_required
|
||||||
def financial_verification_submitted():
|
def financial_verification_submitted():
|
||||||
pass
|
pass
|
||||||
|
@ -3,6 +3,7 @@ from flask import render_template, g
|
|||||||
|
|
||||||
from . import requests_bp
|
from . import requests_bp
|
||||||
from atst.domain.requests import Requests
|
from atst.domain.requests import Requests
|
||||||
|
from atst.domain.auth import login_required
|
||||||
|
|
||||||
|
|
||||||
def map_request(user, request):
|
def map_request(user, request):
|
||||||
@ -20,6 +21,7 @@ def map_request(user, request):
|
|||||||
|
|
||||||
|
|
||||||
@requests_bp.route("/requests", methods=["GET"])
|
@requests_bp.route("/requests", methods=["GET"])
|
||||||
|
@login_required
|
||||||
def requests_index():
|
def requests_index():
|
||||||
requests = []
|
requests = []
|
||||||
if (
|
if (
|
||||||
|
@ -3,10 +3,11 @@ from flask import g, redirect, render_template, url_for, request as http_request
|
|||||||
from . import requests_bp
|
from . import requests_bp
|
||||||
from atst.domain.requests import Requests
|
from atst.domain.requests import Requests
|
||||||
from atst.routes.requests.jedi_request_flow import JEDIRequestFlow
|
from atst.routes.requests.jedi_request_flow import JEDIRequestFlow
|
||||||
|
from atst.domain.auth import login_required
|
||||||
|
|
||||||
|
|
||||||
@requests_bp.route("/requests/new", defaults={"screen": 1})
|
|
||||||
@requests_bp.route("/requests/new/<int:screen>", methods=["GET"])
|
@requests_bp.route("/requests/new/<int:screen>", methods=["GET"])
|
||||||
|
@login_required
|
||||||
def requests_form_new(screen):
|
def requests_form_new(screen):
|
||||||
jedi_flow = JEDIRequestFlow(screen, request=None)
|
jedi_flow = JEDIRequestFlow(screen, request=None)
|
||||||
|
|
||||||
@ -25,6 +26,7 @@ def requests_form_new(screen):
|
|||||||
"/requests/new/<int:screen>", methods=["GET"], defaults={"request_id": None}
|
"/requests/new/<int:screen>", methods=["GET"], defaults={"request_id": None}
|
||||||
)
|
)
|
||||||
@requests_bp.route("/requests/new/<int:screen>/<string:request_id>", methods=["GET"])
|
@requests_bp.route("/requests/new/<int:screen>/<string:request_id>", methods=["GET"])
|
||||||
|
@login_required
|
||||||
def requests_form_update(screen=1, request_id=None):
|
def requests_form_update(screen=1, request_id=None):
|
||||||
request = Requests.get(request_id) if request_id is not None else None
|
request = Requests.get(request_id) if request_id is not None else None
|
||||||
jedi_flow = JEDIRequestFlow(screen, request, request_id=request_id)
|
jedi_flow = JEDIRequestFlow(screen, request, request_id=request_id)
|
||||||
@ -45,6 +47,7 @@ def requests_form_update(screen=1, request_id=None):
|
|||||||
"/requests/new/<int:screen>", methods=["POST"], defaults={"request_id": None}
|
"/requests/new/<int:screen>", methods=["POST"], defaults={"request_id": None}
|
||||||
)
|
)
|
||||||
@requests_bp.route("/requests/new/<int:screen>/<string:request_id>", methods=["POST"])
|
@requests_bp.route("/requests/new/<int:screen>/<string:request_id>", methods=["POST"])
|
||||||
|
@login_required
|
||||||
def requests_update(screen=1, request_id=None):
|
def requests_update(screen=1, request_id=None):
|
||||||
screen = int(screen)
|
screen = int(screen)
|
||||||
post_data = http_request.form
|
post_data = http_request.form
|
||||||
@ -89,6 +92,7 @@ def requests_update(screen=1, request_id=None):
|
|||||||
|
|
||||||
|
|
||||||
@requests_bp.route("/requests/submit/<string:request_id>", methods=["POST"])
|
@requests_bp.route("/requests/submit/<string:request_id>", methods=["POST"])
|
||||||
|
@login_required
|
||||||
def requests_submit(request_id=None):
|
def requests_submit(request_id=None):
|
||||||
request = Requests.get(request_id)
|
request = Requests.get(request_id)
|
||||||
Requests.submit(request)
|
Requests.submit(request)
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
from flask import Blueprint, render_template
|
from flask import Blueprint, render_template
|
||||||
|
|
||||||
from atst.domain.workspaces import Projects, Members
|
from atst.domain.workspaces import Projects, Members
|
||||||
|
from atst.domain.auth import login_required
|
||||||
|
|
||||||
|
|
||||||
bp = Blueprint("workspaces", __name__)
|
bp = Blueprint("workspaces", __name__)
|
||||||
@ -16,11 +17,13 @@ mock_workspaces = [
|
|||||||
|
|
||||||
|
|
||||||
@bp.route("/workspaces")
|
@bp.route("/workspaces")
|
||||||
|
@login_required
|
||||||
def workspaces():
|
def workspaces():
|
||||||
return render_template("workspaces.html", page=5, workspaces=mock_workspaces)
|
return render_template("workspaces.html", page=5, workspaces=mock_workspaces)
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/workspaces/<workspace_id>/projects")
|
@bp.route("/workspaces/<workspace_id>/projects")
|
||||||
|
@login_required
|
||||||
def workspace_projects(workspace_id):
|
def workspace_projects(workspace_id):
|
||||||
projects_repo = Projects()
|
projects_repo = Projects()
|
||||||
projects = projects_repo.get_many(workspace_id)
|
projects = projects_repo.get_many(workspace_id)
|
||||||
@ -30,6 +33,7 @@ def workspace_projects(workspace_id):
|
|||||||
|
|
||||||
|
|
||||||
@bp.route("/workspaces/<workspace_id>/members")
|
@bp.route("/workspaces/<workspace_id>/members")
|
||||||
|
@login_required
|
||||||
def workspace_members(workspace_id):
|
def workspace_members(workspace_id):
|
||||||
members_repo = Members()
|
members_repo = Members()
|
||||||
members = members_repo.get_many(workspace_id)
|
members = members_repo.get_many(workspace_id)
|
||||||
|
@ -5,6 +5,7 @@ import alembic.command
|
|||||||
|
|
||||||
from atst.app import make_app, make_config
|
from atst.app import make_app, make_config
|
||||||
from atst.database import db as _db
|
from atst.database import db as _db
|
||||||
|
from .mocks import MOCK_USER
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(scope='session')
|
@pytest.fixture(scope='session')
|
||||||
@ -79,3 +80,11 @@ def dummy_form():
|
|||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def dummy_field():
|
def dummy_field():
|
||||||
return DummyField()
|
return DummyField()
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def user_session(monkeypatch):
|
||||||
|
|
||||||
|
def set_user_session(user = MOCK_USER):
|
||||||
|
monkeypatch.setattr("atst.domain.auth.get_current_user", lambda *args: user)
|
||||||
|
|
||||||
|
return set_user_session
|
||||||
|
@ -32,6 +32,7 @@ class TestPENumberInForm:
|
|||||||
def _set_monkeypatches(self, monkeypatch):
|
def _set_monkeypatches(self, monkeypatch):
|
||||||
monkeypatch.setattr("atst.forms.financial.FinancialForm.validate", lambda s: True)
|
monkeypatch.setattr("atst.forms.financial.FinancialForm.validate", lambda s: True)
|
||||||
monkeypatch.setattr("atst.domain.requests.Requests.get", lambda i: MOCK_REQUEST)
|
monkeypatch.setattr("atst.domain.requests.Requests.get", lambda i: MOCK_REQUEST)
|
||||||
|
monkeypatch.setattr("atst.domain.auth.get_current_user", lambda *args: MOCK_USER)
|
||||||
|
|
||||||
def submit_data(self, client, data):
|
def submit_data(self, client, data):
|
||||||
response = client.post(
|
response = client.post(
|
||||||
|
@ -15,7 +15,8 @@ MOCK_REQUEST = RequestFactory.create(
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_submit_invalid_request_form(monkeypatch, client):
|
def test_submit_invalid_request_form(monkeypatch, client, user_session):
|
||||||
|
user_session()
|
||||||
response = client.post(
|
response = client.post(
|
||||||
"/requests/new/1",
|
"/requests/new/1",
|
||||||
headers={"Content-Type": "application/x-www-form-urlencoded"},
|
headers={"Content-Type": "application/x-www-form-urlencoded"},
|
||||||
@ -24,7 +25,8 @@ def test_submit_invalid_request_form(monkeypatch, client):
|
|||||||
assert re.search(ERROR_CLASS, response.data.decode())
|
assert re.search(ERROR_CLASS, response.data.decode())
|
||||||
|
|
||||||
|
|
||||||
def test_submit_valid_request_form(monkeypatch, client):
|
def test_submit_valid_request_form(monkeypatch, client, user_session):
|
||||||
|
user_session()
|
||||||
monkeypatch.setattr("atst.forms.request.RequestForm.validate", lambda s: True)
|
monkeypatch.setattr("atst.forms.request.RequestForm.validate", lambda s: True)
|
||||||
|
|
||||||
response = client.post(
|
response = client.post(
|
||||||
|
@ -7,7 +7,8 @@ def _mock_func(*args, **kwargs):
|
|||||||
return RequestFactory.create()
|
return RequestFactory.create()
|
||||||
|
|
||||||
|
|
||||||
def test_submit_reviewed_request(monkeypatch, client):
|
def test_submit_reviewed_request(monkeypatch, client, user_session):
|
||||||
|
user_session()
|
||||||
monkeypatch.setattr("atst.domain.requests.Requests.get", _mock_func)
|
monkeypatch.setattr("atst.domain.requests.Requests.get", _mock_func)
|
||||||
monkeypatch.setattr("atst.domain.requests.Requests.submit", _mock_func)
|
monkeypatch.setattr("atst.domain.requests.Requests.submit", _mock_func)
|
||||||
monkeypatch.setattr("atst.models.request.Request.status", "pending")
|
monkeypatch.setattr("atst.models.request.Request.status", "pending")
|
||||||
@ -22,7 +23,8 @@ def test_submit_reviewed_request(monkeypatch, client):
|
|||||||
assert "modal" not in response.headers["Location"]
|
assert "modal" not in response.headers["Location"]
|
||||||
|
|
||||||
|
|
||||||
def test_submit_autoapproved_reviewed_request(monkeypatch, client):
|
def test_submit_autoapproved_reviewed_request(monkeypatch, client, user_session):
|
||||||
|
user_session()
|
||||||
monkeypatch.setattr("atst.domain.requests.Requests.get", _mock_func)
|
monkeypatch.setattr("atst.domain.requests.Requests.get", _mock_func)
|
||||||
monkeypatch.setattr("atst.domain.requests.Requests.submit", _mock_func)
|
monkeypatch.setattr("atst.domain.requests.Requests.submit", _mock_func)
|
||||||
monkeypatch.setattr("atst.models.request.Request.status", "approved")
|
monkeypatch.setattr("atst.models.request.Request.status", "approved")
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
from flask import session
|
from flask import session, url_for
|
||||||
from .mocks import DOD_SDN
|
from .mocks import DOD_SDN
|
||||||
|
|
||||||
|
|
||||||
@ -31,3 +31,24 @@ def test_unsuccessful_login_redirect(client, monkeypatch):
|
|||||||
assert resp.status_code == 302
|
assert resp.status_code == 302
|
||||||
assert "unauthorized" in resp.headers["Location"]
|
assert "unauthorized" in resp.headers["Location"]
|
||||||
assert "user_id" not in session
|
assert "user_id" not in session
|
||||||
|
|
||||||
|
UNPROTECTED_ROUTES = ["/", "/login-dev", "/login-redirect", "/unauthorized"]
|
||||||
|
|
||||||
|
# checks that all of the routes in the app are protected by auth
|
||||||
|
def test_protected_route(client, app):
|
||||||
|
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 route in UNPROTECTED_ROUTES or "/static" in route:
|
||||||
|
continue
|
||||||
|
|
||||||
|
if "GET" in rule.methods:
|
||||||
|
resp = client.get(route)
|
||||||
|
assert resp.status_code == 302
|
||||||
|
assert resp.headers["Location"] == "http://localhost/"
|
||||||
|
|
||||||
|
if "POST" in rule.methods:
|
||||||
|
resp = client.post(route)
|
||||||
|
assert resp.status_code == 302
|
||||||
|
assert resp.headers["Location"] == "http://localhost/"
|
||||||
|
@ -5,14 +5,13 @@ import pytest
|
|||||||
"/home",
|
"/home",
|
||||||
"/workspaces",
|
"/workspaces",
|
||||||
"/requests",
|
"/requests",
|
||||||
"/requests/new",
|
"/requests/new/1",
|
||||||
"/requests/new/2",
|
|
||||||
"/users",
|
"/users",
|
||||||
"/reports",
|
"/reports",
|
||||||
"/calculator",
|
"/calculator",
|
||||||
))
|
))
|
||||||
def test_routes(path, client, monkeypatch):
|
def test_routes(path, client, user_session):
|
||||||
monkeypatch.setattr("atst.domain.auth.get_current_user", lambda *args: True)
|
user_session()
|
||||||
|
|
||||||
response = client.get(path)
|
response = client.get(path)
|
||||||
assert response.status_code == 200
|
assert response.status_code == 200
|
||||||
|
Loading…
x
Reference in New Issue
Block a user