356 lines
15 KiB
Python
356 lines
15 KiB
Python
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
|