dab47f0cb3
- 添加 .env.local 支持,app.sh 和 dev-migrate.sh 自动覆盖 - Docker Compose 使用 profiles 区分 dev/prod 环境 - 改进认证 dev session 判断逻辑,使用 test account 配置 - 修复 CoinPackageCard 重复代码问题 - 清理 opencode 配置,移除敏感信息 - 新增 infra/docker/README.md 文档 - 修复 ruff/pyright/flutter lint 错误 - 更新测试用例移除已删除的 country 字段
68 lines
2.7 KiB
Python
68 lines
2.7 KiB
Python
from __future__ import annotations
|
|
|
|
import base64
|
|
import json
|
|
|
|
from v1.payments.apple_verifier import (
|
|
AppleJwsVerifier,
|
|
VerificationError,
|
|
)
|
|
|
|
|
|
def _make_jws_parts(header: dict[str, object], payload: dict[str, object]) -> tuple[str, str]:
|
|
h = base64.urlsafe_b64encode(json.dumps(header).encode()).rstrip(b"=").decode()
|
|
p = base64.urlsafe_b64encode(json.dumps(payload).encode()).rstrip(b"=").decode()
|
|
return h, p
|
|
|
|
|
|
class TestAppleJwsVerifierInvalidInput:
|
|
def test_invalid_header_returns_error(self) -> None:
|
|
verifier = AppleJwsVerifier()
|
|
result = verifier.verify_signed_transaction(
|
|
"not-a-jws",
|
|
expected_bundle_id="com.meeyao.qianwen",
|
|
expected_product_id="com.meeyao.qianwen.starter_pack",
|
|
)
|
|
assert isinstance(result, VerificationError)
|
|
assert result.code == "PAYMENT_TRANSACTION_INVALID"
|
|
assert "decode" in result.detail.lower() or "header" in result.detail.lower()
|
|
|
|
def test_missing_x5c_returns_error(self) -> None:
|
|
verifier = AppleJwsVerifier()
|
|
h, p = _make_jws_parts({"alg": "ES256"}, {"bundleId": "test"})
|
|
result = verifier.verify_signed_transaction(
|
|
f"{h}.{p}.fake",
|
|
expected_bundle_id="com.meeyao.qianwen",
|
|
expected_product_id="com.meeyao.qianwen.starter_pack",
|
|
)
|
|
assert isinstance(result, VerificationError)
|
|
assert "x5c" in result.detail
|
|
|
|
def test_short_x5c_returns_error(self) -> None:
|
|
verifier = AppleJwsVerifier()
|
|
h, p = _make_jws_parts({"alg": "ES256", "x5c": ["one"]}, {"bundleId": "test"})
|
|
result = verifier.verify_signed_transaction(
|
|
f"{h}.{p}.fake",
|
|
expected_bundle_id="com.meeyao.qianwen",
|
|
expected_product_id="com.meeyao.qianwen.starter_pack",
|
|
)
|
|
assert isinstance(result, VerificationError)
|
|
assert "x5c" in result.detail
|
|
|
|
def test_issuer_subject_mismatch_returns_error(self) -> None:
|
|
verifier = AppleJwsVerifier()
|
|
leaf_cert_b64 = base64.b64encode(b"fake_leaf_cert").decode()
|
|
intermediate_cert_b64 = base64.b64encode(b"fake_intermediate_cert").decode()
|
|
root_cert_b64 = base64.b64encode(b"fake_root_cert").decode()
|
|
h, p = _make_jws_parts(
|
|
{"alg": "ES256", "x5c": [leaf_cert_b64, intermediate_cert_b64, root_cert_b64]},
|
|
{"bundleId": "com.meeyao.qianwen"},
|
|
)
|
|
result = verifier.verify_signed_transaction(
|
|
f"{h}.{p}.fake",
|
|
expected_bundle_id="com.meeyao.qianwen",
|
|
expected_product_id="com.meeyao.qianwen.starter_pack",
|
|
)
|
|
assert isinstance(result, VerificationError)
|
|
assert "fingerprint" in result.detail or "issuer" in result.detail or "subject" in result.detail
|