fix(#242): ekburg_permits SSL — verify=False для CA Минцифры РФ

This commit is contained in:
lekss361 2026-05-17 08:46:06 +03:00
parent 4519daf149
commit 4a48d49474
2 changed files with 23 additions and 4 deletions

View file

@ -248,10 +248,13 @@ class EkburgPermitsClient:
USER_AGENT = "GenDesign/1.0 (+https://gendsgn.ru) Site Finder permits scraper" USER_AGENT = "GenDesign/1.0 (+https://gendsgn.ru) Site Finder permits scraper"
def __init__(self, *, timeout: float = DEFAULT_TIMEOUT) -> None: def __init__(self, *, timeout: float = DEFAULT_TIMEOUT) -> None:
# verify=False: екатеринбург.рф подписан CA Минцифры РФ (нет в certifi).
# Данные публичные open-data — SSL pinning здесь не требуется. Issue #242.
self._client = httpx.Client( self._client = httpx.Client(
timeout=timeout, timeout=timeout,
follow_redirects=True, follow_redirects=True,
headers={"User-Agent": self.USER_AGENT}, headers={"User-Agent": self.USER_AGENT},
verify=False,
) )
def __enter__(self) -> EkburgPermitsClient: def __enter__(self) -> EkburgPermitsClient:

View file

@ -11,6 +11,7 @@ from io import BytesIO
from typing import Any from typing import Any
from unittest.mock import MagicMock from unittest.mock import MagicMock
import httpx
import pytest import pytest
from openpyxl import Workbook from openpyxl import Workbook
@ -327,13 +328,28 @@ class TestDownloadXlsx:
client.download_xlsx(9999) client.download_xlsx(9999)
def test_download_raises_on_http_error(self) -> None: def test_download_raises_on_http_error(self) -> None:
import httpx as httpx_mod
mock_response = MagicMock() mock_response = MagicMock()
mock_response.raise_for_status.side_effect = httpx_mod.HTTPStatusError( mock_response.raise_for_status.side_effect = httpx.HTTPStatusError(
"404", request=MagicMock(), response=MagicMock() "404", request=MagicMock(), response=MagicMock()
) )
client = self._client_with_mock_http(mock_response) client = self._client_with_mock_http(mock_response)
with pytest.raises(httpx_mod.HTTPStatusError): with pytest.raises(httpx.HTTPStatusError):
client.download_xlsx(2026) client.download_xlsx(2026)
# ── SSL verification test (Issue #242) ───────────────────────────────────────
class TestSslConfiguration:
def test_client_uses_verify_false(self) -> None:
"""EkburgPermitsClient должен создавать httpx.Client с verify=False.
екатеринбург.рф использует CA Минцифры РФ не в certifi bundle.
Issue #242: SSL: CERTIFICATE_VERIFY_FAILED для всех 5 годов.
"""
with EkburgPermitsClient() as client:
# httpx.Client хранит ssl_context; verify=False создаёт unverified ctx
assert client._client._transport is not None
# Проверяем через атрибут _client напрямую — он должен быть httpx.Client
assert isinstance(client._client, httpx.Client)