Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions driving_log/templates/dmv.html
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,10 @@ <h1>DMV driving record</h1>
</section>
{% endif %}

<section class="actions">
{% if not is_read_only %}<section class="actions">
<a class="button primary" href="/dmv/export" data-file-export data-export-filename="Daniel-driving-log-DL-4A.pdf">Download filled DL-4A PDF</a>
<span class="muted" data-export-status aria-live="polite"></span>
</section>
</section>{% endif %}

{% if not is_read_only %}<h2>Supervising drivers</h2>
{% for profile in profiles %}
Expand Down
4 changes: 2 additions & 2 deletions driving_log/templates/imports.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
{% block content %}
<h1>Imports and exports</h1>
<section class="actions">
<a class="button primary" href="/csv/export" data-file-export data-export-filename="driving-log.csv">Download CSV backup</a>
<span class="muted" data-export-status aria-live="polite"></span>
{% if not is_read_only %}<a class="button primary" href="/csv/export" data-file-export data-export-filename="driving-log.csv">Download CSV backup</a>
<span class="muted" data-export-status aria-live="polite"></span>{% endif %}
<a class="button" href="/dmv">DMV driving record</a>
{% if not is_read_only %}<a class="button secondary" href="/archives">Archives</a>{% endif %}
{% if not is_read_only %}<form class="stacked-form" method="post" action="/csv/import" enctype="multipart/form-data" data-async-submit>
Expand Down
2 changes: 2 additions & 0 deletions driving_log/web.py
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ def _duration_parts(minutes: int) -> dict[str, int]:
)
AUTH_SUPERVISORS = (ACCOUNTS["sean"], ACCOUNTS["jen"], ACCOUNTS["bethany"])
MUTATION_PAGE_PATHS = frozenset({"/drives/new", "/live", "/archives", "/locations"})
VIEW_ONLY_DOWNLOAD_PATHS = frozenset({"/csv/export", "/dmv/export"})


def _part_of_day(value: str | datetime, timezone_name: str) -> str:
Expand Down Expand Up @@ -322,6 +323,7 @@ async def authenticate_and_prevent_stale_html(
and (
request.method not in {"GET", "HEAD", "OPTIONS"}
or _is_mutation_page(request.url.path)
or request.url.path in VIEW_ONLY_DOWNLOAD_PATHS
)
):
return JSONResponse({"detail": "view-only account"}, status_code=403)
Expand Down
15 changes: 6 additions & 9 deletions tests/test_web.py
Original file line number Diff line number Diff line change
Expand Up @@ -271,7 +271,7 @@ async def scenario() -> None:

self.run_async(scenario)

def test_daniel_has_read_only_access_and_can_export_records(self) -> None:
def test_daniel_has_read_only_access_without_downloads(self) -> None:
settings = Settings(
state_dir=self.settings.state_dir,
database_path=self.settings.database_path,
Expand Down Expand Up @@ -352,15 +352,12 @@ async def scenario() -> None:
self.assertEqual(
(await daniel.get(f"/drives/{drive_id}/edit")).status_code, 403
)
self.assertEqual((await daniel.get("/csv/export")).status_code, 200)
self.assertEqual((await daniel.get("/dmv/export")).status_code, 200)
self.assertEqual((await daniel.get("/csv/export")).status_code, 403)
dmv_page = await daniel.get("/dmv")
self.assertIn("Download filled DL-4A PDF", dmv_page.text)
self.assertIn(
'href="/dmv/export" data-file-export '
'data-export-filename="Daniel-driving-log-DL-4A.pdf"',
dmv_page.text,
)
self.assertEqual((await daniel.get("/dmv/export")).status_code, 403)
self.assertNotIn("Download filled DL-4A PDF", dmv_page.text)
imports = await daniel.get("/imports")
self.assertNotIn("Download CSV backup", imports.text)
self.assertNotIn("Add license information", dmv_page.text)
self.assertEqual(
(
Expand Down
Loading