stoobly-agent 0.30.0__py3-none-any.whl → 0.30.1__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.
stoobly_agent/__init__.py CHANGED
@@ -1,2 +1,2 @@
1
1
  COMMAND = 'stoobly-agent'
2
- VERSION = '0.30.0'
2
+ VERSION = '0.30.1'
@@ -27,8 +27,14 @@ class OpenApiEndpointAdapter():
27
27
 
28
28
  with open(file_path, "r") as stream:
29
29
  file_data: Dict = yaml.safe_load(stream)
30
+
30
31
  if 'info' not in file_data:
31
32
  self.__add_info(file_data)
33
+
34
+ missing_oauth2_scopes = self.__is_missing_oauth2_scopes(file_data)
35
+ if missing_oauth2_scopes:
36
+ self.__add_oauth2_default_scopes(file_data)
37
+
32
38
  spec = Spec.from_dict(file_data)
33
39
 
34
40
  return self.adapt(spec)
@@ -36,7 +42,7 @@ class OpenApiEndpointAdapter():
36
42
  def adapt(self, spec: Spec) -> List[EndpointShowResponse]:
37
43
  endpoints = []
38
44
  endpoint_counter = 0
39
- components = spec.get("components")
45
+ components = spec.get("components", {})
40
46
  schemas = components.get("schemas", {})
41
47
  paths = spec.getkey('paths')
42
48
 
@@ -184,12 +190,12 @@ class OpenApiEndpointAdapter():
184
190
  request_body = operation.get("requestBody", {})
185
191
  required_request_body = request_body.get("required")
186
192
  required_body_params = []
187
- param_properties = {}
188
193
  literal_body_params = {}
189
194
  request_body_array = False
190
195
 
191
196
  content = request_body.get("content", {})
192
197
  for mimetype, media_type in content.items():
198
+ param_properties = {}
193
199
  schema = media_type['schema']
194
200
 
195
201
  # If Spec Component reference, look it up in components
@@ -202,12 +208,10 @@ class OpenApiEndpointAdapter():
202
208
  schema_type = schema.get('type')
203
209
  if schema_type:
204
210
  if schema_type == 'object':
205
- param_properties = schema['properties']
211
+ param_properties = schema.get('properties', {})
206
212
  elif schema_type == 'array':
207
213
  request_body_array = True
208
214
  param_properties = {'tmp': schema['items']}
209
- else:
210
- param_properties = {}
211
215
 
212
216
  for property_key, property_value in param_properties.items():
213
217
  if property_key in required_body_params:
@@ -247,6 +251,57 @@ class OpenApiEndpointAdapter():
247
251
  'title': ''
248
252
  }
249
253
 
254
+ def __is_missing_oauth2_scopes(self, file_data: Dict):
255
+ is_missing = False
256
+ if 'components' in file_data:
257
+ components = file_data['components']
258
+
259
+ if 'securitySchemes' in components:
260
+ security_schemes = components['securitySchemes']
261
+
262
+ for scheme_name, scheme in security_schemes.items():
263
+ if scheme.get('type') == 'oauth2':
264
+ flows = scheme.get('flows')
265
+
266
+ if flows and flows.get('clientCredentials'):
267
+ scopes = flows.get('clientCredentials').get('scopes')
268
+
269
+ if scopes is None:
270
+ return True
271
+
272
+ break
273
+
274
+ return is_missing
275
+
276
+ def __add_oauth2_default_scopes(self, file_data: Dict):
277
+ if 'components' not in file_data:
278
+ return
279
+ components = file_data['components']
280
+
281
+ if 'securitySchemes' not in components:
282
+ return
283
+ security_schemes = components['securitySchemes']
284
+
285
+ oauth_security_scheme = {}
286
+ for scheme_name, scheme in security_schemes.items():
287
+ if scheme.get('type') == 'oauth2':
288
+ oauth_security_scheme = scheme
289
+ break
290
+
291
+ # If empty dict or None
292
+ if not oauth_security_scheme:
293
+ return
294
+
295
+ flows = oauth_security_scheme['flows']
296
+ if not flows:
297
+ return
298
+
299
+ client_credentials = flows['clientCredentials']
300
+ if not client_credentials:
301
+ return
302
+
303
+ client_credentials['scopes'] = {}
304
+
250
305
  def __get_most_recent_param(self, literal_params: dict):
251
306
  return list(literal_params)[-1] if literal_params else None
252
307
 
@@ -41,7 +41,7 @@ def handle_request_mock_generic(context: MockContext, **options: MockOptions):
41
41
  # Rewrite request with paramter rules for mock
42
42
  request: MitmproxyRequest = context.flow.request
43
43
  request_facade = MitmproxyRequestFacade(request)
44
- request_facade.with_parameter_rules(rewrite_rules).rewrite()
44
+ request_facade.with_parameter_rules(rewrite_rules).with_url_rules(rewrite_rules).rewrite()
45
45
 
46
46
  __mock_hook(lifecycle_hooks.BEFORE_MOCK, context)
47
47
 
@@ -185,7 +185,7 @@ class MitmproxyRequestFacade(Request):
185
185
  self.request.host = rewrite.host
186
186
 
187
187
  if rewrite.port:
188
- self.request.port = rewrite.port
188
+ self.request.port = int(rewrite.port)
189
189
 
190
190
  def __rewrite_headers(self, rewrites: List[ParameterRule]):
191
191
  self.__apply_headers(rewrites, self.__rewrite_handler)
@@ -26,7 +26,7 @@ def join_rewritten_request(flow: MitmproxyHTTPFlow, intercept_settings: Intercep
26
26
  response = MitmproxyResponseFacade(flow.response)
27
27
  rewrite_rules = intercept_settings.record_rewrite_rules
28
28
 
29
- request.with_parameter_rules(rewrite_rules).rewrite()
29
+ request.with_parameter_rules(rewrite_rules).with_url_rules(rewrite_rules).rewrite()
30
30
  response.with_rewrite_rules(rewrite_rules).rewrite()
31
31
 
32
32
  return join_request(request, response, intercept_settings)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: stoobly-agent
3
- Version: 0.30.0
3
+ Version: 0.30.1
4
4
  Summary: Client agent for Stoobly
5
5
  Home-page: https://github.com/Stoobly/stoobly-agent
6
6
  Author: Michael Yen
@@ -1,4 +1,4 @@
1
- stoobly_agent/__init__.py,sha256=oRS5sVm-ReZZRfzauK-Zo_6QLdKp4io3Ss5jkgMqd4A,45
1
+ stoobly_agent/__init__.py,sha256=ERtaDwMrq3L1TiLsgj7017T43LEdDMO9MX7tpGaf4AA,45
2
2
  stoobly_agent/cli.py,sha256=4ZAnhcjY1a9RA3YZy-RkkUFx4DKw6KpGZq1ZoJZ7akM,7439
3
3
  stoobly_agent/mock.py,sha256=P9cr9yW8PF1XolPfNSftcJVn1xEqcD-SEyIROsFxY20,2549
4
4
  stoobly_agent/app/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -44,7 +44,7 @@ stoobly_agent/app/cli/helpers/handle_mock_service.py,sha256=OkOaTgCd9ZqYle4_F8jv
44
44
  stoobly_agent/app/cli/helpers/handle_replay_service.py,sha256=EmFNISE-e-NzdlCCS_Nx89B2NHjxUXJtUXDe4Caxc7Y,3886
45
45
  stoobly_agent/app/cli/helpers/handle_test_service.py,sha256=4g94uexoAvMPis-fB027TmkZNp4qpj0AO7DZtcHSm5E,6007
46
46
  stoobly_agent/app/cli/helpers/iterate_group_by.py,sha256=oN9JC58LHLiElQC0M6JdjBAVlqIEwoBmNJuSJyIs-cI,3099
47
- stoobly_agent/app/cli/helpers/openapi_endpoint_adapter.py,sha256=RcF3F_9KWTHexNkrsN0RBW-eWPo6uP7yYGBuBZsIxS0,18261
47
+ stoobly_agent/app/cli/helpers/openapi_endpoint_adapter.py,sha256=7p0hlvXie7DYVMgnSMA28p4KBWxLY1qpXSr8TFvR1Jk,19744
48
48
  stoobly_agent/app/cli/helpers/print_service.py,sha256=SQ5vt5DrGbm7syQNCXy6UzHCelMdGBtzEDZllpQ-1zk,1612
49
49
  stoobly_agent/app/cli/helpers/project_facade.py,sha256=rThwVur2clCCBcHa-U4_vGynj0miKv78B3uF6ZRmBSQ,1905
50
50
  stoobly_agent/app/cli/helpers/replay_facade.py,sha256=e-g1gidt6-1zdFYQOJEtz8BHAv0tYHgMFz52DPVgspk,3441
@@ -150,7 +150,7 @@ stoobly_agent/app/models/types/response.py,sha256=OQNvHnyLvRSJF3E4A1GaROlZekKvfl
150
150
  stoobly_agent/app/models/types/scenario.py,sha256=fcO2rhrFNNDsEd02Mt4TXlVrdAvtkF7I5tIpoR_dkN0,172
151
151
  stoobly_agent/app/proxy/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
152
152
  stoobly_agent/app/proxy/context.py,sha256=XLteUEP8T8aT0hHI_jHDaL2382OaC7QyVwlni5_FS9U,456
153
- stoobly_agent/app/proxy/handle_mock_service.py,sha256=fBOoIbW7zk1X9fyiLzBOknNbCw9WiEn36HN8oMbG4yo,6013
153
+ stoobly_agent/app/proxy/handle_mock_service.py,sha256=4q0brrNcgiClS02Hx6HKbRzO1glvQUUXrEwsslwZQQE,6043
154
154
  stoobly_agent/app/proxy/handle_record_service.py,sha256=n43FJKGvwgS25QexhfRKBtl3OBMbBN3Trb-R4hqQ3Yc,3362
155
155
  stoobly_agent/app/proxy/handle_replay_service.py,sha256=tJlzRZxu50QGd49MKXoXMiX4UT6GudZbonK7sNFWHHQ,1797
156
156
  stoobly_agent/app/proxy/handle_test_service.py,sha256=F4in8KNyLL8nA30dbmYdRJMCkFV9hc3xJPPYgCUKA0E,3806
@@ -166,7 +166,7 @@ stoobly_agent/app/proxy/mitmproxy/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeR
166
166
  stoobly_agent/app/proxy/mitmproxy/flow_mock.py,sha256=YxQV3pXIzicvLOCFn7zmnSoAstAmR8fzONYOXAkYbT4,1153
167
167
  stoobly_agent/app/proxy/mitmproxy/request.py,sha256=niy38718CAe4Li4k40GXnWDDmUTCPkXesDZTaC8BeLc,878
168
168
  stoobly_agent/app/proxy/mitmproxy/request_body_facade.py,sha256=kMJ8YH2FKW9qV68QcUbOCLfiGgKrFV5krzt7usGf0as,649
169
- stoobly_agent/app/proxy/mitmproxy/request_facade.py,sha256=1IzcECCtrmAKE2qIeWw8IAnaEU7t-a2lhGdW6PBAR7w,7598
169
+ stoobly_agent/app/proxy/mitmproxy/request_facade.py,sha256=Hq7l6JNDZll3DWqFzAAlkXvLyqGM7jOK7GjcXUIwgLQ,7603
170
170
  stoobly_agent/app/proxy/mitmproxy/response.py,sha256=BFaJlB1D98EOjrc-kUmunUCTUuiZsPDqq2QgAHDocQI,339
171
171
  stoobly_agent/app/proxy/mitmproxy/response_facade.py,sha256=NsNH0aW-mMfLcUXB-Wt9wH5cDyw_4ezdddtCWPHr5hQ,1209
172
172
  stoobly_agent/app/proxy/mock/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -177,7 +177,7 @@ stoobly_agent/app/proxy/mock/hashed_request_decorator.py,sha256=8SnIplrK7VocpvAF
177
177
  stoobly_agent/app/proxy/mock/request_hasher.py,sha256=91RLNk163digRaMd1Kg88RLzXrXkpvoNKDQxB_NeiNo,3723
178
178
  stoobly_agent/app/proxy/record/__init__.py,sha256=lbW-G6DZ8IrRpRzvgt-1tn2cRuyLT744u9ERIrZ2dFI,233
179
179
  stoobly_agent/app/proxy/record/context.py,sha256=L9tykwoB35hOPHft3IHSPjuJ2v3TSj9SQAJ9E1q-U_4,343
180
- stoobly_agent/app/proxy/record/join_request_service.py,sha256=JhuRAC5eyawz12hb4EJeONBk0_vBXhfbl67IaX3Gy3Q,1277
180
+ stoobly_agent/app/proxy/record/join_request_service.py,sha256=Cz34NWBHBIRhHGtfdgnuhTYLPfWPWx6R_mSqljPGr7k,1307
181
181
  stoobly_agent/app/proxy/record/joined_request.py,sha256=va79Pkz5RWACJn07ipV_FtVmGUzjSlqhfUu_amw9bX8,1553
182
182
  stoobly_agent/app/proxy/record/overwrite_scenario_service.py,sha256=3em2a2ry4MrE30XlAukat-l3L9cu4o13Cxhi6BBUgkc,940
183
183
  stoobly_agent/app/proxy/record/proxy_request.py,sha256=6DqQ2KH7AtfvXg5HNDWwvwgjO7x1QrWDYgJOBMWPKqs,418
@@ -480,9 +480,9 @@ stoobly_agent/test/app/test/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMp
480
480
  stoobly_agent/test/mock_data/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
481
481
  stoobly_agent/test/mock_data/endpoint_show_response.py,sha256=JFEkceHI6nH38zitCbFMozE1lODahxmvj70N5eM_sec,5901
482
482
  stoobly_agent/test/mock_data/request_show_response.py,sha256=K_a0fP0QT58T8sX9PaM6hqtX1A1depZsqg_GsNPf--k,707
483
- stoobly_agent-0.30.0.dist-info/LICENSE,sha256=8WuxPI7sA6w_Yhwqn6v6Ch2Kvu6fo0cwMNIgxSE7oq8,548
484
- stoobly_agent-0.30.0.dist-info/METADATA,sha256=ggSlLoBos8KXIZEHi1RkTbYGGOYrXPvYY3M0hBHrgls,807
485
- stoobly_agent-0.30.0.dist-info/WHEEL,sha256=5sUXSg9e4bi7lTLOHcm6QEYwO5TIF1TNbTSVFVjcJcc,92
486
- stoobly_agent-0.30.0.dist-info/entry_points.txt,sha256=4fpF9D1sN3q8Z6d0MmNAKUy0dz-ZxoH9mqfYMhErRCg,57
487
- stoobly_agent-0.30.0.dist-info/top_level.txt,sha256=fTxn372sBnUMXVSJxpaVAMBWB3HU3_Mq-WXJCM6mMj8,14
488
- stoobly_agent-0.30.0.dist-info/RECORD,,
483
+ stoobly_agent-0.30.1.dist-info/LICENSE,sha256=8WuxPI7sA6w_Yhwqn6v6Ch2Kvu6fo0cwMNIgxSE7oq8,548
484
+ stoobly_agent-0.30.1.dist-info/METADATA,sha256=wnM9LNhjZn2xLx-iKYvYj-8_2IcjaNiUIP4ohAbsmoo,807
485
+ stoobly_agent-0.30.1.dist-info/WHEEL,sha256=5sUXSg9e4bi7lTLOHcm6QEYwO5TIF1TNbTSVFVjcJcc,92
486
+ stoobly_agent-0.30.1.dist-info/entry_points.txt,sha256=4fpF9D1sN3q8Z6d0MmNAKUy0dz-ZxoH9mqfYMhErRCg,57
487
+ stoobly_agent-0.30.1.dist-info/top_level.txt,sha256=fTxn372sBnUMXVSJxpaVAMBWB3HU3_Mq-WXJCM6mMj8,14
488
+ stoobly_agent-0.30.1.dist-info/RECORD,,