verify-industry-existing-data-public.py 3.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. """Verify the read-only industry release and public static bytes; never collect upstream."""
  2. import argparse
  3. from concurrent.futures import ThreadPoolExecutor
  4. import hashlib
  5. import json
  6. from pathlib import Path
  7. from urllib.parse import urlsplit
  8. from urllib.request import Request, urlopen
  9. ROOT = Path(__file__).resolve().parents[1]
  10. def main():
  11. parser = argparse.ArgumentParser(description=__doc__)
  12. parser.add_argument('--base-url', default='https://kangshifu.fmode.cn')
  13. args = parser.parse_args()
  14. base = args.base_url.rstrip('/')
  15. url = urlsplit(base)
  16. assert url.scheme in ('http', 'https') and url.netloc and not url.username and not url.password and not url.query and not url.fragment, 'INVALID_PUBLIC_URL'
  17. release = json.loads((ROOT / 'RELEASE.json').read_bytes())
  18. manifest = json.loads((ROOT / 'deploy/industry-ui-files.json').read_bytes())
  19. generation = release['generation']
  20. def post(op, **fields):
  21. body = json.dumps(dict(op=op, generation=generation, **fields)).encode()
  22. request = Request(base + '/api/industry', data=body, headers={'Content-Type': 'application/json'}, method='POST')
  23. with urlopen(request, timeout=30) as response:
  24. data = json.load(response)
  25. assert data['ok'] and data['generation'] == generation and data['readOnly'] and data['databaseWrites'] == 0, op
  26. return data
  27. contract = post('contract')
  28. assert 'workshop' in contract['commands']
  29. primary = post('reviews', filters={'platform': 'jd', 'shopId': '1000084104'})
  30. assert (primary['products'], primary['reviewRows'], primary['uniqueReadableTexts']) == (165, 746, 701)
  31. policies = post('policies', policyQuery={'application': 'sodium-claims'})
  32. evidence = policies['applications']['reviewedEvidence']
  33. assert evidence['connected'] and (evidence['verifiedClauses'], evidence['pendingClauses'], evidence['originalDocuments']) == (12, 19, 13)
  34. assert evidence['inputSha256'] == release['policyReviewSha256']
  35. for op in ('listings', 'rankings', 'workshop'):
  36. post(op)
  37. def static(entry):
  38. request = Request(base + '/' + entry['path'], headers={'Cache-Control': 'no-cache'})
  39. with urlopen(request, timeout=25) as response:
  40. raw = response.read(3_000_000)
  41. digest = hashlib.sha256(raw).hexdigest()
  42. assert digest == entry['sha256'], 'PUBLIC_STATIC_SHA_MISMATCH:' + entry['path']
  43. return dict(path=entry['path'], sha256=digest, matched=True)
  44. files = list(manifest['files']) + [dict(path='index.html', sha256=manifest['homepageSha256'])]
  45. with ThreadPoolExecutor(max_workers=6) as pool:
  46. verified = list(pool.map(static, files))
  47. print(json.dumps(dict(ok=True, generation=generation, readOnly=True, databaseWrites=0, paidCalls=0,
  48. primaryStore={key: primary[key] for key in ('products', 'reviewRows', 'uniqueReadableTexts')},
  49. verifiedPolicyClauses=12, pendingPolicyClauses=19, originalDocuments=13,
  50. publicStaticFiles=verified, browserVerificationRequired=True,
  51. overallMainlineComplete=False), ensure_ascii=False, indent=2))
  52. if __name__ == '__main__':
  53. try:
  54. main()
  55. except Exception as error:
  56. print(json.dumps(dict(ok=False, error=str(error) if isinstance(error, AssertionError) else type(error).__name__,
  57. databaseWrites=0, paidCalls=0)))
  58. raise SystemExit(1)