pyntcli 0.1.92__py3-none-any.whl → 0.1.93__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.
pyntcli/__init__.py CHANGED
@@ -1 +1 @@
1
- __version__ = "0.1.92"
1
+ __version__ = "0.1.93"
pyntcli/commands/burp.py CHANGED
@@ -147,7 +147,7 @@ def burp_usage():
147
147
  .with_line("\t--insecure - Use when target uses self signed certificates")
148
148
  .with_line("\t--application-id - Attach the scan to an application, you can find the ID in your applications area at app.pynt.io")
149
149
  .with_line("\t--host-ca - Path to the CA file in PEM format to enable SSL certificate verification for pynt when running through a VPN.")
150
- .with_line("\t--return-error - 'all-findings' (warnings, or errors), 'errors-only', 'never' (default)")
150
+ .with_line("\t--severity-level - 'all', 'medium', 'high', 'critical', 'none' (default) ")
151
151
  .with_line("\t--verbose - Use to get more detailed information about the run")
152
152
  )
153
153
 
@@ -171,11 +171,7 @@ class BurpCommand(sub_command.PyntSubCommand):
171
171
  burp_cmd.add_argument("--ca-path", type=str, default="")
172
172
  burp_cmd.add_argument("--report", type=str, default="")
173
173
  burp_cmd.add_argument("--captured-domains", nargs="+", help="", default="")
174
- burp_cmd.add_argument(
175
- "--return-error",
176
- choices=["all-findings", "errors-only", "never"],
177
- default="never",
178
- )
174
+ burp_cmd.add_argument("--severity-level", choices=["all", "medium", "high", "critical", "none"], default="none")
179
175
  burp_cmd.print_usage = self.print_usage
180
176
  burp_cmd.print_help = self.print_usage
181
177
  return burp_cmd
@@ -296,7 +292,10 @@ class BurpCommand(sub_command.PyntSubCommand):
296
292
  base_container=container,
297
293
  use_native=args.use_docker_native)
298
294
 
295
+ proxy_docker.prepare_client()
296
+ proxy_docker.pre_run_validation(args.port)
299
297
  proxy_docker.run()
298
+
300
299
  ui_thread.print_generator(proxy_docker.stdout)
301
300
 
302
301
  util.wait_for_healthcheck("http://localhost:{}".format(args.port))
@@ -355,3 +354,4 @@ class BurpCommand(sub_command.PyntSubCommand):
355
354
  json_obj = json.loads(json_report)
356
355
  if json_obj:
357
356
  util.check_for_findings_or_warnings(args, json_obj)
357
+ util.check_severity(args.severity_level, json_obj)
@@ -42,7 +42,7 @@ def command_usage():
42
42
  .with_line("\t--no-proxy-export - Pynt will not export the proxy settings to the environment")
43
43
  .with_line("\t--application-id - Attach the scan to an application, you can find the ID in your applications area at app.pynt.io")
44
44
  .with_line("\t--host-ca - Path to the CA file in PEM format to enable SSL certificate verification for pynt when running through a VPN.")
45
- .with_line("\t--return-error - 'all-findings' (warnings, or errors), 'errors-only', 'never' (default) ")
45
+ .with_line("\t--severity-level - 'all', 'medium', 'high', 'critical', 'none' (default) ")
46
46
  .with_line("\t--verbose - Use to get more detailed information about the run")
47
47
  )
48
48
 
@@ -70,7 +70,7 @@ class CommandSubCommand(sub_command.PyntSubCommand):
70
70
  proxy_cmd.add_argument("--ca-path", type=str, default="")
71
71
  proxy_cmd.add_argument("--self-signed", action="store_true")
72
72
  proxy_cmd.add_argument("--report", type=str, default="")
73
- proxy_cmd.add_argument("--return-error", choices=["all-findings", "errors-only", "never"], default="never")
73
+ proxy_cmd.add_argument("--severity-level", choices=["all", "medium", "high", "critical", "none"], default="none")
74
74
  proxy_cmd.print_usage = self.print_usage
75
75
  proxy_cmd.print_help = self.print_usage
76
76
  return proxy_cmd
@@ -183,7 +183,10 @@ class CommandSubCommand(sub_command.PyntSubCommand):
183
183
  base_container=container,
184
184
  use_native=args.use_docker_native)
185
185
 
186
+ proxy_docker.prepare_client()
187
+ proxy_docker.pre_run_validation(args.port)
186
188
  proxy_docker.run()
189
+
187
190
  ui_thread.print_generator(proxy_docker.stdout)
188
191
 
189
192
  util.wait_for_healthcheck("http://localhost:{}".format(args.port))
@@ -261,3 +264,4 @@ class CommandSubCommand(sub_command.PyntSubCommand):
261
264
  json_obj = json.loads(json_report)
262
265
  if json_obj:
263
266
  util.check_for_findings_or_warnings(args, json_obj)
267
+ util.check_severity(args.severity_level, json_obj)
pyntcli/commands/har.py CHANGED
@@ -30,6 +30,7 @@ def har_usage():
30
30
  .with_line(
31
31
  "\t--host-ca - Path to the CA file in PEM format to enable SSL certificate verification for pynt when running through a VPN."
32
32
  )
33
+ .with_line("\t--severity-level - 'all', 'medium', 'high', 'critical', 'none' (default) ")
33
34
  .with_line("\t--verbose - Use to get more detailed information about the run")
34
35
  .with_line("")
35
36
  )
@@ -49,6 +50,7 @@ class HarSubCommand(sub_command.PyntSubCommand):
49
50
  "--captured-domains", nargs="+", help="", default="", required=True
50
51
  )
51
52
  har_cmd.add_argument("--reporters", action="store_true")
53
+ har_cmd.add_argument("--severity-level", choices=["all", "medium", "high", "critical", "none"], default="none")
52
54
  har_cmd.print_usage = self.usage
53
55
  har_cmd.print_help = self.usage
54
56
  return har_cmd
@@ -91,6 +93,8 @@ class HarSubCommand(sub_command.PyntSubCommand):
91
93
  base_container=container,
92
94
  use_native=args.use_docker_native)
93
95
 
96
+ har_docker.prepare_client()
97
+ har_docker.pre_run_validation(port)
94
98
  har_docker.run()
95
99
 
96
100
  healthcheck = partial(
@@ -36,7 +36,7 @@ def listen_usage():
36
36
  .with_line("\t--application-id - Attach the scan to an application, you can find the ID in your applications area at app.pynt.io")
37
37
  .with_line("\t--insecure - use when target uses self signed certificates")
38
38
  .with_line("\t--host-ca - path to the CA file in PEM format to enable SSL certificate verification for pynt when running through a VPN.")
39
- .with_line("\t--return-error - 'all-findings' (warnings, or errors), 'errors-only', 'never' (default) ")
39
+ .with_line("\t--severity-level - 'all', 'medium', 'high', 'critical', 'none' (default) ")
40
40
  .with_line("\t--verbose - Use to get more detailed information about the run")
41
41
  )
42
42
 
@@ -61,7 +61,7 @@ class ListenSubCommand(sub_command.PyntSubCommand):
61
61
  listen_cmd.add_argument("--allow-errors", action="store_true")
62
62
  listen_cmd.add_argument("--ca-path", type=str, default="")
63
63
  listen_cmd.add_argument("--report", type=str, default="")
64
- listen_cmd.add_argument("--return-error", choices=["all-findings", "errors-only", "never"], default="never")
64
+ listen_cmd.add_argument("--severity-level", choices=["all", "medium", "high", "critical", "none"], default="none")
65
65
  listen_cmd.print_usage = self.print_usage
66
66
  listen_cmd.print_help = self.print_usage
67
67
  return listen_cmd
@@ -140,7 +140,11 @@ class ListenSubCommand(sub_command.PyntSubCommand):
140
140
  tag="proxy-latest",
141
141
  detach=True,
142
142
  base_container=container)
143
+
144
+ proxy_docker.prepare_client()
145
+ proxy_docker.pre_run_validation(args.port)
143
146
  proxy_docker.run()
147
+
144
148
  ui_thread.print_generator(proxy_docker.stdout)
145
149
 
146
150
  util.wait_for_healthcheck("http://localhost:{}".format(args.port))
@@ -208,3 +212,4 @@ class ListenSubCommand(sub_command.PyntSubCommand):
208
212
  json_obj = json.loads(json_report)
209
213
  if json_obj:
210
214
  util.check_for_findings_or_warnings(args, json_obj)
215
+ util.check_severity(args.severity_level, json_obj)
@@ -30,9 +30,7 @@ def newman_usage():
30
30
  .with_line(
31
31
  "\t--application-id - Attach the scan to an application, you can find the ID in your applications area at app.pynt.io"
32
32
  )
33
- .with_line(
34
- "\t--return-error - 'all-findings' (warnings, or errors), 'errors-only', 'never' (default) "
35
- )
33
+ .with_line("\t--severity-level - 'all', 'medium', 'high', 'critical', 'none' (default) ")
36
34
  .with_line("\t--verbose - Use to get more detailed information about the run")
37
35
  )
38
36
 
@@ -51,12 +49,7 @@ class NewmanSubCommand(sub_command.PyntSubCommand):
51
49
  newman_cmd.add_argument(
52
50
  "--reporters", action="store_true", default=False, required=False
53
51
  )
54
- newman_cmd.add_argument(
55
- "--return-error",
56
- choices=["all-findings", "errors-only", "never"],
57
- default="never"
58
- )
59
-
52
+ newman_cmd.add_argument("--severity-level", choices=["all", "medium", "high", "critical", "none"], default="none")
60
53
  newman_cmd.print_usage = self.usage
61
54
  newman_cmd.print_help = self.usage
62
55
  return newman_cmd
@@ -113,7 +106,11 @@ class NewmanSubCommand(sub_command.PyntSubCommand):
113
106
  detach=True,
114
107
  base_container=container,
115
108
  use_native=args.use_docker_native)
109
+
110
+ newman_docker.prepare_client()
111
+ newman_docker.pre_run_validation(port)
116
112
  newman_docker.run()
113
+
117
114
  healthcheck = partial(
118
115
  util.wait_for_healthcheck, "http://localhost:{}".format(port)
119
116
  )
@@ -102,8 +102,10 @@ class PostmanSubCommand(sub_command.PyntSubCommand):
102
102
  detach=True,
103
103
  base_container=container,
104
104
  use_native=args.use_docker_native)
105
-
105
+ postman_docker.prepare_client()
106
+ postman_docker.pre_run_validation(args.port)
106
107
  postman_docker.run()
108
+
107
109
  ui_thread.print_generator(postman_docker.stdout)
108
110
 
109
111
  util.wait_for_healthcheck("http://localhost:{}".format(args.port))
pyntcli/commands/util.py CHANGED
@@ -68,6 +68,10 @@ class SomeFindingsOrWarningsException(Exception):
68
68
  pass
69
69
 
70
70
 
71
+ class SeverityException(Exception):
72
+ pass
73
+
74
+
71
75
  @contextmanager
72
76
  def create_default_file_mounts(args):
73
77
  html_report_path = os.path.join(tempfile.gettempdir(), "results.html")
@@ -93,8 +97,10 @@ def create_default_file_mounts(args):
93
97
  report.PyntReporter(json_report_path).print_summary()
94
98
 
95
99
  check_for_findings_or_warnings(args, json.load(open(json_report_path)))
100
+ check_severity(args.severity_level, json.load(open(json_report_path)))
96
101
 
97
102
 
103
+ # Deprecate - keep it for backward customers that use it
98
104
  def check_for_findings_or_warnings(args, json_report):
99
105
  security_tests = json_report.get("securityTests", {})
100
106
  findings = security_tests.get("Findings", 0)
@@ -105,3 +111,30 @@ def check_for_findings_or_warnings(args, json_report):
105
111
 
106
112
  if "return_error" in args and args.return_error == "all-findings" and warnings != 0:
107
113
  raise SomeFindingsOrWarningsException()
114
+
115
+
116
+ def check_severity(severity_flag, json_report):
117
+ severity_levels = ['medium', 'high', 'critical']
118
+
119
+ if severity_flag is None or severity_flag.lower() == "none":
120
+ return
121
+
122
+ risk_data = json_report.get("securityTests", {})
123
+
124
+ # Normalize all te keys to lower to reduce the risk that user input is diff then what we have internally
125
+ risks_counter = {key.lower(): value for key, value in risk_data['RisksCounter'].items()}
126
+
127
+ severity_filter = severity_flag.lower()
128
+
129
+ if severity_filter == "all":
130
+ severities_to_check = severity_levels
131
+ else:
132
+ if severity_filter not in severity_levels:
133
+ raise ValueError(f"Invalid user filter for severity level: {severity_filter}")
134
+
135
+ flag_index = severity_levels.index(severity_filter)
136
+ severities_to_check = severity_levels[flag_index:]
137
+
138
+ for severity in severities_to_check:
139
+ if risks_counter.get(severity, 0) > 0:
140
+ raise SeverityException(f"Severity '{severity}' has a count greater than 0.")
pyntcli/main.py CHANGED
@@ -12,7 +12,7 @@ from requests.exceptions import SSLError
12
12
  from requests.exceptions import ProxyError
13
13
  from pyntcli.transport.pynt_requests import InvalidPathException, InvalidCertFormat
14
14
  from pyntcli.commands.util import HtmlReportNotCreatedException
15
- from pyntcli.commands.util import SomeFindingsOrWarningsException
15
+ from pyntcli.commands.util import SomeFindingsOrWarningsException, SeverityException
16
16
  from pyntcli.commands.postman import PyntWebSocketException
17
17
  from pyntcli import __version__
18
18
 
@@ -131,6 +131,8 @@ def main():
131
131
  analytics.emit(analytics.ERROR, {"error": "port in use. e: {}".format(e)})
132
132
  except SomeFindingsOrWarningsException as e:
133
133
  exit(1)
134
+ except SeverityException as e:
135
+ exit(1)
134
136
  except Exception as e:
135
137
  analytics.emit(analytics.ERROR, {"error": "{}".format(e)})
136
138
  pynt_errors.unexpected_error(e)
@@ -2,6 +2,7 @@ import platform
2
2
  import subprocess
3
3
  import docker
4
4
  from docker.errors import DockerException, APIError, ImageNotFound
5
+ from requests.exceptions import ReadTimeout
5
6
  from docker.types import Mount
6
7
  import os
7
8
  import json
@@ -17,6 +18,9 @@ from pyntcli.store import CredStore
17
18
  from pyntcli.auth.login import PYNT_ID, PYNT_SAAS, PYNT_BUCKET_NAME, PYNT_PARAM1, PYNT_PARAM2
18
19
 
19
20
  PYNT_DOCKER_IMAGE = "ghcr.io/pynt-io/pynt"
21
+ IMAGE_TAGS = ["postman-latest", "newman-latest", "har-latest", "proxy-latest"]
22
+
23
+ PYNT_CONTAINER_INTERNAL_PORT = "5001"
20
24
 
21
25
 
22
26
  def create_mount(src, destination, mount_type="bind"):
@@ -37,7 +41,8 @@ class ImageUnavailableException(Exception):
37
41
 
38
42
  class PortInUseException(Exception):
39
43
  def __init__(self, port=""):
40
- self.message = ui_thread.print(ui_thread.PrinterText("Port: {} already in use, please use a different one".format(port), ui_thread.PrinterText.WARNING))
44
+ self.message = ui_thread.print(
45
+ ui_thread.PrinterText(f"Port: {port} already in use, please use a different one", ui_thread.PrinterText.WARNING))
41
46
  super().__init__(self.message)
42
47
 
43
48
 
@@ -87,8 +92,6 @@ def get_container_with_arguments(args: argparse.Namespace, *port_args: PyntDocke
87
92
  docker_arguments = []
88
93
  ports = {}
89
94
  for p in port_args:
90
- if container_utils.is_port_in_use(p.dest):
91
- raise PortInUseException(p.dest)
92
95
  if "desktop" in get_docker_type().lower():
93
96
  ports[str(p.src)] = int(p.dest)
94
97
  else:
@@ -189,9 +192,11 @@ class PyntContainerNative:
189
192
 
190
193
  return len(result.stdout.splitlines()) > 1
191
194
 
195
+ def prepare_client(self):
196
+ pass
197
+
192
198
  def run(self):
193
199
  self.running = True
194
- self.kill_other_instances()
195
200
 
196
201
  self.get_image()
197
202
  args = self.base_container.docker_arguments if self.base_container.docker_arguments else None
@@ -247,18 +252,22 @@ class PyntContainerNative:
247
252
 
248
253
  self.stdout = logs_stdout
249
254
 
250
- def kill_other_instances(self):
255
+ def kill_other_instances(self, report_to_user=True):
256
+ ui_thread.print_verbose("Killing other pynt containers if such exist")
251
257
  try:
252
- ui_thread.print_verbose("Killing other pynt containers if such exist")
253
- command = ["docker", "ps", "-q", "-f", f"ancestor={self.image_name}:{self.tag}"]
254
- containers_output = subprocess.check_output(command, text=True)
255
- if not containers_output:
256
- return
257
-
258
- container_ids = containers_output.splitlines()
259
- for container_id in container_ids:
260
- command = ["docker", "kill", container_id]
261
- subprocess.run(command)
258
+ for tag in IMAGE_TAGS:
259
+ command = ["docker", "ps", "-q", "-f", f"ancestor={self.image_name}:{tag}"]
260
+ containers_output = subprocess.check_output(command, text=True)
261
+ if not containers_output:
262
+ continue
263
+
264
+ container_ids = containers_output.splitlines()
265
+ for container_id in container_ids:
266
+ command = ["docker", "kill", container_id]
267
+ subprocess.run(command)
268
+ if report_to_user:
269
+ ui_thread.print(
270
+ ui_thread.PrinterText("Another Pynt container was running, killed it", ui_thread.PrinterText))
262
271
 
263
272
  except subprocess.CalledProcessError:
264
273
  analytics.emit(analytics.ERROR, {"error": "Unable to kill other pynt containers"})
@@ -305,7 +314,7 @@ class PyntContainerNative:
305
314
  def stop(self):
306
315
  if not self.running:
307
316
  return
308
- self.kill_other_instances()
317
+ self.kill_other_instances(report_to_user=False)
309
318
  self.running = False
310
319
 
311
320
  def adapt_run_command(self, docker_command=[]):
@@ -333,6 +342,7 @@ class PyntContainerSDK:
333
342
  self.container_name = ""
334
343
  self.stdout = None
335
344
  self.running = False
345
+ self.system = platform.system().lower()
336
346
 
337
347
  def _initialize(self):
338
348
  self.docker_client = docker.from_env()
@@ -352,15 +362,16 @@ class PyntContainerSDK:
352
362
 
353
363
  return l[0].status == "running"
354
364
 
365
+ def prepare_client(self):
366
+ if not self.docker_client:
367
+ self._initialize()
368
+
355
369
  def run(self):
356
370
  if not self.docker_client:
357
371
  self._initialize()
358
372
 
359
373
  self.running = True
360
374
 
361
- ui_thread.print_verbose("Killing other pynt containers if such exist")
362
- self.kill_other_instances()
363
-
364
375
  image = self.get_image()
365
376
  ui_thread.print(ui_thread.PrinterText("Docker pull done", ui_thread.PrinterText.INFO))
366
377
 
@@ -383,10 +394,25 @@ class PyntContainerSDK:
383
394
  self.container_name = c.name
384
395
  self.stdout = c.logs(stream=True)
385
396
 
386
- def kill_other_instances(self):
397
+ def kill_other_instances(self, report_to_user=True):
387
398
  for c in self.docker_client.containers.list():
388
399
  if len(c.image.tags) and _container_image_from_tag(c.image.tags[0]) == self.image_name:
389
400
  c.kill()
401
+ self.wait_for_container_end(c)
402
+ if report_to_user:
403
+ ui_thread.print(ui_thread.PrinterText("Another Pynt container was running, killed it", ui_thread.PrinterText))
404
+
405
+ def wait_for_container_end(self, container):
406
+ # only windows kill is require a wait for the container to stop, otherwise the port stays in use
407
+ if self.system != "windows":
408
+ return
409
+ try:
410
+ container.wait(timeout=10)
411
+ except ReadTimeout: # container is still running
412
+ ui_thread.print(
413
+ ui_thread.PrinterText("Timeout reached while waiting for container to stop", ui_thread.PrinterText))
414
+ except APIError: # container is already stopped
415
+ pass
390
416
 
391
417
  def pull_image(self):
392
418
  try:
@@ -410,7 +436,7 @@ class PyntContainerSDK:
410
436
  def stop(self):
411
437
  if not self.running:
412
438
  return
413
- self.kill_other_instances()
439
+ self.kill_other_instances(report_to_user=False)
414
440
  self.docker_client.close()
415
441
  self.docker_client = None
416
442
  self.running = False
@@ -452,6 +478,15 @@ class PyntContainer:
452
478
  self.stdout = self.client_implementation.stdout
453
479
  PyntContainerRegistry.instance().register_container(self)
454
480
 
481
+ def pre_run_validation(self, port):
482
+ self.kill_other_instances()
483
+
484
+ if container_utils.is_port_in_use(int(port)):
485
+ raise PortInUseException(port)
486
+
487
+ def prepare_client(self):
488
+ self.client_implementation.prepare_client()
489
+
455
490
  def running(self):
456
491
  return self.client_implementation.running
457
492
 
@@ -1,16 +1,16 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: pyntcli
3
- Version: 0.1.92
3
+ Version: 0.1.93
4
4
  Summary: Command line utility to handle all of Pynt's different integrations
5
5
  Author-email: Pynt-io <support@pynt.io>
6
6
  Project-URL: Homepage, https://pynt.io
7
7
  Requires-Python: >=3.7
8
8
  Requires-Dist: docker
9
9
  Requires-Dist: rich
10
- Requires-Dist: requests ==2.31.0
10
+ Requires-Dist: requests==2.31.0
11
11
  Requires-Dist: pem
12
- Requires-Dist: certifi >=2017.4.17
13
- Requires-Dist: logzio-python-handler >=4.1.0
12
+ Requires-Dist: certifi>=2017.4.17
13
+ Requires-Dist: logzio-python-handler>=4.1.0
14
14
  Requires-Dist: websocket-client
15
15
  Requires-Dist: xmltodict
16
16
 
@@ -1,27 +1,30 @@
1
- pyntcli/__init__.py,sha256=jibR5k16CvIIIRqIusW7mrU6CMM0wet7LwtTuFLXbmU,23
2
- pyntcli/main.py,sha256=ucC9d4wlhUpvA92OXRIZ55iMdFXEDiAOVvP_wtRu7zs,6432
1
+ ignoreTests/conftest.py,sha256=gToq5K74GtgeGQXjFvXSzMaE6axBYxAzcFG5XJPOXjI,427
2
+ ignoreTests/auth/login.py,sha256=KFlzWhXBAuwdi7GXf16gCB3ya94LQG2wjcSChE149rQ,3798
3
+ ignoreTests/store/cred_store.py,sha256=_7-917EtNC9eKEumO2_lt-7KuDmCwOZFaowCm7DbA_A,254
4
+ pyntcli/__init__.py,sha256=9ZJPYemtF-vnUzZtNNDjmi0UnkkMXYvPkfRASPJ5iWc,23
5
+ pyntcli/main.py,sha256=HORWY5AEK5xmEQybUZBW9ZEDIga8vSnqDfmAR3TY9F0,6502
3
6
  pyntcli/analytics/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
7
  pyntcli/analytics/send.py,sha256=9TRAEoPbv4rWOZfcNaGanrRJAFvNs39P-uKSl49GcQE,3679
5
8
  pyntcli/auth/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
6
9
  pyntcli/auth/login.py,sha256=TljsRXbEkNI1YUrKm5mlTw4YiecYScYUsit8Z8vstss,5228
7
10
  pyntcli/commands/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
8
- pyntcli/commands/burp.py,sha256=NfvMPlw8yISaDzvSuF96MXGVTPKRS7yR84TNDqFiblU,12274
9
- pyntcli/commands/command.py,sha256=mYeNer6WeswYLPSZhvNC04S5FOdMqH-Jk8a4iPRJtpc,10973
10
- pyntcli/commands/har.py,sha256=IZGd900hz0fFM3iZTG3NNXB2NiuAJGeuv-I49eXrf-o,4158
11
+ pyntcli/commands/burp.py,sha256=TYUspSLhubtKEL4ShUOvT7Fnq3MFsFo-HyrPXiZboZ4,12380
12
+ pyntcli/commands/command.py,sha256=cMVrlxMZgx0jFrlpMTKPEYfsSv2RhN6XuPrRqqqYB6k,11125
13
+ pyntcli/commands/har.py,sha256=yUuLvxlAoq2dQotJe8PV02sZD-WgYSefzGc6bhdroSo,4464
11
14
  pyntcli/commands/id_command.py,sha256=UBEgMIpm4vauTCsKyixltiGUolNg_OfHEJvJ_i5BpJY,943
12
- pyntcli/commands/listen.py,sha256=0wY9itDQyxSeHQA4GCGF67Xkb4ym48uP17WCPJMcLBE,8910
13
- pyntcli/commands/newman.py,sha256=ocg85L7HopXRYkhLc75QUtHH9ey48Z6Yxy1stgVW1aE,5283
14
- pyntcli/commands/postman.py,sha256=T1qdFHXX_kTW9p8PPbY9P7ynK4UcGoG3FfEMrRetwco,5163
15
+ pyntcli/commands/listen.py,sha256=b_ES6VRmPFkIkCCQ6MuP6KOeUlf5vT1e7AafnDqJVak,9063
16
+ pyntcli/commands/newman.py,sha256=o3kobgUFoC3jw2XmbYEsQNdYpGO5suFA92lxHw71dzw,5301
17
+ pyntcli/commands/postman.py,sha256=VNARuyCDaDYlrzRMmJk4oM4YTCExOQUDziOS8NpU-KA,5256
15
18
  pyntcli/commands/pynt_cmd.py,sha256=X39hiDq6blGh2sGpwVeUXOgnDlhHruGkOoR5aUBzw_k,2982
16
19
  pyntcli/commands/root.py,sha256=-2aAiOKc_yXAlymxGove6su1mcvYsk4kCNaEawDKwy8,3677
17
20
  pyntcli/commands/static_file_extensions.py,sha256=PZJb02BI-64tbU-j3rdCNsXzTh7gkIDGxGKbKNw3h5k,1995
18
21
  pyntcli/commands/sub_command.py,sha256=GF3-rE_qk2L4jGPFqHLm9SdGINmu3EakhjJTFyWjRms,374
19
- pyntcli/commands/util.py,sha256=4p4rzNqL8nUJJfj1uy_JOHsFBEvVT6-k-V9GbAqHVyM,3218
22
+ pyntcli/commands/util.py,sha256=csZHQ2Xbdh-_KX-yIVrnaeNsT0NbuS-ej6kND3CxD_w,4414
20
23
  pyntcli/log/__init__.py,sha256=cOGwOYzMoshEbZiiasBGkj6wF0SBu3Jdpl-AuakDesw,19
21
24
  pyntcli/log/log.py,sha256=cWCdWmUaAwePwdhYDcgNMEG9d9RM34sGahxBCYEdv2Y,1069
22
25
  pyntcli/pynt_docker/__init__.py,sha256=PQIOVxc7XXtMLfEX7ojgwf_Z3mmTllO3ZvzUZTPOxQY,30
23
26
  pyntcli/pynt_docker/container_utils.py,sha256=_Onn7loInzyJAG2-Uk6CGpsuRyelmUFHOvtJj4Uzi9A,175
24
- pyntcli/pynt_docker/pynt_container.py,sha256=sqWKi3HUIn3AR9HgDYQtofCkaEQiOT3hG1nYQHf8RD8,17500
27
+ pyntcli/pynt_docker/pynt_container.py,sha256=R2iq4Gbbkxg3OEJfJwUp-vroHf9-pJ6HWFqvWucPsGA,18965
25
28
  pyntcli/store/__init__.py,sha256=xuS9OB21F6B1sUx5XPGxz_6WpG6-KTMbuq50RrZS5OY,29
26
29
  pyntcli/store/json_connector.py,sha256=UGs3uORw3iyn0YJ8kzab-veEZToA6d-ByXYuqEleWsA,560
27
30
  pyntcli/store/store.py,sha256=4YqmcHRltbbSWewKQoOZH8QdyMFs6i3L8o2bXY_YvSw,1909
@@ -33,11 +36,9 @@ pyntcli/ui/progress.py,sha256=RrnO_jJNunoyupylakmWmHOEPw3lh99OHpKBzL6OBiE,1008
33
36
  pyntcli/ui/pynt_errors.py,sha256=00UprD4tFViREv7kuXGQ99PAKGTpXYixxi3Ndeoeiew,689
34
37
  pyntcli/ui/report.py,sha256=W-icPSZrGLOubXgam0LpOvHLl_aZg9Zx9qIkL8Ym5PE,1930
35
38
  pyntcli/ui/ui_thread.py,sha256=XUBgLpYQjVhrilU-ofw7VSXgTiwneSdTxm61EvC3x4Q,5091
36
- tests/conftest.py,sha256=gToq5K74GtgeGQXjFvXSzMaE6axBYxAzcFG5XJPOXjI,427
37
- tests/auth/test_login.py,sha256=KFlzWhXBAuwdi7GXf16gCB3ya94LQG2wjcSChE149rQ,3798
38
- tests/store/test_cred_store.py,sha256=_7-917EtNC9eKEumO2_lt-7KuDmCwOZFaowCm7DbA_A,254
39
- pyntcli-0.1.92.dist-info/METADATA,sha256=MS97IJ6CIx7fidgjFBCYP8gKop_deMK3JGRBfXCsj5Y,463
40
- pyntcli-0.1.92.dist-info/WHEEL,sha256=Wyh-_nZ0DJYolHNn1_hMa4lM7uDedD_RGVwbmTjyItk,91
41
- pyntcli-0.1.92.dist-info/entry_points.txt,sha256=kcGmqAxXDttNk2EPRcqunc_LTVp61gzakz0v-GEE2SY,43
42
- pyntcli-0.1.92.dist-info/top_level.txt,sha256=u9MDStwVHB7UG8PUcODeWCul_NvzL2EzoLvSlgwLHFs,30
43
- pyntcli-0.1.92.dist-info/RECORD,,
39
+ tests/test_utils.py,sha256=t5fTQUk1U_Js6iMxcGYGqt4C-crzOJ0CqCKtLkRtUi0,2050
40
+ pyntcli-0.1.93.dist-info/METADATA,sha256=VRflEz4VuO9RUwlmI0nWXOqHaTWdkwCvdcPq7cixewY,460
41
+ pyntcli-0.1.93.dist-info/WHEEL,sha256=Mdi9PDNwEZptOjTlUcAth7XJDFtKrHYaQMPulZeBCiQ,91
42
+ pyntcli-0.1.93.dist-info/entry_points.txt,sha256=kcGmqAxXDttNk2EPRcqunc_LTVp61gzakz0v-GEE2SY,43
43
+ pyntcli-0.1.93.dist-info/top_level.txt,sha256=64XSgBzSpgwjYjEKHZE7q3JH2a816zEeyZBXfJi3AKI,42
44
+ pyntcli-0.1.93.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (71.1.0)
2
+ Generator: setuptools (73.0.1)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -1,4 +1,5 @@
1
1
  automation
2
2
  dist
3
+ ignoreTests
3
4
  pyntcli
4
5
  tests
tests/test_utils.py ADDED
@@ -0,0 +1,75 @@
1
+ import pytest
2
+ from pyntcli.commands.util import check_severity, SeverityException
3
+
4
+
5
+ @pytest.fixture
6
+ def risk_data():
7
+ return {
8
+ "securityTests": {
9
+ 'DidNotRun': 0,
10
+ 'Duration': 0,
11
+ 'Findings': 5,
12
+ 'Passed': 27,
13
+ 'RisksCounter': {'Critical': 2, 'High': 0, 'Low': 3, 'Medium': 3},
14
+ 'Warnings': 1
15
+ }
16
+ }
17
+
18
+
19
+ def test_exception_on_medium_severity(risk_data):
20
+ with pytest.raises(SeverityException):
21
+ check_severity('MEDIUM', risk_data)
22
+
23
+
24
+ def test_exception_on_high_severity(risk_data):
25
+ with pytest.raises(SeverityException):
26
+ check_severity('HIGH', risk_data)
27
+
28
+
29
+ def test_exception_on_critical_severity(risk_data):
30
+ with pytest.raises(SeverityException):
31
+ check_severity('CRITICAL', risk_data)
32
+
33
+
34
+ def test_no_exception_on_higher_than_all_severity():
35
+ data_with_low_risk_only = {
36
+ "securityTests": {
37
+ 'DidNotRun': 0,
38
+ 'Duration': 0,
39
+ 'Findings': 5,
40
+ 'Passed': 27,
41
+ 'RisksCounter': {'Critical': 0, 'High': 0, 'Low': 3, 'Medium': 0},
42
+ 'Warnings': 1
43
+ }
44
+ }
45
+ try:
46
+ check_severity('HIGH', data_with_low_risk_only)
47
+ except SeverityException:
48
+ pytest.fail("SeverityException was raised unexpectedly!")
49
+
50
+
51
+ def test_invalid_severity_flag(risk_data):
52
+ with pytest.raises(ValueError):
53
+ check_severity('invalid', risk_data)
54
+
55
+
56
+ def test_exception_on_all_flag(risk_data):
57
+ with pytest.raises(SeverityException):
58
+ check_severity('ALL', risk_data)
59
+
60
+
61
+ def test_no_exception_on_all_flag_when_empty():
62
+ data_with_no_risks = {
63
+ "securityTests": {
64
+ 'DidNotRun': 0,
65
+ 'Duration': 0,
66
+ 'Findings': 5,
67
+ 'Passed': 27,
68
+ 'RisksCounter': {'Critical': 0, 'High': 0, 'Low': 0, 'Medium': 0},
69
+ 'Warnings': 1
70
+ }
71
+ }
72
+ try:
73
+ check_severity('ALL', data_with_no_risks)
74
+ except SeverityException:
75
+ pytest.fail("SeverityException was raised unexpectedly!")
File without changes
File without changes