"""Framework enforcement is scoped to the registered handler, never a nearby method.""" import pytest from openultrasast.mapping import analyze_entry_points from openultrasast.preprocess import build_file_target from openultrasast.semantic.obligations.dominance import OrderDominance from openultrasast.semantic.obligations.operations import Operation def mapped(tmp_path, files): targets = [] for name, text in files.items(): path = tmp_path / name path.parent.mkdir(parents=True, exist_ok=True) path.write_text(text) if path.suffix in {".php", ".py"}: targets.append(build_file_target(tmp_path, path)) return [ e for e in analyze_entry_points(tmp_path, targets, texts=files, include_manifests=False) if e.kind == "route" and e.function_name ] @pytest.mark.parametrize("guard", ["auth", "can:edit", "role:admin", "permission:edit"]) def test_laravel_route_middleware(tmp_path, guard): from openultrasast.semantic.obligations.enforcement import witnesses files = { "Editor.php": "middleware(['{guard}']);", } rows = witnesses(root=tmp_path, texts=files, entries=mapped(tmp_path, files), language="php") (witness,) = rows assert (witness.path, witness.function, witness.line, witness.scope) == ("Editor.php", "store", None, "router") assert "routes/web.php" in witness.detail assert OrderDominance(files).dominates( witness, Operation("Editor.php", 1, "store", "protected_write", "x", None, ("path_guard",)), None ) @pytest.mark.parametrize("guard", ["$this->middleware('auth');", "$this->authorizeResource(Item::class, 'item');"]) def test_laravel_constructor(tmp_path, guard): from openultrasast.semantic.obligations.enforcement import witnesses files = { "Editor.php": f"""only(['store'])", "->except(['other'])"]) def test_constructor_restrictions_do_not_guard_other_handlers(tmp_path, restriction): from openultrasast.semantic.obligations.enforcement import witnesses files = { "Editor.php": f"""middleware('auth'){restriction}; }} public function store() {{}} public function other() {{}} }} Route::post('/items', [Editor::class, 'store']); Route::get('/other', [Editor::class, 'other']); """ } rows = witnesses(root=tmp_path, texts=files, entries=mapped(tmp_path, files), language="php") assert [row.function for row in rows] == ["store"] def test_symfony_first_public_rule_does_not_become_a_guard(tmp_path): from openultrasast.semantic.obligations.enforcement import witnesses files = { "Editor.php": "middleware('auth'); Route::post('/items', [Editor::class, 'store'])->middleware('throttle:10'); """, "app.py": "class Handler(RequestHandler):\n @not_authenticated\n def get(self):\n pass\n", } entries = mapped(tmp_path, files) assert witnesses(root=tmp_path, texts=files, entries=entries, language="php") == [] assert witnesses(root=tmp_path, texts=files, entries=entries, language="python") == []