Build reusable bot framework
Some checks failed
CI / test (push) Has been cancelled
CI / compose-smoke (push) Has been cancelled

This commit is contained in:
Chelsea Lee
2026-07-19 21:53:24 -05:00
parent 7ecc1107b2
commit fbdf33e894
66 changed files with 8428 additions and 0 deletions

View File

@@ -0,0 +1,264 @@
"""Flask API integration tests for authentication and route boundaries."""
import uuid
SERVICE_KEY = "integration-service-key-0123456789abcdef"
ALLOWED_DISCORD_ID = "integration-discord-user"
def _bearer(token):
return {"Authorization": f"Bearer {token}"}
def test_health_and_error_routes(client):
assert client.get("/health/live").get_json() == {"status": "ok"}
assert client.get("/health/ready").get_json() == {"status": "ready"}
assert client.get("/health").get_json() == {"status": "ready"}
missing = client.get("/api/route-that-does-not-exist")
assert missing.status_code == 404
assert missing.get_json() == {"error": "not found"}
wrongMethod = client.get("/api/register")
assert wrongMethod.status_code == 405
assert wrongMethod.get_json() == {"error": "method not allowed"}
invalidJson = client.post(
"/api/register", data="[]", content_type="application/json"
)
assert invalidJson.status_code == 400
assert invalidJson.get_json() == {"error": "JSON object required"}
def test_password_registration_keeps_values_parameterized_and_protected(client):
from core import postgres
injectedUsername = "alice'; DROP TABLE users; --"
injectedUUID = str(uuid.uuid4())
response = client.post(
"/api/register",
json={
"username": injectedUsername,
"password": "long-enough-password",
"timezone": "America/Chicago",
"id": injectedUUID,
"password_hashed": "attacker-controlled",
"created_at": "1900-01-01T00:00:00Z",
"unexpected_admin": True,
},
)
assert response.status_code == 201, response.get_json()
assert postgres.table_exists("users")
record = postgres.select_one("users", {"username": injectedUsername})
assert record is not None
assert str(record["id"]) != injectedUUID
assert bytes(record["password_hashed"]) != b"attacker-controlled"
assert record["timezone"] == "America/Chicago"
assert record["created_at"].year > 1900
login = client.post(
"/api/login",
json={"username": injectedUsername, "password": "long-enough-password"},
)
assert login.status_code == 200
assert login.get_json()["token"]
def test_jwt_user_key_creation_authentication_and_revocation(
client, createAuthenticatedUser
):
from core import postgres
user = createAuthenticatedUser("api-key-owner")
jwtHeaders = _bearer(user["token"])
profile = client.get(f"/api/user/{user['user_uuid']}", headers=jwtHeaders)
assert profile.status_code == 200
assert profile.get_json()["username"] == user["username"]
assert "password_hashed" not in profile.get_json()
update = client.put(
f"/api/user/{user['user_uuid']}",
headers=jwtHeaders,
json={"timezone": "America/Chicago", "username": "cannot-change"},
)
assert update.status_code == 200
assert client.get(
"/api/user/me/timezone", headers=jwtHeaders
).get_json() == {"timezone": "America/Chicago"}
created = client.post(
"/api/keys", headers=jwtHeaders, json={"name": "integration key"}
)
assert created.status_code == 201, created.get_json()
keyRecord = created.get_json()
secret = keyRecord["key"]
assert secret.startswith("llmbot_user_")
assert "key_hash" not in keyRecord
storedKey = postgres.select_one("api_keys", {"id": keyRecord["id"]})
assert storedKey["key_hash"] != secret
assert secret not in {str(value) for value in storedKey.values()}
listed = client.get("/api/keys", headers=jwtHeaders)
assert listed.status_code == 200
listedKey = listed.get_json()["keys"][0]
assert listedKey["id"] == keyRecord["id"]
assert "key" not in listedKey
assert "key_hash" not in listedKey
apiKeyHeaders = _bearer(secret)
timezone = client.get("/api/user/me/timezone", headers=apiKeyHeaders)
assert timezone.status_code == 200
assert timezone.get_json() == {"timezone": "America/Chicago"}
assert postgres.select_one("api_keys", {"id": keyRecord["id"]})[
"last_used_at"
] is not None
cannotManageKeys = client.post(
"/api/keys", headers=apiKeyHeaders, json={"name": "nested key"}
)
assert cannotManageKeys.status_code == 401
revoked = client.delete(f"/api/keys/{keyRecord['id']}", headers=jwtHeaders)
assert revoked.status_code == 200
assert postgres.select_one("api_keys", {"id": keyRecord["id"]})[
"revoked_at"
] is not None
assert client.get("/api/user/me/timezone", headers=apiKeyHeaders).status_code == 401
def test_discord_allowlist_and_service_key_boundaries(client, createAuthenticatedUser):
serviceHeaders = _bearer(SERVICE_KEY)
assert client.post(
"/api/auth/discord/session",
json={"discord_id": ALLOWED_DISCORD_ID},
).status_code == 401
assert client.post(
"/api/auth/discord/session",
headers=_bearer("not-the-configured-service-key-0123456789"),
json={"discord_id": ALLOWED_DISCORD_ID},
).status_code == 401
denied = client.post(
"/api/auth/discord/session",
headers=serviceHeaders,
json={"discord_id": "not-allowlisted", "display_name": "No Access"},
)
assert denied.status_code == 403
accepted = client.post(
"/api/auth/discord/session",
headers=serviceHeaders,
json={"discord_id": ALLOWED_DISCORD_ID, "display_name": "First Name"},
)
assert accepted.status_code == 200, accepted.get_json()
discordSession = accepted.get_json()
assert discordSession["timezone"] == "UTC"
assert discordSession["token"]
repeated = client.post(
"/api/auth/discord/session",
headers=serviceHeaders,
json={"discord_id": ALLOWED_DISCORD_ID, "display_name": "New Name"},
)
assert repeated.status_code == 200
assert repeated.get_json()["user_uuid"] == discordSession["user_uuid"]
profile = client.get(
f"/api/user/{discordSession['user_uuid']}",
headers=_bearer(discordSession["token"]),
)
assert profile.status_code == 200
assert profile.get_json()["username"] is None
passwordUser = createAuthenticatedUser("service-boundary-user")
assert client.post(
"/api/auth/discord/session",
headers=_bearer(passwordUser["token"]),
json={"discord_id": ALLOWED_DISCORD_ID},
).status_code == 401
assert client.get(
"/api/user/me/timezone", headers=serviceHeaders
).status_code == 401
def test_service_outbox_claim_retry_and_delivery_routes(client):
from core import outbox, postgres
serviceHeaders = _bearer(SERVICE_KEY)
session = client.post(
"/api/auth/discord/session",
headers=serviceHeaders,
json={"discord_id": ALLOWED_DISCORD_ID, "display_name": "Recipient"},
).get_json()
queued = outbox.enqueue_message(
session["user_uuid"],
"discord_dm",
{"content": "integration delivery"},
idempotency_key=f"api-outbox-{uuid.uuid4()}",
)
claimed = client.post(
"/api/internal/outbox/claim",
headers=serviceHeaders,
json={"worker_id": "api-worker-one", "limit": 1},
)
assert claimed.status_code == 200
message = claimed.get_json()["messages"][0]
assert message["id"] == str(queued["id"])
assert message["provider_user_id"] == ALLOWED_DISCORD_ID
assert message["content"] == "integration delivery"
assert message["worker_id"] == "api-worker-one"
missingWorker = client.post(
f"/api/internal/outbox/{message['id']}/result",
headers=serviceHeaders,
json={"status": "sent"},
)
assert missingWorker.status_code == 409
wrongWorker = client.post(
f"/api/internal/outbox/{message['id']}/result",
headers=serviceHeaders,
json={"status": "sent", "worker_id": "not-the-lease-owner"},
)
assert wrongWorker.status_code == 409
stillLeased = outbox.get_message(message["id"])
assert stillLeased["status"] == "delivering"
assert stillLeased["leased_by"] == "api-worker-one"
assert stillLeased["delivered_at"] is None
retried = client.post(
f"/api/internal/outbox/{message['id']}/result",
headers=serviceHeaders,
json={
"status": "retry",
"error": "temporary failure",
"worker_id": "api-worker-one",
},
)
assert retried.status_code == 200
assert retried.get_json()["message"]["status"] == "pending"
postgres.execute(
"UPDATE outbound_messages SET available_at = NOW() WHERE id = %(id)s",
{"id": message["id"]},
)
claimedAgain = client.post(
"/api/internal/outbox/claim",
headers=serviceHeaders,
json={"worker_id": "api-worker-two", "limit": 1},
)
assert claimedAgain.status_code == 200
assert claimedAgain.get_json()["messages"][0]["attempts"] == 2
delivered = client.post(
f"/api/internal/outbox/{message['id']}/result",
headers=serviceHeaders,
json={"status": "sent", "worker_id": "api-worker-two"},
)
assert delivered.status_code == 200
assert delivered.get_json()["message"]["status"] == "delivered"