feat: add POST /api/federation/generate-key endpoint
This commit is contained in:
@@ -962,6 +962,26 @@ async def federation_sessions(request: Request) -> list[dict]:
|
||||
return all_sessions
|
||||
|
||||
|
||||
@app.post("/api/federation/generate-key")
|
||||
async def federation_generate_key() -> dict:
|
||||
"""Generate a new federation key, write it to FEDERATION_KEY_PATH, and return it.
|
||||
|
||||
Creates the parent directory (mode 0700) if it doesn't exist.
|
||||
Writes the key with a trailing newline and sets file mode to 0600.
|
||||
|
||||
Returns {key: str, path: str}.
|
||||
"""
|
||||
import secrets as _secrets
|
||||
from muxplex.settings import FEDERATION_KEY_PATH
|
||||
|
||||
key = _secrets.token_urlsafe(32)
|
||||
path = FEDERATION_KEY_PATH
|
||||
path.parent.mkdir(mode=0o700, parents=True, exist_ok=True)
|
||||
path.write_text(key + "\n")
|
||||
path.chmod(0o600)
|
||||
return {"key": key, "path": str(path)}
|
||||
|
||||
|
||||
@app.post("/api/federation/{remote_id}/connect/{session_name}")
|
||||
async def federation_connect(
|
||||
remote_id: str, session_name: str, request: Request
|
||||
|
||||
@@ -1785,6 +1785,49 @@ def test_federation_connect_returns_503_when_remote_unreachable(
|
||||
assert response.status_code == 503
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# POST /api/federation/generate-key (task-13)
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
|
||||
def test_federation_generate_key_creates_file(client, tmp_path, monkeypatch):
|
||||
"""POST /api/federation/generate-key creates a key file and returns the key in the response.
|
||||
|
||||
- Endpoint returns 200 with {"key": <str>, "path": <str>}
|
||||
- Returned key length > 20
|
||||
- The key file is created at the redirected FEDERATION_KEY_PATH
|
||||
- The file contents match the returned key (with trailing newline stripped)
|
||||
"""
|
||||
import muxplex.settings as settings_mod
|
||||
|
||||
key_path = tmp_path / "federation_key"
|
||||
monkeypatch.setattr(settings_mod, "FEDERATION_KEY_PATH", key_path)
|
||||
|
||||
response = client.post("/api/federation/generate-key")
|
||||
assert response.status_code == 200, (
|
||||
f"Expected 200, got {response.status_code}: {response.text}"
|
||||
)
|
||||
|
||||
data = response.json()
|
||||
assert "key" in data, f"Response must include 'key' field, got: {data}"
|
||||
assert "path" in data, f"Response must include 'path' field, got: {data}"
|
||||
|
||||
returned_key = data["key"]
|
||||
assert len(returned_key) > 20, (
|
||||
f"Key must be longer than 20 chars, got length {len(returned_key)}"
|
||||
)
|
||||
|
||||
# Verify file was created
|
||||
assert key_path.exists(), f"Key file must be created at {key_path}"
|
||||
|
||||
# Verify file contents match returned key
|
||||
file_contents = key_path.read_text().strip()
|
||||
assert file_contents == returned_key, (
|
||||
f"File contents must match returned key. "
|
||||
f"File: {file_contents!r}, key: {returned_key!r}"
|
||||
)
|
||||
|
||||
|
||||
def test_federation_connect_returns_502_when_remote_returns_error_status(
|
||||
client, monkeypatch, tmp_path
|
||||
):
|
||||
|
||||
Reference in New Issue
Block a user