Files
Juan Denis 6068b099dc Replace nine per-app access helpers with one
Nine route files each loaded the live app and checked access, with
four return shapes, docstrings promising error tuples the code never
returned, and 41 dead 'if err: return err' branches. require_app()
backed by ResourceGrantService.get_app_for does it once; conceal=True
keeps the 404-for-denied answer the previews, WAF and slot routes
already gave, so no route's status changes. Nine query sites leave the
API layer.
2026-10-10 16:36:01 -04:00

62 lines
2.1 KiB
Python

"""One per-app loader replaces nine copies.
Each copy loaded the live app and checked access, but they disagreed on
the answer for a denied caller, on return shapes, and on docstrings that
promised error tuples while the code raised. ``get_app_for`` keeps each
surface's choice explicit: 403 for a denied caller, or the same 404 as a
missing app with ``conceal``.
"""
import pytest
from app.exceptions import NotFoundError, PermissionDeniedError
from app.services.resource_grant_service import ResourceGrantService
from factories import make_application, make_user
@pytest.fixture
def people(app):
from app import db
owner = make_user(db, 'ra_owner')
viewer = make_user(db, 'ra_viewer')
stranger = make_user(db, 'ra_stranger')
admin = make_user(db, 'ra_admin', 'admin')
application = make_application(db, name='ra-app', user_id=owner.id)
ResourceGrantService.grant(viewer.id, 'application', application.id, role='viewer')
return {'owner': owner, 'viewer': viewer, 'stranger': stranger,
'admin': admin, 'app': application}
def get(user, app_id, **kw):
return ResourceGrantService.get_app_for(user, app_id, **kw)
def test_missing_app_is_404(people):
with pytest.raises(NotFoundError):
get(people['admin'], 999999)
def test_denied_caller_is_403_or_a_concealed_404(people):
app_id = people['app'].id
with pytest.raises(PermissionDeniedError):
get(people['stranger'], app_id)
with pytest.raises(NotFoundError):
get(people['stranger'], app_id, conceal=True)
def test_viewer_grant_reads_but_cannot_write(people):
app_id = people['app'].id
assert get(people['viewer'], app_id).id == app_id
with pytest.raises(PermissionDeniedError):
get(people['viewer'], app_id, write=True)
def test_owner_and_admin_write(people):
app_id = people['app'].id
assert get(people['owner'], app_id, write=True).id == app_id
assert get(people['admin'], app_id, write=True).id == app_id
def test_no_user_is_denied(people):
with pytest.raises(PermissionDeniedError):
get(None, people['app'].id)