diff --git a/status_list/status_list/v1_0/status_handler.py b/status_list/status_list/v1_0/status_handler.py index c1202d43e..deabee62e 100644 --- a/status_list/status_list/v1_0/status_handler.py +++ b/status_list/status_list/v1_0/status_handler.py @@ -115,6 +115,11 @@ def write_to_file( os.fsync(tmp.fileno()) temp_path = Path(tmp.name) + # NamedTemporaryFile always creates 0600, which a separate web server + # serving the published lists cannot read. Set this before the .alt + # copy below, which copies the mode along with the contents. + os.chmod(temp_path, 0o644) + if with_alt: alt_path = alt_name(full_path) alt_temp = alt_path.with_suffix(alt_path.suffix + ".tmp") diff --git a/status_list/status_list/v1_0/tests/test_status_handler.py b/status_list/status_list/v1_0/tests/test_status_handler.py index 5261f2ce6..a8f3a622a 100644 --- a/status_list/status_list/v1_0/tests/test_status_handler.py +++ b/status_list/status_list/v1_0/tests/test_status_handler.py @@ -55,6 +55,16 @@ def wrapped(): assert mock_sleep.call_count == 2 +def test_write_to_file_is_world_readable(tmp_path): + """Published lists must be readable by a web server running as another user.""" + file_path = tmp_path / "published" + + status_handler.write_to_file(str(file_path), b"status list", with_alt=True) + + assert file_path.stat().st_mode & 0o777 == 0o644 + assert status_handler.alt_name(file_path).stat().st_mode & 0o777 == 0o644 + + def test_write_to_file_success(tmp_path): file_path = tmp_path / "test.txt" content = b"hello world"