Files
kefu/deploy/patient-session-20260918/identity-compatibility/tests/test_zyt_auth.py
T
2026-09-21 10:34:06 +08:00

101 lines
4.8 KiB
Python

"""跨服务器桌面认证:只在路由缺失时兼容,拒绝结果不能降级。"""
import io
import json
import unittest
import urllib.error
from unittest import mock
import zyt_auth
class DesktopVerificationRegressionTest(unittest.TestCase):
def response(self, payload):
return io.BytesIO(json.dumps(payload).encode("utf-8"))
def session(self, **updates):
data = {"user_id": "admin:9", "terminal": 7, "status": "active",
"root": False, "role_ids": [2], "permissions": ["tcm.diagnosis/lists"]}
data.update(updates)
return {"code": 1, "data": data}
def verify(self):
return zyt_auth.verify_desktop_token("test-token", api_url="https://identity.example.test")
def missing(self, status=404):
return urllib.error.HTTPError("https://identity.example.test", status, "test", None, None)
def test_success_never_requests_ip_bound_web_profile(self):
with mock.patch.object(zyt_auth.urllib.request, "urlopen", side_effect=[
self.response(self.session(root=True, permissions=["*"])),
self.response({"code": -1, "msg": "ip地址发生变化,请重新登录"}),
]) as opened:
identity = self.verify()
self.assertEqual(opened.call_count, 1)
self.assertTrue(identity["root"])
self.assertEqual(identity["role_ids"], [2])
self.assertEqual(identity["permissions"], ["*"])
self.assertTrue(identity["permissions_known"])
def test_missing_permissions_do_not_trigger_profile_request(self):
payload = self.session()
del payload["data"]["permissions"]
with mock.patch.object(zyt_auth.urllib.request, "urlopen", return_value=self.response(payload)) as opened:
identity = self.verify()
self.assertEqual(opened.call_count, 1)
self.assertEqual(identity["permissions"], [])
self.assertFalse(identity["permissions_known"])
def test_empty_permissions_are_known(self):
with mock.patch.object(zyt_auth.urllib.request, "urlopen", return_value=self.response(self.session(permissions=[]))):
identity = self.verify()
self.assertTrue(identity["permissions_known"])
self.assertEqual(identity["permissions"], [])
def test_only_missing_routes_allow_legacy_verification(self):
for status in (404, 405):
with self.subTest(status=status), mock.patch.object(zyt_auth.urllib.request, "urlopen", side_effect=[
self.missing(status), self.response({"code": 1, "data": {
"user": {"id": 9, "disable": 0, "role_ids": [2]}, "permissions": []}}),
]) as opened:
identity = self.verify()
self.assertEqual(identity["user_id"], "admin:9")
self.assertEqual(opened.call_count, 2)
def test_http_rejections_do_not_fall_back(self):
for status in (401, 403, 500, 502):
with self.subTest(status=status), mock.patch.object(zyt_auth.urllib.request, "urlopen", side_effect=self.missing(status)) as opened:
with self.assertRaises(zyt_auth.ZytAuthError):
self.verify()
self.assertEqual(opened.call_count, 1)
def test_invalid_identity_cannot_be_accepted_through_web_fallback(self):
failures = [{"code": -1, "msg": "登录已失效"}, {"code": "bad"}, [],
{"code": 1, "data": []}, self.session(user_id=""),
self.session(terminal=1), self.session(terminal="bad"),
self.session(status="disabled")]
for payload in failures:
with self.subTest(payload=payload), mock.patch.object(zyt_auth.urllib.request, "urlopen", side_effect=[
self.response(payload), self.response({"code": 1, "data": {"user": {"id": 9}}}),
]) as opened:
with self.assertRaises(zyt_auth.ZytAuthError):
self.verify()
self.assertEqual(opened.call_count, 1)
def test_bad_json_and_network_failure_do_not_fall_back(self):
for result in (io.BytesIO(b"<html>error</html>"), urllib.error.URLError("offline")):
with self.subTest(result=result), mock.patch.object(zyt_auth.urllib.request, "urlopen", side_effect=[result]) as opened:
with self.assertRaises(zyt_auth.ZytAuthError):
self.verify()
self.assertEqual(opened.call_count, 1)
def test_legacy_ip_error_identifies_missing_server_deployment(self):
with mock.patch.object(zyt_auth.urllib.request, "urlopen", side_effect=[
self.missing(), self.response({"code": -1, "msg": "ip地址发生变化,请重新登录"}),
]):
with self.assertRaisesRegex(zyt_auth.ZytAuthError, "/adminapi/desktop/session"):
self.verify()
if __name__ == "__main__":
unittest.main()