fix: align external pool POST and stats responses with external API contract
This commit is contained in:
1 parent
0c0dc40750
commit
6d95c74272
4 files changed
+60
-25
No files matched your search
+1
-1
@@ -134,7 +134,7 @@ def create_app(*, autostart_scheduler: Optional[bool] = None):
|
||||
app.register_blueprint(system.create_blueprint())
|
||||
app.register_blueprint(audit.create_blueprint())
|
||||
app.register_blueprint(pool.create_blueprint())
|
||||
app.register_blueprint(external_pool.create_blueprint())
|
||||
app.register_blueprint(external_pool.create_blueprint(csrf_exempt=csrf_exempt))
|
||||
|
||||
# 打印初始化信息
|
||||
print("=" * 60)
|
||||
|
||||
@@ -272,10 +272,9 @@ def get_stats(conn: sqlite3.Connection) -> dict:
|
||||
"cooldown": 0,
|
||||
"frozen": 0,
|
||||
"retired": 0,
|
||||
"not_in_pool": 0,
|
||||
}
|
||||
for row in rows:
|
||||
key = row["pool_status"] if row["pool_status"] is not None else "not_in_pool"
|
||||
key = row["pool_status"]
|
||||
if key in pool_counts:
|
||||
pool_counts[key] = row["cnt"]
|
||||
|
||||
|
||||
@@ -1,30 +1,38 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Callable, Optional
|
||||
|
||||
from flask import Blueprint
|
||||
|
||||
from outlook_web.controllers import external_pool as external_pool_controller
|
||||
|
||||
|
||||
def create_blueprint() -> Blueprint:
|
||||
def create_blueprint(csrf_exempt: Optional[Callable] = None) -> Blueprint:
|
||||
bp = Blueprint("external_pool", __name__)
|
||||
bp.add_url_rule(
|
||||
"/api/external/pool/claim-random",
|
||||
view_func=external_pool_controller.api_external_pool_claim_random,
|
||||
methods=["POST"],
|
||||
)
|
||||
bp.add_url_rule(
|
||||
"/api/external/pool/claim-release",
|
||||
view_func=external_pool_controller.api_external_pool_claim_release,
|
||||
methods=["POST"],
|
||||
)
|
||||
bp.add_url_rule(
|
||||
"/api/external/pool/claim-complete",
|
||||
view_func=external_pool_controller.api_external_pool_claim_complete,
|
||||
methods=["POST"],
|
||||
)
|
||||
bp.add_url_rule(
|
||||
"/api/external/pool/stats",
|
||||
view_func=external_pool_controller.api_external_pool_stats,
|
||||
methods=["GET"],
|
||||
)
|
||||
handlers = [
|
||||
(
|
||||
"/api/external/pool/claim-random",
|
||||
external_pool_controller.api_external_pool_claim_random,
|
||||
["POST"],
|
||||
),
|
||||
(
|
||||
"/api/external/pool/claim-release",
|
||||
external_pool_controller.api_external_pool_claim_release,
|
||||
["POST"],
|
||||
),
|
||||
(
|
||||
"/api/external/pool/claim-complete",
|
||||
external_pool_controller.api_external_pool_claim_complete,
|
||||
["POST"],
|
||||
),
|
||||
(
|
||||
"/api/external/pool/stats",
|
||||
external_pool_controller.api_external_pool_stats,
|
||||
["GET"],
|
||||
),
|
||||
]
|
||||
|
||||
for path, handler, methods in handlers:
|
||||
view_func = csrf_exempt(handler) if csrf_exempt else handler
|
||||
bp.add_url_rule(path, view_func=view_func, methods=methods)
|
||||
return bp
|
||||
@@ -161,6 +161,30 @@ class ExternalPoolApiTests(unittest.TestCase):
|
||||
self.assertIn("claim_token", payload)
|
||||
self.assertIn("lease_expires_at", payload)
|
||||
|
||||
def test_external_pool_post_does_not_require_csrf(self):
|
||||
client = self.app.test_client()
|
||||
self._set_external_api_key("abc123")
|
||||
with self.app.app_context():
|
||||
from outlook_web.repositories import settings as settings_repo
|
||||
|
||||
settings_repo.set_setting("pool_external_enabled", "true")
|
||||
self._insert_pool_account(provider="outlook")
|
||||
|
||||
resp = client.post(
|
||||
"/api/external/pool/claim-random",
|
||||
headers=self._auth_headers(),
|
||||
json={
|
||||
"caller_id": "csrf-free-worker",
|
||||
"task_id": "csrf-free-task",
|
||||
"provider": "outlook",
|
||||
},
|
||||
)
|
||||
|
||||
self.assertEqual(resp.status_code, 200)
|
||||
data = resp.get_json()
|
||||
self.assertTrue(data.get("success"))
|
||||
self.assertEqual(data.get("code"), "OK")
|
||||
|
||||
def test_external_pool_claim_release_caller_mismatch(self):
|
||||
client = self.app.test_client()
|
||||
self._set_external_api_key("abc123")
|
||||
@@ -254,7 +278,11 @@ class ExternalPoolApiTests(unittest.TestCase):
|
||||
data = resp.get_json()
|
||||
self.assertTrue(data.get("success"))
|
||||
self.assertEqual(data.get("code"), "OK")
|
||||
self.assertIn("pool_counts", data.get("data", {}))
|
||||
pool_counts = data.get("data", {}).get("pool_counts", {})
|
||||
self.assertEqual(
|
||||
set(pool_counts.keys()),
|
||||
{"available", "claimed", "used", "cooldown", "frozen", "retired"},
|
||||
)
|
||||
|
||||
def test_external_pool_stats_returns_feature_disabled_when_switch_off(self):
|
||||
client = self.app.test_client()
|
||||
|
||||
Reference in new issue
Block a user