Добавлена Яндекс.Капча

This commit is contained in:
mi
2026-07-23 18:53:32 +03:00
parent 31efbf3b69
commit 8c3c454998
36 changed files with 836 additions and 35 deletions
+62 -1
View File
@@ -43,7 +43,8 @@ class InfrastructureConfigTests(unittest.TestCase):
application = (ROOT / "infra/compose/application.yml").read_text(encoding="utf-8")
self.assertIn("networks: [backend, observability, egress]", application)
self.assertIn("networks: [public, backend, observability]", application)
self.assertIn("networks: [public, backend, observability, egress]", application)
self.assertIn('KEYCLOAK_YANDEX_CAPTCHA_SERVER_KEY: ""', application)
self.assertEqual(
application.count(
"IDGTL_SMS_API_KEY: ${IDGTL_SMS_API_KEY:?IDGTL_SMS_API_KEY is required}"
@@ -99,6 +100,23 @@ class InfrastructureConfigTests(unittest.TestCase):
self.assertIn("location = /auth/callback", site)
self.assertIn("location ^~ /auth/resources/", site)
self.assertIn("location ^~ /auth/realms/", site)
self.assertIn(
"location = /auth/realms/han-chat/protocol/openid-connect/auth", site
)
self.assertIn(
"location = /auth/realms/han-chat/login-actions/authenticate", site
)
captcha_csp = (
ROOT / "nginx/snippets/proxy-keycloak-captcha-csp.conf"
).read_text(encoding="utf-8")
self.assertIn("proxy_hide_header Content-Security-Policy", captcha_csp)
self.assertIn("smartcaptcha.cloud.yandex.ru", captcha_csp)
self.assertIn("yastatic.net", captcha_csp)
for directive in ("default-src 'self'", "base-uri 'self'", "form-action 'self'"):
self.assertIn(directive, captcha_csp)
self.assertNotIn("browserSecurityHeaders", (
ROOT / "keycloak/realm/han-chat-realm.json"
).read_text(encoding="utf-8"))
self.assertIn("location = /callbacks/idgtl/sms", site)
self.assertIn("allow 185.203.96.7;", site)
self.assertIn("proxy_pass http://sms_service_upstream;", site)
@@ -225,6 +243,9 @@ class InfrastructureConfigTests(unittest.TestCase):
"KC_DB_SCHEMA",
"KEYCLOAK_OTP_MOCK_ENABLED",
"KEYCLOAK_OTP_MOCK_CODE",
"KEYCLOAK_YANDEX_CAPTCHA_ENABLED",
"KEYCLOAK_YANDEX_CAPTCHA_CLIENT_KEY",
"KEYCLOAK_YANDEX_CAPTCHA_SERVER_KEY",
"KEYCLOAK_OTP_HMAC_KEY",
"KEYCLOAK_OTP_SETTINGS_MAX_STALE_SEC",
"KEYCLOAK_SETTINGS_BRIDGE_URL",
@@ -264,6 +285,46 @@ class InfrastructureConfigTests(unittest.TestCase):
)
self.assertEqual(result.returncode, 0, result.stderr)
def test_env_validator_requires_captcha_keys_only_when_enabled(self) -> None:
example = (ROOT / ".env.example").read_text(encoding="utf-8")
materialized = example.replace(
"change-me", "0123456789abcdef0123456789abcdef"
).replace(
"KEYCLOAK_OTP_MOCK_RISK_ACCEPTED=false",
"KEYCLOAK_OTP_MOCK_RISK_ACCEPTED=true",
)
enabled_without_keys = materialized.replace(
"KEYCLOAK_YANDEX_CAPTCHA_ENABLED=false",
"KEYCLOAK_YANDEX_CAPTCHA_ENABLED=true",
)
enabled_with_keys = enabled_without_keys.replace(
"KEYCLOAK_YANDEX_CAPTCHA_CLIENT_KEY=",
"KEYCLOAK_YANDEX_CAPTCHA_CLIENT_KEY=client-key",
).replace(
"KEYCLOAK_YANDEX_CAPTCHA_SERVER_KEY=",
"KEYCLOAK_YANDEX_CAPTCHA_SERVER_KEY=server-key-0123456789",
)
with tempfile.TemporaryDirectory() as directory:
env_file = Path(directory) / ".env"
env_file.write_text(enabled_without_keys, encoding="utf-8")
missing = subprocess.run(
[sys.executable, str(ROOT / "scripts/validate-env"), str(env_file)],
text=True,
capture_output=True,
check=False,
)
env_file.write_text(enabled_with_keys, encoding="utf-8")
configured = subprocess.run(
[sys.executable, str(ROOT / "scripts/validate-env"), str(env_file)],
text=True,
capture_output=True,
check=False,
)
self.assertNotEqual(missing.returncode, 0)
self.assertIn("KEYCLOAK_YANDEX_CAPTCHA_CLIENT_KEY", missing.stderr)
self.assertIn("KEYCLOAK_YANDEX_CAPTCHA_SERVER_KEY", missing.stderr)
self.assertEqual(configured.returncode, 0, configured.stderr)
if __name__ == "__main__":
unittest.main()