from tests.unit.services.service_helpers import * def test_vaultwarden_invite_uses_admin_session(monkeypatch) -> None: dummy_settings = types.SimpleNamespace( vaultwarden_namespace="vaultwarden", vaultwarden_admin_secret_name="vaultwarden-admin", vaultwarden_admin_secret_key="ADMIN_TOKEN", vaultwarden_admin_rate_limit_backoff_sec=600, vaultwarden_admin_session_ttl_sec=900, vaultwarden_service_host="vaultwarden-service.vaultwarden.svc.cluster.local", vaultwarden_pod_label="app=vaultwarden", vaultwarden_pod_port=80, ) client = DummyVaultwardenClient() monkeypatch.setattr("ariadne.services.vaultwarden.settings", dummy_settings) monkeypatch.setattr("ariadne.services.vaultwarden.get_secret_value", lambda *args, **kwargs: "token") monkeypatch.setattr("ariadne.services.vaultwarden.httpx.Client", lambda *args, **kwargs: client) monkeypatch.setattr( "ariadne.services.vaultwarden.VaultwardenService._find_pod_ip", staticmethod(lambda *args, **kwargs: "127.0.0.1"), ) svc = VaultwardenService() result = svc.invite_user("alice@bstein.dev") assert result.ok is True assert any(call[0] == "/admin" for call in client.calls) assert any(call[0] == "/admin/invite" for call in client.calls) def test_vaultwarden_invite_handles_rate_limit(monkeypatch) -> None: dummy_settings = types.SimpleNamespace( vaultwarden_namespace="vaultwarden", vaultwarden_admin_secret_name="vaultwarden-admin", vaultwarden_admin_secret_key="ADMIN_TOKEN", vaultwarden_admin_rate_limit_backoff_sec=600, vaultwarden_admin_session_ttl_sec=900, vaultwarden_service_host="vaultwarden-service.vaultwarden.svc.cluster.local", vaultwarden_pod_label="app=vaultwarden", vaultwarden_pod_port=80, ) client = DummyVaultwardenClient() client.responses["/admin/invite"] = DummyResponse(429, "rate limited") monkeypatch.setattr("ariadne.services.vaultwarden.settings", dummy_settings) monkeypatch.setattr("ariadne.services.vaultwarden.get_secret_value", lambda *args, **kwargs: "token") monkeypatch.setattr("ariadne.services.vaultwarden.httpx.Client", lambda *args, **kwargs: client) monkeypatch.setattr( "ariadne.services.vaultwarden.VaultwardenService._find_pod_ip", staticmethod(lambda *args, **kwargs: "127.0.0.1"), ) svc = VaultwardenService() result = svc.invite_user("alice@bstein.dev") assert result.status == "rate_limited" def test_vaultwarden_invite_existing_user(monkeypatch) -> None: dummy_settings = types.SimpleNamespace( vaultwarden_namespace="vaultwarden", vaultwarden_admin_secret_name="vaultwarden-admin", vaultwarden_admin_secret_key="ADMIN_TOKEN", vaultwarden_admin_rate_limit_backoff_sec=600, vaultwarden_admin_session_ttl_sec=900, vaultwarden_service_host="vaultwarden-service.vaultwarden.svc.cluster.local", vaultwarden_pod_label="app=vaultwarden", vaultwarden_pod_port=80, ) client = DummyVaultwardenClient() client.responses["/admin/invite"] = DummyResponse(409, "user already exists") monkeypatch.setattr("ariadne.services.vaultwarden.settings", dummy_settings) monkeypatch.setattr("ariadne.services.vaultwarden.get_secret_value", lambda *args, **kwargs: "token") monkeypatch.setattr("ariadne.services.vaultwarden.httpx.Client", lambda *args, **kwargs: client) monkeypatch.setattr( "ariadne.services.vaultwarden.VaultwardenService._find_pod_ip", staticmethod(lambda *args, **kwargs: "127.0.0.1"), ) svc = VaultwardenService() result = svc.invite_user("alice@bstein.dev") assert result.status == "already_present" def test_vaultwarden_invite_rejects_invalid_email() -> None: svc = VaultwardenService() result = svc.invite_user("bad-email") assert result.status == "invalid_email" def test_vaultwarden_invite_rate_limited_short_circuit() -> None: svc = VaultwardenService() svc._rate_limited_until = time.time() + 60 result = svc.invite_user("alice@bstein.dev") assert result.status == "rate_limited" def test_vaultwarden_lookup_user_present(monkeypatch) -> None: dummy_settings = types.SimpleNamespace( vaultwarden_namespace="vaultwarden", vaultwarden_admin_secret_name="vaultwarden-admin", vaultwarden_admin_secret_key="ADMIN_TOKEN", vaultwarden_admin_rate_limit_backoff_sec=600, vaultwarden_admin_session_ttl_sec=900, vaultwarden_service_host="vaultwarden-service.vaultwarden.svc.cluster.local", vaultwarden_pod_label="app=vaultwarden", vaultwarden_pod_port=80, ) client = DummyVaultwardenClient() client.responses["/admin/users"] = DummyResponse(200, "", json_data=[{"email": "alice@bstein.dev"}]) monkeypatch.setattr("ariadne.services.vaultwarden.settings", dummy_settings) monkeypatch.setattr("ariadne.services.vaultwarden.get_secret_value", lambda *args, **kwargs: "token") monkeypatch.setattr("ariadne.services.vaultwarden.httpx.Client", lambda *args, **kwargs: client) monkeypatch.setattr( "ariadne.services.vaultwarden.VaultwardenService._find_pod_ip", staticmethod(lambda *args, **kwargs: "127.0.0.1"), ) svc = VaultwardenService() result = svc.find_user_by_email("alice@bstein.dev") assert result.status == "present" def test_vaultwarden_lookup_user_missing(monkeypatch) -> None: dummy_settings = types.SimpleNamespace( vaultwarden_namespace="vaultwarden", vaultwarden_admin_secret_name="vaultwarden-admin", vaultwarden_admin_secret_key="ADMIN_TOKEN", vaultwarden_admin_rate_limit_backoff_sec=600, vaultwarden_admin_session_ttl_sec=900, vaultwarden_service_host="vaultwarden-service.vaultwarden.svc.cluster.local", vaultwarden_pod_label="app=vaultwarden", vaultwarden_pod_port=80, ) client = DummyVaultwardenClient() client.responses["/admin/users"] = DummyResponse(200, "", json_data=[{"email": "bob@bstein.dev"}]) monkeypatch.setattr("ariadne.services.vaultwarden.settings", dummy_settings) monkeypatch.setattr("ariadne.services.vaultwarden.get_secret_value", lambda *args, **kwargs: "token") monkeypatch.setattr("ariadne.services.vaultwarden.httpx.Client", lambda *args, **kwargs: client) monkeypatch.setattr( "ariadne.services.vaultwarden.VaultwardenService._find_pod_ip", staticmethod(lambda *args, **kwargs: "127.0.0.1"), ) svc = VaultwardenService() result = svc.find_user_by_email("alice@bstein.dev") assert result.status == "missing" def test_vaultwarden_invite_handles_admin_exception(monkeypatch) -> None: dummy_settings = types.SimpleNamespace( vaultwarden_namespace="vaultwarden", vaultwarden_admin_secret_name="vaultwarden-admin", vaultwarden_admin_secret_key="ADMIN_TOKEN", vaultwarden_admin_rate_limit_backoff_sec=600, vaultwarden_admin_session_ttl_sec=900, vaultwarden_service_host="vaultwarden-service.vaultwarden.svc.cluster.local", vaultwarden_pod_label="app=vaultwarden", vaultwarden_pod_port=80, ) monkeypatch.setattr("ariadne.services.vaultwarden.settings", dummy_settings) monkeypatch.setattr( "ariadne.services.vaultwarden.VaultwardenService._find_pod_ip", staticmethod(lambda *args, **kwargs: (_ for _ in ()).throw(RuntimeError("boom"))), ) svc = VaultwardenService() monkeypatch.setattr( svc, "_admin_session", lambda *_args, **_kwargs: (_ for _ in ()).throw(RuntimeError("rate limited")), ) result = svc.invite_user("alice@bstein.dev") assert result.status == "rate_limited" def test_vaultwarden_invite_handles_bad_body(monkeypatch) -> None: dummy_settings = types.SimpleNamespace( vaultwarden_namespace="vaultwarden", vaultwarden_admin_secret_name="vaultwarden-admin", vaultwarden_admin_secret_key="ADMIN_TOKEN", vaultwarden_admin_rate_limit_backoff_sec=600, vaultwarden_admin_session_ttl_sec=900, vaultwarden_service_host="vaultwarden-service.vaultwarden.svc.cluster.local", vaultwarden_pod_label="app=vaultwarden", vaultwarden_pod_port=80, ) class BadTextResponse: def __init__(self, status_code=500): self.status_code = status_code def raise_for_status(self): return None @property def text(self): raise RuntimeError("boom") class BadTextClient(DummyVaultwardenClient): def post(self, path, json=None, data=None): self.calls.append((path, json, data)) return BadTextResponse(500) monkeypatch.setattr("ariadne.services.vaultwarden.settings", dummy_settings) monkeypatch.setattr("ariadne.services.vaultwarden.get_secret_value", lambda *args, **kwargs: "token") monkeypatch.setattr("ariadne.services.vaultwarden.httpx.Client", lambda *args, **kwargs: BadTextClient()) monkeypatch.setattr( "ariadne.services.vaultwarden.VaultwardenService._find_pod_ip", staticmethod(lambda *args, **kwargs: "127.0.0.1"), ) svc = VaultwardenService() result = svc.invite_user("alice@bstein.dev") assert result.status == "error" def test_vaultwarden_invite_handles_fallback_skip(monkeypatch) -> None: dummy_settings = types.SimpleNamespace( vaultwarden_namespace="vaultwarden", vaultwarden_admin_secret_name="vaultwarden-admin", vaultwarden_admin_secret_key="ADMIN_TOKEN", vaultwarden_admin_rate_limit_backoff_sec=600, vaultwarden_admin_session_ttl_sec=900, vaultwarden_service_host="vaultwarden-service.vaultwarden.svc.cluster.local", vaultwarden_pod_label="app=vaultwarden", vaultwarden_pod_port=80, ) monkeypatch.setattr("ariadne.services.vaultwarden.settings", dummy_settings) monkeypatch.setattr( "ariadne.services.vaultwarden.VaultwardenService._find_pod_ip", staticmethod(lambda *args, **kwargs: (_ for _ in ()).throw(RuntimeError("boom"))), ) svc = VaultwardenService() monkeypatch.setattr(svc, "_admin_session", lambda *_args, **_kwargs: (_ for _ in ()).throw(RuntimeError("nope"))) result = svc.invite_user("alice@bstein.dev") assert result.status == "error" def test_vaultwarden_find_pod_ip(monkeypatch) -> None: monkeypatch.setattr( "ariadne.services.vaultwarden.get_json", lambda *args, **kwargs: { "items": [ { "status": { "phase": "Running", "podIP": "10.0.0.1", "conditions": [{"type": "Ready", "status": "True"}], } } ] }, ) assert VaultwardenService._find_pod_ip("ns", "app=vaultwarden") == "10.0.0.1" def test_vaultwarden_find_pod_ip_skips_missing_ip(monkeypatch) -> None: monkeypatch.setattr( "ariadne.services.vaultwarden.get_json", lambda *args, **kwargs: { "items": [ {"status": {"phase": "Running", "podIP": ""}}, {"status": {"phase": "Running", "podIP": "10.0.0.2", "conditions": []}}, ] }, ) assert VaultwardenService._find_pod_ip("ns", "app=vaultwarden") == "10.0.0.2" def test_vaultwarden_find_pod_ip_conditions_default_ready(monkeypatch) -> None: monkeypatch.setattr( "ariadne.services.vaultwarden.get_json", lambda *args, **kwargs: { "items": [ {"status": {"phase": "Running", "podIP": "10.0.0.3", "conditions": ["bad"]}}, ] }, ) assert VaultwardenService._find_pod_ip("ns", "app=vaultwarden") == "10.0.0.3" def test_vaultwarden_find_pod_ip_no_pods(monkeypatch) -> None: monkeypatch.setattr("ariadne.services.vaultwarden.get_json", lambda *args, **kwargs: {"items": []}) with pytest.raises(RuntimeError): VaultwardenService._find_pod_ip("ns", "app=vaultwarden") def test_vaultwarden_find_pod_ip_missing_ip(monkeypatch) -> None: monkeypatch.setattr( "ariadne.services.vaultwarden.get_json", lambda *args, **kwargs: { "items": [ {"status": {"phase": "Pending", "conditions": ["bad"]}}, ] }, ) with pytest.raises(RuntimeError): VaultwardenService._find_pod_ip("ns", "app=vaultwarden") def test_vaultwarden_admin_session_rate_limit(monkeypatch) -> None: dummy_settings = types.SimpleNamespace( vaultwarden_namespace="vaultwarden", vaultwarden_admin_secret_name="vaultwarden-admin", vaultwarden_admin_secret_key="ADMIN_TOKEN", vaultwarden_admin_rate_limit_backoff_sec=1, vaultwarden_admin_session_ttl_sec=900, vaultwarden_service_host="vaultwarden-service.vaultwarden.svc.cluster.local", vaultwarden_pod_label="app=vaultwarden", vaultwarden_pod_port=80, ) client = DummyVaultwardenClient() client.responses["/admin"] = DummyResponse(429, "") monkeypatch.setattr("ariadne.services.vaultwarden.settings", dummy_settings) monkeypatch.setattr("ariadne.services.vaultwarden.get_secret_value", lambda *args, **kwargs: "token") monkeypatch.setattr("ariadne.services.vaultwarden.httpx.Client", lambda *args, **kwargs: client) svc = VaultwardenService() with pytest.raises(RuntimeError): svc._admin_session("http://vaultwarden") def test_vaultwarden_admin_session_reuses_client() -> None: svc = VaultwardenService() svc._admin_client = DummyVaultwardenClient() svc._admin_session_expires_at = time.time() + 60 svc._admin_session_base_url = "http://vaultwarden" client = svc._admin_session("http://vaultwarden") assert client is svc._admin_client def test_vaultwarden_admin_session_rate_limited_until() -> None: svc = VaultwardenService() svc._rate_limited_until = time.time() + 60 with pytest.raises(RuntimeError): svc._admin_session("http://vaultwarden") def test_vaultwarden_admin_session_closes_existing(monkeypatch) -> None: dummy_settings = types.SimpleNamespace( vaultwarden_namespace="vaultwarden", vaultwarden_admin_secret_name="vaultwarden-admin", vaultwarden_admin_secret_key="ADMIN_TOKEN", vaultwarden_admin_rate_limit_backoff_sec=600, vaultwarden_admin_session_ttl_sec=900, vaultwarden_service_host="vaultwarden-service.vaultwarden.svc.cluster.local", vaultwarden_pod_label="app=vaultwarden", vaultwarden_pod_port=80, ) class CloseFail: def close(self): raise RuntimeError("boom") monkeypatch.setattr("ariadne.services.vaultwarden.settings", dummy_settings) monkeypatch.setattr("ariadne.services.vaultwarden.get_secret_value", lambda *args, **kwargs: "token") monkeypatch.setattr("ariadne.services.vaultwarden.httpx.Client", lambda *args, **kwargs: DummyVaultwardenClient()) svc = VaultwardenService() svc._admin_client = CloseFail() svc._admin_session_expires_at = time.time() - 10 svc._admin_session_base_url = "http://old" assert svc._admin_session("http://vaultwarden") is not None