test_client_ip.py 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. """client_ip 回环地址替换测试(同机 localhost 访问记本机网卡 IPv4)。"""
  2. from __future__ import annotations
  3. import ipaddress
  4. import pytest
  5. from dms.services import audit_service
  6. from dms.services.audit_service import _is_loopback, client_ip
  7. LAN_IP = "192.168.1.5"
  8. @pytest.fixture(autouse=True)
  9. def stub_primary_address(monkeypatch):
  10. """默认钉住本机网卡解析结果,仅真实解析用例放行。"""
  11. monkeypatch.setattr(audit_service, "_primary_local_address", lambda: LAN_IP)
  12. monkeypatch.setattr(audit_service, "_primary_address_cache", None)
  13. def request_client_ip(flask_app, remote_addr=None, headers=None):
  14. with flask_app.test_request_context(
  15. "/", environ_base={"REMOTE_ADDR": remote_addr} if remote_addr else {},
  16. headers=headers or {},
  17. ):
  18. return client_ip()
  19. def test_loopback_ipv6_replaced_with_lan_ip(flask_app):
  20. assert request_client_ip(flask_app, "::1") == LAN_IP
  21. assert request_client_ip(flask_app, "0:0:0:0:0:0:0:1") == LAN_IP
  22. def test_loopback_ipv4_replaced_with_lan_ip(flask_app):
  23. assert request_client_ip(flask_app, "127.0.0.1") == LAN_IP
  24. def test_xff_takes_precedence_and_passes_through(flask_app):
  25. assert request_client_ip(
  26. flask_app, "::1", headers={"X-Forwarded-For": "192.0.2.10, 10.0.0.1"}
  27. ) == "192.0.2.10"
  28. def test_non_loopback_remote_addr_passes_through(flask_app):
  29. assert request_client_ip(flask_app, "192.168.1.20") == "192.168.1.20"
  30. def test_is_loopback_variants():
  31. assert _is_loopback("::1")
  32. assert _is_loopback("0:0:0:0:0:0:0:1")
  33. assert _is_loopback("127.0.0.1")
  34. assert _is_loopback("127.0.1.9")
  35. assert _is_loopback("::ffff:127.0.0.1")
  36. assert _is_loopback("fe80::1%eth0") is False
  37. assert not _is_loopback("192.168.1.5")
  38. assert not _is_loopback("not-an-ip")
  39. def test_primary_local_address_real_resolution(flask_app, monkeypatch):
  40. """真实选路:返回有效 IPv4 且非 ::1 形态(无网卡环境回退 127.0.0.1)。"""
  41. monkeypatch.undo()
  42. monkeypatch.setattr(audit_service, "_primary_address_cache", None)
  43. resolved = audit_service._primary_local_address()
  44. assert ipaddress.ip_address(resolved).version == 4