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.
- synapse/__init__.py +27 -0
- synapse/assets/__init__.py +35 -0
- synapse/axon.py +2014 -0
- synapse/cells.py +1 -0
- synapse/common.py +1172 -0
- synapse/cortex.py +7567 -0
- synapse/daemon.py +459 -0
- synapse/data/__init__.py +37 -0
- synapse/data/attack-flow/LICENSE.txt +201 -0
- synapse/data/attack-flow/README.md +3 -0
- synapse/data/attack-flow/attack-flow-schema-2.0.0.json +468 -0
- synapse/data/certs/cas/The Vertex Project Intermediate CA (2026).crt +29 -0
- synapse/data/certs/cas/The Vertex Project ROOT CA (2026).crt +29 -0
- synapse/data/certs/crls/The Vertex Project Intermediate CA (2026).crl +2 -0
- synapse/data/certs/crls/The Vertex Project ROOT CA (2026).crl +2 -0
- synapse/data/iana.tlds.mpk +1 -0
- synapse/data/iana.uris.mpk +1 -0
- synapse/data/jsonschemas/README.md +29 -0
- synapse/data/jsonschemas/json-schema.org/draft-07/schema +244 -0
- synapse/data/jsonschemas/raw.githubusercontent.com/oasis-open/LICENSE.txt +27 -0
- synapse/data/jsonschemas/raw.githubusercontent.com/oasis-open/cti-stix2-json-schemas/stix2.1/schemas/common/binary.json +8 -0
- synapse/data/jsonschemas/raw.githubusercontent.com/oasis-open/cti-stix2-json-schemas/stix2.1/schemas/common/bundle.json +213 -0
- synapse/data/jsonschemas/raw.githubusercontent.com/oasis-open/cti-stix2-json-schemas/stix2.1/schemas/common/core.json +159 -0
- synapse/data/jsonschemas/raw.githubusercontent.com/oasis-open/cti-stix2-json-schemas/stix2.1/schemas/common/cyber-observable-core.json +97 -0
- synapse/data/jsonschemas/raw.githubusercontent.com/oasis-open/cti-stix2-json-schemas/stix2.1/schemas/common/dictionary.json +34 -0
- synapse/data/jsonschemas/raw.githubusercontent.com/oasis-open/cti-stix2-json-schemas/stix2.1/schemas/common/extension-definition.json +96 -0
- synapse/data/jsonschemas/raw.githubusercontent.com/oasis-open/cti-stix2-json-schemas/stix2.1/schemas/common/extension.json +28 -0
- synapse/data/jsonschemas/raw.githubusercontent.com/oasis-open/cti-stix2-json-schemas/stix2.1/schemas/common/external-reference.json +106 -0
- synapse/data/jsonschemas/raw.githubusercontent.com/oasis-open/cti-stix2-json-schemas/stix2.1/schemas/common/granular-marking.json +37 -0
- synapse/data/jsonschemas/raw.githubusercontent.com/oasis-open/cti-stix2-json-schemas/stix2.1/schemas/common/hashes-type.json +55 -0
- synapse/data/jsonschemas/raw.githubusercontent.com/oasis-open/cti-stix2-json-schemas/stix2.1/schemas/common/hex.json +8 -0
- synapse/data/jsonschemas/raw.githubusercontent.com/oasis-open/cti-stix2-json-schemas/stix2.1/schemas/common/identifier.json +8 -0
- synapse/data/jsonschemas/raw.githubusercontent.com/oasis-open/cti-stix2-json-schemas/stix2.1/schemas/common/kill-chain-phase.json +21 -0
- synapse/data/jsonschemas/raw.githubusercontent.com/oasis-open/cti-stix2-json-schemas/stix2.1/schemas/common/language-content.json +54 -0
- synapse/data/jsonschemas/raw.githubusercontent.com/oasis-open/cti-stix2-json-schemas/stix2.1/schemas/common/marking-definition.json +338 -0
- synapse/data/jsonschemas/raw.githubusercontent.com/oasis-open/cti-stix2-json-schemas/stix2.1/schemas/common/properties.json +38 -0
- synapse/data/jsonschemas/raw.githubusercontent.com/oasis-open/cti-stix2-json-schemas/stix2.1/schemas/common/timestamp.json +8 -0
- synapse/data/jsonschemas/raw.githubusercontent.com/oasis-open/cti-stix2-json-schemas/stix2.1/schemas/common/url-regex.json +8 -0
- synapse/data/jsonschemas/raw.githubusercontent.com/oasis-open/cti-stix2-json-schemas/stix2.1/schemas/observables/artifact.json +125 -0
- synapse/data/jsonschemas/raw.githubusercontent.com/oasis-open/cti-stix2-json-schemas/stix2.1/schemas/observables/autonomous-system.json +42 -0
- synapse/data/jsonschemas/raw.githubusercontent.com/oasis-open/cti-stix2-json-schemas/stix2.1/schemas/observables/directory.json +60 -0
- synapse/data/jsonschemas/raw.githubusercontent.com/oasis-open/cti-stix2-json-schemas/stix2.1/schemas/observables/domain-name.json +43 -0
- synapse/data/jsonschemas/raw.githubusercontent.com/oasis-open/cti-stix2-json-schemas/stix2.1/schemas/observables/email-addr.json +43 -0
- synapse/data/jsonschemas/raw.githubusercontent.com/oasis-open/cti-stix2-json-schemas/stix2.1/schemas/observables/email-message.json +205 -0
- synapse/data/jsonschemas/raw.githubusercontent.com/oasis-open/cti-stix2-json-schemas/stix2.1/schemas/observables/file.json +569 -0
- synapse/data/jsonschemas/raw.githubusercontent.com/oasis-open/cti-stix2-json-schemas/stix2.1/schemas/observables/ipv4-addr.json +51 -0
- synapse/data/jsonschemas/raw.githubusercontent.com/oasis-open/cti-stix2-json-schemas/stix2.1/schemas/observables/ipv6-addr.json +51 -0
- synapse/data/jsonschemas/raw.githubusercontent.com/oasis-open/cti-stix2-json-schemas/stix2.1/schemas/observables/mac-addr.json +35 -0
- synapse/data/jsonschemas/raw.githubusercontent.com/oasis-open/cti-stix2-json-schemas/stix2.1/schemas/observables/mutex.json +34 -0
- synapse/data/jsonschemas/raw.githubusercontent.com/oasis-open/cti-stix2-json-schemas/stix2.1/schemas/observables/network-traffic.json +330 -0
- synapse/data/jsonschemas/raw.githubusercontent.com/oasis-open/cti-stix2-json-schemas/stix2.1/schemas/observables/process.json +265 -0
- synapse/data/jsonschemas/raw.githubusercontent.com/oasis-open/cti-stix2-json-schemas/stix2.1/schemas/observables/software.json +60 -0
- synapse/data/jsonschemas/raw.githubusercontent.com/oasis-open/cti-stix2-json-schemas/stix2.1/schemas/observables/url.json +34 -0
- synapse/data/jsonschemas/raw.githubusercontent.com/oasis-open/cti-stix2-json-schemas/stix2.1/schemas/observables/user-account.json +170 -0
- synapse/data/jsonschemas/raw.githubusercontent.com/oasis-open/cti-stix2-json-schemas/stix2.1/schemas/observables/windows-registry-key.json +98 -0
- synapse/data/jsonschemas/raw.githubusercontent.com/oasis-open/cti-stix2-json-schemas/stix2.1/schemas/observables/x509-certificate.json +191 -0
- synapse/data/jsonschemas/raw.githubusercontent.com/oasis-open/cti-stix2-json-schemas/stix2.1/schemas/sdos/attack-pattern.json +53 -0
- synapse/data/jsonschemas/raw.githubusercontent.com/oasis-open/cti-stix2-json-schemas/stix2.1/schemas/sdos/campaign.json +58 -0
- synapse/data/jsonschemas/raw.githubusercontent.com/oasis-open/cti-stix2-json-schemas/stix2.1/schemas/sdos/course-of-action.json +38 -0
- synapse/data/jsonschemas/raw.githubusercontent.com/oasis-open/cti-stix2-json-schemas/stix2.1/schemas/sdos/grouping.json +61 -0
- synapse/data/jsonschemas/raw.githubusercontent.com/oasis-open/cti-stix2-json-schemas/stix2.1/schemas/sdos/identity.json +115 -0
- synapse/data/jsonschemas/raw.githubusercontent.com/oasis-open/cti-stix2-json-schemas/stix2.1/schemas/sdos/incident.json +38 -0
- synapse/data/jsonschemas/raw.githubusercontent.com/oasis-open/cti-stix2-json-schemas/stix2.1/schemas/sdos/indicator.json +101 -0
- synapse/data/jsonschemas/raw.githubusercontent.com/oasis-open/cti-stix2-json-schemas/stix2.1/schemas/sdos/infrastructure.json +88 -0
- synapse/data/jsonschemas/raw.githubusercontent.com/oasis-open/cti-stix2-json-schemas/stix2.1/schemas/sdos/intrusion-set.json +106 -0
- synapse/data/jsonschemas/raw.githubusercontent.com/oasis-open/cti-stix2-json-schemas/stix2.1/schemas/sdos/location.json +175 -0
- synapse/data/jsonschemas/raw.githubusercontent.com/oasis-open/cti-stix2-json-schemas/stix2.1/schemas/sdos/malware-analysis.json +159 -0
- synapse/data/jsonschemas/raw.githubusercontent.com/oasis-open/cti-stix2-json-schemas/stix2.1/schemas/sdos/malware.json +254 -0
- synapse/data/jsonschemas/raw.githubusercontent.com/oasis-open/cti-stix2-json-schemas/stix2.1/schemas/sdos/note.json +55 -0
- synapse/data/jsonschemas/raw.githubusercontent.com/oasis-open/cti-stix2-json-schemas/stix2.1/schemas/sdos/observed-data.json +150 -0
- synapse/data/jsonschemas/raw.githubusercontent.com/oasis-open/cti-stix2-json-schemas/stix2.1/schemas/sdos/opinion.json +62 -0
- synapse/data/jsonschemas/raw.githubusercontent.com/oasis-open/cti-stix2-json-schemas/stix2.1/schemas/sdos/report.json +77 -0
- synapse/data/jsonschemas/raw.githubusercontent.com/oasis-open/cti-stix2-json-schemas/stix2.1/schemas/sdos/threat-actor.json +175 -0
- synapse/data/jsonschemas/raw.githubusercontent.com/oasis-open/cti-stix2-json-schemas/stix2.1/schemas/sdos/tool.json +81 -0
- synapse/data/jsonschemas/raw.githubusercontent.com/oasis-open/cti-stix2-json-schemas/stix2.1/schemas/sdos/vulnerability.json +38 -0
- synapse/data/jsonschemas/raw.githubusercontent.com/oasis-open/cti-stix2-json-schemas/stix2.1/schemas/sros/relationship.json +76 -0
- synapse/data/jsonschemas/raw.githubusercontent.com/oasis-open/cti-stix2-json-schemas/stix2.1/schemas/sros/sighting.json +115 -0
- synapse/data/lark/__init__.py +0 -0
- synapse/data/lark/imap.lark +8 -0
- synapse/data/lark/storm.lark +784 -0
- synapse/data/skills/storm/SKILL.md +878 -0
- synapse/data/v2modelmap.yaml +684 -0
- synapse/datamodel.py +2086 -0
- synapse/exc.py +437 -0
- synapse/glob.py +98 -0
- synapse/lib/__init__.py +2 -0
- synapse/lib/agenda.py +1060 -0
- synapse/lib/aha.py +2129 -0
- synapse/lib/ast.py +6457 -0
- synapse/lib/auth.py +1738 -0
- synapse/lib/autodoc.py +1990 -0
- synapse/lib/base.py +904 -0
- synapse/lib/boss.py +143 -0
- synapse/lib/cache.py +232 -0
- synapse/lib/cell.py +5818 -0
- synapse/lib/certdir.py +1850 -0
- synapse/lib/chop.py +350 -0
- synapse/lib/cli.py +546 -0
- synapse/lib/cluster.py +358 -0
- synapse/lib/cmd.py +69 -0
- synapse/lib/config.py +583 -0
- synapse/lib/const.py +56 -0
- synapse/lib/coro.py +224 -0
- synapse/lib/crypto/__init__.py +0 -0
- synapse/lib/crypto/coin.py +176 -0
- synapse/lib/crypto/ecc.py +264 -0
- synapse/lib/crypto/jwk.py +82 -0
- synapse/lib/crypto/passwd.py +146 -0
- synapse/lib/crypto/rsa.py +261 -0
- synapse/lib/crypto/tinfoil.py +191 -0
- synapse/lib/crypto/utils.py +142 -0
- synapse/lib/datfile.py +25 -0
- synapse/lib/drive.py +1161 -0
- synapse/lib/dyndeps.py +147 -0
- synapse/lib/editor.py +1154 -0
- synapse/lib/gis.py +251 -0
- synapse/lib/grammar.py +92 -0
- synapse/lib/hashitem.py +30 -0
- synapse/lib/hashset.py +60 -0
- synapse/lib/health.py +53 -0
- synapse/lib/httpapi.py +1590 -0
- synapse/lib/json.py +214 -0
- synapse/lib/jsonstor.py +633 -0
- synapse/lib/jsrpc.py +372 -0
- synapse/lib/layer.py +7062 -0
- synapse/lib/link.py +419 -0
- synapse/lib/lmdbslab.py +2762 -0
- synapse/lib/logging.py +425 -0
- synapse/lib/mcp.py +1292 -0
- synapse/lib/mddocs.py +1001 -0
- synapse/lib/mdstorm.py +934 -0
- synapse/lib/modelrev.py +383 -0
- synapse/lib/msgpack.py +300 -0
- synapse/lib/multislabseqn.py +562 -0
- synapse/lib/nexus.py +846 -0
- synapse/lib/node.py +2025 -0
- synapse/lib/oauth.py +513 -0
- synapse/lib/output.py +49 -0
- synapse/lib/parser.py +922 -0
- synapse/lib/platforms/__init__.py +8 -0
- synapse/lib/platforms/common.py +61 -0
- synapse/lib/platforms/darwin.py +9 -0
- synapse/lib/platforms/freebsd.py +9 -0
- synapse/lib/platforms/linux.py +237 -0
- synapse/lib/platforms/windows.py +84 -0
- synapse/lib/process.py +93 -0
- synapse/lib/processpool.py +224 -0
- synapse/lib/provision.py +135 -0
- synapse/lib/queue.py +177 -0
- synapse/lib/reflect.py +111 -0
- synapse/lib/schemas.py +1724 -0
- synapse/lib/scope.py +249 -0
- synapse/lib/scrape.py +706 -0
- synapse/lib/share.py +29 -0
- synapse/lib/slabseqn.py +400 -0
- synapse/lib/spawner.py +122 -0
- synapse/lib/spooled.py +211 -0
- synapse/lib/storm.py +6455 -0
- synapse/lib/storm_format.py +161 -0
- synapse/lib/stormctrl.py +91 -0
- synapse/lib/stormhttp.py +592 -0
- synapse/lib/stormlib/__init__.py +0 -0
- synapse/lib/stormlib/aha.py +623 -0
- synapse/lib/stormlib/auth.py +1908 -0
- synapse/lib/stormlib/basex.py +73 -0
- synapse/lib/stormlib/bytes.py +48 -0
- synapse/lib/stormlib/cache.py +206 -0
- synapse/lib/stormlib/cell.py +146 -0
- synapse/lib/stormlib/compression.py +179 -0
- synapse/lib/stormlib/cortex.py +1273 -0
- synapse/lib/stormlib/cryptoutils.py +86 -0
- synapse/lib/stormlib/easyperm.py +122 -0
- synapse/lib/stormlib/ecc.py +164 -0
- synapse/lib/stormlib/ethereum.py +37 -0
- synapse/lib/stormlib/file.py +67 -0
- synapse/lib/stormlib/gen.py +188 -0
- synapse/lib/stormlib/gis.py +41 -0
- synapse/lib/stormlib/graph.py +177 -0
- synapse/lib/stormlib/hashes.py +112 -0
- synapse/lib/stormlib/hex.py +142 -0
- synapse/lib/stormlib/imap.py +842 -0
- synapse/lib/stormlib/index.py +52 -0
- synapse/lib/stormlib/infosec.py +570 -0
- synapse/lib/stormlib/ipv6.py +51 -0
- synapse/lib/stormlib/iters.py +92 -0
- synapse/lib/stormlib/json.py +146 -0
- synapse/lib/stormlib/jwt.py +1031 -0
- synapse/lib/stormlib/log.py +180 -0
- synapse/lib/stormlib/macro.py +237 -0
- synapse/lib/stormlib/math.py +37 -0
- synapse/lib/stormlib/mime.py +45 -0
- synapse/lib/stormlib/model.py +778 -0
- synapse/lib/stormlib/modelext.py +243 -0
- synapse/lib/stormlib/oauth.py +406 -0
- synapse/lib/stormlib/pack.py +68 -0
- synapse/lib/stormlib/pkg.py +635 -0
- synapse/lib/stormlib/quorum.py +114 -0
- synapse/lib/stormlib/random.py +117 -0
- synapse/lib/stormlib/rsa.py +172 -0
- synapse/lib/stormlib/scrape.py +149 -0
- synapse/lib/stormlib/smtp.py +214 -0
- synapse/lib/stormlib/spooled.py +113 -0
- synapse/lib/stormlib/stats.py +253 -0
- synapse/lib/stormlib/stix.py +1599 -0
- synapse/lib/stormlib/storm.py +178 -0
- synapse/lib/stormlib/tabular.py +212 -0
- synapse/lib/stormlib/task.py +116 -0
- synapse/lib/stormlib/utils.py +48 -0
- synapse/lib/stormlib/vault.py +896 -0
- synapse/lib/stormlib/version.py +66 -0
- synapse/lib/stormlib/vertex.py +421 -0
- synapse/lib/stormlib/xml.py +99 -0
- synapse/lib/stormlib/yaml.py +49 -0
- synapse/lib/stormsvc.py +112 -0
- synapse/lib/stormtypes.py +10549 -0
- synapse/lib/task.py +264 -0
- synapse/lib/thishost.py +40 -0
- synapse/lib/thisplat.py +17 -0
- synapse/lib/threads.py +10 -0
- synapse/lib/time.py +542 -0
- synapse/lib/trigger.py +513 -0
- synapse/lib/types.py +5151 -0
- synapse/lib/urlhelp.py +112 -0
- synapse/lib/version.py +387 -0
- synapse/lib/view.py +3898 -0
- synapse/lookup/__init__.py +0 -0
- synapse/lookup/cvss.py +89 -0
- synapse/lookup/iana.py +322 -0
- synapse/lookup/macho.py +73 -0
- synapse/lookup/pe.py +530 -0
- synapse/lookup/phonenum.py +386 -0
- synapse/lookup/timezones.py +43 -0
- synapse/models/__init__.py +29 -0
- synapse/models/auth.py +59 -0
- synapse/models/base.py +972 -0
- synapse/models/belief.py +42 -0
- synapse/models/biz.py +206 -0
- synapse/models/crypto.py +805 -0
- synapse/models/dns.py +401 -0
- synapse/models/doc.py +258 -0
- synapse/models/economic.py +629 -0
- synapse/models/entity.py +810 -0
- synapse/models/files.py +817 -0
- synapse/models/geopol.py +226 -0
- synapse/models/geospace.py +567 -0
- synapse/models/gov.py +70 -0
- synapse/models/ind.py +63 -0
- synapse/models/inet.py +3397 -0
- synapse/models/infotech.py +3070 -0
- synapse/models/language.py +231 -0
- synapse/models/material.py +203 -0
- synapse/models/orgs.py +652 -0
- synapse/models/person.py +201 -0
- synapse/models/planning.py +148 -0
- synapse/models/proj.py +108 -0
- synapse/models/risk.py +668 -0
- synapse/models/science.py +96 -0
- synapse/models/syn.py +312 -0
- synapse/models/telco.py +262 -0
- synapse/models/transport.py +562 -0
- synapse/servers/__init__.py +0 -0
- synapse/servers/aha.py +8 -0
- synapse/servers/axon.py +8 -0
- synapse/servers/cell.py +21 -0
- synapse/servers/cortex.py +8 -0
- synapse/servers/jsonstor.py +8 -0
- synapse/telepath.py +1294 -0
- synapse/tests/__init__.py +0 -0
- synapse/tests/files/TestUtilsGetrefs.test_basics.yaml +182 -0
- synapse/tests/files/__init__.py +80 -0
- synapse/tests/files/aha/certs/cas/synapse.crt.tinfoil +0 -0
- synapse/tests/files/aha/certs/cas/synapse.key.tinfoil +0 -0
- synapse/tests/files/aha/certs/hosts/00.aha.loop.vertex.link.crt.tinfoil +0 -0
- synapse/tests/files/aha/certs/hosts/00.aha.loop.vertex.link.key.tinfoil +0 -0
- synapse/tests/files/aha/certs/users/root@synapse.crt.tinfoil +0 -0
- synapse/tests/files/aha/certs/users/root@synapse.key.tinfoil +0 -0
- synapse/tests/files/attack_flow/CISA AA22-138B VMWare Workspace (Alt).json +486 -0
- synapse/tests/files/attack_flow/CISA_Iranian_APT.json +1083 -0
- synapse/tests/files/certdir/cas/ca.crt.tinfoil +0 -0
- synapse/tests/files/certdir/cas/ca.key.tinfoil +0 -0
- synapse/tests/files/certdir/hosts/localhost.crt.tinfoil +0 -0
- synapse/tests/files/certdir/hosts/localhost.key.tinfoil +0 -0
- synapse/tests/files/certdir/users/root.crt.tinfoil +0 -0
- synapse/tests/files/certdir/users/root.key.tinfoil +0 -0
- synapse/tests/files/certdir/users/user.crt.tinfoil +0 -0
- synapse/tests/files/certdir/users/user.key.tinfoil +0 -0
- synapse/tests/files/cpedata.json +525034 -0
- synapse/tests/files/mdstorm/httprespmulti.yaml +78 -0
- synapse/tests/files/mdstorm/testsvc.py +76 -0
- synapse/tests/files/stix_export/basic.json +501 -0
- synapse/tests/files/stix_export/custom0.json +222 -0
- synapse/tests/files/stix_export/risk0.json +159 -0
- synapse/tests/files/stix_import/apt1.json +1206 -0
- synapse/tests/files/stix_import/oasis-example-00.json +100 -0
- synapse/tests/files/stix_import/scos.json +83 -0
- synapse/tests/files/stormcov/argvquery.storm +10 -0
- synapse/tests/files/stormcov/argvquery2.storm +4 -0
- synapse/tests/files/stormcov/argvquery3.storm +6 -0
- synapse/tests/files/stormcov/argvquery4.storm +7 -0
- synapse/tests/files/stormcov/argvquery5.storm +11 -0
- synapse/tests/files/stormcov/badstorm.storm +1 -0
- synapse/tests/files/stormcov/continueloop.storm +5 -0
- synapse/tests/files/stormcov/dupesubs.storm +28 -0
- synapse/tests/files/stormcov/dupewarn.storm +39 -0
- synapse/tests/files/stormcov/dupfunc.storm +13 -0
- synapse/tests/files/stormcov/embedquery.storm +21 -0
- synapse/tests/files/stormcov/embedquery2.storm +4 -0
- synapse/tests/files/stormcov/embedquery3.storm +6 -0
- synapse/tests/files/stormcov/embedquery4.storm +7 -0
- synapse/tests/files/stormcov/embedquery5.storm +11 -0
- synapse/tests/files/stormcov/emptybody.storm +12 -0
- synapse/tests/files/stormcov/exprdict.storm +10 -0
- synapse/tests/files/stormcov/forloop.storm +10 -0
- synapse/tests/files/stormcov/ifelif.storm +9 -0
- synapse/tests/files/stormcov/ifelse.storm +9 -0
- synapse/tests/files/stormcov/lookup.storm +7 -0
- synapse/tests/files/stormcov/pivot.storm +4 -0
- synapse/tests/files/stormcov/pragma-nocov.storm +20 -0
- synapse/tests/files/stormcov/runtsafety.storm +7 -0
- synapse/tests/files/stormcov/spin.storm +5 -0
- synapse/tests/files/stormcov/stopreturn.storm +4 -0
- synapse/tests/files/stormcov/stormctrl.storm +8 -0
- synapse/tests/files/stormcov/switch.storm +9 -0
- synapse/tests/files/stormcov/switchnodefault.storm +8 -0
- synapse/tests/files/stormcov/trycatch.storm +8 -0
- synapse/tests/files/stormcov/whilebackedge.storm +12 -0
- synapse/tests/files/stormcov/whilecontinue.storm +13 -0
- synapse/tests/files/stormcov/whileloop.storm +8 -0
- synapse/tests/files/stormcov/whilewithnode.storm +10 -0
- synapse/tests/files/stormmod/common +1 -0
- synapse/tests/files/stormpkg/badapidef.yaml +13 -0
- synapse/tests/files/stormpkg/badcmdname.yaml +6 -0
- synapse/tests/files/stormpkg/badendpoints.yaml +7 -0
- synapse/tests/files/stormpkg/badinits.yaml +12 -0
- synapse/tests/files/stormpkg/badjsonpkg.yaml +8 -0
- synapse/tests/files/stormpkg/badvaultskeys.yaml +9 -0
- synapse/tests/files/stormpkg/badvaultsschema.yaml +11 -0
- synapse/tests/files/stormpkg/declaredfiles.yaml +4 -0
- synapse/tests/files/stormpkg/docs/foobar.md +3 -0
- synapse/tests/files/stormpkg/docs/foobar.svg +1 -0
- synapse/tests/files/stormpkg/docs/index.md +5 -0
- synapse/tests/files/stormpkg/dotstorm/dotstorm.yaml +14 -0
- synapse/tests/files/stormpkg/dotstorm_noevents/dotstorm.yaml +11 -0
- synapse/tests/files/stormpkg/dotstorm_noevents/storm/commands/dotstorm.bar.storm +1 -0
- synapse/tests/files/stormpkg/dotstorm_noevents/storm/modules/dotstorm.foo.storm +1 -0
- synapse/tests/files/stormpkg/files/data.dat +1 -0
- synapse/tests/files/stormpkg/files/sub/nested.dat +1 -0
- synapse/tests/files/stormpkg/nomime.yaml +5 -0
- synapse/tests/files/stormpkg/nopath.yaml +5 -0
- synapse/tests/files/stormpkg/nosuchfile.yaml +4 -0
- synapse/tests/files/stormpkg/optic/index.html +1 -0
- synapse/tests/files/stormpkg/storm/commands/invalidCMD.storm +0 -0
- synapse/tests/files/stormpkg/storm/commands/testpkg.baz.storm +0 -0
- synapse/tests/files/stormpkg/storm/commands/testpkgcmd.storm +1 -0
- synapse/tests/files/stormpkg/storm/modules/apimod.storm +10 -0
- synapse/tests/files/stormpkg/storm/modules/testmod.storm +1 -0
- synapse/tests/files/stormpkg/testpkg.yaml +219 -0
- synapse/tests/files/stormpkg/workflows/testpkg-bam.newp +2 -0
- synapse/tests/files/stormpkg/workflows/testpkg-baz.yaml +2 -0
- synapse/tests/files/stormpkg/workflows/testpkg-foo.yaml +2 -0
- synapse/tests/files/test.dat +1 -0
- synapse/tests/files/testpkg_build_docs/docs/index.md +7 -0
- synapse/tests/files/testpkg_build_docs/docs/mocks/cassette.yaml +78 -0
- synapse/tests/files/testpkg_build_docs/docs/stormpackage.md +2 -0
- synapse/tests/files/testpkg_build_docs/docs/sub/image.svg +1 -0
- synapse/tests/files/testpkg_build_docs/docs/sub/nested.md +3 -0
- synapse/tests/files/testpkg_build_docs/docs/userguide.md +9 -0
- synapse/tests/files/testpkg_build_docs/storm/commands/testcmd.storm +0 -0
- synapse/tests/files/testpkg_build_docs/storm/modules/apimod.storm +0 -0
- synapse/tests/files/testpkg_build_docs/storm/modules/testmod.storm +0 -0
- synapse/tests/files/testpkg_build_docs/storm/testcmd.storm +5 -0
- synapse/tests/files/testpkg_build_docs/testpkg.yaml +64 -0
- synapse/tests/files/testpkg_build_docs_no_h1/docs/index.md +5 -0
- synapse/tests/files/testpkg_build_docs_no_h1/docs/noh1.md +3 -0
- synapse/tests/files/testpkg_build_docs_no_h1/testpkg.yaml +2 -0
- synapse/tests/nopmod.py +3 -0
- synapse/tests/test_assets.py +26 -0
- synapse/tests/test_axon.py +1412 -0
- synapse/tests/test_common.py +552 -0
- synapse/tests/test_cortex.py +10107 -0
- synapse/tests/test_daemon.py +540 -0
- synapse/tests/test_data.py +8 -0
- synapse/tests/test_datamodel.py +1993 -0
- synapse/tests/test_exc.py +89 -0
- synapse/tests/test_glob.py +52 -0
- synapse/tests/test_lib_agenda.py +2091 -0
- synapse/tests/test_lib_aha.py +2361 -0
- synapse/tests/test_lib_ast.py +5286 -0
- synapse/tests/test_lib_auth.py +1415 -0
- synapse/tests/test_lib_autodoc.py +876 -0
- synapse/tests/test_lib_base.py +782 -0
- synapse/tests/test_lib_boss.py +144 -0
- synapse/tests/test_lib_cache.py +283 -0
- synapse/tests/test_lib_cell.py +3675 -0
- synapse/tests/test_lib_certdir.py +2084 -0
- synapse/tests/test_lib_chop.py +154 -0
- synapse/tests/test_lib_cli.py +295 -0
- synapse/tests/test_lib_cluster.py +26 -0
- synapse/tests/test_lib_config.py +512 -0
- synapse/tests/test_lib_const.py +24 -0
- synapse/tests/test_lib_coro.py +132 -0
- synapse/tests/test_lib_crypto_coin.py +31 -0
- synapse/tests/test_lib_crypto_ecc.py +236 -0
- synapse/tests/test_lib_crypto_jwk.py +97 -0
- synapse/tests/test_lib_crypto_passwd.py +171 -0
- synapse/tests/test_lib_crypto_rsa.py +213 -0
- synapse/tests/test_lib_crypto_tinfoil.py +184 -0
- synapse/tests/test_lib_datfile.py +15 -0
- synapse/tests/test_lib_drive.py +1119 -0
- synapse/tests/test_lib_dyndeps.py +55 -0
- synapse/tests/test_lib_gis.py +179 -0
- synapse/tests/test_lib_grammar.py +2147 -0
- synapse/tests/test_lib_hashitem.py +32 -0
- synapse/tests/test_lib_hashset.py +49 -0
- synapse/tests/test_lib_health.py +35 -0
- synapse/tests/test_lib_httpapi.py +2331 -0
- synapse/tests/test_lib_json.py +240 -0
- synapse/tests/test_lib_jsonstor.py +204 -0
- synapse/tests/test_lib_jsrpc.py +345 -0
- synapse/tests/test_lib_layer.py +4256 -0
- synapse/tests/test_lib_link.py +446 -0
- synapse/tests/test_lib_lmdbslab.py +2598 -0
- synapse/tests/test_lib_logging.py +514 -0
- synapse/tests/test_lib_mcp.py +1109 -0
- synapse/tests/test_lib_mddocs.py +1441 -0
- synapse/tests/test_lib_mdstorm.py +1701 -0
- synapse/tests/test_lib_modelrev.py +57 -0
- synapse/tests/test_lib_msgpack.py +315 -0
- synapse/tests/test_lib_multislabseqn.py +646 -0
- synapse/tests/test_lib_nexus.py +869 -0
- synapse/tests/test_lib_node.py +905 -0
- synapse/tests/test_lib_output.py +26 -0
- synapse/tests/test_lib_platforms_linux.py +66 -0
- synapse/tests/test_lib_process.py +67 -0
- synapse/tests/test_lib_processpool.py +220 -0
- synapse/tests/test_lib_provision.py +89 -0
- synapse/tests/test_lib_queue.py +37 -0
- synapse/tests/test_lib_reflect.py +84 -0
- synapse/tests/test_lib_scope.py +176 -0
- synapse/tests/test_lib_scrape.py +1250 -0
- synapse/tests/test_lib_slabseqn.py +208 -0
- synapse/tests/test_lib_spawner.py +147 -0
- synapse/tests/test_lib_spooled.py +139 -0
- synapse/tests/test_lib_storm.py +6459 -0
- synapse/tests/test_lib_storm_format.py +9 -0
- synapse/tests/test_lib_stormctrl.py +65 -0
- synapse/tests/test_lib_stormhttp.py +1050 -0
- synapse/tests/test_lib_stormlib_aha.py +383 -0
- synapse/tests/test_lib_stormlib_auth.py +1863 -0
- synapse/tests/test_lib_stormlib_basex.py +42 -0
- synapse/tests/test_lib_stormlib_cache.py +304 -0
- synapse/tests/test_lib_stormlib_cell.py +154 -0
- synapse/tests/test_lib_stormlib_compression.py +61 -0
- synapse/tests/test_lib_stormlib_cortex.py +1493 -0
- synapse/tests/test_lib_stormlib_easyperm.py +124 -0
- synapse/tests/test_lib_stormlib_ecc.py +144 -0
- synapse/tests/test_lib_stormlib_env.py +37 -0
- synapse/tests/test_lib_stormlib_ethereum.py +22 -0
- synapse/tests/test_lib_stormlib_file.py +115 -0
- synapse/tests/test_lib_stormlib_gen.py +239 -0
- synapse/tests/test_lib_stormlib_gis.py +21 -0
- synapse/tests/test_lib_stormlib_hashes.py +136 -0
- synapse/tests/test_lib_stormlib_hex.py +105 -0
- synapse/tests/test_lib_stormlib_imap.py +1443 -0
- synapse/tests/test_lib_stormlib_index.py +39 -0
- synapse/tests/test_lib_stormlib_infosec.py +405 -0
- synapse/tests/test_lib_stormlib_ipv6.py +26 -0
- synapse/tests/test_lib_stormlib_iters.py +118 -0
- synapse/tests/test_lib_stormlib_json.py +89 -0
- synapse/tests/test_lib_stormlib_jwt.py +1380 -0
- synapse/tests/test_lib_stormlib_log.py +40 -0
- synapse/tests/test_lib_stormlib_macro.py +414 -0
- synapse/tests/test_lib_stormlib_mime.py +82 -0
- synapse/tests/test_lib_stormlib_model.py +323 -0
- synapse/tests/test_lib_stormlib_modelext.py +718 -0
- synapse/tests/test_lib_stormlib_oauth.py +1248 -0
- synapse/tests/test_lib_stormlib_pack.py +36 -0
- synapse/tests/test_lib_stormlib_pkg.py +558 -0
- synapse/tests/test_lib_stormlib_quorum.py +68 -0
- synapse/tests/test_lib_stormlib_random.py +115 -0
- synapse/tests/test_lib_stormlib_rsa.py +244 -0
- synapse/tests/test_lib_stormlib_scrape.py +225 -0
- synapse/tests/test_lib_stormlib_smtp.py +91 -0
- synapse/tests/test_lib_stormlib_spooled.py +221 -0
- synapse/tests/test_lib_stormlib_stats.py +284 -0
- synapse/tests/test_lib_stormlib_stix.py +807 -0
- synapse/tests/test_lib_stormlib_storm.py +192 -0
- synapse/tests/test_lib_stormlib_tabular.py +226 -0
- synapse/tests/test_lib_stormlib_task.py +96 -0
- synapse/tests/test_lib_stormlib_utils.py +13 -0
- synapse/tests/test_lib_stormlib_vault.py +721 -0
- synapse/tests/test_lib_stormlib_vertex.py +578 -0
- synapse/tests/test_lib_stormlib_xml.py +112 -0
- synapse/tests/test_lib_stormlib_yaml.py +38 -0
- synapse/tests/test_lib_stormsvc.py +1266 -0
- synapse/tests/test_lib_stormtypes.py +8805 -0
- synapse/tests/test_lib_task.py +133 -0
- synapse/tests/test_lib_thishost.py +14 -0
- synapse/tests/test_lib_time.py +219 -0
- synapse/tests/test_lib_trigger.py +1017 -0
- synapse/tests/test_lib_types.py +3978 -0
- synapse/tests/test_lib_urlhelp.py +106 -0
- synapse/tests/test_lib_version.py +363 -0
- synapse/tests/test_lib_view.py +2714 -0
- synapse/tests/test_lookup_phonenum.py +9 -0
- synapse/tests/test_model_auth.py +22 -0
- synapse/tests/test_model_base.py +474 -0
- synapse/tests/test_model_belief.py +27 -0
- synapse/tests/test_model_biz.py +122 -0
- synapse/tests/test_model_crypto.py +804 -0
- synapse/tests/test_model_dns.py +385 -0
- synapse/tests/test_model_doc.py +157 -0
- synapse/tests/test_model_economic.py +932 -0
- synapse/tests/test_model_entity.py +517 -0
- synapse/tests/test_model_files.py +877 -0
- synapse/tests/test_model_geopol.py +195 -0
- synapse/tests/test_model_geospace.py +524 -0
- synapse/tests/test_model_gov.py +21 -0
- synapse/tests/test_model_gov_cn.py +17 -0
- synapse/tests/test_model_gov_intl.py +40 -0
- synapse/tests/test_model_gov_us.py +12 -0
- synapse/tests/test_model_inet.py +3856 -0
- synapse/tests/test_model_infotech.py +2772 -0
- synapse/tests/test_model_language.py +142 -0
- synapse/tests/test_model_material.py +84 -0
- synapse/tests/test_model_orgs.py +583 -0
- synapse/tests/test_model_person.py +197 -0
- synapse/tests/test_model_planning.py +131 -0
- synapse/tests/test_model_proj.py +82 -0
- synapse/tests/test_model_risk.py +600 -0
- synapse/tests/test_model_science.py +65 -0
- synapse/tests/test_model_syn.py +896 -0
- synapse/tests/test_model_telco.py +167 -0
- synapse/tests/test_model_transport.py +341 -0
- synapse/tests/test_servers_axon.py +32 -0
- synapse/tests/test_servers_cortex.py +33 -0
- synapse/tests/test_servers_univ.py +70 -0
- synapse/tests/test_telepath.py +1424 -0
- synapse/tests/test_tools_aha.py +419 -0
- synapse/tests/test_tools_axon_copy.py +33 -0
- synapse/tests/test_tools_axon_dump_load.py +304 -0
- synapse/tests/test_tools_axon_get.py +63 -0
- synapse/tests/test_tools_axon_put.py +129 -0
- synapse/tests/test_tools_cortex_csv.py +255 -0
- synapse/tests/test_tools_cortex_docmodel.py +649 -0
- synapse/tests/test_tools_cortex_feed.py +215 -0
- synapse/tests/test_tools_cortex_layer.py +418 -0
- synapse/tests/test_tools_docker_validate.py +100 -0
- synapse/tests/test_tools_service_apikey.py +224 -0
- synapse/tests/test_tools_service_backup.py +444 -0
- synapse/tests/test_tools_service_demote.py +86 -0
- synapse/tests/test_tools_service_healthcheck.py +83 -0
- synapse/tests/test_tools_service_modrole.py +142 -0
- synapse/tests/test_tools_service_moduser.py +258 -0
- synapse/tests/test_tools_service_promote.py +88 -0
- synapse/tests/test_tools_service_reload.py +54 -0
- synapse/tests/test_tools_service_shutdown.py +77 -0
- synapse/tests/test_tools_service_snapshot.py +47 -0
- synapse/tests/test_tools_storm_cli.py +985 -0
- synapse/tests/test_tools_storm_pkg_doc.py +280 -0
- synapse/tests/test_tools_storm_pkg_gen.py +676 -0
- synapse/tests/test_tools_storm_pkg_publish.py +379 -0
- synapse/tests/test_tools_storm_printer.py +203 -0
- synapse/tests/test_tools_storm_tester.py +153 -0
- synapse/tests/test_tools_storm_validate.py +82 -0
- synapse/tests/test_tools_utils_doc.py +153 -0
- synapse/tests/test_tools_utils_easycert.py +215 -0
- synapse/tests/test_tools_utils_guid.py +12 -0
- synapse/tests/test_tools_utils_json2mpk.py +33 -0
- synapse/tests/test_tools_utils_mdstorm.py +49 -0
- synapse/tests/test_utils.py +512 -0
- synapse/tests/test_utils_getrefs.py +81 -0
- synapse/tests/test_utils_stormcov.py +376 -0
- synapse/tests/utils.py +2654 -0
- synapse/tools/__init__.py +0 -0
- synapse/tools/aha/__init__.py +0 -0
- synapse/tools/aha/clone.py +48 -0
- synapse/tools/aha/del.py +47 -0
- synapse/tools/aha/easycert.py +53 -0
- synapse/tools/aha/enroll.py +103 -0
- synapse/tools/aha/list.py +55 -0
- synapse/tools/aha/mirror.py +171 -0
- synapse/tools/aha/provision/__init__.py +0 -0
- synapse/tools/aha/provision/service.py +72 -0
- synapse/tools/aha/provision/user.py +50 -0
- synapse/tools/axon/__init__.py +0 -0
- synapse/tools/axon/copy.py +44 -0
- synapse/tools/axon/dump.py +155 -0
- synapse/tools/axon/get.py +76 -0
- synapse/tools/axon/load.py +89 -0
- synapse/tools/axon/put.py +122 -0
- synapse/tools/cortex/__init__.py +0 -0
- synapse/tools/cortex/csv.py +269 -0
- synapse/tools/cortex/docmodel.py +829 -0
- synapse/tools/cortex/feed.py +172 -0
- synapse/tools/cortex/layer/__init__.py +0 -0
- synapse/tools/cortex/layer/dump.py +184 -0
- synapse/tools/cortex/layer/load.py +128 -0
- synapse/tools/docker/__init__.py +0 -0
- synapse/tools/docker/validate.py +154 -0
- synapse/tools/service/__init__.py +0 -0
- synapse/tools/service/apikey.py +90 -0
- synapse/tools/service/backup.py +334 -0
- synapse/tools/service/demote.py +47 -0
- synapse/tools/service/healthcheck.py +108 -0
- synapse/tools/service/modrole.py +116 -0
- synapse/tools/service/moduser.py +184 -0
- synapse/tools/service/promote.py +54 -0
- synapse/tools/service/reload.py +68 -0
- synapse/tools/service/shutdown.py +61 -0
- synapse/tools/service/snapshot.py +64 -0
- synapse/tools/storm/__init__.py +0 -0
- synapse/tools/storm/__main__.py +5 -0
- synapse/tools/storm/_cli.py +580 -0
- synapse/tools/storm/_http.py +409 -0
- synapse/tools/storm/_printer.py +152 -0
- synapse/tools/storm/pkg/__init__.py +0 -0
- synapse/tools/storm/pkg/doc.py +111 -0
- synapse/tools/storm/pkg/gen.py +485 -0
- synapse/tools/storm/pkg/publish.py +176 -0
- synapse/tools/storm/tester.py +94 -0
- synapse/tools/storm/validate.py +50 -0
- synapse/tools/utils/__init__.py +0 -0
- synapse/tools/utils/doc.py +47 -0
- synapse/tools/utils/easycert.py +136 -0
- synapse/tools/utils/guid.py +11 -0
- synapse/tools/utils/json2mpk.py +46 -0
- synapse/tools/utils/mdstorm.py +78 -0
- synapse/utils/__init__.py +0 -0
- synapse/utils/getrefs.py +96 -0
- synapse/utils/stormcov.py +910 -0
- synapse/vendor/__init__.py +0 -0
- synapse/vendor/cashaddress/LICENSE +25 -0
- synapse/vendor/cashaddress/__init__.py +5 -0
- synapse/vendor/cashaddress/base58.py +134 -0
- synapse/vendor/cashaddress/convert.py +131 -0
- synapse/vendor/cashaddress/crypto.py +70 -0
- synapse/vendor/cashaddress/tests/__init__.py +0 -0
- synapse/vendor/cashaddress/tests/test_cashaddress.py +65 -0
- synapse/vendor/cpython/LICENSE +279 -0
- synapse/vendor/cpython/__init__.py +0 -0
- synapse/vendor/cpython/lib/__init__.py +0 -0
- synapse/vendor/cpython/lib/email/__init__.py +0 -0
- synapse/vendor/cpython/lib/email/_parseaddr.py +566 -0
- synapse/vendor/cpython/lib/email/utils.py +494 -0
- synapse/vendor/cpython/lib/ipaddress.py +2420 -0
- synapse/vendor/cpython/lib/json.py +35 -0
- synapse/vendor/cpython/lib/test/__init__.py +0 -0
- synapse/vendor/cpython/lib/test/support/__init__.py +114 -0
- synapse/vendor/cpython/lib/test/test_email/__init__.py +0 -0
- synapse/vendor/cpython/lib/test/test_email/test_email.py +490 -0
- synapse/vendor/cpython/lib/test/test_email/test_parseaddr.py +47 -0
- synapse/vendor/cpython/lib/test/test_email/test_utils.py +173 -0
- synapse/vendor/cpython/lib/test/test_ipaddress.py +2862 -0
- synapse/vendor/cpython/lib/test/test_json.py +22 -0
- synapse/vendor/substrateinterface/LICENSE +206 -0
- synapse/vendor/substrateinterface/__init__.py +20 -0
- synapse/vendor/substrateinterface/tests/__init__.py +0 -0
- synapse/vendor/substrateinterface/tests/test_ss58.py +207 -0
- synapse/vendor/substrateinterface/utils/__init__.py +34 -0
- synapse/vendor/substrateinterface/utils/ss58.py +250 -0
- synapse/vendor/utils.py +9 -0
- synapse/vendor/xrpl/LICENSE +13 -0
- synapse/vendor/xrpl/__init__.py +26 -0
- synapse/vendor/xrpl/constants.py +30 -0
- synapse/vendor/xrpl/core/__init__.py +5 -0
- synapse/vendor/xrpl/core/addresscodec/__init__.py +39 -0
- synapse/vendor/xrpl/core/addresscodec/codec.py +210 -0
- synapse/vendor/xrpl/core/addresscodec/exceptions.py +9 -0
- synapse/vendor/xrpl/core/addresscodec/main.py +156 -0
- synapse/vendor/xrpl/core/addresscodec/utils.py +7 -0
- synapse/vendor/xrpl/tests/__init__.py +0 -0
- synapse/vendor/xrpl/tests/test_codec.py +170 -0
- synapse/vendor/xrpl/tests/test_main.py +134 -0
- synapse/vendor/xrpl/tests/test_main_test_cases.py +134 -0
- synapse-3.0.0.dist-info/METADATA +89 -0
- synapse-3.0.0.dist-info/RECORD +680 -0
- synapse-3.0.0.dist-info/WHEEL +5 -0
- synapse-3.0.0.dist-info/licenses/LICENSE +202 -0
- 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'])
|