fix(site): report unauthenticated userdata refresh failures

This commit is contained in:
jxxghp
2026-09-12 21:11:14 +08:00
parent ee4dcd9d89
commit 4d4327e25a
6 changed files with 69 additions and 3 deletions

View File

@@ -488,7 +488,14 @@ def refresh_userdata(
return _SchemaResponse(
success=False, message="站点不支持索引或未通过用户认证!"
)
user_data = SiteChain().refresh_userdata(site=indexer) or {}
user_data = SiteChain().refresh_userdata(site=indexer)
if not user_data or not user_data.userid:
message = (
user_data.err_msg
if user_data and user_data.err_msg
else "未获取到站点用户数据,请检查 Cookie 是否有效!"
)
return _SchemaResponse(success=False, message=message)
return _SchemaResponse(success=True, data=user_data)

View File

@@ -212,7 +212,7 @@ class SiteChain(InteractionChainMixin, ChainBase):
:return: 用户数据
"""
userdata: SiteUserData = self.run_module("refresh_userdata", site=site)
if userdata and site:
if userdata and userdata.userid and site:
domain = site_rules.extract_domain(
str(site.get("domain") or site.get("url") or "")
)
@@ -302,7 +302,7 @@ class SiteChain(InteractionChainMixin, ChainBase):
},
)
userdata = self.refresh_userdata(site)
if userdata:
if userdata and userdata.userid:
any_site_updated = True
result[site.get("name")] = userdata
if progress_callback:

View File

@@ -799,6 +799,8 @@ class IndexerModule(_ModuleBase):
site_obj = alt_obj
logger.info(f"站点 {site.get('name')} 改用 {site_schema.schema.value} 模型解析成功")
break
if not site_obj.userid and not site.get("public"):
site_obj.err_msg = site_obj.err_msg or "未获取到站点用户信息,请检查 Cookie 是否有效"
return SiteUserData(
domain=site_rules.extract_domain(site.get("url")),
userid=site_obj.userid,

View File

@@ -59,6 +59,7 @@ def test_refresh_userdata_fallback_only_uses_common_schemas(monkeypatch):
})
assert result.userid is None
assert result.err_msg == "未获取到站点用户信息,请检查 Cookie 是否有效"
assert calls == [
SiteSchema.NexusPhp.value,
SiteSchema.Gazelle.value,

View File

@@ -1,9 +1,12 @@
"""站点连通性测试链路的数据库回归测试。"""
from unittest.mock import Mock
from app.application.site.contract import SiteSnapshot
from app.chain.site import SiteChain
from app.db.models.site import Site
from app.db.models.sitestatistic import SiteStatistic
from app.schemas.site import SiteUserData
def test_site_connectivity_records_result_without_injected_session(db, monkeypatch):
@@ -59,3 +62,27 @@ def test_resource_login_path_uses_generic_connectivity_test(db, monkeypatch):
assert (status, message) == (True, "连接成功")
assert observed[0].url == "https://resource-path.test/index.php"
def test_failed_userdata_is_not_persisted_as_a_successful_refresh(monkeypatch):
"""解析器未取得用户身份时不得写入空数据或发送刷新成功事件。"""
chain = object.__new__(SiteChain)
chain.site_repository = Mock()
chain.eventmanager = Mock()
failed_data = SiteUserData(
domain="www.musopia.vip",
err_msg="未检测到已登陆请检查cookies是否过期",
)
monkeypatch.setattr(
SiteChain,
"run_module",
lambda _self, _method, **_kwargs: failed_data,
)
result = chain.refresh_userdata(
site={"id": 1, "domain": "www.musopia.vip", "name": "音乐乌托邦"}
)
assert result is failed_data
chain.site_repository.update_userdata.assert_not_called()
chain.eventmanager.send_event.assert_not_called()

View File

@@ -4,6 +4,7 @@ from unittest.mock import AsyncMock, Mock, patch
from app import schemas
from app.api.endpoints import site as site_endpoint
from app.schemas.site import SiteUserData
def test_update_cookie_by_body_uses_request_body():
@@ -85,3 +86,31 @@ def test_set_cookie_by_body_persists_only_browser_cookie_fields():
cookie="sid=browser",
ua="Browser UA",
)
def test_refresh_userdata_reports_parser_failure_instead_of_empty_success():
"""用户解析未拿到身份时应返回业务失败,不能伪造空数据成功。"""
fake_site = SimpleNamespace(id=1, domain="www.musopia.vip")
fake_chain = Mock()
fake_chain.refresh_userdata.return_value = SiteUserData(
domain="www.musopia.vip",
err_msg="未检测到已登陆请检查cookies是否过期",
)
with patch.object(site_endpoint, "SiteChain", return_value=fake_chain), patch.object(
site_endpoint,
"SitesHelper",
) as sites_helper:
sites_helper.return_value.get_indexer.return_value = {
"name": "音乐乌托邦",
"domain": "www.musopia.vip",
}
response = site_endpoint.refresh_userdata(
site_id=1,
query=SimpleNamespace(get_sync=lambda _site_id: fake_site),
_=Mock(),
)
assert response.success is False
assert response.message == "未检测到已登陆请检查cookies是否过期"
assert response.data is None