stoobly-agent 0.21.2__py3-none-any.whl → 0.22.3__py3-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 (216) hide show
  1. stoobly_agent/__init__.py +2 -1
  2. stoobly_agent/app/api/bodies_controller.py +2 -2
  3. stoobly_agent/app/api/requests_controller.py +28 -10
  4. stoobly_agent/app/api/simple_http_request_handler.py +1 -1
  5. stoobly_agent/app/cli/ca_cert_installer.py +16 -5
  6. stoobly_agent/app/cli/config_cli.py +32 -20
  7. stoobly_agent/app/cli/helpers/context.py +7 -0
  8. stoobly_agent/app/cli/helpers/handle_mock_service.py +14 -0
  9. stoobly_agent/app/cli/helpers/print_service.py +1 -1
  10. stoobly_agent/app/cli/intercept.py +46 -2
  11. stoobly_agent/app/cli/main_group.py +3 -3
  12. stoobly_agent/app/cli/project_cli.py +3 -1
  13. stoobly_agent/app/cli/request_cli.py +6 -10
  14. stoobly_agent/app/models/adapters/mitmproxy/__init__.py +2 -0
  15. stoobly_agent/app/models/adapters/mitmproxy/request/__init__.py +12 -0
  16. stoobly_agent/app/models/adapters/mitmproxy/request/python_adapter.py +16 -0
  17. stoobly_agent/app/models/adapters/mitmproxy/response/__init__.py +12 -0
  18. stoobly_agent/app/models/adapters/mitmproxy/response/python_adapter.py +24 -0
  19. stoobly_agent/app/models/adapters/python/__init__.py +2 -0
  20. stoobly_agent/app/models/adapters/python/request/__init__.py +18 -0
  21. stoobly_agent/app/models/adapters/python/request/mitmproxy_adapter.py +53 -0
  22. stoobly_agent/app/models/adapters/python/request/stoobly_adapter.py +49 -0
  23. stoobly_agent/app/models/adapters/python/response/__init__.py +13 -0
  24. stoobly_agent/app/models/adapters/{mitmproxy_response_adapter.py → python/response/mitmproxy_adapter.py} +15 -7
  25. stoobly_agent/app/models/adapters/raw_http_response_adapter.py +10 -3
  26. stoobly_agent/app/models/adapters/stoobly/request/__init__.py +11 -0
  27. stoobly_agent/app/models/adapters/stoobly/request/mitmproxy_adapter.py +32 -0
  28. stoobly_agent/app/models/body_model.py +2 -2
  29. stoobly_agent/app/models/factories/__init__.py +0 -0
  30. stoobly_agent/app/models/factories/resource/__init__.py +0 -0
  31. stoobly_agent/app/models/{adapters/body_adapter_factory.py → factories/resource/body.py} +1 -1
  32. stoobly_agent/app/models/{adapters/header_adapter_factory.py → factories/resource/header.py} +1 -1
  33. stoobly_agent/app/models/factories/resource/local_db/__init__.py +0 -0
  34. stoobly_agent/app/models/{adapters → factories/resource}/local_db/replayed_response_adapter.py +1 -2
  35. stoobly_agent/app/models/{adapters → factories/resource}/local_db/request_adapter.py +15 -8
  36. stoobly_agent/app/models/{adapters → factories/resource}/local_db/scenario_adapter.py +13 -7
  37. stoobly_agent/app/models/{adapters/query_param_adapter_factory.py → factories/resource/query_param.py} +1 -1
  38. stoobly_agent/app/models/{adapters/replayed_response_adapter_factory.py → factories/resource/replayed_response.py} +1 -1
  39. stoobly_agent/app/models/{adapters/request_adapter_factory.py → factories/resource/request.py} +2 -2
  40. stoobly_agent/app/models/{adapters/response_adapter_factory.py → factories/resource/response.py} +1 -1
  41. stoobly_agent/app/models/{adapters/response_header_adapter_factory.py → factories/resource/response_header.py} +1 -1
  42. stoobly_agent/app/models/{adapters/scenario_adapter_factory.py → factories/resource/scenario.py} +2 -2
  43. stoobly_agent/app/models/factories/resource/stoobly/__init__.py +0 -0
  44. stoobly_agent/app/models/{adapters/stoobly_request_adapter.py → factories/resource/stoobly/request_adapter.py} +1 -2
  45. stoobly_agent/app/models/{adapters/stoobly_scenario_adapter.py → factories/resource/stoobly/scenario_adapter.py} +1 -2
  46. stoobly_agent/app/models/header_model.py +2 -2
  47. stoobly_agent/app/models/query_param_model.py +2 -2
  48. stoobly_agent/app/models/replayed_response_model.py +2 -2
  49. stoobly_agent/app/models/request_model.py +4 -5
  50. stoobly_agent/app/models/response_header_model.py +2 -2
  51. stoobly_agent/app/models/response_model.py +2 -2
  52. stoobly_agent/app/models/scenario_model.py +4 -4
  53. stoobly_agent/app/models/schemas/request.py +8 -1
  54. stoobly_agent/app/models/types/__init__.py +6 -0
  55. stoobly_agent/app/proxy/__init__.py +0 -5
  56. stoobly_agent/app/proxy/handle_mock_service.py +0 -3
  57. stoobly_agent/app/proxy/handle_test_service.py +1 -1
  58. stoobly_agent/app/proxy/intercept_handler.py +0 -1
  59. stoobly_agent/app/proxy/mitmproxy/flow_mock.py +35 -0
  60. stoobly_agent/app/proxy/mitmproxy/request_facade.py +11 -2
  61. stoobly_agent/app/proxy/replay/replay_request_service.py +57 -40
  62. stoobly_agent/app/proxy/simulate_intercept_service.py +30 -0
  63. stoobly_agent/app/proxy/test/__init__.py +1 -0
  64. stoobly_agent/app/proxy/test/context.py +2 -1
  65. stoobly_agent/app/proxy/test/context_abc.py +155 -0
  66. stoobly_agent/app/proxy/test/matchers/context.py +1 -1
  67. stoobly_agent/app/proxy/test/matchers/contract.py +1 -1
  68. stoobly_agent/app/proxy/test/matchers/custom.py +1 -1
  69. stoobly_agent/app/proxy/test/matchers/diff.py +1 -1
  70. stoobly_agent/app/proxy/test/matchers/fuzzy.py +1 -1
  71. stoobly_agent/app/proxy/test/test_service.py +1 -1
  72. stoobly_agent/app/proxy/upload/joined_request.py +0 -1
  73. stoobly_agent/app/proxy/upload/proxy_request.py +4 -1
  74. stoobly_agent/app/proxy/upload/request_string.py +1 -1
  75. stoobly_agent/app/settings/constants/mode.py +3 -0
  76. stoobly_agent/cli.py +76 -7
  77. stoobly_agent/config/constants/env_vars.py +2 -1
  78. stoobly_agent/config/data_dir.py +11 -8
  79. stoobly_agent/lib/api/api.py +4 -4
  80. stoobly_agent/lib/api/keys/organization_key.py +2 -0
  81. stoobly_agent/lib/api/keys/project_key.py +9 -0
  82. stoobly_agent/lib/api/scenarios_resource.py +1 -1
  83. stoobly_agent/lib/api/stoobly_api.py +9 -5
  84. stoobly_agent/lib/orm/__init__.py +1 -1
  85. stoobly_agent/lib/orm/replayed_response.py +3 -3
  86. stoobly_agent/lib/orm/request.py +25 -5
  87. stoobly_agent/lib/orm/transformers/orm_to_stoobly_request_transformer.py +1 -1
  88. stoobly_agent/mock.py +94 -0
  89. stoobly_agent/public/{2-es2015.3d54569af612a07a2e06.js → 1-es2015.37917aa26708d8f35d36.js} +1 -1
  90. stoobly_agent/public/{2-es5.3d54569af612a07a2e06.js → 1-es5.37917aa26708d8f35d36.js} +1 -1
  91. stoobly_agent/public/10-es2015.e9556b0d0f0e92fb548b.js +1 -0
  92. stoobly_agent/public/10-es5.e9556b0d0f0e92fb548b.js +1 -0
  93. stoobly_agent/public/11-es2015.bc6212fccbe72a623f81.js +1 -0
  94. stoobly_agent/public/11-es5.bc6212fccbe72a623f81.js +1 -0
  95. stoobly_agent/public/{13-es2015.76b6c147b0c46f995cd7.js → 12-es2015.d0768894ddffd6efa5e5.js} +1 -1
  96. stoobly_agent/public/{13-es5.76b6c147b0c46f995cd7.js → 12-es5.d0768894ddffd6efa5e5.js} +1 -1
  97. stoobly_agent/public/13-es2015.8a044490a76fd298162d.js +1 -0
  98. stoobly_agent/public/13-es5.8a044490a76fd298162d.js +1 -0
  99. stoobly_agent/public/{15-es2015.60c3b41c385f5bdedb7b.js → 14-es2015.1cd1a021e51ca0e62e1c.js} +1 -1
  100. stoobly_agent/public/{15-es5.60c3b41c385f5bdedb7b.js → 14-es5.1cd1a021e51ca0e62e1c.js} +1 -1
  101. stoobly_agent/public/{16-es2015.5d395009a77978db4405.js → 15-es2015.587781d19864ff0eb4f5.js} +1 -1
  102. stoobly_agent/public/{16-es5.5d395009a77978db4405.js → 15-es5.587781d19864ff0eb4f5.js} +1 -1
  103. stoobly_agent/public/16-es2015.ec6a175b1f9578203cd8.js +1 -0
  104. stoobly_agent/public/16-es5.ec6a175b1f9578203cd8.js +1 -0
  105. stoobly_agent/public/17-es2015.ad9c4756c96a15bd29d7.js +1 -0
  106. stoobly_agent/public/17-es5.ad9c4756c96a15bd29d7.js +1 -0
  107. stoobly_agent/public/{19-es2015.517f68e08f4c582dae66.js → 18-es2015.8583df0f8eccb3e47c0b.js} +1 -1
  108. stoobly_agent/public/{19-es5.517f68e08f4c582dae66.js → 18-es5.8583df0f8eccb3e47c0b.js} +1 -1
  109. stoobly_agent/public/{20-es2015.473486aabfa4d4a6431b.js → 19-es2015.d0225852a844dc03a09f.js} +1 -1
  110. stoobly_agent/public/{20-es5.473486aabfa4d4a6431b.js → 19-es5.d0225852a844dc03a09f.js} +1 -1
  111. stoobly_agent/public/{3-es5.1dad290844ea619e4c16.js → 2-es2015.8f184ac63348ba447b1f.js} +1 -1
  112. stoobly_agent/public/{3-es2015.1dad290844ea619e4c16.js → 2-es5.8f184ac63348ba447b1f.js} +1 -1
  113. stoobly_agent/public/{21-es2015.56aa10803cc1348a55a3.js → 20-es2015.f7c107847935264d58aa.js} +1 -1
  114. stoobly_agent/public/{21-es5.56aa10803cc1348a55a3.js → 20-es5.f7c107847935264d58aa.js} +1 -1
  115. stoobly_agent/public/{22-es2015.46d81010003b2a50eeab.js → 21-es2015.dd358e1edaf3d32dd2c0.js} +1 -1
  116. stoobly_agent/public/{22-es5.46d81010003b2a50eeab.js → 21-es5.dd358e1edaf3d32dd2c0.js} +1 -1
  117. stoobly_agent/public/26-es2015.6332c32f1b7c8c288f2f.js +1 -0
  118. stoobly_agent/public/26-es5.6332c32f1b7c8c288f2f.js +1 -0
  119. stoobly_agent/public/27-es2015.af505e744b0c869a93d1.js +1 -0
  120. stoobly_agent/public/27-es5.af505e744b0c869a93d1.js +1 -0
  121. stoobly_agent/public/28-es2015.7c7c0f64e4af29d2e4d4.js +1 -0
  122. stoobly_agent/public/28-es5.7c7c0f64e4af29d2e4d4.js +1 -0
  123. stoobly_agent/public/32-es2015.2ab8267be7275dee9059.js +1 -0
  124. stoobly_agent/public/32-es5.2ab8267be7275dee9059.js +1 -0
  125. stoobly_agent/public/{34-es2015.ef24f6f7630620a38b19.js → 33-es2015.5b575f3a87c6c2c6b93b.js} +1 -1
  126. stoobly_agent/public/{34-es5.ef24f6f7630620a38b19.js → 33-es5.5b575f3a87c6c2c6b93b.js} +1 -1
  127. stoobly_agent/public/{35-es2015.0667e742725cc828f59f.js → 34-es2015.6a1160649c718cdb9338.js} +1 -1
  128. stoobly_agent/public/{35-es5.0667e742725cc828f59f.js → 34-es5.6a1160649c718cdb9338.js} +1 -1
  129. stoobly_agent/public/35-es2015.1b9dc7a46a6d5296c3ae.js +1 -0
  130. stoobly_agent/public/35-es5.1b9dc7a46a6d5296c3ae.js +1 -0
  131. stoobly_agent/public/{37-es2015.50d0c2d3fe4d0a74fc8f.js → 36-es2015.2fc9151fe6a5ff2bff31.js} +1 -1
  132. stoobly_agent/public/{37-es5.50d0c2d3fe4d0a74fc8f.js → 36-es5.2fc9151fe6a5ff2bff31.js} +1 -1
  133. stoobly_agent/public/{38-es2015.c14bde0b8d0cc14e915e.js → 37-es2015.ac7108c3625fd6e1d981.js} +1 -1
  134. stoobly_agent/public/{38-es5.c14bde0b8d0cc14e915e.js → 37-es5.ac7108c3625fd6e1d981.js} +1 -1
  135. stoobly_agent/public/38-es2015.9c183b14373c0e449932.js +1 -0
  136. stoobly_agent/public/38-es5.9c183b14373c0e449932.js +1 -0
  137. stoobly_agent/public/39-es2015.4624cdeb29fe9850b216.js +1 -0
  138. stoobly_agent/public/39-es5.4624cdeb29fe9850b216.js +1 -0
  139. stoobly_agent/public/40-es2015.24d981230c0c8f369cde.js +1 -0
  140. stoobly_agent/public/40-es5.24d981230c0c8f369cde.js +1 -0
  141. stoobly_agent/public/{46-es2015.abc7e4fd207d54277fcb.js → 45-es2015.c76937ed45d460bcd36f.js} +1 -1
  142. stoobly_agent/public/{46-es5.abc7e4fd207d54277fcb.js → 45-es5.c76937ed45d460bcd36f.js} +1 -1
  143. stoobly_agent/public/6-es2015.53acc5d2ca7f48ef857f.js +1 -0
  144. stoobly_agent/public/6-es5.53acc5d2ca7f48ef857f.js +1 -0
  145. stoobly_agent/public/7-es2015.1c6b3d315d50ccd228cb.js +1 -0
  146. stoobly_agent/public/7-es5.1c6b3d315d50ccd228cb.js +1 -0
  147. stoobly_agent/public/{9-es2015.ef0f7cb32f5fadb085d0.js → 8-es2015.0fe7492f7b61eb4699b6.js} +1 -1
  148. stoobly_agent/public/{9-es5.ef0f7cb32f5fadb085d0.js → 8-es5.0fe7492f7b61eb4699b6.js} +1 -1
  149. stoobly_agent/public/common-es2015.86f70de6df2c705a87f6.js +1 -0
  150. stoobly_agent/public/common-es5.86f70de6df2c705a87f6.js +1 -0
  151. stoobly_agent/public/dashboard.agent-alpha-0.22.3.tar.gz +0 -0
  152. stoobly_agent/public/index.html +1 -1
  153. stoobly_agent/public/main-es2015.aceb967cb4cccc0bc521.js +1 -0
  154. stoobly_agent/public/main-es5.aceb967cb4cccc0bc521.js +1 -0
  155. stoobly_agent/public/{polyfills-es2015.2b40b2ecdf98a9210572.js → polyfills-es2015.580f7a6e775c2c348c9d.js} +1 -1
  156. stoobly_agent/public/{polyfills-es5.d9fb2eee68607c3f7f64.js → polyfills-es5.4c3461a071d35be3dd81.js} +1 -1
  157. stoobly_agent/public/runtime-es2015.49eaebd2913fa7fe2b97.js +1 -0
  158. stoobly_agent/public/runtime-es5.49eaebd2913fa7fe2b97.js +1 -0
  159. stoobly_agent/test/test_helper.py +4 -5
  160. {stoobly_agent-0.21.2.dist-info → stoobly_agent-0.22.3.dist-info}/METADATA +1 -1
  161. {stoobly_agent-0.21.2.dist-info → stoobly_agent-0.22.3.dist-info}/RECORD +175 -157
  162. {stoobly_agent-0.21.2.dist-info → stoobly_agent-0.22.3.dist-info}/WHEEL +1 -1
  163. stoobly_agent/app/models/adapters/mitmproxy_request_adapter.py +0 -60
  164. stoobly_agent/app/models/adapters/types/__init__.py +0 -3
  165. stoobly_agent/public/11-es2015.b85bdc528bab0ee542fe.js +0 -1
  166. stoobly_agent/public/11-es5.b85bdc528bab0ee542fe.js +0 -1
  167. stoobly_agent/public/12-es2015.72399d40488de533bb97.js +0 -1
  168. stoobly_agent/public/12-es5.72399d40488de533bb97.js +0 -1
  169. stoobly_agent/public/14-es2015.7cedfd0829bd7a64677a.js +0 -1
  170. stoobly_agent/public/14-es5.7cedfd0829bd7a64677a.js +0 -1
  171. stoobly_agent/public/17-es2015.f6f28ba9f681063632a8.js +0 -1
  172. stoobly_agent/public/17-es5.f6f28ba9f681063632a8.js +0 -1
  173. stoobly_agent/public/18-es2015.b0cd6822ebd1090b0d60.js +0 -1
  174. stoobly_agent/public/18-es5.b0cd6822ebd1090b0d60.js +0 -1
  175. stoobly_agent/public/27-es2015.4635450ff709f7868796.js +0 -1
  176. stoobly_agent/public/27-es5.4635450ff709f7868796.js +0 -1
  177. stoobly_agent/public/28-es2015.1b29b35529772ab108f1.js +0 -1
  178. stoobly_agent/public/28-es5.1b29b35529772ab108f1.js +0 -1
  179. stoobly_agent/public/32-es2015.862b67803e6242451976.js +0 -1
  180. stoobly_agent/public/32-es5.862b67803e6242451976.js +0 -1
  181. stoobly_agent/public/33-es2015.4ff4325d1aec37e1b43c.js +0 -1
  182. stoobly_agent/public/33-es5.4ff4325d1aec37e1b43c.js +0 -1
  183. stoobly_agent/public/36-es2015.cd370fdf8990019d0c8e.js +0 -1
  184. stoobly_agent/public/36-es5.cd370fdf8990019d0c8e.js +0 -1
  185. stoobly_agent/public/39-es2015.4ec5fc16202c4759eac4.js +0 -1
  186. stoobly_agent/public/39-es5.4ec5fc16202c4759eac4.js +0 -1
  187. stoobly_agent/public/40-es2015.25287ce77b40050f3471.js +0 -1
  188. stoobly_agent/public/40-es5.25287ce77b40050f3471.js +0 -1
  189. stoobly_agent/public/45-es2015.fd110741ac0fbaada177.js +0 -1
  190. stoobly_agent/public/45-es5.fd110741ac0fbaada177.js +0 -1
  191. stoobly_agent/public/6-es2015.7219d596e3545ebaed3a.js +0 -1
  192. stoobly_agent/public/6-es5.7219d596e3545ebaed3a.js +0 -1
  193. stoobly_agent/public/7-es2015.98b085349ebd9d246060.js +0 -1
  194. stoobly_agent/public/7-es5.98b085349ebd9d246060.js +0 -1
  195. stoobly_agent/public/8-es2015.335fd5c122ad083aec65.js +0 -1
  196. stoobly_agent/public/8-es5.335fd5c122ad083aec65.js +0 -1
  197. stoobly_agent/public/common-es2015.81f870bf87411a04446d.js +0 -1
  198. stoobly_agent/public/common-es5.81f870bf87411a04446d.js +0 -1
  199. stoobly_agent/public/dashboard.agent-alpha-0.21.0.tar.gz +0 -0
  200. stoobly_agent/public/main-es2015.575c1d17fc866d3a6649.js +0 -1
  201. stoobly_agent/public/main-es5.575c1d17fc866d3a6649.js +0 -1
  202. stoobly_agent/public/runtime-es2015.8915d042dc9b55368999.js +0 -1
  203. stoobly_agent/public/runtime-es5.8915d042dc9b55368999.js +0 -1
  204. /stoobly_agent/app/models/adapters/{local_db → stoobly}/__init__.py +0 -0
  205. /stoobly_agent/app/models/{adapters → factories/resource}/local_db/body_adapter.py +0 -0
  206. /stoobly_agent/app/models/{adapters → factories/resource}/local_db/header_adapter.py +0 -0
  207. /stoobly_agent/app/models/{adapters → factories/resource}/local_db/query_param_adapter.py +0 -0
  208. /stoobly_agent/app/models/{adapters → factories/resource}/local_db/response_adapter.py +0 -0
  209. /stoobly_agent/app/models/{adapters → factories/resource}/local_db/response_header_adapter.py +0 -0
  210. /stoobly_agent/app/models/{adapters/types → types}/replayed_response.py +0 -0
  211. /stoobly_agent/app/models/{adapters/types → types}/request_create_params.py +0 -0
  212. /stoobly_agent/app/models/{adapters/types → types}/request_show_params.py +0 -0
  213. /stoobly_agent/app/models/{adapters/types → types}/scenario_create_params.py +0 -0
  214. {stoobly_agent-0.21.2.dist-info → stoobly_agent-0.22.3.dist-info}/LICENSE +0 -0
  215. {stoobly_agent-0.21.2.dist-info → stoobly_agent-0.22.3.dist-info}/entry_points.txt +0 -0
  216. {stoobly_agent-0.21.2.dist-info → stoobly_agent-0.22.3.dist-info}/top_level.txt +0 -0
@@ -1,13 +1,21 @@
1
- from time import time
1
+ import pdb
2
2
  import requests
3
3
 
4
4
  from mitmproxy.http import Headers, Response as MitmproxyResponse
5
+ from time import time
6
+
7
+ from stoobly_agent.app.models.adapters.raw_http_request_adapter import DEFAULT_HTTP_VERSION
5
8
 
6
9
  class MitmproxyResponseAdapter():
7
10
 
8
- def __init__(self, http_version, response: requests.Response):
11
+ def __init__(self, response: requests.Response):
9
12
  self.__timestamp_start = time()
10
- self.__http_version = http_version
13
+
14
+ if hasattr(response, 'raw'):
15
+ self.__http_version = f"HTTP/{response.raw.version / 10.0}"
16
+ else:
17
+ self.__http_version = DEFAULT_HTTP_VERSION
18
+
11
19
  self.__latency = 0 # Seconds
12
20
  self.__response = response
13
21
 
@@ -41,11 +49,11 @@ class MitmproxyResponseAdapter():
41
49
 
42
50
  def adapt(self):
43
51
  body = b''
44
-
45
- try:
46
- body = self.__response.raw.data
47
- except:
52
+
53
+ if self.__response._content_consumed or not hasattr(self.__response, 'raw'):
48
54
  body = self.__response.content
55
+ else:
56
+ body = self.__response.raw.data
49
57
 
50
58
  return MitmproxyResponse(
51
59
  self.__http_version,
@@ -6,6 +6,7 @@ from io import BytesIO
6
6
  from mitmproxy.net import encoding
7
7
  from requests.structures import CaseInsensitiveDict
8
8
  from typing import Union
9
+ from urllib3 import HTTPResponse
9
10
 
10
11
  from stoobly_agent.app.proxy.mitmproxy.response import Response
11
12
  from stoobly_agent.lib.orm.utils.response_parse_handler import Response as ResponseDict, ResponseParseHandler
@@ -39,8 +40,14 @@ class RawHttpResponseAdapter():
39
40
  response.status_code = self.status
40
41
  response.headers = self.headers
41
42
 
42
- content_encoding = response.headers.get('content-encoding')
43
- response.raw = self.__decode_body(self.body, content_encoding)
43
+ response.raw = HTTPResponse(
44
+ body=BytesIO(self.body),
45
+ decode_content=False,
46
+ headers=self.headers,
47
+ preload_content=False
48
+ )
49
+
50
+ #response.raw = self.__decode_body(self.body, content_encoding)
44
51
 
45
52
  return response
46
53
 
@@ -70,7 +77,7 @@ class RawHttpResponseAdapter():
70
77
  def __parse_response_line(self, response_line):
71
78
  response_parts = response_line.split(b' ')
72
79
  self.protocol = self.__decode(response_parts[0]) if len(response_parts) > 2 else DEFAULT_HTTP_VERSION
73
- self.status = self.__decode(response_parts[1])
80
+ self.status = int(self.__decode(response_parts[1]))
74
81
  self.reason = self.__decode(response_parts[2]) if len(response_parts) > 2 else ''
75
82
 
76
83
  def __str__(self):
@@ -0,0 +1,11 @@
1
+ from lib.api.interfaces.requests import RequestShowResponse
2
+
3
+ from .mitmproxy_adapter import MitmproxyRequestAdapter
4
+
5
+ class StooblyRequestAdapterFactory():
6
+
7
+ def __init__(self, request: RequestShowResponse):
8
+ self.__request = request
9
+
10
+ def mitmproxy_request(self):
11
+ return MitmproxyRequestAdapter(self.__request)
@@ -0,0 +1,32 @@
1
+ import pdb
2
+ import requests
3
+
4
+ from mitmproxy.http import Headers, Request as MitmproxyRequest
5
+
6
+ from stoobly_agent.app.models.schemas.request import Request
7
+
8
+ class MitmproxyRequestAdapter():
9
+
10
+ def __init__(self, request: Request):
11
+ self.__http_version = 'HTTP/1.1'
12
+ self.__request = request
13
+
14
+ @property
15
+ def headers(self):
16
+ return Headers(**self.__decode_dict(self.__request.headers))
17
+
18
+ def adapt(self):
19
+ request = MitmproxyRequest.make(
20
+ self.__request.method,
21
+ self.__request.url,
22
+ self.__request.body,
23
+ self.headers,
24
+ )
25
+ request.http_version = self.__http_version
26
+ return request
27
+
28
+ def __decode_dict(self, d):
29
+ new_d = {}
30
+ for k, v in d.items():
31
+ new_d[k.decode() if isinstance(k, bytes) else k] = v.decode() if isinstance(v, bytes) else v
32
+ return new_d
@@ -1,10 +1,10 @@
1
1
  import pdb
2
2
  import requests
3
3
 
4
- from stoobly_agent.app.models.adapters.body_adapter_factory import BodyAdapterFactory
5
4
  from stoobly_agent.app.settings import Settings
6
5
  from stoobly_agent.lib.logger import Logger
7
6
 
7
+ from .factories.resource.body import BodyResourceFactory
8
8
  from .model import Model
9
9
 
10
10
  class BodyModel(Model):
@@ -13,7 +13,7 @@ class BodyModel(Model):
13
13
  super().__init__(settings)
14
14
 
15
15
  def as_local(self):
16
- self.adapter = BodyAdapterFactory(self.settings.remote).local_db()
16
+ self.adapter = BodyResourceFactory(self.settings.remote).local_db()
17
17
 
18
18
  def as_remote(self):
19
19
  # 'Not yet supported.'
File without changes
@@ -3,7 +3,7 @@ from stoobly_agent.lib.orm.request import Request
3
3
 
4
4
  from .local_db.body_adapter import LocalDBBodyAdapter
5
5
 
6
- class BodyAdapterFactory():
6
+ class BodyResourceFactory():
7
7
 
8
8
  def __init__(self, settings: RemoteSettings):
9
9
  self.__remote_settings = settings
@@ -3,7 +3,7 @@ from stoobly_agent.lib.orm.request import Request
3
3
 
4
4
  from .local_db.header_adapter import LocalDBHeaderAdapter
5
5
 
6
- class HeaderAdapterFactory():
6
+ class HeaderResourceFactory():
7
7
 
8
8
  def __init__(self, settings: RemoteSettings):
9
9
  self.__remote_settings = settings
@@ -1,14 +1,13 @@
1
1
  import pdb
2
2
  import requests
3
3
 
4
+ from stoobly_agent.app.models.types import ReplayedResponseIndexQueryParams
4
5
  from stoobly_agent.lib.api.interfaces.requests import RequestShowResponse
5
6
  from stoobly_agent.lib.orm.replayed_response import ReplayedResponse
6
7
  from stoobly_agent.lib.orm.transformers.orm_to_requests_response_transformer import ORMToRequestsResponseTransformer
7
8
  from stoobly_agent.lib.orm.transformers.orm_to_stoobly_request_transformer import ORMToStooblyRequestTransformer
8
9
  from stoobly_agent.lib.orm.utils.response_parse_handler import Response
9
10
 
10
- from ..types.replayed_response import ReplayedResponseIndexQueryParams
11
-
12
11
  class LocalDBReplayedResponseAdapter():
13
12
  __replayed_response_orm = None
14
13
 
@@ -3,13 +3,12 @@ from urllib.parse import urlparse
3
3
  import requests
4
4
 
5
5
  from mitmproxy.http import HTTPFlow as MitmproxyHTTPFlow, Request as MitmproxyRequest
6
- from typing import List
7
6
 
7
+ from stoobly_agent.app.models.types import RequestCreateParams, RequestShowParams
8
8
  from stoobly_agent.app.proxy.mock.custom_not_found_response_builder import CustomNotFoundResponseBuilder
9
9
  from stoobly_agent.app.proxy.mock.hashed_request_decorator import HashedRequestDecorator
10
10
  from stoobly_agent.app.proxy.mitmproxy.request_facade import MitmproxyRequestFacade
11
11
  from stoobly_agent.app.proxy.upload.joined_request import JoinedRequest
12
-
13
12
  from stoobly_agent.lib.orm import ORM
14
13
  from stoobly_agent.lib.orm.request import Request
15
14
  from stoobly_agent.lib.orm.response import Response
@@ -19,8 +18,6 @@ from stoobly_agent.lib.orm.types.response_columns import ResponseColumns
19
18
  from stoobly_agent.lib.orm.transformers import ORMToRequestsResponseTransformer, ORMToStooblyResponseTransformer
20
19
  from stoobly_agent.lib.api.interfaces import RequestsIndexQueryParams, RequestsIndexResponse, RequestShowResponse
21
20
 
22
- from ..types import RequestCreateParams, RequestShowParams
23
-
24
21
  class LocalDBRequestAdapter():
25
22
  __request_orm = None
26
23
  __response_orm = None
@@ -73,14 +70,23 @@ class LocalDBRequestAdapter():
73
70
  def show(self, request_id: str, **options: RequestShowParams) -> RequestShowResponse:
74
71
  request = self.__request_orm.find(request_id)
75
72
 
73
+ if not request:
74
+ return CustomNotFoundResponseBuilder().build()
75
+
76
76
  return ORMToStooblyRequestTransformer(request, options).transform()
77
77
 
78
78
  def response(self, **query_params: RequestColumns) -> requests.Response:
79
- request_columns = { **query_params }
80
- self.__filter_request_response_columns(request_columns)
79
+ request = None
80
+
81
+ if not query_params.get('request_id'):
82
+ request_columns = { **query_params }
81
83
 
82
- # Find most recent matching record
83
- request = self.__request_orm.where_for(**request_columns).get().last()
84
+ self.__filter_request_response_columns(request_columns)
85
+
86
+ # Find most recent matching record
87
+ request = self.__request_orm.where_for(**request_columns).get().last()
88
+ else:
89
+ request = self.__request_orm.find(query_params.get('request_id'))
84
90
 
85
91
  if not request:
86
92
  return CustomNotFoundResponseBuilder().build()
@@ -107,6 +113,7 @@ class LocalDBRequestAdapter():
107
113
 
108
114
  if scenario_id:
109
115
  requests = requests.where('scenario_id', int(scenario_id))
116
+ sort_order = query_params.get('sort_order') or 'asc'
110
117
 
111
118
  if starred:
112
119
  requests = requests.where('starred', starred)
@@ -1,13 +1,11 @@
1
1
  import pdb
2
2
 
3
- from stoobly_agent.app.models.adapters.types.scenario_create_params import ScenarioCreateParams
3
+ from stoobly_agent.app.models.types import ScenarioCreateParams
4
4
  from stoobly_agent.lib.api.interfaces import ScenariosIndexQueryParams, ScenariosIndexResponse, ScenarioShowResponse
5
5
  from stoobly_agent.lib.api.keys.scenario_key import ScenarioKey
6
6
  from stoobly_agent.lib.orm import ORM
7
7
  from stoobly_agent.lib.orm.scenario import Scenario
8
8
 
9
- from ..types import ScenarioCreateParams
10
-
11
9
  class LocalDBScenarioAdapter():
12
10
  __scenario_orm = None
13
11
 
@@ -30,13 +28,21 @@ class LocalDBScenarioAdapter():
30
28
  sort_by = query_params.get('sort_by') or 'id'
31
29
  sort_order = query_params.get('sort_order') or 'desc'
32
30
 
33
- is_deleted = query_params.get('filter') == 'is_deleted'
34
- starred = query_params.get('filter') == 'starred'
31
+ filter = query_params.get('filter')
32
+ is_deleted = filter == 'is_deleted'
35
33
 
36
34
  scenarios = Scenario.where('is_deleted', is_deleted)
37
35
 
38
- if starred:
39
- scenarios = scenarios.where('starred', starred)
36
+ if filter == 'starred':
37
+ scenarios = scenarios.where('starred', True)
38
+ elif filter == 'high_priority':
39
+ scenarios = scenarios.where('priority', 3)
40
+ elif filter == 'medium_priority':
41
+ scenarios = scenarios.where('priority', 2)
42
+ elif filter == 'low_priority':
43
+ scenarios = scenarios.where('priority', 1)
44
+ elif filter == 'none_priority':
45
+ scenarios = scenarios.where('priority', 0)
40
46
 
41
47
  if query:
42
48
  scenarios = self.__search(scenarios, query)
@@ -3,7 +3,7 @@ from stoobly_agent.lib.orm.request import Request
3
3
 
4
4
  from .local_db.query_param_adapter import LocalDBQueryParamAdapter
5
5
 
6
- class QueryParamAdapterFactory():
6
+ class QueryParamResourceFactory():
7
7
 
8
8
  def __init__(self, settings: RemoteSettings):
9
9
  self.__remote_settings = settings
@@ -3,7 +3,7 @@ from stoobly_agent.lib.orm.replayed_response import ReplayedResponse
3
3
 
4
4
  from .local_db.replayed_response_adapter import LocalDBReplayedResponseAdapter
5
5
 
6
- class ReplayedResponseAdapterFactory():
6
+ class ReplayedResponseResourceFactory():
7
7
 
8
8
  def __init__(self, settings: RemoteSettings):
9
9
  self.__remote_settings = settings
@@ -3,9 +3,9 @@ from stoobly_agent.lib.api.requests_resource import RequestsResource
3
3
  from stoobly_agent.app.settings import RemoteSettings
4
4
 
5
5
  from .local_db.request_adapter import LocalDBRequestAdapter
6
- from .stoobly_request_adapter import StooblyRequestAdapter
6
+ from .stoobly.request_adapter import StooblyRequestAdapter
7
7
 
8
- class RequestAdapterFactory():
8
+ class RequestResourceFactory():
9
9
 
10
10
  def __init__(self, settings: RemoteSettings):
11
11
  self.__remote_settings = settings
@@ -3,7 +3,7 @@ from stoobly_agent.lib.orm.request import Request
3
3
 
4
4
  from .local_db.response_adapter import LocalDBResponseAdapter
5
5
 
6
- class ResponseAdapterFactory():
6
+ class ResponseResourceFactory():
7
7
 
8
8
  def __init__(self, settings: RemoteSettings):
9
9
  self.__remote_settings = settings
@@ -3,7 +3,7 @@ from stoobly_agent.lib.orm.request import Request
3
3
 
4
4
  from .local_db.response_header_adapter import LocalDBResponseHeaderAdapter
5
5
 
6
- class ResponseHeaderAdapterFactory():
6
+ class ResponseHeaderResourceFactory():
7
7
 
8
8
  def __init__(self, settings: RemoteSettings):
9
9
  self.__remote_settings = settings
@@ -3,9 +3,9 @@ from stoobly_agent.lib.api.scenarios_resource import ScenariosResource
3
3
  from stoobly_agent.app.settings import RemoteSettings
4
4
 
5
5
  from .local_db.scenario_adapter import LocalDBScenarioAdapter
6
- from .stoobly_scenario_adapter import StooblyScenarioAdapter
6
+ from .stoobly.scenario_adapter import StooblyScenarioAdapter
7
7
 
8
- class ScenarioAdapterFactory():
8
+ class ScenarioResourceFactory():
9
9
 
10
10
  def __init__(self, settings: RemoteSettings):
11
11
  self.__remote_settings = settings
@@ -1,11 +1,10 @@
1
1
  import pdb
2
2
  import requests
3
3
 
4
+ from stoobly_agent.app.models.types import RequestCreateParams, RequestShowParams
4
5
  from stoobly_agent.lib.api.requests_resource import RequestsResource
5
6
  from stoobly_agent.lib.api.interfaces import RequestShowResponse, RequestsIndexResponse
6
7
 
7
- from .types import RequestCreateParams, RequestShowParams
8
-
9
8
  class StooblyRequestAdapter():
10
9
 
11
10
  def __init__(self, __api: RequestsResource):
@@ -1,10 +1,9 @@
1
1
  import pdb
2
2
 
3
+ from stoobly_agent.app.models.types import ScenarioCreateParams
3
4
  from stoobly_agent.lib.api.scenarios_resource import ScenariosResource
4
5
  from stoobly_agent.lib.api.interfaces.scenarios import ScenarioShowResponse, ScenariosIndexResponse
5
6
 
6
- from .types import ScenarioCreateParams
7
-
8
7
  class StooblyScenarioAdapter():
9
8
 
10
9
  def __init__(self, __api: ScenariosResource):
@@ -2,12 +2,12 @@ import pdb
2
2
  import requests
3
3
 
4
4
  from typing import Union
5
- from stoobly_agent.app.models.adapters.header_adapter_factory import HeaderAdapterFactory
6
5
 
7
6
  from stoobly_agent.app.models.types.request_components import HeaderIndexResponse
8
7
  from stoobly_agent.app.settings import Settings
9
8
  from stoobly_agent.lib.logger import Logger
10
9
 
10
+ from .factories.resource.header import HeaderResourceFactory
11
11
  from .model import Model
12
12
 
13
13
  class HeaderModel(Model):
@@ -16,7 +16,7 @@ class HeaderModel(Model):
16
16
  super().__init__(settings)
17
17
 
18
18
  def as_local(self):
19
- self.adapter = HeaderAdapterFactory(self.settings.remote).local_db()
19
+ self.adapter = HeaderResourceFactory(self.settings.remote).local_db()
20
20
 
21
21
  def as_remote(self):
22
22
  # raise('Not yet supported.')
@@ -7,7 +7,7 @@ from stoobly_agent.app.models.types.request_components import QueryParamIndexRes
7
7
  from stoobly_agent.app.settings import Settings
8
8
  from stoobly_agent.lib.logger import Logger
9
9
 
10
- from .adapters.query_param_adapter_factory import QueryParamAdapterFactory
10
+ from .factories.resource.query_param import QueryParamResourceFactory
11
11
  from .model import Model
12
12
 
13
13
  class QueryParamModel(Model):
@@ -16,7 +16,7 @@ class QueryParamModel(Model):
16
16
  super().__init__(settings)
17
17
 
18
18
  def as_local(self):
19
- self.adapter = QueryParamAdapterFactory(self.settings.remote).local_db()
19
+ self.adapter = QueryParamResourceFactory(self.settings.remote).local_db()
20
20
 
21
21
  def as_remote(self):
22
22
  #raise('Not yet supported.')
@@ -1,10 +1,10 @@
1
1
  import pdb
2
2
  import requests
3
3
 
4
- from stoobly_agent.app.models.adapters.replayed_response_adapter_factory import ReplayedResponseAdapterFactory
5
4
  from stoobly_agent.app.settings import Settings
6
5
  from stoobly_agent.lib.logger import Logger
7
6
 
7
+ from .factories.resource.replayed_response import ReplayedResponseResourceFactory
8
8
  from .model import Model
9
9
 
10
10
  class ReplayedResponseModel(Model):
@@ -13,7 +13,7 @@ class ReplayedResponseModel(Model):
13
13
  super().__init__(settings)
14
14
 
15
15
  def as_local(self):
16
- self.adapter = ReplayedResponseAdapterFactory(self.settings.remote).local_db()
16
+ self.adapter = ReplayedResponseResourceFactory(self.settings.remote).local_db()
17
17
 
18
18
  def as_remote(self):
19
19
  # raise('Not yet supported.')
@@ -8,10 +8,9 @@ from stoobly_agent.app.settings import Settings
8
8
  from stoobly_agent.lib.api.interfaces import RequestShowResponse
9
9
  from stoobly_agent.lib.logger import Logger
10
10
 
11
- from .adapters.request_adapter_factory import RequestAdapterFactory
12
- from .adapters.types import RequestCreateParams, RequestShowParams
11
+ from .factories.resource.request import RequestResourceFactory
13
12
  from .model import Model
14
- from .types.requests_model_index import RequestsModelIndex
13
+ from .types import RequestCreateParams, RequestShowParams, RequestsModelIndex
15
14
 
16
15
  class RequestModel(Model):
17
16
 
@@ -19,10 +18,10 @@ class RequestModel(Model):
19
18
  super().__init__(settings)
20
19
 
21
20
  def as_local(self):
22
- self.adapter = RequestAdapterFactory(self.settings.remote).local_db()
21
+ self.adapter = RequestResourceFactory(self.settings.remote).local_db()
23
22
 
24
23
  def as_remote(self):
25
- self.adapter = RequestAdapterFactory(self.settings.remote).stoobly()
24
+ self.adapter = RequestResourceFactory(self.settings.remote).stoobly()
26
25
 
27
26
  def create(self, **body_params: RequestCreateParams) -> Union[RequestsModelIndex, None]:
28
27
  try:
@@ -7,7 +7,7 @@ from stoobly_agent.app.models.types.request_components import ResponseHeaderInde
7
7
  from stoobly_agent.app.settings import Settings
8
8
  from stoobly_agent.lib.logger import Logger
9
9
 
10
- from .adapters.response_header_adapter_factory import ResponseHeaderAdapterFactory
10
+ from .factories.resource.response_header import ResponseHeaderResourceFactory
11
11
  from .model import Model
12
12
 
13
13
  class ResponseHeaderModel(Model):
@@ -16,7 +16,7 @@ class ResponseHeaderModel(Model):
16
16
  super().__init__(settings)
17
17
 
18
18
  def as_local(self):
19
- self.adapter = ResponseHeaderAdapterFactory(self.settings.remote).local_db()
19
+ self.adapter = ResponseHeaderResourceFactory(self.settings.remote).local_db()
20
20
 
21
21
  def as_remote(self):
22
22
  # raise('Not yet supported.')
@@ -1,10 +1,10 @@
1
1
  import pdb
2
2
  import requests
3
3
 
4
- from stoobly_agent.app.models.adapters.response_adapter_factory import ResponseAdapterFactory
5
4
  from stoobly_agent.app.settings import Settings
6
5
  from stoobly_agent.lib.logger import Logger
7
6
 
7
+ from .factories.resource.response import ResponseResourceFactory
8
8
  from .model import Model
9
9
 
10
10
  class ResponseModel(Model):
@@ -13,7 +13,7 @@ class ResponseModel(Model):
13
13
  super().__init__(settings)
14
14
 
15
15
  def as_local(self):
16
- self.adapter = ResponseAdapterFactory(self.settings.remote).local_db()
16
+ self.adapter = ResponseResourceFactory(self.settings.remote).local_db()
17
17
 
18
18
  def as_remote(self):
19
19
  # raise('Not yet supported.')
@@ -7,8 +7,8 @@ from stoobly_agent.lib.logger import Logger
7
7
  from stoobly_agent.lib.api.interfaces.scenarios import ScenarioShowResponse, ScenariosIndexResponse
8
8
  from stoobly_agent.app.settings import Settings
9
9
 
10
- from .adapters.scenario_adapter_factory import ScenarioAdapterFactory
11
- from .adapters.types import ScenarioCreateParams
10
+ from .types import ScenarioCreateParams
11
+ from .factories.resource.scenario import ScenarioResourceFactory
12
12
  from .model import Model
13
13
 
14
14
  class ScenarioModel(Model):
@@ -17,10 +17,10 @@ class ScenarioModel(Model):
17
17
  super().__init__(settings)
18
18
 
19
19
  def as_local(self):
20
- self.adapter = ScenarioAdapterFactory(self.settings.remote).local_db()
20
+ self.adapter = ScenarioResourceFactory(self.settings.remote).local_db()
21
21
 
22
22
  def as_remote(self):
23
- self.adapter = ScenarioAdapterFactory(self.settings.remote).stoobly()
23
+ self.adapter = ScenarioResourceFactory(self.settings.remote).stoobly()
24
24
 
25
25
  def create(self, **body_params: ScenarioCreateParams) -> Union[ScenarioShowResponse, None]:
26
26
  try:
@@ -96,6 +96,10 @@ class Request():
96
96
  def headers(self, v: MultiDict):
97
97
  self.__set_dict('headers', v)
98
98
 
99
+ @property
100
+ def query(self) -> str:
101
+ return urlencode(self.query_params)
102
+
99
103
  @property
100
104
  def query_params(self) -> MultiDict:
101
105
  query_params = MultiDict()
@@ -115,7 +119,10 @@ class Request():
115
119
  if not encoded_body:
116
120
  return ''
117
121
 
118
- return base64.b64decode(encoded_body)
122
+ try:
123
+ return base64.b64decode(encoded_body)
124
+ except Exception as e:
125
+ return encoded_body
119
126
 
120
127
  @body.setter
121
128
  def body(self, v: Union[bytes, str]):
@@ -0,0 +1,6 @@
1
+ from .replayed_response import *
2
+ from .request_components import *
3
+ from .request_create_params import *
4
+ from .request_show_params import *
5
+ from .requests_model_index import *
6
+ from .scenario_create_params import *
@@ -83,10 +83,6 @@ def __commit_options(options: dict):
83
83
  if options.get('proxy_host') and options.get('proxy_port'):
84
84
  settings.proxy.url = f"http://{options.get('proxy_host')}:{options.get('proxy_port')}"
85
85
 
86
- if options.get('intercept_mode'):
87
- settings.proxy.intercept.mode = options['intercept_mode']
88
- settings.proxy.intercept.active = True
89
-
90
86
  settings.ui.active = not options.get('headless')
91
87
 
92
88
  settings.commit()
@@ -112,7 +108,6 @@ def __filter_options(options):
112
108
  if 'ui_port' in options:
113
109
  del options['ui_port']
114
110
 
115
- del options['intercept_mode']
116
111
  del options['log_level']
117
112
  del options['proxy_host']
118
113
  del options['proxy_mode']
@@ -2,15 +2,12 @@ import requests
2
2
  import time
3
3
  import pdb
4
4
 
5
- from mitmproxy.http import HTTPFlow as MitmproxyHTTPFlow
6
5
  from mitmproxy.http import Request as MitmproxyRequest
7
6
  from typing import Callable, TypedDict
8
7
 
9
8
  from stoobly_agent.app.models.request_model import RequestModel
10
- from stoobly_agent.app.proxy.intercept_settings import InterceptSettings
11
9
  from stoobly_agent.app.proxy.mitmproxy.request_facade import MitmproxyRequestFacade
12
10
  from stoobly_agent.app.proxy.utils.rewrite_rules_to_ignored_components_service import rewrite_rules_to_ignored_components
13
- from stoobly_agent.app.settings import intercept_settings
14
11
  from stoobly_agent.config.constants import custom_headers, mock_policy
15
12
  from stoobly_agent.lib.logger import Logger
16
13
 
@@ -13,7 +13,7 @@ from stoobly_agent.lib.logger import Logger
13
13
 
14
14
  from .handle_mock_service import handle_request_mock_generic
15
15
  from .mock.context import MockContext
16
- from .test.context import TestContext
16
+ from .test.context_abc import TestContextABC as TestContext
17
17
  from .test.test_service import test
18
18
  from .upload.upload_test_service import inject_upload_test
19
19
 
@@ -28,7 +28,6 @@ LOG_ID = 'InterceptHandler'
28
28
 
29
29
  def request(flow: MitmproxyHTTPFlow):
30
30
  request: MitmproxyRequest = flow.request
31
-
32
31
  intercept_settings = InterceptSettings(Settings.instance(), request)
33
32
 
34
33
  active_mode = intercept_settings.mode