synapse 3.0.0__py314-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (680) hide show
  1. synapse/__init__.py +27 -0
  2. synapse/assets/__init__.py +35 -0
  3. synapse/axon.py +2014 -0
  4. synapse/cells.py +1 -0
  5. synapse/common.py +1172 -0
  6. synapse/cortex.py +7567 -0
  7. synapse/daemon.py +459 -0
  8. synapse/data/__init__.py +37 -0
  9. synapse/data/attack-flow/LICENSE.txt +201 -0
  10. synapse/data/attack-flow/README.md +3 -0
  11. synapse/data/attack-flow/attack-flow-schema-2.0.0.json +468 -0
  12. synapse/data/certs/cas/The Vertex Project Intermediate CA (2026).crt +29 -0
  13. synapse/data/certs/cas/The Vertex Project ROOT CA (2026).crt +29 -0
  14. synapse/data/certs/crls/The Vertex Project Intermediate CA (2026).crl +2 -0
  15. synapse/data/certs/crls/The Vertex Project ROOT CA (2026).crl +2 -0
  16. synapse/data/iana.tlds.mpk +1 -0
  17. synapse/data/iana.uris.mpk +1 -0
  18. synapse/data/jsonschemas/README.md +29 -0
  19. synapse/data/jsonschemas/json-schema.org/draft-07/schema +244 -0
  20. synapse/data/jsonschemas/raw.githubusercontent.com/oasis-open/LICENSE.txt +27 -0
  21. synapse/data/jsonschemas/raw.githubusercontent.com/oasis-open/cti-stix2-json-schemas/stix2.1/schemas/common/binary.json +8 -0
  22. synapse/data/jsonschemas/raw.githubusercontent.com/oasis-open/cti-stix2-json-schemas/stix2.1/schemas/common/bundle.json +213 -0
  23. synapse/data/jsonschemas/raw.githubusercontent.com/oasis-open/cti-stix2-json-schemas/stix2.1/schemas/common/core.json +159 -0
  24. synapse/data/jsonschemas/raw.githubusercontent.com/oasis-open/cti-stix2-json-schemas/stix2.1/schemas/common/cyber-observable-core.json +97 -0
  25. synapse/data/jsonschemas/raw.githubusercontent.com/oasis-open/cti-stix2-json-schemas/stix2.1/schemas/common/dictionary.json +34 -0
  26. synapse/data/jsonschemas/raw.githubusercontent.com/oasis-open/cti-stix2-json-schemas/stix2.1/schemas/common/extension-definition.json +96 -0
  27. synapse/data/jsonschemas/raw.githubusercontent.com/oasis-open/cti-stix2-json-schemas/stix2.1/schemas/common/extension.json +28 -0
  28. synapse/data/jsonschemas/raw.githubusercontent.com/oasis-open/cti-stix2-json-schemas/stix2.1/schemas/common/external-reference.json +106 -0
  29. synapse/data/jsonschemas/raw.githubusercontent.com/oasis-open/cti-stix2-json-schemas/stix2.1/schemas/common/granular-marking.json +37 -0
  30. synapse/data/jsonschemas/raw.githubusercontent.com/oasis-open/cti-stix2-json-schemas/stix2.1/schemas/common/hashes-type.json +55 -0
  31. synapse/data/jsonschemas/raw.githubusercontent.com/oasis-open/cti-stix2-json-schemas/stix2.1/schemas/common/hex.json +8 -0
  32. synapse/data/jsonschemas/raw.githubusercontent.com/oasis-open/cti-stix2-json-schemas/stix2.1/schemas/common/identifier.json +8 -0
  33. synapse/data/jsonschemas/raw.githubusercontent.com/oasis-open/cti-stix2-json-schemas/stix2.1/schemas/common/kill-chain-phase.json +21 -0
  34. synapse/data/jsonschemas/raw.githubusercontent.com/oasis-open/cti-stix2-json-schemas/stix2.1/schemas/common/language-content.json +54 -0
  35. synapse/data/jsonschemas/raw.githubusercontent.com/oasis-open/cti-stix2-json-schemas/stix2.1/schemas/common/marking-definition.json +338 -0
  36. synapse/data/jsonschemas/raw.githubusercontent.com/oasis-open/cti-stix2-json-schemas/stix2.1/schemas/common/properties.json +38 -0
  37. synapse/data/jsonschemas/raw.githubusercontent.com/oasis-open/cti-stix2-json-schemas/stix2.1/schemas/common/timestamp.json +8 -0
  38. synapse/data/jsonschemas/raw.githubusercontent.com/oasis-open/cti-stix2-json-schemas/stix2.1/schemas/common/url-regex.json +8 -0
  39. synapse/data/jsonschemas/raw.githubusercontent.com/oasis-open/cti-stix2-json-schemas/stix2.1/schemas/observables/artifact.json +125 -0
  40. synapse/data/jsonschemas/raw.githubusercontent.com/oasis-open/cti-stix2-json-schemas/stix2.1/schemas/observables/autonomous-system.json +42 -0
  41. synapse/data/jsonschemas/raw.githubusercontent.com/oasis-open/cti-stix2-json-schemas/stix2.1/schemas/observables/directory.json +60 -0
  42. synapse/data/jsonschemas/raw.githubusercontent.com/oasis-open/cti-stix2-json-schemas/stix2.1/schemas/observables/domain-name.json +43 -0
  43. synapse/data/jsonschemas/raw.githubusercontent.com/oasis-open/cti-stix2-json-schemas/stix2.1/schemas/observables/email-addr.json +43 -0
  44. synapse/data/jsonschemas/raw.githubusercontent.com/oasis-open/cti-stix2-json-schemas/stix2.1/schemas/observables/email-message.json +205 -0
  45. synapse/data/jsonschemas/raw.githubusercontent.com/oasis-open/cti-stix2-json-schemas/stix2.1/schemas/observables/file.json +569 -0
  46. synapse/data/jsonschemas/raw.githubusercontent.com/oasis-open/cti-stix2-json-schemas/stix2.1/schemas/observables/ipv4-addr.json +51 -0
  47. synapse/data/jsonschemas/raw.githubusercontent.com/oasis-open/cti-stix2-json-schemas/stix2.1/schemas/observables/ipv6-addr.json +51 -0
  48. synapse/data/jsonschemas/raw.githubusercontent.com/oasis-open/cti-stix2-json-schemas/stix2.1/schemas/observables/mac-addr.json +35 -0
  49. synapse/data/jsonschemas/raw.githubusercontent.com/oasis-open/cti-stix2-json-schemas/stix2.1/schemas/observables/mutex.json +34 -0
  50. synapse/data/jsonschemas/raw.githubusercontent.com/oasis-open/cti-stix2-json-schemas/stix2.1/schemas/observables/network-traffic.json +330 -0
  51. synapse/data/jsonschemas/raw.githubusercontent.com/oasis-open/cti-stix2-json-schemas/stix2.1/schemas/observables/process.json +265 -0
  52. synapse/data/jsonschemas/raw.githubusercontent.com/oasis-open/cti-stix2-json-schemas/stix2.1/schemas/observables/software.json +60 -0
  53. synapse/data/jsonschemas/raw.githubusercontent.com/oasis-open/cti-stix2-json-schemas/stix2.1/schemas/observables/url.json +34 -0
  54. synapse/data/jsonschemas/raw.githubusercontent.com/oasis-open/cti-stix2-json-schemas/stix2.1/schemas/observables/user-account.json +170 -0
  55. synapse/data/jsonschemas/raw.githubusercontent.com/oasis-open/cti-stix2-json-schemas/stix2.1/schemas/observables/windows-registry-key.json +98 -0
  56. synapse/data/jsonschemas/raw.githubusercontent.com/oasis-open/cti-stix2-json-schemas/stix2.1/schemas/observables/x509-certificate.json +191 -0
  57. synapse/data/jsonschemas/raw.githubusercontent.com/oasis-open/cti-stix2-json-schemas/stix2.1/schemas/sdos/attack-pattern.json +53 -0
  58. synapse/data/jsonschemas/raw.githubusercontent.com/oasis-open/cti-stix2-json-schemas/stix2.1/schemas/sdos/campaign.json +58 -0
  59. synapse/data/jsonschemas/raw.githubusercontent.com/oasis-open/cti-stix2-json-schemas/stix2.1/schemas/sdos/course-of-action.json +38 -0
  60. synapse/data/jsonschemas/raw.githubusercontent.com/oasis-open/cti-stix2-json-schemas/stix2.1/schemas/sdos/grouping.json +61 -0
  61. synapse/data/jsonschemas/raw.githubusercontent.com/oasis-open/cti-stix2-json-schemas/stix2.1/schemas/sdos/identity.json +115 -0
  62. synapse/data/jsonschemas/raw.githubusercontent.com/oasis-open/cti-stix2-json-schemas/stix2.1/schemas/sdos/incident.json +38 -0
  63. synapse/data/jsonschemas/raw.githubusercontent.com/oasis-open/cti-stix2-json-schemas/stix2.1/schemas/sdos/indicator.json +101 -0
  64. synapse/data/jsonschemas/raw.githubusercontent.com/oasis-open/cti-stix2-json-schemas/stix2.1/schemas/sdos/infrastructure.json +88 -0
  65. synapse/data/jsonschemas/raw.githubusercontent.com/oasis-open/cti-stix2-json-schemas/stix2.1/schemas/sdos/intrusion-set.json +106 -0
  66. synapse/data/jsonschemas/raw.githubusercontent.com/oasis-open/cti-stix2-json-schemas/stix2.1/schemas/sdos/location.json +175 -0
  67. synapse/data/jsonschemas/raw.githubusercontent.com/oasis-open/cti-stix2-json-schemas/stix2.1/schemas/sdos/malware-analysis.json +159 -0
  68. synapse/data/jsonschemas/raw.githubusercontent.com/oasis-open/cti-stix2-json-schemas/stix2.1/schemas/sdos/malware.json +254 -0
  69. synapse/data/jsonschemas/raw.githubusercontent.com/oasis-open/cti-stix2-json-schemas/stix2.1/schemas/sdos/note.json +55 -0
  70. synapse/data/jsonschemas/raw.githubusercontent.com/oasis-open/cti-stix2-json-schemas/stix2.1/schemas/sdos/observed-data.json +150 -0
  71. synapse/data/jsonschemas/raw.githubusercontent.com/oasis-open/cti-stix2-json-schemas/stix2.1/schemas/sdos/opinion.json +62 -0
  72. synapse/data/jsonschemas/raw.githubusercontent.com/oasis-open/cti-stix2-json-schemas/stix2.1/schemas/sdos/report.json +77 -0
  73. synapse/data/jsonschemas/raw.githubusercontent.com/oasis-open/cti-stix2-json-schemas/stix2.1/schemas/sdos/threat-actor.json +175 -0
  74. synapse/data/jsonschemas/raw.githubusercontent.com/oasis-open/cti-stix2-json-schemas/stix2.1/schemas/sdos/tool.json +81 -0
  75. synapse/data/jsonschemas/raw.githubusercontent.com/oasis-open/cti-stix2-json-schemas/stix2.1/schemas/sdos/vulnerability.json +38 -0
  76. synapse/data/jsonschemas/raw.githubusercontent.com/oasis-open/cti-stix2-json-schemas/stix2.1/schemas/sros/relationship.json +76 -0
  77. synapse/data/jsonschemas/raw.githubusercontent.com/oasis-open/cti-stix2-json-schemas/stix2.1/schemas/sros/sighting.json +115 -0
  78. synapse/data/lark/__init__.py +0 -0
  79. synapse/data/lark/imap.lark +8 -0
  80. synapse/data/lark/storm.lark +784 -0
  81. synapse/data/skills/storm/SKILL.md +878 -0
  82. synapse/data/v2modelmap.yaml +684 -0
  83. synapse/datamodel.py +2086 -0
  84. synapse/exc.py +437 -0
  85. synapse/glob.py +98 -0
  86. synapse/lib/__init__.py +2 -0
  87. synapse/lib/agenda.py +1060 -0
  88. synapse/lib/aha.py +2129 -0
  89. synapse/lib/ast.py +6457 -0
  90. synapse/lib/auth.py +1738 -0
  91. synapse/lib/autodoc.py +1990 -0
  92. synapse/lib/base.py +904 -0
  93. synapse/lib/boss.py +143 -0
  94. synapse/lib/cache.py +232 -0
  95. synapse/lib/cell.py +5818 -0
  96. synapse/lib/certdir.py +1850 -0
  97. synapse/lib/chop.py +350 -0
  98. synapse/lib/cli.py +546 -0
  99. synapse/lib/cluster.py +358 -0
  100. synapse/lib/cmd.py +69 -0
  101. synapse/lib/config.py +583 -0
  102. synapse/lib/const.py +56 -0
  103. synapse/lib/coro.py +224 -0
  104. synapse/lib/crypto/__init__.py +0 -0
  105. synapse/lib/crypto/coin.py +176 -0
  106. synapse/lib/crypto/ecc.py +264 -0
  107. synapse/lib/crypto/jwk.py +82 -0
  108. synapse/lib/crypto/passwd.py +146 -0
  109. synapse/lib/crypto/rsa.py +261 -0
  110. synapse/lib/crypto/tinfoil.py +191 -0
  111. synapse/lib/crypto/utils.py +142 -0
  112. synapse/lib/datfile.py +25 -0
  113. synapse/lib/drive.py +1161 -0
  114. synapse/lib/dyndeps.py +147 -0
  115. synapse/lib/editor.py +1154 -0
  116. synapse/lib/gis.py +251 -0
  117. synapse/lib/grammar.py +92 -0
  118. synapse/lib/hashitem.py +30 -0
  119. synapse/lib/hashset.py +60 -0
  120. synapse/lib/health.py +53 -0
  121. synapse/lib/httpapi.py +1590 -0
  122. synapse/lib/json.py +214 -0
  123. synapse/lib/jsonstor.py +633 -0
  124. synapse/lib/jsrpc.py +372 -0
  125. synapse/lib/layer.py +7062 -0
  126. synapse/lib/link.py +419 -0
  127. synapse/lib/lmdbslab.py +2762 -0
  128. synapse/lib/logging.py +425 -0
  129. synapse/lib/mcp.py +1292 -0
  130. synapse/lib/mddocs.py +1001 -0
  131. synapse/lib/mdstorm.py +934 -0
  132. synapse/lib/modelrev.py +383 -0
  133. synapse/lib/msgpack.py +300 -0
  134. synapse/lib/multislabseqn.py +562 -0
  135. synapse/lib/nexus.py +846 -0
  136. synapse/lib/node.py +2025 -0
  137. synapse/lib/oauth.py +513 -0
  138. synapse/lib/output.py +49 -0
  139. synapse/lib/parser.py +922 -0
  140. synapse/lib/platforms/__init__.py +8 -0
  141. synapse/lib/platforms/common.py +61 -0
  142. synapse/lib/platforms/darwin.py +9 -0
  143. synapse/lib/platforms/freebsd.py +9 -0
  144. synapse/lib/platforms/linux.py +237 -0
  145. synapse/lib/platforms/windows.py +84 -0
  146. synapse/lib/process.py +93 -0
  147. synapse/lib/processpool.py +224 -0
  148. synapse/lib/provision.py +135 -0
  149. synapse/lib/queue.py +177 -0
  150. synapse/lib/reflect.py +111 -0
  151. synapse/lib/schemas.py +1724 -0
  152. synapse/lib/scope.py +249 -0
  153. synapse/lib/scrape.py +706 -0
  154. synapse/lib/share.py +29 -0
  155. synapse/lib/slabseqn.py +400 -0
  156. synapse/lib/spawner.py +122 -0
  157. synapse/lib/spooled.py +211 -0
  158. synapse/lib/storm.py +6455 -0
  159. synapse/lib/storm_format.py +161 -0
  160. synapse/lib/stormctrl.py +91 -0
  161. synapse/lib/stormhttp.py +592 -0
  162. synapse/lib/stormlib/__init__.py +0 -0
  163. synapse/lib/stormlib/aha.py +623 -0
  164. synapse/lib/stormlib/auth.py +1908 -0
  165. synapse/lib/stormlib/basex.py +73 -0
  166. synapse/lib/stormlib/bytes.py +48 -0
  167. synapse/lib/stormlib/cache.py +206 -0
  168. synapse/lib/stormlib/cell.py +146 -0
  169. synapse/lib/stormlib/compression.py +179 -0
  170. synapse/lib/stormlib/cortex.py +1273 -0
  171. synapse/lib/stormlib/cryptoutils.py +86 -0
  172. synapse/lib/stormlib/easyperm.py +122 -0
  173. synapse/lib/stormlib/ecc.py +164 -0
  174. synapse/lib/stormlib/ethereum.py +37 -0
  175. synapse/lib/stormlib/file.py +67 -0
  176. synapse/lib/stormlib/gen.py +188 -0
  177. synapse/lib/stormlib/gis.py +41 -0
  178. synapse/lib/stormlib/graph.py +177 -0
  179. synapse/lib/stormlib/hashes.py +112 -0
  180. synapse/lib/stormlib/hex.py +142 -0
  181. synapse/lib/stormlib/imap.py +842 -0
  182. synapse/lib/stormlib/index.py +52 -0
  183. synapse/lib/stormlib/infosec.py +570 -0
  184. synapse/lib/stormlib/ipv6.py +51 -0
  185. synapse/lib/stormlib/iters.py +92 -0
  186. synapse/lib/stormlib/json.py +146 -0
  187. synapse/lib/stormlib/jwt.py +1031 -0
  188. synapse/lib/stormlib/log.py +180 -0
  189. synapse/lib/stormlib/macro.py +237 -0
  190. synapse/lib/stormlib/math.py +37 -0
  191. synapse/lib/stormlib/mime.py +45 -0
  192. synapse/lib/stormlib/model.py +778 -0
  193. synapse/lib/stormlib/modelext.py +243 -0
  194. synapse/lib/stormlib/oauth.py +406 -0
  195. synapse/lib/stormlib/pack.py +68 -0
  196. synapse/lib/stormlib/pkg.py +635 -0
  197. synapse/lib/stormlib/quorum.py +114 -0
  198. synapse/lib/stormlib/random.py +117 -0
  199. synapse/lib/stormlib/rsa.py +172 -0
  200. synapse/lib/stormlib/scrape.py +149 -0
  201. synapse/lib/stormlib/smtp.py +214 -0
  202. synapse/lib/stormlib/spooled.py +113 -0
  203. synapse/lib/stormlib/stats.py +253 -0
  204. synapse/lib/stormlib/stix.py +1599 -0
  205. synapse/lib/stormlib/storm.py +178 -0
  206. synapse/lib/stormlib/tabular.py +212 -0
  207. synapse/lib/stormlib/task.py +116 -0
  208. synapse/lib/stormlib/utils.py +48 -0
  209. synapse/lib/stormlib/vault.py +896 -0
  210. synapse/lib/stormlib/version.py +66 -0
  211. synapse/lib/stormlib/vertex.py +421 -0
  212. synapse/lib/stormlib/xml.py +99 -0
  213. synapse/lib/stormlib/yaml.py +49 -0
  214. synapse/lib/stormsvc.py +112 -0
  215. synapse/lib/stormtypes.py +10549 -0
  216. synapse/lib/task.py +264 -0
  217. synapse/lib/thishost.py +40 -0
  218. synapse/lib/thisplat.py +17 -0
  219. synapse/lib/threads.py +10 -0
  220. synapse/lib/time.py +542 -0
  221. synapse/lib/trigger.py +513 -0
  222. synapse/lib/types.py +5151 -0
  223. synapse/lib/urlhelp.py +112 -0
  224. synapse/lib/version.py +387 -0
  225. synapse/lib/view.py +3898 -0
  226. synapse/lookup/__init__.py +0 -0
  227. synapse/lookup/cvss.py +89 -0
  228. synapse/lookup/iana.py +322 -0
  229. synapse/lookup/macho.py +73 -0
  230. synapse/lookup/pe.py +530 -0
  231. synapse/lookup/phonenum.py +386 -0
  232. synapse/lookup/timezones.py +43 -0
  233. synapse/models/__init__.py +29 -0
  234. synapse/models/auth.py +59 -0
  235. synapse/models/base.py +972 -0
  236. synapse/models/belief.py +42 -0
  237. synapse/models/biz.py +206 -0
  238. synapse/models/crypto.py +805 -0
  239. synapse/models/dns.py +401 -0
  240. synapse/models/doc.py +258 -0
  241. synapse/models/economic.py +629 -0
  242. synapse/models/entity.py +810 -0
  243. synapse/models/files.py +817 -0
  244. synapse/models/geopol.py +226 -0
  245. synapse/models/geospace.py +567 -0
  246. synapse/models/gov.py +70 -0
  247. synapse/models/ind.py +63 -0
  248. synapse/models/inet.py +3397 -0
  249. synapse/models/infotech.py +3070 -0
  250. synapse/models/language.py +231 -0
  251. synapse/models/material.py +203 -0
  252. synapse/models/orgs.py +652 -0
  253. synapse/models/person.py +201 -0
  254. synapse/models/planning.py +148 -0
  255. synapse/models/proj.py +108 -0
  256. synapse/models/risk.py +668 -0
  257. synapse/models/science.py +96 -0
  258. synapse/models/syn.py +312 -0
  259. synapse/models/telco.py +262 -0
  260. synapse/models/transport.py +562 -0
  261. synapse/servers/__init__.py +0 -0
  262. synapse/servers/aha.py +8 -0
  263. synapse/servers/axon.py +8 -0
  264. synapse/servers/cell.py +21 -0
  265. synapse/servers/cortex.py +8 -0
  266. synapse/servers/jsonstor.py +8 -0
  267. synapse/telepath.py +1294 -0
  268. synapse/tests/__init__.py +0 -0
  269. synapse/tests/files/TestUtilsGetrefs.test_basics.yaml +182 -0
  270. synapse/tests/files/__init__.py +80 -0
  271. synapse/tests/files/aha/certs/cas/synapse.crt.tinfoil +0 -0
  272. synapse/tests/files/aha/certs/cas/synapse.key.tinfoil +0 -0
  273. synapse/tests/files/aha/certs/hosts/00.aha.loop.vertex.link.crt.tinfoil +0 -0
  274. synapse/tests/files/aha/certs/hosts/00.aha.loop.vertex.link.key.tinfoil +0 -0
  275. synapse/tests/files/aha/certs/users/root@synapse.crt.tinfoil +0 -0
  276. synapse/tests/files/aha/certs/users/root@synapse.key.tinfoil +0 -0
  277. synapse/tests/files/attack_flow/CISA AA22-138B VMWare Workspace (Alt).json +486 -0
  278. synapse/tests/files/attack_flow/CISA_Iranian_APT.json +1083 -0
  279. synapse/tests/files/certdir/cas/ca.crt.tinfoil +0 -0
  280. synapse/tests/files/certdir/cas/ca.key.tinfoil +0 -0
  281. synapse/tests/files/certdir/hosts/localhost.crt.tinfoil +0 -0
  282. synapse/tests/files/certdir/hosts/localhost.key.tinfoil +0 -0
  283. synapse/tests/files/certdir/users/root.crt.tinfoil +0 -0
  284. synapse/tests/files/certdir/users/root.key.tinfoil +0 -0
  285. synapse/tests/files/certdir/users/user.crt.tinfoil +0 -0
  286. synapse/tests/files/certdir/users/user.key.tinfoil +0 -0
  287. synapse/tests/files/cpedata.json +525034 -0
  288. synapse/tests/files/mdstorm/httprespmulti.yaml +78 -0
  289. synapse/tests/files/mdstorm/testsvc.py +76 -0
  290. synapse/tests/files/stix_export/basic.json +501 -0
  291. synapse/tests/files/stix_export/custom0.json +222 -0
  292. synapse/tests/files/stix_export/risk0.json +159 -0
  293. synapse/tests/files/stix_import/apt1.json +1206 -0
  294. synapse/tests/files/stix_import/oasis-example-00.json +100 -0
  295. synapse/tests/files/stix_import/scos.json +83 -0
  296. synapse/tests/files/stormcov/argvquery.storm +10 -0
  297. synapse/tests/files/stormcov/argvquery2.storm +4 -0
  298. synapse/tests/files/stormcov/argvquery3.storm +6 -0
  299. synapse/tests/files/stormcov/argvquery4.storm +7 -0
  300. synapse/tests/files/stormcov/argvquery5.storm +11 -0
  301. synapse/tests/files/stormcov/badstorm.storm +1 -0
  302. synapse/tests/files/stormcov/continueloop.storm +5 -0
  303. synapse/tests/files/stormcov/dupesubs.storm +28 -0
  304. synapse/tests/files/stormcov/dupewarn.storm +39 -0
  305. synapse/tests/files/stormcov/dupfunc.storm +13 -0
  306. synapse/tests/files/stormcov/embedquery.storm +21 -0
  307. synapse/tests/files/stormcov/embedquery2.storm +4 -0
  308. synapse/tests/files/stormcov/embedquery3.storm +6 -0
  309. synapse/tests/files/stormcov/embedquery4.storm +7 -0
  310. synapse/tests/files/stormcov/embedquery5.storm +11 -0
  311. synapse/tests/files/stormcov/emptybody.storm +12 -0
  312. synapse/tests/files/stormcov/exprdict.storm +10 -0
  313. synapse/tests/files/stormcov/forloop.storm +10 -0
  314. synapse/tests/files/stormcov/ifelif.storm +9 -0
  315. synapse/tests/files/stormcov/ifelse.storm +9 -0
  316. synapse/tests/files/stormcov/lookup.storm +7 -0
  317. synapse/tests/files/stormcov/pivot.storm +4 -0
  318. synapse/tests/files/stormcov/pragma-nocov.storm +20 -0
  319. synapse/tests/files/stormcov/runtsafety.storm +7 -0
  320. synapse/tests/files/stormcov/spin.storm +5 -0
  321. synapse/tests/files/stormcov/stopreturn.storm +4 -0
  322. synapse/tests/files/stormcov/stormctrl.storm +8 -0
  323. synapse/tests/files/stormcov/switch.storm +9 -0
  324. synapse/tests/files/stormcov/switchnodefault.storm +8 -0
  325. synapse/tests/files/stormcov/trycatch.storm +8 -0
  326. synapse/tests/files/stormcov/whilebackedge.storm +12 -0
  327. synapse/tests/files/stormcov/whilecontinue.storm +13 -0
  328. synapse/tests/files/stormcov/whileloop.storm +8 -0
  329. synapse/tests/files/stormcov/whilewithnode.storm +10 -0
  330. synapse/tests/files/stormmod/common +1 -0
  331. synapse/tests/files/stormpkg/badapidef.yaml +13 -0
  332. synapse/tests/files/stormpkg/badcmdname.yaml +6 -0
  333. synapse/tests/files/stormpkg/badendpoints.yaml +7 -0
  334. synapse/tests/files/stormpkg/badinits.yaml +12 -0
  335. synapse/tests/files/stormpkg/badjsonpkg.yaml +8 -0
  336. synapse/tests/files/stormpkg/badvaultskeys.yaml +9 -0
  337. synapse/tests/files/stormpkg/badvaultsschema.yaml +11 -0
  338. synapse/tests/files/stormpkg/declaredfiles.yaml +4 -0
  339. synapse/tests/files/stormpkg/docs/foobar.md +3 -0
  340. synapse/tests/files/stormpkg/docs/foobar.svg +1 -0
  341. synapse/tests/files/stormpkg/docs/index.md +5 -0
  342. synapse/tests/files/stormpkg/dotstorm/dotstorm.yaml +14 -0
  343. synapse/tests/files/stormpkg/dotstorm_noevents/dotstorm.yaml +11 -0
  344. synapse/tests/files/stormpkg/dotstorm_noevents/storm/commands/dotstorm.bar.storm +1 -0
  345. synapse/tests/files/stormpkg/dotstorm_noevents/storm/modules/dotstorm.foo.storm +1 -0
  346. synapse/tests/files/stormpkg/files/data.dat +1 -0
  347. synapse/tests/files/stormpkg/files/sub/nested.dat +1 -0
  348. synapse/tests/files/stormpkg/nomime.yaml +5 -0
  349. synapse/tests/files/stormpkg/nopath.yaml +5 -0
  350. synapse/tests/files/stormpkg/nosuchfile.yaml +4 -0
  351. synapse/tests/files/stormpkg/optic/index.html +1 -0
  352. synapse/tests/files/stormpkg/storm/commands/invalidCMD.storm +0 -0
  353. synapse/tests/files/stormpkg/storm/commands/testpkg.baz.storm +0 -0
  354. synapse/tests/files/stormpkg/storm/commands/testpkgcmd.storm +1 -0
  355. synapse/tests/files/stormpkg/storm/modules/apimod.storm +10 -0
  356. synapse/tests/files/stormpkg/storm/modules/testmod.storm +1 -0
  357. synapse/tests/files/stormpkg/testpkg.yaml +219 -0
  358. synapse/tests/files/stormpkg/workflows/testpkg-bam.newp +2 -0
  359. synapse/tests/files/stormpkg/workflows/testpkg-baz.yaml +2 -0
  360. synapse/tests/files/stormpkg/workflows/testpkg-foo.yaml +2 -0
  361. synapse/tests/files/test.dat +1 -0
  362. synapse/tests/files/testpkg_build_docs/docs/index.md +7 -0
  363. synapse/tests/files/testpkg_build_docs/docs/mocks/cassette.yaml +78 -0
  364. synapse/tests/files/testpkg_build_docs/docs/stormpackage.md +2 -0
  365. synapse/tests/files/testpkg_build_docs/docs/sub/image.svg +1 -0
  366. synapse/tests/files/testpkg_build_docs/docs/sub/nested.md +3 -0
  367. synapse/tests/files/testpkg_build_docs/docs/userguide.md +9 -0
  368. synapse/tests/files/testpkg_build_docs/storm/commands/testcmd.storm +0 -0
  369. synapse/tests/files/testpkg_build_docs/storm/modules/apimod.storm +0 -0
  370. synapse/tests/files/testpkg_build_docs/storm/modules/testmod.storm +0 -0
  371. synapse/tests/files/testpkg_build_docs/storm/testcmd.storm +5 -0
  372. synapse/tests/files/testpkg_build_docs/testpkg.yaml +64 -0
  373. synapse/tests/files/testpkg_build_docs_no_h1/docs/index.md +5 -0
  374. synapse/tests/files/testpkg_build_docs_no_h1/docs/noh1.md +3 -0
  375. synapse/tests/files/testpkg_build_docs_no_h1/testpkg.yaml +2 -0
  376. synapse/tests/nopmod.py +3 -0
  377. synapse/tests/test_assets.py +26 -0
  378. synapse/tests/test_axon.py +1412 -0
  379. synapse/tests/test_common.py +552 -0
  380. synapse/tests/test_cortex.py +10107 -0
  381. synapse/tests/test_daemon.py +540 -0
  382. synapse/tests/test_data.py +8 -0
  383. synapse/tests/test_datamodel.py +1993 -0
  384. synapse/tests/test_exc.py +89 -0
  385. synapse/tests/test_glob.py +52 -0
  386. synapse/tests/test_lib_agenda.py +2091 -0
  387. synapse/tests/test_lib_aha.py +2361 -0
  388. synapse/tests/test_lib_ast.py +5286 -0
  389. synapse/tests/test_lib_auth.py +1415 -0
  390. synapse/tests/test_lib_autodoc.py +876 -0
  391. synapse/tests/test_lib_base.py +782 -0
  392. synapse/tests/test_lib_boss.py +144 -0
  393. synapse/tests/test_lib_cache.py +283 -0
  394. synapse/tests/test_lib_cell.py +3675 -0
  395. synapse/tests/test_lib_certdir.py +2084 -0
  396. synapse/tests/test_lib_chop.py +154 -0
  397. synapse/tests/test_lib_cli.py +295 -0
  398. synapse/tests/test_lib_cluster.py +26 -0
  399. synapse/tests/test_lib_config.py +512 -0
  400. synapse/tests/test_lib_const.py +24 -0
  401. synapse/tests/test_lib_coro.py +132 -0
  402. synapse/tests/test_lib_crypto_coin.py +31 -0
  403. synapse/tests/test_lib_crypto_ecc.py +236 -0
  404. synapse/tests/test_lib_crypto_jwk.py +97 -0
  405. synapse/tests/test_lib_crypto_passwd.py +171 -0
  406. synapse/tests/test_lib_crypto_rsa.py +213 -0
  407. synapse/tests/test_lib_crypto_tinfoil.py +184 -0
  408. synapse/tests/test_lib_datfile.py +15 -0
  409. synapse/tests/test_lib_drive.py +1119 -0
  410. synapse/tests/test_lib_dyndeps.py +55 -0
  411. synapse/tests/test_lib_gis.py +179 -0
  412. synapse/tests/test_lib_grammar.py +2147 -0
  413. synapse/tests/test_lib_hashitem.py +32 -0
  414. synapse/tests/test_lib_hashset.py +49 -0
  415. synapse/tests/test_lib_health.py +35 -0
  416. synapse/tests/test_lib_httpapi.py +2331 -0
  417. synapse/tests/test_lib_json.py +240 -0
  418. synapse/tests/test_lib_jsonstor.py +204 -0
  419. synapse/tests/test_lib_jsrpc.py +345 -0
  420. synapse/tests/test_lib_layer.py +4256 -0
  421. synapse/tests/test_lib_link.py +446 -0
  422. synapse/tests/test_lib_lmdbslab.py +2598 -0
  423. synapse/tests/test_lib_logging.py +514 -0
  424. synapse/tests/test_lib_mcp.py +1109 -0
  425. synapse/tests/test_lib_mddocs.py +1441 -0
  426. synapse/tests/test_lib_mdstorm.py +1701 -0
  427. synapse/tests/test_lib_modelrev.py +57 -0
  428. synapse/tests/test_lib_msgpack.py +315 -0
  429. synapse/tests/test_lib_multislabseqn.py +646 -0
  430. synapse/tests/test_lib_nexus.py +869 -0
  431. synapse/tests/test_lib_node.py +905 -0
  432. synapse/tests/test_lib_output.py +26 -0
  433. synapse/tests/test_lib_platforms_linux.py +66 -0
  434. synapse/tests/test_lib_process.py +67 -0
  435. synapse/tests/test_lib_processpool.py +220 -0
  436. synapse/tests/test_lib_provision.py +89 -0
  437. synapse/tests/test_lib_queue.py +37 -0
  438. synapse/tests/test_lib_reflect.py +84 -0
  439. synapse/tests/test_lib_scope.py +176 -0
  440. synapse/tests/test_lib_scrape.py +1250 -0
  441. synapse/tests/test_lib_slabseqn.py +208 -0
  442. synapse/tests/test_lib_spawner.py +147 -0
  443. synapse/tests/test_lib_spooled.py +139 -0
  444. synapse/tests/test_lib_storm.py +6459 -0
  445. synapse/tests/test_lib_storm_format.py +9 -0
  446. synapse/tests/test_lib_stormctrl.py +65 -0
  447. synapse/tests/test_lib_stormhttp.py +1050 -0
  448. synapse/tests/test_lib_stormlib_aha.py +383 -0
  449. synapse/tests/test_lib_stormlib_auth.py +1863 -0
  450. synapse/tests/test_lib_stormlib_basex.py +42 -0
  451. synapse/tests/test_lib_stormlib_cache.py +304 -0
  452. synapse/tests/test_lib_stormlib_cell.py +154 -0
  453. synapse/tests/test_lib_stormlib_compression.py +61 -0
  454. synapse/tests/test_lib_stormlib_cortex.py +1493 -0
  455. synapse/tests/test_lib_stormlib_easyperm.py +124 -0
  456. synapse/tests/test_lib_stormlib_ecc.py +144 -0
  457. synapse/tests/test_lib_stormlib_env.py +37 -0
  458. synapse/tests/test_lib_stormlib_ethereum.py +22 -0
  459. synapse/tests/test_lib_stormlib_file.py +115 -0
  460. synapse/tests/test_lib_stormlib_gen.py +239 -0
  461. synapse/tests/test_lib_stormlib_gis.py +21 -0
  462. synapse/tests/test_lib_stormlib_hashes.py +136 -0
  463. synapse/tests/test_lib_stormlib_hex.py +105 -0
  464. synapse/tests/test_lib_stormlib_imap.py +1443 -0
  465. synapse/tests/test_lib_stormlib_index.py +39 -0
  466. synapse/tests/test_lib_stormlib_infosec.py +405 -0
  467. synapse/tests/test_lib_stormlib_ipv6.py +26 -0
  468. synapse/tests/test_lib_stormlib_iters.py +118 -0
  469. synapse/tests/test_lib_stormlib_json.py +89 -0
  470. synapse/tests/test_lib_stormlib_jwt.py +1380 -0
  471. synapse/tests/test_lib_stormlib_log.py +40 -0
  472. synapse/tests/test_lib_stormlib_macro.py +414 -0
  473. synapse/tests/test_lib_stormlib_mime.py +82 -0
  474. synapse/tests/test_lib_stormlib_model.py +323 -0
  475. synapse/tests/test_lib_stormlib_modelext.py +718 -0
  476. synapse/tests/test_lib_stormlib_oauth.py +1248 -0
  477. synapse/tests/test_lib_stormlib_pack.py +36 -0
  478. synapse/tests/test_lib_stormlib_pkg.py +558 -0
  479. synapse/tests/test_lib_stormlib_quorum.py +68 -0
  480. synapse/tests/test_lib_stormlib_random.py +115 -0
  481. synapse/tests/test_lib_stormlib_rsa.py +244 -0
  482. synapse/tests/test_lib_stormlib_scrape.py +225 -0
  483. synapse/tests/test_lib_stormlib_smtp.py +91 -0
  484. synapse/tests/test_lib_stormlib_spooled.py +221 -0
  485. synapse/tests/test_lib_stormlib_stats.py +284 -0
  486. synapse/tests/test_lib_stormlib_stix.py +807 -0
  487. synapse/tests/test_lib_stormlib_storm.py +192 -0
  488. synapse/tests/test_lib_stormlib_tabular.py +226 -0
  489. synapse/tests/test_lib_stormlib_task.py +96 -0
  490. synapse/tests/test_lib_stormlib_utils.py +13 -0
  491. synapse/tests/test_lib_stormlib_vault.py +721 -0
  492. synapse/tests/test_lib_stormlib_vertex.py +578 -0
  493. synapse/tests/test_lib_stormlib_xml.py +112 -0
  494. synapse/tests/test_lib_stormlib_yaml.py +38 -0
  495. synapse/tests/test_lib_stormsvc.py +1266 -0
  496. synapse/tests/test_lib_stormtypes.py +8805 -0
  497. synapse/tests/test_lib_task.py +133 -0
  498. synapse/tests/test_lib_thishost.py +14 -0
  499. synapse/tests/test_lib_time.py +219 -0
  500. synapse/tests/test_lib_trigger.py +1017 -0
  501. synapse/tests/test_lib_types.py +3978 -0
  502. synapse/tests/test_lib_urlhelp.py +106 -0
  503. synapse/tests/test_lib_version.py +363 -0
  504. synapse/tests/test_lib_view.py +2714 -0
  505. synapse/tests/test_lookup_phonenum.py +9 -0
  506. synapse/tests/test_model_auth.py +22 -0
  507. synapse/tests/test_model_base.py +474 -0
  508. synapse/tests/test_model_belief.py +27 -0
  509. synapse/tests/test_model_biz.py +122 -0
  510. synapse/tests/test_model_crypto.py +804 -0
  511. synapse/tests/test_model_dns.py +385 -0
  512. synapse/tests/test_model_doc.py +157 -0
  513. synapse/tests/test_model_economic.py +932 -0
  514. synapse/tests/test_model_entity.py +517 -0
  515. synapse/tests/test_model_files.py +877 -0
  516. synapse/tests/test_model_geopol.py +195 -0
  517. synapse/tests/test_model_geospace.py +524 -0
  518. synapse/tests/test_model_gov.py +21 -0
  519. synapse/tests/test_model_gov_cn.py +17 -0
  520. synapse/tests/test_model_gov_intl.py +40 -0
  521. synapse/tests/test_model_gov_us.py +12 -0
  522. synapse/tests/test_model_inet.py +3856 -0
  523. synapse/tests/test_model_infotech.py +2772 -0
  524. synapse/tests/test_model_language.py +142 -0
  525. synapse/tests/test_model_material.py +84 -0
  526. synapse/tests/test_model_orgs.py +583 -0
  527. synapse/tests/test_model_person.py +197 -0
  528. synapse/tests/test_model_planning.py +131 -0
  529. synapse/tests/test_model_proj.py +82 -0
  530. synapse/tests/test_model_risk.py +600 -0
  531. synapse/tests/test_model_science.py +65 -0
  532. synapse/tests/test_model_syn.py +896 -0
  533. synapse/tests/test_model_telco.py +167 -0
  534. synapse/tests/test_model_transport.py +341 -0
  535. synapse/tests/test_servers_axon.py +32 -0
  536. synapse/tests/test_servers_cortex.py +33 -0
  537. synapse/tests/test_servers_univ.py +70 -0
  538. synapse/tests/test_telepath.py +1424 -0
  539. synapse/tests/test_tools_aha.py +419 -0
  540. synapse/tests/test_tools_axon_copy.py +33 -0
  541. synapse/tests/test_tools_axon_dump_load.py +304 -0
  542. synapse/tests/test_tools_axon_get.py +63 -0
  543. synapse/tests/test_tools_axon_put.py +129 -0
  544. synapse/tests/test_tools_cortex_csv.py +255 -0
  545. synapse/tests/test_tools_cortex_docmodel.py +649 -0
  546. synapse/tests/test_tools_cortex_feed.py +215 -0
  547. synapse/tests/test_tools_cortex_layer.py +418 -0
  548. synapse/tests/test_tools_docker_validate.py +100 -0
  549. synapse/tests/test_tools_service_apikey.py +224 -0
  550. synapse/tests/test_tools_service_backup.py +444 -0
  551. synapse/tests/test_tools_service_demote.py +86 -0
  552. synapse/tests/test_tools_service_healthcheck.py +83 -0
  553. synapse/tests/test_tools_service_modrole.py +142 -0
  554. synapse/tests/test_tools_service_moduser.py +258 -0
  555. synapse/tests/test_tools_service_promote.py +88 -0
  556. synapse/tests/test_tools_service_reload.py +54 -0
  557. synapse/tests/test_tools_service_shutdown.py +77 -0
  558. synapse/tests/test_tools_service_snapshot.py +47 -0
  559. synapse/tests/test_tools_storm_cli.py +985 -0
  560. synapse/tests/test_tools_storm_pkg_doc.py +280 -0
  561. synapse/tests/test_tools_storm_pkg_gen.py +676 -0
  562. synapse/tests/test_tools_storm_pkg_publish.py +379 -0
  563. synapse/tests/test_tools_storm_printer.py +203 -0
  564. synapse/tests/test_tools_storm_tester.py +153 -0
  565. synapse/tests/test_tools_storm_validate.py +82 -0
  566. synapse/tests/test_tools_utils_doc.py +153 -0
  567. synapse/tests/test_tools_utils_easycert.py +215 -0
  568. synapse/tests/test_tools_utils_guid.py +12 -0
  569. synapse/tests/test_tools_utils_json2mpk.py +33 -0
  570. synapse/tests/test_tools_utils_mdstorm.py +49 -0
  571. synapse/tests/test_utils.py +512 -0
  572. synapse/tests/test_utils_getrefs.py +81 -0
  573. synapse/tests/test_utils_stormcov.py +376 -0
  574. synapse/tests/utils.py +2654 -0
  575. synapse/tools/__init__.py +0 -0
  576. synapse/tools/aha/__init__.py +0 -0
  577. synapse/tools/aha/clone.py +48 -0
  578. synapse/tools/aha/del.py +47 -0
  579. synapse/tools/aha/easycert.py +53 -0
  580. synapse/tools/aha/enroll.py +103 -0
  581. synapse/tools/aha/list.py +55 -0
  582. synapse/tools/aha/mirror.py +171 -0
  583. synapse/tools/aha/provision/__init__.py +0 -0
  584. synapse/tools/aha/provision/service.py +72 -0
  585. synapse/tools/aha/provision/user.py +50 -0
  586. synapse/tools/axon/__init__.py +0 -0
  587. synapse/tools/axon/copy.py +44 -0
  588. synapse/tools/axon/dump.py +155 -0
  589. synapse/tools/axon/get.py +76 -0
  590. synapse/tools/axon/load.py +89 -0
  591. synapse/tools/axon/put.py +122 -0
  592. synapse/tools/cortex/__init__.py +0 -0
  593. synapse/tools/cortex/csv.py +269 -0
  594. synapse/tools/cortex/docmodel.py +829 -0
  595. synapse/tools/cortex/feed.py +172 -0
  596. synapse/tools/cortex/layer/__init__.py +0 -0
  597. synapse/tools/cortex/layer/dump.py +184 -0
  598. synapse/tools/cortex/layer/load.py +128 -0
  599. synapse/tools/docker/__init__.py +0 -0
  600. synapse/tools/docker/validate.py +154 -0
  601. synapse/tools/service/__init__.py +0 -0
  602. synapse/tools/service/apikey.py +90 -0
  603. synapse/tools/service/backup.py +334 -0
  604. synapse/tools/service/demote.py +47 -0
  605. synapse/tools/service/healthcheck.py +108 -0
  606. synapse/tools/service/modrole.py +116 -0
  607. synapse/tools/service/moduser.py +184 -0
  608. synapse/tools/service/promote.py +54 -0
  609. synapse/tools/service/reload.py +68 -0
  610. synapse/tools/service/shutdown.py +61 -0
  611. synapse/tools/service/snapshot.py +64 -0
  612. synapse/tools/storm/__init__.py +0 -0
  613. synapse/tools/storm/__main__.py +5 -0
  614. synapse/tools/storm/_cli.py +580 -0
  615. synapse/tools/storm/_http.py +409 -0
  616. synapse/tools/storm/_printer.py +152 -0
  617. synapse/tools/storm/pkg/__init__.py +0 -0
  618. synapse/tools/storm/pkg/doc.py +111 -0
  619. synapse/tools/storm/pkg/gen.py +485 -0
  620. synapse/tools/storm/pkg/publish.py +176 -0
  621. synapse/tools/storm/tester.py +94 -0
  622. synapse/tools/storm/validate.py +50 -0
  623. synapse/tools/utils/__init__.py +0 -0
  624. synapse/tools/utils/doc.py +47 -0
  625. synapse/tools/utils/easycert.py +136 -0
  626. synapse/tools/utils/guid.py +11 -0
  627. synapse/tools/utils/json2mpk.py +46 -0
  628. synapse/tools/utils/mdstorm.py +78 -0
  629. synapse/utils/__init__.py +0 -0
  630. synapse/utils/getrefs.py +96 -0
  631. synapse/utils/stormcov.py +910 -0
  632. synapse/vendor/__init__.py +0 -0
  633. synapse/vendor/cashaddress/LICENSE +25 -0
  634. synapse/vendor/cashaddress/__init__.py +5 -0
  635. synapse/vendor/cashaddress/base58.py +134 -0
  636. synapse/vendor/cashaddress/convert.py +131 -0
  637. synapse/vendor/cashaddress/crypto.py +70 -0
  638. synapse/vendor/cashaddress/tests/__init__.py +0 -0
  639. synapse/vendor/cashaddress/tests/test_cashaddress.py +65 -0
  640. synapse/vendor/cpython/LICENSE +279 -0
  641. synapse/vendor/cpython/__init__.py +0 -0
  642. synapse/vendor/cpython/lib/__init__.py +0 -0
  643. synapse/vendor/cpython/lib/email/__init__.py +0 -0
  644. synapse/vendor/cpython/lib/email/_parseaddr.py +566 -0
  645. synapse/vendor/cpython/lib/email/utils.py +494 -0
  646. synapse/vendor/cpython/lib/ipaddress.py +2420 -0
  647. synapse/vendor/cpython/lib/json.py +35 -0
  648. synapse/vendor/cpython/lib/test/__init__.py +0 -0
  649. synapse/vendor/cpython/lib/test/support/__init__.py +114 -0
  650. synapse/vendor/cpython/lib/test/test_email/__init__.py +0 -0
  651. synapse/vendor/cpython/lib/test/test_email/test_email.py +490 -0
  652. synapse/vendor/cpython/lib/test/test_email/test_parseaddr.py +47 -0
  653. synapse/vendor/cpython/lib/test/test_email/test_utils.py +173 -0
  654. synapse/vendor/cpython/lib/test/test_ipaddress.py +2862 -0
  655. synapse/vendor/cpython/lib/test/test_json.py +22 -0
  656. synapse/vendor/substrateinterface/LICENSE +206 -0
  657. synapse/vendor/substrateinterface/__init__.py +20 -0
  658. synapse/vendor/substrateinterface/tests/__init__.py +0 -0
  659. synapse/vendor/substrateinterface/tests/test_ss58.py +207 -0
  660. synapse/vendor/substrateinterface/utils/__init__.py +34 -0
  661. synapse/vendor/substrateinterface/utils/ss58.py +250 -0
  662. synapse/vendor/utils.py +9 -0
  663. synapse/vendor/xrpl/LICENSE +13 -0
  664. synapse/vendor/xrpl/__init__.py +26 -0
  665. synapse/vendor/xrpl/constants.py +30 -0
  666. synapse/vendor/xrpl/core/__init__.py +5 -0
  667. synapse/vendor/xrpl/core/addresscodec/__init__.py +39 -0
  668. synapse/vendor/xrpl/core/addresscodec/codec.py +210 -0
  669. synapse/vendor/xrpl/core/addresscodec/exceptions.py +9 -0
  670. synapse/vendor/xrpl/core/addresscodec/main.py +156 -0
  671. synapse/vendor/xrpl/core/addresscodec/utils.py +7 -0
  672. synapse/vendor/xrpl/tests/__init__.py +0 -0
  673. synapse/vendor/xrpl/tests/test_codec.py +170 -0
  674. synapse/vendor/xrpl/tests/test_main.py +134 -0
  675. synapse/vendor/xrpl/tests/test_main_test_cases.py +134 -0
  676. synapse-3.0.0.dist-info/METADATA +89 -0
  677. synapse-3.0.0.dist-info/RECORD +680 -0
  678. synapse-3.0.0.dist-info/WHEEL +5 -0
  679. synapse-3.0.0.dist-info/licenses/LICENSE +202 -0
  680. synapse-3.0.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,1050 @@
1
+ import os
2
+ import ssl
3
+ import shutil
4
+
5
+ import synapse.exc as s_exc
6
+ import synapse.common as s_common
7
+
8
+ import synapse.lib.json as s_json
9
+ import synapse.lib.certdir as s_certdir
10
+ import synapse.lib.httpapi as s_httpapi
11
+ import synapse.lib.stormctrl as s_stormctrl
12
+
13
+ import synapse.tests.utils as s_test
14
+
15
+ class TstWebSock(s_httpapi.WebSocket):
16
+
17
+ def initialize(self):
18
+ pass
19
+
20
+ async def open(self):
21
+ resp = {'hi': 'woot', 'headers': dict(self.request.headers)}
22
+
23
+ params = {}
24
+ for k, v in self.request.query_arguments.items():
25
+ v = [_s.decode() for _s in v]
26
+ params[k] = v
27
+
28
+ if params:
29
+ resp['params'] = params
30
+
31
+ await self.sendJsonMesg(resp)
32
+
33
+ async def on_message(self, byts):
34
+ mesg = s_json.loads(byts)
35
+ await self.sendJsonMesg(('echo', mesg), binary=True)
36
+
37
+ async def sendJsonMesg(self, item, binary=False):
38
+ byts = s_json.dumps(item)
39
+ await self.write_message(byts, binary=binary)
40
+
41
+ class HttpNotJson(s_httpapi.Handler):
42
+ async def get(self):
43
+ self.write(b"{'not':'json!'}")
44
+
45
+ class HttpBadJson(s_httpapi.Handler):
46
+ async def get(self):
47
+ self.write(b'{"foo": "bar\x80"}')
48
+
49
+ class HttpGiantHeader(s_httpapi.Handler):
50
+ async def get(self):
51
+ self.set_header('Giant', 'x' * 64_000)
52
+ self.write('test')
53
+
54
+ class HttpMultiCookie(s_httpapi.Handler):
55
+ async def get(self):
56
+ self.add_header('Set-Cookie', 'cookie_one=value1; Path=/')
57
+ self.add_header('Set-Cookie', 'cookie_two=value2; Path=/')
58
+ self.write('ok')
59
+
60
+ class StormHttpTest(s_test.SynTest):
61
+
62
+ async def test_storm_http_get(self):
63
+
64
+ async with self.getTestCore() as core:
65
+ addr, port = await core.addHttpsPort(0)
66
+ root = await core.auth.getUserByName('root')
67
+ visi = await core.auth.addUser('visi')
68
+ await root.setPasswd('root')
69
+
70
+ core.addHttpApi('/api/v0/test', s_test.HttpReflector, {'cell': core})
71
+ core.addHttpApi('/api/v0/notjson', HttpNotJson, {'cell': core})
72
+ core.addHttpApi('/api/v0/badjson', HttpBadJson, {'cell': core})
73
+ core.addHttpApi('/api/v0/giantheader', HttpGiantHeader, {'cell': core})
74
+ url = f'https://root:root@127.0.0.1:{port}/api/v0/test'
75
+ status_url = f'https://127.0.0.1:{port}/api/v3/status'
76
+ opts = {'vars': {'url': url, 'port': port, 'status_url': status_url}}
77
+
78
+ # Request URL is exposed
79
+ q = '''
80
+ $resp = $lib.inet.http.get($url, ssl=({"verify": false}))
81
+ return ( $resp.url )
82
+ '''
83
+ resp = await core.callStorm(q, opts=opts)
84
+ # The password is omitted
85
+ self.eq(resp, f'https://127.0.0.1:{port}/api/v0/test')
86
+
87
+ # Redirects expose the final URL
88
+ q = '''
89
+ $params = ({'redirect': $status_url})
90
+ $resp = $lib.inet.http.get($url, params=$params, ssl=({"verify": false}))
91
+ return ( $resp.url )
92
+ '''
93
+ resp = await core.callStorm(q, opts=opts)
94
+ self.eq(resp, f'https://127.0.0.1:{port}/api/v3/status')
95
+
96
+ q = '''
97
+ $_url = `https://root:root@127.0.0.1:{($port + (1))}/api/v0/newp`
98
+ $resp = $lib.inet.http.get($_url, ssl=({"verify": false}))
99
+ if ( $resp.code != (-1) ) { $lib.exit(mesg='Test fail!') }
100
+ return ( $resp.url )
101
+ '''
102
+ resp = await core.callStorm(q, opts=opts)
103
+ # The password is present
104
+ self.eq(resp, f'https://root:root@127.0.0.1:{port + 1}/api/v0/newp')
105
+
106
+ # Header and params as dict
107
+ q = '''
108
+ $params=({"key": "valu", "foo": "bar", "baz": false})
109
+ $hdr = ({"true": true})
110
+ $hdr."User-Agent"="Storm HTTP Stuff"
111
+ $k = (0)
112
+ $hdr.$k="Why"
113
+ $resp = $lib.inet.http.get($url, headers=$hdr, params=$params, ssl=({"verify": false}))
114
+ return ( $resp.json() )
115
+ '''
116
+ resp = await core.callStorm(q, opts=opts)
117
+ data = resp.get('result')
118
+ self.eq(data.get('params'), {'key': ('valu',), 'foo': ('bar',), 'baz': ('False',)})
119
+ self.eq(data.get('headers').get('User-Agent'), 'Storm HTTP Stuff')
120
+ self.eq(data.get('headers').get('0'), 'Why')
121
+ self.eq(data.get('headers').get('True'), 'True')
122
+
123
+ # headers / params as list of key/value pairs
124
+ q = '''
125
+ $params=((foo, bar), (key, valu), (baz, (false)))
126
+ $hdr = (
127
+ ("User-Agent", "Storm HTTP Stuff"),
128
+ ((0), "Why"),
129
+ ("true", (true)),
130
+ )
131
+ $resp = $lib.inet.http.get($url, headers=$hdr, params=$params, ssl=({"verify": false}))
132
+ return ( $resp.json() )
133
+ '''
134
+ resp = await core.callStorm(q, opts=opts)
135
+ data = resp.get('result')
136
+ self.eq(data.get('params'), {'key': ('valu',), 'foo': ('bar',), 'baz': ('False',)})
137
+ self.eq(data.get('headers').get('User-Agent'), 'Storm HTTP Stuff')
138
+ self.eq(data.get('headers').get('0'), 'Why')
139
+ self.eq(data.get('headers').get('True'), 'True')
140
+
141
+ # headers
142
+ q = '''
143
+ $resp = $lib.inet.http.get($url, ssl=({"verify": false}))
144
+ return ( $resp.headers."Content-Type" )
145
+ '''
146
+ resp = await core.callStorm(q, opts=opts)
147
+ self.eq(resp, 'application/json; charset=UTF-8')
148
+
149
+ # Request headers
150
+ q = '''
151
+ $headers = ({"Wow": "OhMy"})
152
+ $resp = $lib.inet.http.get($url, headers=$headers, ssl=({"verify": false}))
153
+ return ( $resp.request_headers )
154
+ '''
155
+ resp = await core.callStorm(q, opts=opts)
156
+ self.eq(resp.get('Wow'), 'OhMy')
157
+ # Authorization header derived from the basic auth in $url
158
+ self.isin('Authorization', resp)
159
+
160
+ badurl = f'https://root:root@127.0.0.1:{port}/api/v0/notjson'
161
+ badopts = {'vars': {'url': badurl}}
162
+ q = '''
163
+ $resp = $lib.inet.http.get($url, ssl=({"verify": false}))
164
+ return ( $resp.json() )
165
+ '''
166
+ with self.raises(s_exc.BadJsonText) as cm:
167
+ resp = await core.callStorm(q, opts=badopts)
168
+ self.isin('Unable to decode HTTP response as json', cm.exception.get('mesg'))
169
+ self.eq(cm.exception.get('text'), "{'not':'json!'}")
170
+
171
+ # params as a urlencoded string
172
+ q = '''
173
+ $params="foo=bar&key=valu&foo=baz"
174
+ $resp = $lib.inet.http.get($url, params=$params, ssl=({"verify": false}))
175
+ return ( $resp.json() )
176
+ '''
177
+ resp = await core.callStorm(q, opts=opts)
178
+ data = resp.get('result')
179
+ self.eq(data.get('params'), {'key': ('valu',), 'foo': ('bar', 'baz')})
180
+
181
+ # Bad param
182
+ q = '''
183
+ $params=(1138)
184
+ $resp = $lib.inet.http.get($url, params=$params, ssl=({"verify": false}))
185
+ return ( ($resp.code, $resp.reason, $resp.err) )
186
+ '''
187
+ code, reason, (errname, _) = await core.callStorm(q, opts=opts)
188
+ self.eq(code, -1)
189
+ self.isin('Exception occurred during request: ', reason)
190
+ self.isin('Invalid query type', reason)
191
+ self.eq('TypeError', errname)
192
+
193
+ # SSL Verify enabled results in an aiohttp.ClientConnectorCertificateError
194
+ q = '''
195
+ $params=((foo, bar), (key, valu))
196
+ $resp = $lib.inet.http.get($url, params=$params)
197
+ return ( ($resp.code, $resp.reason, $resp.err) )
198
+ '''
199
+ code, reason, (errname, _) = await core.callStorm(q, opts=opts)
200
+ self.eq(code, -1)
201
+ self.isin('certificate verify failed', reason)
202
+ self.eq('ClientConnectorCertificateError', errname)
203
+
204
+ retn = await core.callStorm('return($lib.inet.http.urlencode("http://go ogle.com"))')
205
+ self.eq('http%3A%2F%2Fgo+ogle.com', retn)
206
+
207
+ retn = await core.callStorm('return($lib.inet.http.urldecode("http%3A%2F%2Fgo+ogle.com"))')
208
+ self.eq('http://go ogle.com', retn)
209
+
210
+ badurl = f'https://root:root@127.0.0.1:{port}/api/v0/badjson'
211
+ badopts = {'vars': {'url': badurl}}
212
+ q = '''
213
+ $resp = $lib.inet.http.get($url, ssl=({"verify": false}))
214
+ return ( $resp.json(strict=(true)) )
215
+ '''
216
+ with self.raises(s_exc.StormRuntimeError) as cm:
217
+ resp = await core.callStorm(q, opts=badopts)
218
+
219
+ q = '''
220
+ $resp = $lib.inet.http.get($url, ssl=({"verify": false}))
221
+ return ( $resp.json(encoding=utf8) )
222
+ '''
223
+ self.eq({"foo": "bar�"}, await core.callStorm(q, opts=badopts))
224
+
225
+ retn = await core.callStorm('return($lib.inet.http.codereason(404))')
226
+ self.eq(retn, 'Not Found')
227
+
228
+ retn = await core.callStorm('return($lib.inet.http.codereason(123))')
229
+ self.eq(retn, 'Unknown HTTP status code 123')
230
+
231
+ # Request history is preserved across multiple redirects.
232
+ q = '''$api = $lib.cortex.httpapi.add(dyn00)
233
+ $api.methods.get = ${
234
+ $api = $request.api
235
+ if $n {
236
+ $part = `redir0{$n}`
237
+ $redir = `/api/ext/{$part}`
238
+ $headers = ({"Location": $redir})
239
+ $api.vars.n = ($n - (1) )
240
+ $api.path = $part
241
+ $request.reply(301, headers=$headers)
242
+ } else {
243
+ $api.vars.n = $initial_n
244
+ $api.path = dyn00
245
+ $request.reply(200, body=({"end": "youMadeIt"}) )
246
+ }
247
+ }
248
+ $api.authenticated = (false)
249
+ $api.vars.initial_n = (3)
250
+ $api.vars.n = (3)
251
+ return ( ($api.iden) )'''
252
+ iden00 = await core.callStorm(q)
253
+
254
+ q = '''
255
+ $url = `https://127.0.0.1:{$port}/api/ext/dyn00`
256
+ $resp = $lib.inet.http.get($url, ssl=({"verify": false}))
257
+ return ( $resp )
258
+ '''
259
+ resp = await core.callStorm(q, opts=opts)
260
+ self.eq(resp.get('url'), f'https://127.0.0.1:{port}/api/ext/redir01')
261
+ self.eq([hnfo.get('url') for hnfo in resp.get('history')],
262
+ [f'https://127.0.0.1:{port}/api/ext/dyn00',
263
+ f'https://127.0.0.1:{port}/api/ext/redir03',
264
+ f'https://127.0.0.1:{port}/api/ext/redir02',
265
+ ])
266
+
267
+ # The gtor returns a list of objects
268
+ q = '''
269
+ $url = `https://127.0.0.1:{$port}/api/ext/dyn00`
270
+ $resp = $lib.inet.http.get($url, ssl=({"verify": false}))
271
+ return ( $resp.history.0 )
272
+ '''
273
+ resp = await core.callStorm(q, opts=opts)
274
+ self.eq(resp.get('url'), f'https://127.0.0.1:{port}/api/ext/dyn00')
275
+
276
+ # The history is not available if there is a fatal error when
277
+ # following redirects.
278
+ q = '''
279
+ $_url = `https://127.0.0.1:{($port + (1))}/api/v0/newp`
280
+ $params = ({'redirect': $_url})
281
+ $resp = $lib.inet.http.get($url, params=$params, ssl=({"verify": false}))
282
+ if ( $resp.code != (-1) ) { $lib.exit(mesg='Test fail!') }
283
+ return ( $resp.history )
284
+ '''
285
+ resp = await core.callStorm(q, opts=opts)
286
+ self.isinstance(resp, tuple)
287
+ self.len(0, resp)
288
+
289
+ gianturl = f'https://root:root@127.0.0.1:{port}/api/v0/giantheader'
290
+ giantopts = {'vars': {'url': gianturl}}
291
+ q = '''
292
+ $resp = $lib.inet.http.get($url, ssl=({"verify": false}))
293
+ return ( $resp )
294
+ '''
295
+ resp = await core.callStorm(q, opts=giantopts)
296
+ self.eq(resp['body'], b'test')
297
+ self.len(64_000, resp['headers'].get('Giant'))
298
+
299
+ async def test_storm_http_multi_value_headers(self):
300
+
301
+ async with self.getTestCore() as core:
302
+ addr, port = await core.addHttpsPort(0)
303
+ root = await core.auth.getUserByName('root')
304
+ await root.setPasswd('root')
305
+
306
+ core.addHttpApi('/api/v0/multicookie', HttpMultiCookie, {'cell': core})
307
+ url = f'https://root:root@127.0.0.1:{port}/api/v0/multicookie'
308
+ opts = {'vars': {'url': url}}
309
+
310
+ q = '''
311
+ $resp = $lib.inet.http.get($url, ssl=({"verify": false}))
312
+ return ( ($resp.headers."Set-Cookie", $resp.getRawHeaders()) )
313
+ '''
314
+ lastval, rawheaders = await core.callStorm(q, opts=opts)
315
+
316
+ # headers dict last-value-wins
317
+ self.eq(lastval, 'cookie_two=value2; Path=/')
318
+
319
+ # getRawHeaders returns all values per header name
320
+ cookies = rawheaders.get('Set-Cookie')
321
+ self.len(2, cookies)
322
+ self.isin('cookie_one=value1; Path=/', cookies)
323
+ self.isin('cookie_two=value2; Path=/', cookies)
324
+
325
+ async def test_storm_http_inject_ca(self):
326
+
327
+ with self.getTestDir() as dirn:
328
+ cdir = s_common.gendir(dirn, 'certs')
329
+ cadir = s_common.gendir(cdir, 'cas')
330
+ tdir = s_certdir.CertDir(cdir)
331
+ tdir.genCaCert('somelocalca')
332
+ tdir.genHostCert('localhost', signas='somelocalca')
333
+
334
+ localkeyfp = tdir.getHostKeyPath('localhost')
335
+ localcertfp = tdir.getHostCertPath('localhost')
336
+ shutil.copyfile(localkeyfp, s_common.genpath(dirn, 'sslkey.pem'))
337
+ shutil.copyfile(localcertfp, s_common.genpath(dirn, 'sslcert.pem'))
338
+
339
+ tlscadir = s_common.gendir(dirn, 'cadir')
340
+ for fn in os.listdir(cadir):
341
+ if fn.endswith('.crt'):
342
+ shutil.copyfile(os.path.join(cadir, fn), os.path.join(tlscadir, fn))
343
+
344
+ async with self.getTestCore(dirn=dirn) as core:
345
+
346
+ root = await core.auth.getUserByName('root')
347
+ await root.setPasswd('root')
348
+
349
+ addr, port = await core.addHttpsPort(0)
350
+ core.addHttpApi('/api/v0/test', s_test.HttpReflector, {'cell': core})
351
+ url = f'https://root:root@localhost:{port}/api/v0/test'
352
+ opts = {'vars': {'url': url}}
353
+ q = '''
354
+ $params=((foo, bar), (key, valu))
355
+ $resp = $lib.inet.http.get($url, params=$params)
356
+ return ( ($resp.code, $resp.err) )
357
+ '''
358
+ code, (errname, _) = await core.callStorm(q, opts=opts)
359
+ self.eq(code, -1)
360
+ self.eq('ClientConnectorCertificateError', errname)
361
+
362
+ conf = {'tls:ca:dir': tlscadir}
363
+ async with self.getTestCore(dirn=dirn, conf=conf) as core:
364
+ addr, port = await core.addHttpsPort(0)
365
+ core.addHttpApi('/api/v0/test', s_test.HttpReflector, {'cell': core})
366
+ url = f'https://root:root@localhost:{port}/api/v0/test'
367
+ opts = {'vars': {'url': url}}
368
+ q = '''
369
+ $params=((foo, bar), (key, valu))
370
+ $resp = $lib.inet.http.get($url, params=$params)
371
+ return ( $resp.json() )
372
+ '''
373
+ resp = await core.callStorm(q, opts=opts)
374
+ data = resp.get('result')
375
+ self.eq(data.get('params'), {'key': ('valu',), 'foo': ('bar',)})
376
+
377
+ async def test_storm_http_head(self):
378
+
379
+ async with self.getTestCore() as core:
380
+ addr, port = await core.addHttpsPort(0)
381
+ root = await core.auth.getUserByName('root')
382
+ await root.setPasswd('root')
383
+ core.addHttpApi('/api/v0/test', s_test.HttpReflector, {'cell': core})
384
+
385
+ url = f'https://root:root@127.0.0.1:{port}/api/v0/test'
386
+ noauth_url = f'https://127.0.0.1:{port}/api/v0/test'
387
+ newp_url = noauth_url + 'newpnewp'
388
+ opts = {'vars': {'url': url, 'noauth_url': noauth_url, 'newp_url': newp_url}}
389
+
390
+ q = '''
391
+ $params=({"key": "valu", "foo": "bar"})
392
+ $hdr = (
393
+ ("User-Agent", "Storm HTTP Stuff"),
394
+ )
395
+ $resp = $lib.inet.http.head($url, headers=$hdr, params=$params, ssl=({"verify": false}))
396
+ return ( ($resp.code, $resp.reason, $resp.headers, $resp.body) )
397
+ '''
398
+ resp = await core.callStorm(q, opts=opts)
399
+ code, reason, headers, body = resp
400
+ self.eq(code, 200)
401
+ self.eq(reason, 'OK')
402
+ self.eq(b'', body)
403
+ self.eq('0', headers.get('Content-Length'))
404
+ self.eq('1', headers.get('Head'))
405
+
406
+ q = '''
407
+ $params=({"key": "valu", "redirect": 'http://test.newp/'})
408
+ $hdr = (
409
+ ("User-Agent", "Storm HTTP Stuff"),
410
+ )
411
+ $resp = $lib.inet.http.head($url, headers=$hdr, params=$params, ssl=({"verify": false}))
412
+ return ( ($resp.code, $resp.headers, $resp.body) )
413
+ '''
414
+ resp = await core.callStorm(q, opts=opts)
415
+ code, headers, body = resp
416
+ self.eq(code, 302)
417
+ self.eq(b'', body)
418
+ self.eq('0', headers.get('Content-Length'))
419
+ self.eq('1', headers.get('Head'))
420
+ self.eq('1', headers.get('Redirected'))
421
+ self.eq('http://test.newp/', headers.get('Location'))
422
+
423
+ q = '''
424
+ $params=({"key": "valu", "redirect": $noauth_url})
425
+ $hdr = (
426
+ ("User-Agent", "Storm HTTP Stuff"),
427
+ )
428
+ $resp = $lib.inet.http.head($url, headers=$hdr, params=$params, ssl=({"verify": false}), allow_redirects=(true))
429
+ return ( ($resp.code, $resp.headers, $resp.body) )
430
+ '''
431
+ resp = await core.callStorm(q, opts=opts)
432
+ code, headers, body = resp
433
+ self.eq(code, 200)
434
+ self.eq(b'', body)
435
+
436
+ q = '''
437
+ $params=({"key": "valu", "redirect": $newp_url})
438
+ $hdr = (
439
+ ("User-Agent", "Storm HTTP Stuff"),
440
+ )
441
+ $resp = $lib.inet.http.head($url, headers=$hdr, params=$params, ssl=({"verify": false}), allow_redirects=(true))
442
+ return ( ($resp.code, $resp.headers, $resp.body) )
443
+ '''
444
+ resp = await core.callStorm(q, opts=opts)
445
+ code, headers, body = resp
446
+ self.eq(code, 404)
447
+ self.eq(b'', body)
448
+
449
+ q = '''
450
+ $params=({"key": "valu", "redirect": "http://127.0.0.1/newp"})
451
+ $hdr = (
452
+ ("User-Agent", "Storm HTTP Stuff"),
453
+ )
454
+ $resp = $lib.inet.http.head($url, headers=$hdr, params=$params, ssl=({"verify": false}), allow_redirects=(true))
455
+ return ( ($resp.code, $resp.headers, $resp.body) )
456
+ '''
457
+ resp = await core.callStorm(q, opts=opts)
458
+ code, headers, body = resp
459
+ self.eq(code, -1)
460
+ self.eq(b'', body)
461
+
462
+ async def test_storm_http_request(self):
463
+
464
+ async with self.getTestCore() as core:
465
+ addr, port = await core.addHttpsPort(0)
466
+ root = await core.auth.getUserByName('root')
467
+ await root.setPasswd('root')
468
+ core.addHttpApi('/api/v0/test', s_test.HttpReflector, {'cell': core})
469
+ url = f'https://root:root@127.0.0.1:{port}/api/v0/test'
470
+ opts = {'vars': {'url': url}}
471
+ q = '''
472
+ $params=({"key": "valu", "foo": "bar"})
473
+ $hdr = (
474
+ ("User-Agent", "Storm HTTP Stuff"),
475
+ )
476
+ $resp = $lib.inet.http.request(GET, $url, headers=$hdr, params=$params, ssl=({"verify": false}))
477
+ return ( $resp.json() )
478
+ '''
479
+ resp = await core.callStorm(q, opts=opts)
480
+ data = resp.get('result')
481
+ self.eq(data.get('params'), {'key': ('valu',), 'foo': ('bar',)})
482
+ self.eq(data.get('headers').get('User-Agent'), 'Storm HTTP Stuff')
483
+
484
+ # Timeout
485
+ url = f'https://root:root@127.0.0.1:{port}/api/v0/test'
486
+ opts = {'vars': {'url': url, 'sleep': 1, 'timeout': 2}}
487
+ q = '''
488
+ $params=({"key": "valu", "foo": "bar", "sleep": $sleep})
489
+ $hdr = (
490
+ ("User-Agent", "Storm HTTP Stuff"),
491
+ )
492
+ $resp = $lib.inet.http.request(GET, $url, headers=$hdr, params=$params, ssl=({"verify": false}), timeout=$timeout)
493
+ $code = $resp.code
494
+ return ($code)
495
+ '''
496
+ code = await core.callStorm(q, opts=opts)
497
+ self.eq(200, code)
498
+
499
+ url = f'https://root:root@127.0.0.1:{port}/api/v0/test'
500
+ opts = {'vars': {'url': url, 'sleep': 10, 'timeout': 1}}
501
+ q = '''
502
+ $params=({"key": "valu", "foo": "bar", "sleep": $sleep})
503
+ $hdr = (
504
+ ("User-Agent", "Storm HTTP Stuff"),
505
+ )
506
+ $resp = $lib.inet.http.request(GET, $url, headers=$hdr, params=$params, ssl=({"verify": false}), timeout=$timeout)
507
+ $code = $resp.code
508
+ return (($code, $resp.err))
509
+ '''
510
+ code, (errname, errinfo) = await core.callStorm(q, opts=opts)
511
+ self.eq(code, -1)
512
+ self.eq('TimeoutError', errname)
513
+ self.isin('mesg', errinfo)
514
+ self.eq('', errinfo.get('mesg')) # timeouterror has no mesg
515
+
516
+ q = '''
517
+ $params=({"foo": ["bar", "baz"], "key": [["valu"]]})
518
+ $resp = $lib.inet.http.request(GET, $url, params=$params, ssl=({"verify": false}))
519
+ return ( $resp.json() )
520
+ '''
521
+ resp = await core.callStorm(q, opts=opts)
522
+ data = resp.get('result')
523
+ self.eq(data.get('params'), {'foo': ['bar', 'baz'], 'key': ["('valu',)"]})
524
+
525
+ # headers are safe to serialize
526
+ q = '''
527
+ $headers = ({'Foo': 'Bar'})
528
+ $resp = $lib.inet.http.request(GET, $url, headers=$headers, ssl=({"verify": false}))
529
+ return ( ($lib.json.save($resp.headers), $lib.json.save($resp.request_headers)) )
530
+ '''
531
+ resp = await core.callStorm(q, opts=opts)
532
+ (headers, req_headers) = resp
533
+ headers = s_json.loads(headers)
534
+ self.eq(headers.get('Content-Type'), 'application/json; charset=UTF-8')
535
+ req_headers = s_json.loads(req_headers)
536
+ self.eq(req_headers.get('Foo'), 'Bar')
537
+
538
+ async def test_storm_http_post_base(self):
539
+
540
+ async with self.getTestCluster() as clus:
541
+ core = clus.cortex
542
+ addr, port = await core.addHttpsPort(0)
543
+ root = await core.auth.getUserByName('root')
544
+ await root.setPasswd('root')
545
+
546
+ adduser = '''
547
+ $url = `https://root:root@127.0.0.1:{$port}/api/v3/auth/adduser`
548
+ $user = ({"name": $name, "passwd": $passwd})
549
+ $post = $lib.inet.http.post($url, json=$user, ssl=({"verify": false})).json().result.name
550
+ $lib.print($post)
551
+ [ test:str=$post ]
552
+ '''
553
+ opts = {'vars': {'port': port, 'name': 'foo', 'passwd': 'bar'}}
554
+ nodes = await core.nodes(adduser, opts=opts)
555
+ self.len(1, nodes)
556
+ self.assertIn('foo', [u.name for u in core.auth.users()])
557
+
558
+ adduser = '''
559
+ $url = `https://root:root@127.0.0.1:{$port}/api/v3/auth/adduser`
560
+ $user = $lib.json.save( ({"name": $name, "passwd": $passwd}) )
561
+ $header = ({"Content-Type": "application/json"})
562
+ $post = $lib.inet.http.post($url, headers=$header, body=$user, ssl=({"verify": false})).json().result.name
563
+ [ test:str=$post ]
564
+ '''
565
+ opts = {'vars': {'port': port, 'name': 'vertex', 'passwd': 'project'}}
566
+ nodes = await core.nodes(adduser, opts=opts)
567
+ self.len(1, nodes)
568
+ self.assertIn('vertex', [u.name for u in core.auth.users()])
569
+
570
+ core.addHttpApi('/api/v0/test', s_test.HttpReflector, {'cell': core})
571
+ url = f'https://root:root@127.0.0.1:{port}/api/v0/test'
572
+ opts = {'vars': {'url': url, 'buf': b'1234'}}
573
+ q = '''
574
+ $params=({"key": "valu", "foo": "bar"})
575
+ $resp = $lib.inet.http.post($url, params=$params, body=$buf, ssl=({"verify": false}))
576
+ return ( $resp.json() )
577
+ '''
578
+ resp = await core.callStorm(q, opts=opts)
579
+ data = resp.get('result')
580
+ self.eq(data.get('params'), {'key': ('valu',), 'foo': ('bar',)})
581
+ self.eq(data.get('body'), 'MTIzNA==')
582
+
583
+ q = '''
584
+ $fields=([
585
+ {"name": "foo", "value": "bar"},
586
+ {"name": "foo", "value": "bar2"},
587
+ {"name": "baz", "value": "cool"}
588
+ ])
589
+ $resp = $lib.inet.http.post($url, fields=$fields, ssl=({"verify": false}))
590
+ return ( $resp.json() )
591
+ '''
592
+ resp = await core.callStorm(q, opts=opts)
593
+ data = resp.get('result')
594
+ self.eq(data.get('params'), {'foo': ('bar', 'bar2'), 'baz': ('cool',)})
595
+
596
+ # We can send multipart/form-data directly
597
+ q = '''
598
+ $buf = $lib.hex.decode(deadb33f)
599
+ $fields = ([
600
+ {"filename": 'deadb33f.exe', "value": $buf, "name": "word"},
601
+ ])
602
+ return($lib.inet.http.post($url, ssl=({"verify": false}), fields=$fields))
603
+ '''
604
+ resp = await core.callStorm(q, opts=opts)
605
+ request = s_json.loads(resp.get('body'))
606
+ request_headers = request.get('result').get('headers')
607
+ self.isin('multipart/form-data; boundary=', request_headers.get('Content-Type', ''))
608
+
609
+ q = '''
610
+ $fields = ([
611
+ {"forgot": "name", "sha256": "newp"},
612
+ ])
613
+ return($lib.inet.http.post($url, ssl=({"verify": false}), fields=$fields))
614
+ '''
615
+ resp = await core.callStorm(q, opts=opts)
616
+ self.eq(resp.get('code'), -1)
617
+ self.isin('BadArg: Each field requires a "name" key with a string value: None', resp.get('reason'))
618
+
619
+ q = '''
620
+ $buf = $lib.hex.decode(deadb33f)
621
+ $fields = ([
622
+ {"filename": 'deadbeef.exe', "value": $buf},
623
+ ])
624
+ return($lib.inet.http.post($url, ssl=({"verify": false}), fields=$fields))
625
+ '''
626
+ resp = await core.callStorm(q, opts=opts)
627
+ err = resp['err']
628
+ experr = 'Each field requires a "name" key with a string value: None'
629
+ self.eq(experr, err[1].get('mesg'))
630
+
631
+ async def test_storm_http_post_file(self):
632
+
633
+ async with self.getTestCluster() as clus:
634
+ core = clus.cortex
635
+
636
+ addr, port = await core.addHttpsPort(0)
637
+ root = await core.auth.getUserByName('root')
638
+ await root.setPasswd('root')
639
+ rootkey, _ = await core.addUserApiKey(root.iden, 'test')
640
+ text = '''
641
+ $url = `https://127.0.0.1:{$port}/api/v3/storm`
642
+ $stormq = "($size, $sha2) = $lib.axon.put($lib.base64.decode('dmVydGV4')) [ test:str = $sha2 ] [ test:int = $size ]"
643
+ $json = ({"query": $stormq})
644
+ $headers = ({"X-API-KEY": $apikey})
645
+ $bytez = $lib.inet.http.post($url, json=$json, headers=$headers, ssl=({"verify": false}))
646
+ '''
647
+ opts = {'vars': {'port': port, 'apikey': rootkey}}
648
+ nodes = await core.nodes(text, opts=opts)
649
+ nodes = await core.nodes('test:str')
650
+ self.len(1, nodes)
651
+ self.eq(nodes[0].ndef, ('test:str', 'e1b683e26a3aad218df6aa63afe9cf57fdb5dfaf5eb20cddac14305d67f48a02'))
652
+
653
+ nodes = await core.nodes('test:int')
654
+ self.len(1, nodes)
655
+ self.eq(nodes[0].ndef, ('test:int', 6))
656
+
657
+ text = '''
658
+ $url = `https://127.0.0.1:{$port}/api/v3/storm`
659
+ $json = ({"query": "test:str"})
660
+ $body = $json
661
+ $headers = ({"X-API-KEY": $apikey})
662
+ $resp=$lib.inet.http.post($url, json=$json, body=$body, headers=$headers, ssl=({"verify": false}))
663
+ return ( ($resp.code, $resp.err) )
664
+ '''
665
+ code, (errname, _) = await core.callStorm(text, opts=opts)
666
+ self.eq(code, -1)
667
+ self.eq('ValueError', errname)
668
+
669
+ async def test_storm_http_proxy(self):
670
+ conf = {'http:proxy': 'socks5://user:pass@127.0.0.1:1'}
671
+ async with self.getTestCluster({'cortex': {'conf': conf}, 'axon': {'conf': conf}}) as clus:
672
+ core = clus.cortex
673
+ resp = await core.callStorm('return($lib.axon.wget("http://vertex.link"))')
674
+ self.false(resp.get('ok'))
675
+ self.ne(-1, resp['mesg'].find('connect to proxy 127.0.0.1:1'))
676
+
677
+ msgs = await core.stormlist('$resp=$lib.axon.wget("http://vertex.link", proxy=(null)) $lib.print($resp.mesg)')
678
+ self.stormIsInErr('HTTP proxy argument must be a string or bool.', msgs)
679
+
680
+ await self.asyncraises(s_exc.BadArg, core.nodes('$lib.axon.wget("http://vertex.link", proxy=(1.1))'))
681
+
682
+ size, sha256 = await (await core.getAxon()).put(b'asdf')
683
+ opts = {'vars': {'sha256': s_common.ehex(sha256)}}
684
+ resp = await core.callStorm('return($lib.axon.wput($sha256, http://vertex.link))', opts=opts)
685
+ self.false(resp.get('ok'))
686
+ self.isin('connect to proxy 127.0.0.1:1', resp['mesg'])
687
+
688
+ q = '$resp=$lib.inet.http.get("http://vertex.link") return(($resp.code, $resp.err))'
689
+ code, (errname, errinfo) = await core.callStorm(q)
690
+ self.eq(code, -1)
691
+ self.isin("connect to proxy 127.0.0.1:1", errinfo.get('mesg'))
692
+
693
+ msgs = await core.stormlist('$resp=$lib.inet.http.get("http://vertex.link", proxy=(null)) $lib.print($resp.err)')
694
+ self.stormIsInErr('HTTP proxy argument must be a string or bool.', msgs)
695
+
696
+ await self.asyncraises(s_exc.BadArg, core.nodes('$lib.inet.http.get("http://vertex.link", proxy=(1.1))'))
697
+
698
+ async with self.getTestCluster() as clus:
699
+ core = clus.cortex
700
+
701
+ visi = await core.auth.addUser('visi')
702
+ await visi.addRule((True, ('axon', 'get')))
703
+ await visi.addRule((True, ('axon', 'upload')))
704
+
705
+ errmsg = f'User {visi.name!r} ({visi.iden}) must have permission {{perm}}'
706
+
707
+ asvisi = {'user': visi.iden}
708
+ msgs = await core.stormlist('$lib.inet.http.get(http://vertex.link, proxy=(false))', opts=asvisi)
709
+ self.stormIsInErr(errmsg.format(perm='inet.http.proxy'), msgs)
710
+
711
+ asvisi = {'user': visi.iden}
712
+ msgs = await core.stormlist('$lib.inet.http.get(http://vertex.link, proxy=socks5://user:pass@127.0.0.1:1)', opts=asvisi)
713
+ self.stormIsInErr(errmsg.format(perm='inet.http.proxy'), msgs)
714
+
715
+ resp = await core.callStorm('return($lib.inet.http.get(http://vertex.link, proxy=socks5://user:pass@127.0.0.1:1))')
716
+ self.isin("connect to proxy 127.0.0.1:1", resp['err'][1].get('mesg'))
717
+
718
+ # test $lib.axon proxy API
719
+ asvisi = {'user': visi.iden}
720
+ msgs = await core.stormlist('$lib.axon.wget(http://vertex.link, proxy=(false))', opts=asvisi)
721
+ self.stormIsInErr(errmsg.format(perm='inet.http.proxy'), msgs)
722
+
723
+ asvisi = {'user': visi.iden}
724
+ msgs = await core.stormlist('$lib.axon.wget(http://vertex.link, proxy=socks5://user:pass@127.0.0.1:1)', opts=asvisi)
725
+ self.stormIsInErr(errmsg.format(perm='inet.http.proxy'), msgs)
726
+
727
+ asvisi = {'user': visi.iden}
728
+ msgs = await core.stormlist('$lib.axon.wput(asdf, http://vertex.link, proxy=socks5://user:pass@127.0.0.1:1)', opts=asvisi)
729
+ self.stormIsInErr(errmsg.format(perm='inet.http.proxy'), msgs)
730
+
731
+ resp = await core.callStorm('return($lib.axon.wget(http://vertex.link, proxy=socks5://user:pass@127.0.0.1:1))')
732
+ self.false(resp.get('ok'))
733
+ self.isin('connect to proxy 127.0.0.1:1', resp['mesg'])
734
+
735
+ size, sha256 = await (await core.getAxon()).put(b'asdf')
736
+
737
+ sha256 = s_common.ehex(sha256)
738
+ resp = await core.callStorm(f'return($lib.axon.wput({sha256}, http://vertex.link, proxy=socks5://user:pass@127.0.0.1:1))')
739
+ self.false(resp.get('ok'))
740
+ self.isin('connect to proxy 127.0.0.1:1', resp['mesg'])
741
+
742
+ async with self.getTestCluster({'cortex': {'conf': conf}, 'axon': {'conf': conf}}) as clus:
743
+ core = clus.cortex
744
+ # Proxy permission tests in this section
745
+
746
+ visi = await core.auth.addUser('visi')
747
+
748
+ await visi.addRule((True, ('axon', 'get')))
749
+ await visi.addRule((True, ('axon', 'upload')))
750
+
751
+ _, sha256 = await (await core.getAxon()).put(b'asdf')
752
+ sha256 = s_common.ehex(sha256)
753
+
754
+ host, port = await core.addHttpsPort(0)
755
+
756
+ q1 = 'return($lib.inet.http.get(`https://loop.vertex.link:{$port}`, ssl=({"verify": false}), proxy=$proxy))'
757
+ q2 = 'return($lib.axon.wget(`https://loop.vertex.link:{$port}`, ssl=({"verify": false}), proxy=$proxy))'
758
+ q3 = 'return($lib.axon.wput($sha256, `https://loop.vertex.link:{$port}`, ssl=({"verify": false}), proxy=$proxy))'
759
+
760
+ for proxy in ('socks5://user:pass@127.0.0.1:1', False):
761
+ opts = {'vars': {'proxy': proxy, 'port': port, 'sha256': sha256}, 'user': visi.iden}
762
+
763
+ with self.raises(s_exc.AuthDeny):
764
+ await core.callStorm(q1, opts=opts)
765
+
766
+ with self.raises(s_exc.AuthDeny):
767
+ await core.callStorm(q2, opts=opts)
768
+
769
+ with self.raises(s_exc.AuthDeny):
770
+ await core.callStorm(q3, opts=opts)
771
+
772
+ # Add permissions to use a proxy
773
+ await visi.addRule((True, ('inet', 'http', 'proxy')))
774
+
775
+ opts = {'vars': {'proxy': 'socks5://user:pass@127.0.0.1:1', 'port': port, 'sha256': sha256}, 'user': visi.iden}
776
+
777
+ resp = await core.callStorm(q1, opts=opts)
778
+ self.isin("connect to proxy 127.0.0.1:1", resp['err'][1].get('mesg'))
779
+
780
+ resp = await core.callStorm(q2, opts=opts)
781
+ self.isin("connect to proxy 127.0.0.1:1", resp['err'][1].get('mesg'))
782
+
783
+ resp = await core.callStorm(q3, opts=opts)
784
+ self.isin("connect to proxy 127.0.0.1:1", resp['err'][1].get('mesg'))
785
+
786
+ opts = {'vars': {'proxy': False, 'port': port, 'sha256': sha256}, 'user': visi.iden}
787
+
788
+ resp = await core.callStorm(q1, opts=opts)
789
+ self.eq(resp['code'], 404)
790
+ self.eq(resp['reason'], 'Not Found')
791
+
792
+ resp = await core.callStorm(q2, opts=opts)
793
+ self.eq(resp['code'], 404)
794
+ self.eq(resp['reason'], 'Not Found')
795
+
796
+ resp = await core.callStorm(q3, opts=opts)
797
+ self.eq(resp['code'], 404)
798
+ self.eq(resp['reason'], 'Not Found')
799
+
800
+ async def test_storm_http_connect(self):
801
+
802
+ async with self.getTestCore() as core:
803
+
804
+ core.addHttpApi('/test/ws', TstWebSock, {})
805
+ addr, port = await core.addHttpsPort(0)
806
+
807
+ mesg = await core.callStorm('''
808
+ $params = ( { "param1": "somevalu" } )
809
+ $hdr = ( { "key": false } )
810
+ $url = `https://127.0.0.1:{$port}/test/ws`
811
+
812
+ ($ok, $sock) = $lib.inet.http.connect($url, headers=$hdr, params=$params, ssl=({"verify": false}))
813
+ if (not $ok) { $lib.exit($sock) }
814
+
815
+ ($ok, $mesg) = $sock.rx()
816
+ if (not $ok) { $lib.exit($mesg) }
817
+ return($mesg)
818
+ ''', opts={'vars': {'port': port}})
819
+ self.eq(mesg.get('hi'), 'woot')
820
+ self.eq(mesg.get('headers').get('Key'), 'False')
821
+ # HTTP params are received as multidict's and returned in similar shape.
822
+ self.eq(mesg.get('params').get('param1'), ['somevalu', ])
823
+
824
+ mesg = await core.callStorm('''
825
+ $hdr = ( { "key": false } )
826
+ $url = `https://127.0.0.1:{$port}/test/ws`
827
+
828
+ ($ok, $sock) = $lib.inet.http.connect($url, headers=$hdr, ssl=({"verify": false}))
829
+ if (not $ok) { $lib.exit($sock) }
830
+
831
+ ($ok, $mesg) = $sock.rx()
832
+ if (not $ok) { $lib.exit($mesg) }
833
+ return($mesg)
834
+ ''', opts={'vars': {'port': port}})
835
+ self.eq(mesg.get('hi'), 'woot')
836
+ self.eq(mesg.get('headers').get('Key'), 'False')
837
+ self.none(mesg.get('params'))
838
+
839
+ query = '''
840
+ $url = `https://127.0.0.1:{$port}/test/ws`
841
+
842
+ ($ok, $sock) = $lib.inet.http.connect($url, proxy=$proxy, ssl=({"verify": false}))
843
+ if (not $ok) { $lib.exit($sock) }
844
+
845
+ ($ok, $mesg) = $sock.rx()
846
+ if (not $ok) { $lib.exit($mesg) }
847
+
848
+ ($ok, $valu) = $sock.tx(lololol)
849
+ return($sock.rx())
850
+ '''
851
+ opts = {'vars': {'port': port, 'proxy': True}}
852
+ self.eq((True, ('echo', 'lololol')),
853
+ await core.callStorm(query, opts=opts))
854
+
855
+ opts = {'vars': {'port': port, 'proxy': None}}
856
+ mesgs = await core.stormlist(query, opts=opts)
857
+ self.stormIsInErr('HTTP proxy argument must be a string or bool.', mesgs)
858
+
859
+ visi = await core.auth.addUser('visi')
860
+
861
+ opts = {'user': visi.iden, 'vars': {'port': port, 'proxy': False}}
862
+ with self.raises(s_exc.AuthDeny) as cm:
863
+ await core.callStorm(query, opts=opts)
864
+ self.eq(cm.exception.get('mesg'), f'User {visi.name!r} ({visi.iden}) must have permission inet.http.proxy')
865
+
866
+ await visi.setAdmin(True)
867
+
868
+ opts = {'user': visi.iden,
869
+ 'vars': {'port': port, 'proxy': 'socks5://user:pass@127.0.0.1:1'}}
870
+ with self.raises(s_stormctrl.StormExit) as cm:
871
+ await core.callStorm(query, opts=opts)
872
+ self.isin('connect to proxy 127.0.0.1:1', str(cm.exception))
873
+
874
+ async def test_storm_http_mtls(self):
875
+
876
+ with self.getTestDir() as dirn:
877
+
878
+ cdir = s_common.gendir(dirn, 'certs')
879
+ cadir = s_common.gendir(cdir, 'cas')
880
+ tdir = s_certdir.CertDir(cdir)
881
+ tdir.genCaCert('somelocalca')
882
+ tdir.genHostCert('localhost', signas='somelocalca')
883
+
884
+ localkeyfp = tdir.getHostKeyPath('localhost')
885
+ localcertfp = tdir.getHostCertPath('localhost')
886
+ pkeypath = shutil.copyfile(localkeyfp, s_common.genpath(dirn, 'sslkey.pem'))
887
+ certpath = shutil.copyfile(localcertfp, s_common.genpath(dirn, 'sslcert.pem'))
888
+
889
+ tlscadir = s_common.gendir(dirn, 'cadir')
890
+ cacertpath = shutil.copyfile(os.path.join(cadir, 'somelocalca.crt'), os.path.join(tlscadir, 'somelocalca.crt'))
891
+
892
+ with s_common.genfile(cacertpath) as fd:
893
+ ca_cert = fd.read().decode()
894
+
895
+ pkey, cert = tdir.genUserCert('someuser', signas='somelocalca')
896
+ user_pkey = tdir._pkeyToByts(pkey).decode()
897
+ user_cert = tdir._certToByts(cert).decode()
898
+
899
+ user_fullchain = user_cert + s_common.getbytes(cacertpath).decode()
900
+ user_fullchain_key = user_fullchain + user_pkey
901
+
902
+ conf = {'tls:ca:dir': tlscadir}
903
+ async with self.getTestCluster({'cortex': {'conf': conf}}) as clus:
904
+ core = clus.cortex
905
+
906
+ sslctx = core.initSslCtx(certpath, pkeypath)
907
+ sslctx.load_verify_locations(cafile=cacertpath)
908
+
909
+ addr, port = await core.addHttpsPort(0, sslctx=sslctx)
910
+ root = await core.auth.getUserByName('root')
911
+ await root.setPasswd('root')
912
+
913
+ core.addHttpApi('/api/v0/test', s_test.HttpReflector, {'cell': core})
914
+ core.addHttpApi('/test/ws', TstWebSock, {})
915
+
916
+ sslopts = {}
917
+
918
+ opts = {
919
+ 'vars': {
920
+ 'url': f'https://root:root@localhost:{port}/api/v0/test',
921
+ 'ws': f'https://localhost:{port}/test/ws',
922
+ 'sslopts': sslopts,
923
+ },
924
+ }
925
+
926
+ q = 'return($lib.inet.http.get($url, ssl=$sslopts))'
927
+
928
+ size, sha256 = await core.callStorm('return($lib.axon.put($lib.base64.decode(Zm9v)))')
929
+ opts['vars']['sha256'] = sha256
930
+
931
+ # mtls required
932
+
933
+ sslctx.verify_mode = ssl.CERT_REQUIRED
934
+
935
+ ## no client cert provided
936
+ resp = await core.callStorm(q, opts=opts)
937
+ self.eq(-1, resp['code'])
938
+ self.isin('tlsv13 alert certificate required', resp['reason'])
939
+
940
+ ## full chain cert w/key
941
+ sslopts['client_cert'] = user_fullchain_key
942
+ resp = await core.callStorm(q, opts=opts)
943
+ self.eq(200, resp['code'])
944
+
945
+ ## separate cert and key
946
+ sslopts['client_cert'] = user_fullchain
947
+ sslopts['client_key'] = user_pkey
948
+ resp = await core.callStorm(q, opts=opts)
949
+ self.eq(200, resp['code'])
950
+
951
+ ## sslctx's are cached
952
+ self.len(3, core._sslctx_cache)
953
+ resp = await core.callStorm(q, opts=opts)
954
+ self.eq(200, resp['code'])
955
+ self.len(3, core._sslctx_cache)
956
+
957
+ ## remaining methods
958
+ self.eq(200, await core.callStorm('return($lib.inet.http.post($url, ssl=$sslopts).code)', opts=opts))
959
+ self.eq(200, await core.callStorm('return($lib.inet.http.head($url, ssl=$sslopts).code)', opts=opts))
960
+ self.eq(200, await core.callStorm('return($lib.inet.http.request(get, $url, ssl=$sslopts).code)', opts=opts))
961
+
962
+ ## connect
963
+ ret = await core.callStorm('''
964
+ ($ok, $sock) = $lib.inet.http.connect($ws, ssl=$sslopts)
965
+ if (not $ok) { return(($ok, $sock)) }
966
+ ($ok, $mesg) = $sock.rx()
967
+ return(($ok, $mesg))
968
+ ''', opts=opts)
969
+ self.true(ret[0])
970
+ self.eq('woot', ret[1]['hi'])
971
+
972
+ # Axon APIs
973
+
974
+ axon_queries = {
975
+ 'postfile': '''
976
+ $fields = ([{"name": "file", "sha256": $sha256}])
977
+ return($lib.inet.http.post($url, fields=$fields, ssl=$sslopts).code)
978
+ ''',
979
+ 'wget': 'return($lib.axon.wget($url, ssl=$sslopts).code)',
980
+ 'wput': 'return($lib.axon.wput($sha256, $url, method=POST, ssl=$sslopts).code)',
981
+ 'urlfile': 'yield $lib.axon.urlfile($url, ssl=$sslopts)',
982
+ }
983
+
984
+ # verify arg precedence
985
+
986
+ core.conf.pop('tls:ca:dir')
987
+ core._sslctx_cache.clear()
988
+
989
+ ## fail w/o ca
990
+ resp = await core.callStorm(q, opts=opts)
991
+ self.eq(-1, resp['code'])
992
+ self.isin('self-signed certificate', resp['reason'])
993
+
994
+ ## verify arg wins
995
+ sslopts['verify'] = False
996
+ resp = await core.callStorm(q, opts=opts)
997
+ self.eq(200, resp['code'])
998
+
999
+ # bad opts
1000
+
1001
+ ## schema violation
1002
+ sslopts['newp'] = 'wut'
1003
+ await self.asyncraises(s_exc.SchemaViolation, core.callStorm(q, opts=opts))
1004
+ sslopts.pop('newp')
1005
+
1006
+ ## missing key
1007
+ sslopts['client_cert'] = user_fullchain
1008
+ sslopts['client_key'] = None
1009
+ await self.asyncraises(s_exc.BadArg, core.callStorm(q, opts=opts))
1010
+
1011
+ ## bad cert
1012
+ sslopts['client_cert'] = 'not-gonna-work'
1013
+ await self.asyncraises(s_exc.BadArg, core.callStorm(q, opts=opts))
1014
+
1015
+ # Provide a CA certificate directly
1016
+ async with self.getTestCluster() as clus:
1017
+ core = clus.cortex
1018
+
1019
+ sslctx = core.initSslCtx(certpath, pkeypath)
1020
+ sslctx.load_verify_locations(cafile=cacertpath)
1021
+
1022
+ addr, port = await core.addHttpsPort(0, sslctx=sslctx)
1023
+ root = await core.auth.getUserByName('root')
1024
+ await root.setPasswd('root')
1025
+
1026
+ core.addHttpApi('/api/v0/test', s_test.HttpReflector, {'cell': core})
1027
+
1028
+ sslopts = {}
1029
+
1030
+ opts = {
1031
+ 'vars': {
1032
+ 'url': f'https://root:root@localhost:{port}/api/v0/test',
1033
+ 'sslopts': sslopts,
1034
+ },
1035
+ }
1036
+
1037
+ q = 'return($lib.inet.http.get($url, ssl=$sslopts))'
1038
+
1039
+ size, sha256 = await core.callStorm('return($lib.axon.put($lib.base64.decode(Zm9v)))')
1040
+ opts['vars']['sha256'] = sha256
1041
+
1042
+ ## no cert provided
1043
+ resp = await core.callStorm(q, opts=opts)
1044
+ self.eq(-1, resp['code'])
1045
+ self.isin('certificate verify failed', resp['reason'])
1046
+
1047
+ ## provide just the CA Certificate
1048
+ sslopts['ca_cert'] = ca_cert
1049
+ resp = await core.callStorm(q, opts=opts)
1050
+ self.eq(200, resp['code'])