fix: validate platform keys at the gate and stop auto-register
All checks were successful
技能自动化发布 / release (push) Successful in 6s

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-08-22 15:40:30 +08:00
parent 9a20e7fc69
commit 3f1cde1f99
15 changed files with 543 additions and 214 deletions

View File

@@ -56,7 +56,7 @@ class TestDynamicPlatformResolution:
result = resolve_platform_key_dynamic("江厂 空格", conn=clean_db)
assert not result.ok
assert result.error_code == "INVALID_PLATFORM_KEY"
assert result.error_code == "INVALID_PLATFORM"
def test_empty_platform(self, clean_db):
from util.platforms import resolve_platform_key_dynamic
@@ -97,6 +97,43 @@ class TestPlatformEnsure:
assert payload["platform_key"] == "jiangchang"
assert payload["action"] in ("created", "updated")
def test_ensure_requires_display_name(self, clean_db, capsys):
from service.account_service import cmd_platform_ensure
rc = cmd_platform_ensure(key="hao_kan", display_name="")
assert rc == 1
payload = json.loads(capsys.readouterr().out.strip())
assert payload["error"]["code"] == "ERROR:INVALID_PLATFORM_DISPLAY_NAME"
count = clean_db.execute(
"SELECT COUNT(*) FROM platforms WHERE platform_key = 'hao_kan'"
).fetchone()[0]
assert count == 0
def test_ensure_rejects_mixed_case_key(self, clean_db, capsys):
from service.account_service import cmd_platform_ensure
rc = cmd_platform_ensure(key="HaoKan", display_name="好看")
assert rc == 1
payload = json.loads(capsys.readouterr().out.strip())
assert payload["error"]["code"] == "ERROR:INVALID_PLATFORM_KEY"
count = clean_db.execute(
"SELECT COUNT(*) FROM platforms WHERE lower(platform_key) = 'haokan'"
).fetchone()[0]
assert count == 0
def test_ensure_rejects_alias_owned_by_another_platform(self, clean_db, capsys):
from service.account_service import cmd_platform_ensure
rc = cmd_platform_ensure(key="hao_kan", display_name="抖音")
assert rc == 1
payload = json.loads(capsys.readouterr().out.strip())
assert payload["error"]["code"] == "ERROR:PLATFORM_ALIAS_CONFLICT"
assert "douyin" in payload["error"]["message"]
count = clean_db.execute(
"SELECT COUNT(*) FROM platforms WHERE platform_key = 'hao_kan'"
).fetchone()[0]
assert count == 0
class TestCustomPlatformAccounts:
def test_add_web_after_ensure(self, clean_db):
@@ -161,7 +198,8 @@ class TestCustomPlatformAccounts:
payload = json.loads(out)
assert payload["success"] is False
assert payload["error"]["code"] == "ERROR:PLATFORM_NOT_REGISTERED"
assert "--platform-display-name" in payload["error"]["message"]
assert "platform ensure" in payload["error"]["message"]
assert "--platform-display-name" not in payload["error"]["message"]
def test_add_web_unregistered_returns_structured_error(self, clean_db, capsys):
from service.account_service import cmd_account_add_web
@@ -255,7 +293,7 @@ JIANGCHANG_META_KWARGS = dict(
)
class TestAutoRegisterFromCallerMeta:
class TestCallerMetaDoesNotAutoRegister:
def _meta(self):
from service.account_service import PlatformCallerMeta
@@ -293,9 +331,10 @@ class TestAutoRegisterFromCallerMeta:
payload = json.loads(out)
assert payload["success"] is False
assert payload["error"]["code"] == "ERROR:PLATFORM_NOT_REGISTERED"
assert "--platform-display-name" in payload["error"]["message"]
assert "platform ensure" in payload["error"]["message"]
assert "--platform-display-name" not in payload["error"]["message"]
def test_pick_web_unregistered_with_meta_auto_registers(self, clean_db, capsys):
def test_pick_web_unregistered_with_meta_does_not_insert(self, clean_db, capsys):
from service.account_service import cmd_account_pick_web, PlatformCallerMeta
from util.platforms import resolve_platform_key_dynamic
@@ -310,28 +349,33 @@ class TestAutoRegisterFromCallerMeta:
out = capsys.readouterr().out.strip()
payload = json.loads(out)
assert payload["success"] is False
assert payload["error"]["code"] == "ERROR:NO_ACCOUNT"
assert payload["error"]["code"] == "ERROR:PLATFORM_NOT_REGISTERED"
assert "已拒绝写入" in payload["error"]["message"]
result = resolve_platform_key_dynamic("auto_reg_plat", conn=clean_db)
assert result.ok
assert result.platform_key == "auto_reg_plat"
assert not result.ok
assert result.error_code == "PLATFORM_NOT_REGISTERED"
count = clean_db.execute(
"SELECT COUNT(*) FROM platforms WHERE platform_key = 'auto_reg_plat'"
).fetchone()[0]
assert count == 0
def test_add_web_unregistered_with_meta_auto_registers(self, clean_db):
def test_add_web_unregistered_with_meta_does_not_insert(self, clean_db, capsys):
from service.account_service import cmd_account_add_web, PlatformCallerMeta
from db.accounts_repo import find_accounts
meta = PlatformCallerMeta(
display_name="匠厂后台",
display_name="未登记测试",
url=JIANGCHANG_URL,
domain="jc2009.com",
domain="example.com",
auth_strategy="qr_code_manual",
aliases=["jiangchang"],
aliases=["unreg_meta_plat"],
)
cmd_account_add_web(
platform_input="jiangchang",
platform_input="unreg_meta_plat",
login_id="manual",
login_id_type="manual",
label="匠厂后台",
label="未登记",
tenant_id=None,
environment="production",
role="admin",
@@ -341,9 +385,15 @@ class TestAutoRegisterFromCallerMeta:
profile_dir_override=None,
platform_meta=meta,
)
accs = find_accounts(platform_key="jiangchang")
assert len(accs) == 1
assert accs[0]["url"] == JIANGCHANG_URL
out = capsys.readouterr().out.strip()
payload = json.loads(out.splitlines()[0])
assert payload["success"] is False
assert payload["error"]["code"] == "ERROR:PLATFORM_NOT_REGISTERED"
assert find_accounts(platform_key="unreg_meta_plat") == []
count = clean_db.execute(
"SELECT COUNT(*) FROM platforms WHERE platform_key = 'unreg_meta_plat'"
).fetchone()[0]
assert count == 0
def test_invalid_platform_key_no_register(self, clean_db, capsys):
from service.account_service import cmd_account_pick_web, PlatformCallerMeta
@@ -382,7 +432,7 @@ class TestAutoRegisterFromCallerMeta:
).fetchone()[0]
assert enabled == 0
def test_auto_register_idempotent(self, clean_db):
def test_caller_meta_does_not_insert_idempotent(self, clean_db, capsys):
from service.account_service import cmd_account_pick_web, PlatformCallerMeta
meta = PlatformCallerMeta(
@@ -395,4 +445,7 @@ class TestAutoRegisterFromCallerMeta:
count = clean_db.execute(
"SELECT COUNT(*) FROM platforms WHERE platform_key = 'idem_plat'"
).fetchone()[0]
assert count == 1
assert count == 0
out = capsys.readouterr().out.strip().splitlines()[-1]
payload = json.loads(out)
assert payload["error"]["code"] == "ERROR:PLATFORM_NOT_REGISTERED"

View File

@@ -74,3 +74,60 @@ class TestResolvePlatformKeyDynamicParsing:
clean_db.commit()
result = resolve_platform_key_dynamic("bad_alias", conn=clean_db)
assert result.platform_key == "bad_alias"
class TestPlatformKeyFormatAndAmbiguity:
def test_format_rejects_mixed_case(self):
from util.platforms import is_valid_platform_key_format
assert is_valid_platform_key_format("haokan") is True
assert is_valid_platform_key_format("HaoKan") is False
assert is_valid_platform_key_format("hao_kan") is True
def test_deepseek_display_resolves_to_key(self, clean_db):
from util.platforms import resolve_platform_key_dynamic
result = resolve_platform_key_dynamic("DeepSeek", conn=clean_db)
assert result.ok
assert result.platform_key == "deepseek"
def test_douyin_alias_still_unique(self, clean_db):
from util.platforms import resolve_platform_key_dynamic
result = resolve_platform_key_dynamic("抖音", conn=clean_db)
assert result.platform_key == "douyin"
def test_wechat_key_wins(self, clean_db):
from util.platforms import resolve_platform_key_dynamic
result = resolve_platform_key_dynamic("wechat", conn=clean_db)
assert result.ok
assert result.platform_key == "wechat"
def test_gongzhonghao_is_ambiguous(self, clean_db):
from util.platforms import resolve_platform_key_dynamic
result = resolve_platform_key_dynamic("公众号", conn=clean_db)
assert not result.ok
assert result.error_code == "AMBIGUOUS_PLATFORM"
assert "wechat" in (result.message or "")
assert "wechat_mp" in (result.message or "")
def test_unregistered_lookalike_key(self, clean_db):
from util.platforms import resolve_platform_key_dynamic
result = resolve_platform_key_dynamic("HaoKan", conn=clean_db)
assert result.error_code == "INVALID_PLATFORM_KEY"
assert "platform ensure" in (result.message or "")
def test_unregistered_valid_key_not_inserted(self, clean_db):
from util.platforms import resolve_platform_key_dynamic
result = resolve_platform_key_dynamic("hao_kan", conn=clean_db)
assert result.error_code == "PLATFORM_NOT_REGISTERED"
assert "已拒绝写入" in (result.message or "")
count = clean_db.execute(
"SELECT COUNT(*) FROM platforms WHERE platform_key = 'hao_kan'"
).fetchone()[0]
assert count == 0

View File

@@ -39,6 +39,18 @@ class TestRowOpenActions(unittest.TestCase):
self.assertFalse(reveal.get("replaces"))
self.assertFalse(open_browser.get("replaces"))
def test_platform_create_takes_over_host_add(self) -> None:
create = _by_id(_load_actions(), "platform-ensure")
self.assertEqual(create.get("replaces"), "create")
self.assertEqual(create.get("placements") or [], [])
self.assertEqual(create.get("label"), "新增平台")
self.assertEqual((create.get("bind") or {}).get("tables"), ["platforms"])
props = (create.get("inputSchema") or {}).get("properties") or {}
self.assertEqual(set(props), {"platform_key", "display_name", "default_url"})
args = (create.get("entrypoint") or {}).get("args") or []
self.assertIn("--key", args)
self.assertIn("--display-name", args)
def test_create_takes_over_host_add_without_row_duplicate(self) -> None:
create = _by_id(_load_actions(), "account-add-web")
self.assertEqual(create.get("replaces"), "create")