Procházet zdrojové kódy

chore(security): nosec false-positive Bandit findings in tests

  PR #1434 CI flagged 5 B402 (ftplib import) in test_bambu_ftp.py and 2
  B108 (hardcoded /tmp) in test_print_start_assigns_printer_id_to_vp_archive.py.
  Both are intentional in tests: the FTP client tests need real ftplib
  exception classes to construct mock 426 responses, and the /tmp path is
  a MagicMock attribute never written to. Marked with `# nosec B402` /
  `# nosec B108` plus a one-line justification each, matching the
  convention from c2630399.
maziggy před 1 týdnem
rodič
revize
162db57923

+ 5 - 5
backend/tests/unit/services/test_bambu_ftp.py

@@ -397,7 +397,7 @@ class TestUpload:
         succeeding on the printer side (v0.2.4.1 worked because the prior
         succeeding on the printer side (v0.2.4.1 worked because the prior
         proceed-with-warning branch tolerated the noise).
         proceed-with-warning branch tolerated the noise).
         """
         """
-        import ftplib
+        import ftplib  # nosec B402 — tests need the real ftplib to construct mock 426 responses
 
 
         local = tmp_path / "test.bin"
         local = tmp_path / "test.bin"
         local.write_bytes(b"data" * 256)  # 1024 bytes
         local.write_bytes(b"data" * 256)  # 1024 bytes
@@ -427,7 +427,7 @@ class TestUpload:
         isn't on the server at full size (or SIZE itself fails), the upload
         isn't on the server at full size (or SIZE itself fails), the upload
         must fail so the dispatcher doesn't send a print command for a
         must fail so the dispatcher doesn't send a print command for a
         partial 3MF."""
         partial 3MF."""
-        import ftplib
+        import ftplib  # nosec B402 — tests need the real ftplib to construct mock 426 responses
 
 
         local = tmp_path / "test.bin"
         local = tmp_path / "test.bin"
         local.write_bytes(b"data" * 256)
         local.write_bytes(b"data" * 256)
@@ -452,7 +452,7 @@ class TestUpload:
         """If SIZE itself fails (e.g. server too broken to answer), assume
         """If SIZE itself fails (e.g. server too broken to answer), assume
         the worst and fail — better a retry than a print on a partial file.
         the worst and fail — better a retry than a print on a partial file.
         """
         """
-        import ftplib
+        import ftplib  # nosec B402 — tests need the real ftplib to construct mock 426 responses
 
 
         local = tmp_path / "test.bin"
         local = tmp_path / "test.bin"
         local.write_bytes(b"data" * 256)
         local.write_bytes(b"data" * 256)
@@ -474,7 +474,7 @@ class TestUpload:
 
 
     def test_upload_bytes_426_with_intact_file_proceeds(self, ftp_client_factory, ftp_server):
     def test_upload_bytes_426_with_intact_file_proceeds(self, ftp_client_factory, ftp_server):
         """upload_bytes() mirrors the same SIZE-verify logic as upload_file."""
         """upload_bytes() mirrors the same SIZE-verify logic as upload_file."""
-        import ftplib
+        import ftplib  # nosec B402 — tests need the real ftplib to construct mock 426 responses
 
 
         client = ftp_client_factory()
         client = ftp_client_factory()
         client.connect()
         client.connect()
@@ -495,7 +495,7 @@ class TestUpload:
 
 
     def test_upload_bytes_426_with_truncated_file_returns_false(self, ftp_client_factory, ftp_server):
     def test_upload_bytes_426_with_truncated_file_returns_false(self, ftp_client_factory, ftp_server):
         """The truncated branch for upload_bytes()."""
         """The truncated branch for upload_bytes()."""
-        import ftplib
+        import ftplib  # nosec B402 — tests need the real ftplib to construct mock 426 responses
 
 
         client = ftp_client_factory()
         client = ftp_client_factory()
         client.connect()
         client.connect()

+ 2 - 2
backend/tests/unit/test_print_start_assigns_printer_id_to_vp_archive.py

@@ -64,7 +64,7 @@ async def test_expected_archive_path_assigns_printer_id_when_unset():
     mock_archive.printer_id = None
     mock_archive.printer_id = None
     mock_archive.print_name = "A1 Tool Plate 3"
     mock_archive.print_name = "A1 Tool Plate 3"
     mock_archive.status = "archived"
     mock_archive.status = "archived"
-    mock_archive.file_path = "/tmp/fake.3mf"
+    mock_archive.file_path = "/tmp/fake.3mf"  # nosec B108 — mock path; nothing ever writes to it
     mock_archive.energy_start_kwh = None
     mock_archive.energy_start_kwh = None
 
 
     register_expected_print(1, "bambu_lab_a1_tool_plate_3.gcode.3mf", archive_id=42, ams_mapping=None)
     register_expected_print(1, "bambu_lab_a1_tool_plate_3.gcode.3mf", archive_id=42, ams_mapping=None)
@@ -151,7 +151,7 @@ async def test_expected_archive_path_preserves_existing_printer_id():
     mock_archive.printer_id = 7  # already correct
     mock_archive.printer_id = 7  # already correct
     mock_archive.print_name = "MyModel"
     mock_archive.print_name = "MyModel"
     mock_archive.status = "archived"
     mock_archive.status = "archived"
-    mock_archive.file_path = "/tmp/fake.3mf"
+    mock_archive.file_path = "/tmp/fake.3mf"  # nosec B108 — mock path; nothing ever writes to it
     mock_archive.energy_start_kwh = None
     mock_archive.energy_start_kwh = None
 
 
     register_expected_print(7, "MyModel.3mf", archive_id=99, ams_mapping=None)
     register_expected_print(7, "MyModel.3mf", archive_id=99, ams_mapping=None)