pyntcli 0.1.74__py3-none-any.whl → 0.1.75__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.74"
1
+ __version__ = "0.1.75"
pyntcli/commands/har.py CHANGED
@@ -51,9 +51,9 @@ class HarSubCommand(sub_command.PyntSubCommand):
51
51
  return har_cmd
52
52
 
53
53
  def run_cmd(self, args: argparse.Namespace):
54
- port = str(util.find_open_port())
54
+ port = util.find_open_port()
55
55
  container = pynt_container.get_container_with_arguments(
56
- args, pynt_container.PyntDockerPort(src=port, dest=port, name="--port")
56
+ args, pynt_container.PyntDockerPort(src=str(port), dest=port, name="--port")
57
57
  )
58
58
 
59
59
  if not os.path.isfile(args.har):
@@ -59,9 +59,9 @@ class NewmanSubCommand(sub_command.PyntSubCommand):
59
59
  return newman_cmd
60
60
 
61
61
  def run_cmd(self, args: argparse.Namespace):
62
- port = str(util.find_open_port())
62
+ port = util.find_open_port()
63
63
  container = pynt_container.get_container_with_arguments(
64
- args, pynt_container.PyntDockerPort(src=port, dest=port, name="--port")
64
+ args, pynt_container.PyntDockerPort(src=str(port), dest=port, name="--port")
65
65
  )
66
66
 
67
67
  if not os.path.isfile(args.collection):
@@ -94,9 +94,6 @@ class PostmanSubCommand(sub_command.PyntSubCommand):
94
94
 
95
95
  container = pynt_container.get_container_with_arguments(args, pynt_container.PyntDockerPort("5001", args.port, name="--port"))
96
96
 
97
- if util.is_port_in_use(args.port):
98
- ui_thread.print(ui_thread.PrinterText("Port: {} already in use, please use a different one".format(args.port), ui_thread.PrinterText.WARNING))
99
- return
100
97
 
101
98
  postman_docker = pynt_container.PyntContainer(image_name=pynt_container.PYNT_DOCKER_IMAGE,
102
99
  tag="postman-latest",
pyntcli/commands/util.py CHANGED
@@ -15,79 +15,81 @@ from pyntcli.transport import pynt_requests
15
15
 
16
16
  logger = log.get_logger()
17
17
 
18
- def is_port_in_use(port: int) -> bool:
19
- with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
20
- return s.connect_ex(('localhost', port)) == 0
21
18
 
22
19
  def find_open_port() -> int:
23
20
  with socket.socket() as s:
24
- s.bind(('', 0))
25
- return s.getsockname()[1]
21
+ s.bind(('', 0))
22
+ return s.getsockname()[1]
23
+
26
24
 
27
25
  HEALTHCHECK_TIMEOUT = 60
28
26
  HEALTHCHECK_INTERVAL = 0.1
29
27
 
30
- def wait_for_healthcheck(address):
28
+
29
+ def wait_for_healthcheck(address):
31
30
  start = time.time()
32
- while start + HEALTHCHECK_TIMEOUT > time.time():
31
+ while start + HEALTHCHECK_TIMEOUT > time.time():
33
32
  try:
34
33
  res = pynt_requests.get(address + "/healthcheck")
35
34
  if res.status_code == 418:
36
- return
37
- except:
35
+ return
36
+ except:
38
37
  time.sleep(HEALTHCHECK_INTERVAL)
39
38
 
40
39
  logger.debug("Health check timed out!")
41
40
  raise TimeoutError()
42
41
 
43
- def get_user_report_path(path,file_type):
42
+
43
+ def get_user_report_path(path, file_type):
44
44
  path = Path(path)
45
45
  if path.is_dir():
46
- return os.path.join(path, "pynt_results_{}.{}".format(int(time.time()),file_type))
47
-
46
+ return os.path.join(path, "pynt_results_{}.{}".format(int(time.time()), file_type))
47
+
48
48
  return os.path.join(str(path.parent), path.stem + ".{}".format(file_type))
49
-
49
+
50
50
 
51
51
  class HtmlReportNotCreatedException(Exception):
52
52
  pass
53
53
 
54
- class SomeFoundingsOrWargningsException(Exception):
54
+
55
+ class SomeFindingsOrWarningsException(Exception):
55
56
  pass
56
57
 
58
+
57
59
  @contextmanager
58
60
  def create_default_file_mounts(args):
59
61
  html_report_path = os.path.join(tempfile.gettempdir(), "results.html")
60
62
  json_report_path = os.path.join(tempfile.gettempdir(), "results.json")
61
63
 
62
- if "reporters" in args and args.reporters:
64
+ if "reporters" in args and args.reporters:
63
65
  html_report_path = os.path.join(os.getcwd(), "pynt_results.html")
64
66
  json_report_path = os.path.join(os.getcwd(), "pynt_results.json")
65
67
 
66
68
  mounts = []
67
- with open(html_report_path, "w"), open(json_report_path, "w"):
69
+ with open(html_report_path, "w"), open(json_report_path, "w"):
68
70
  mounts.append(pynt_container.create_mount(json_report_path, "/etc/pynt/results/results.json"))
69
71
  mounts.append(pynt_container.create_mount(html_report_path, "/etc/pynt/results/results.html"))
70
-
72
+
71
73
  yield mounts
72
-
74
+
73
75
  if os.stat(html_report_path).st_size == 0:
74
76
  raise HtmlReportNotCreatedException()
75
-
77
+
76
78
  webbrowser.open("file://{}".format(html_report_path))
77
79
 
78
80
  if os.stat(html_report_path).st_size > 0:
79
81
  report.PyntReporter(json_report_path).print_summary()
80
-
82
+
81
83
  check_for_findings_or_warnings(args, json.load(open(json_report_path)))
82
84
 
85
+
83
86
  def check_for_findings_or_warnings(args, json_report):
84
- security_tests = json_report.get("securityTests",{})
87
+ security_tests = json_report.get("securityTests", {})
85
88
  findings = security_tests.get("Findings", 0)
86
89
  warnings = security_tests.get("Warnings", 0)
87
90
 
88
91
  if "return_error" in args and args.return_error != "never" and findings != 0:
89
- raise SomeFoundingsOrWargningsException()
92
+ raise SomeFindingsOrWarningsException()
90
93
 
91
94
  if "return_error" in args and args.return_error == "all-findings" and warnings != 0:
92
- raise SomeFoundingsOrWargningsException()
93
-
95
+ raise SomeFindingsOrWarningsException()
pyntcli/main.py CHANGED
@@ -10,9 +10,10 @@ from pyntcli.ui import ui_thread
10
10
  from pyntcli.auth import login
11
11
  from pyntcli.analytics import send as analytics
12
12
  from requests.exceptions import SSLError
13
+ from requests.exceptions import ProxyError
13
14
  from pyntcli.transport.pynt_requests import InvalidPathException, InvalidCertFormat
14
15
  from pyntcli.commands.util import HtmlReportNotCreatedException
15
- from pyntcli.commands.util import SomeFoundingsOrWargningsException
16
+ from pyntcli.commands.util import SomeFindingsOrWarningsException
16
17
  from pyntcli.commands.postman import PyntWebSocketException
17
18
  from pyntcli import __version__
18
19
 
@@ -58,35 +59,41 @@ def main():
58
59
  cli = pynt_cmd.PyntCommand()
59
60
  cli.run_cmd(cli.parse_args(argv[1:]))
60
61
  analytics.stop()
61
- except pynt_cmd.PyntCommandException:
62
+ except pynt_cmd.PyntCommandException as e:
62
63
  pynt_cmd.root.usage()
63
- except pynt_container.DockerNotAvailableException:
64
+ except pynt_container.DockerNotAvailableException as e:
64
65
  ui_thread.print(ui_thread.PrinterText("Docker was unavailable, please make sure docker is installed and running.", ui_thread.PrinterText.WARNING))
65
- analytics.emit(analytics.ERROR, {"error": "docker unavailable"})
66
- except SSLError:
66
+ analytics.emit(analytics.ERROR, {"error": "docker unavailable. e: {}".format(e)})
67
+ except SSLError as e:
67
68
  ui_thread.print(ui_thread.PrinterText("We encountered SSL issues and could not proceed, this may be the cause of a VPN or a Firewall in place. Run again with --insecure", ui_thread.PrinterText.WARNING))
68
- except login.Timeout:
69
+ analytics.emit(analytics.ERROR, {"error": "ssl error. e: {}".format(e)})
70
+ except login.Timeout as e:
69
71
  ui_thread.print(ui_thread.PrinterText("Pynt CLI exited due to incomplete registration, please try again.", ui_thread.PrinterText.WARNING))
70
- analytics.emit(analytics.ERROR, {"error": "login timeout"})
71
- except login.InvalidTokenInEnvVarsException:
72
+ analytics.emit(analytics.ERROR, {"error": "login timeout. e: {}".format(e)})
73
+ except login.InvalidTokenInEnvVarsException as e:
72
74
  ui_thread.print(ui_thread.PrinterText("Pynt CLI exited due to malformed credentials provided in env vars.", ui_thread.PrinterText.WARNING))
73
- analytics.emit(analytics.ERROR, {"error": "invalid pynt cli credentials in env vars"})
74
- except pynt_container.ImageUnavailableException:
75
- analytics.emit(analytics.ERROR, {"error": "Couldn't pull pynt image and no local image found"})
76
- ui_thread.print(ui_thread.PrinterText("Error: Couldn't pull pynt image and no local image found.",ui_thread.PrinterText.WARNING))
77
- except HtmlReportNotCreatedException:
78
- analytics.emit(analytics.ERROR, {"error": "Html report was not created"})
79
- pynt_errors.unexpected_error()
75
+ analytics.emit(analytics.ERROR, {"error": "invalid pynt cli credentials in env vars. e: {}".format(e)})
76
+ except pynt_container.ImageUnavailableException as e:
77
+ analytics.emit(analytics.ERROR, {"error": "Couldn't pull pynt image and no local image found. e: {}".format(e)})
78
+ ui_thread.print(ui_thread.PrinterText("Error: Couldn't pull pynt image and no local image found.", ui_thread.PrinterText.WARNING))
79
+ except HtmlReportNotCreatedException as e:
80
+ analytics.emit(analytics.ERROR, {"error": "Html report was not created. e: {}".format(e)})
81
+ ui_thread.print(ui_thread.PrinterText("Pynt CLI exited: Html report was not created.", ui_thread.PrinterText.WARNING))
80
82
  except InvalidPathException as e:
81
83
  ui_thread.print(ui_thread.PrinterText("Pynt CLI exited due to invalid host-CA path: {}".format(e), ui_thread.PrinterText.WARNING))
82
- analytics.emit(analytics.ERROR, {"error": "Host CA path provided was invalid"})
84
+ analytics.emit(analytics.ERROR, {"error": "Host CA path provided was invalid. e: {}".format(e)})
83
85
  except InvalidCertFormat as e:
84
86
  ui_thread.print(ui_thread.PrinterText("Pynt CLI exited due to invalid host-CA. Please provide a file in PEM format: {}".format(e), ui_thread.PrinterText.WARNING))
85
- analytics.emit(analytics.ERROR, {"error": "Host CA provided was not in valid pem format"})
86
- except PyntWebSocketException:
87
- analytics.emit(analytics.ERROR, {"error": "postman websocket failed to connect"})
88
- pynt_errors.unexpected_error()
89
- except SomeFoundingsOrWargningsException as e:
87
+ analytics.emit(analytics.ERROR, {"error": "Host CA provided was not in valid pem format. e: {}".format(e)})
88
+ except PyntWebSocketException as e:
89
+ analytics.emit(analytics.ERROR, {"error": "postman websocket failed to connect. e: {}".format(e)})
90
+ ui_thread.print(ui_thread.PrinterText("Pynt CLI exited: postman websocket failed to connect", ui_thread.PrinterText.WARNING))
91
+ except ProxyError as e:
92
+ ui_thread.print(ui_thread.PrinterText("Pynt CLI exited due to a proxy error. check if your proxy is up", ui_thread.PrinterText.WARNING))
93
+ analytics.emit(analytics.ERROR, {"error": "there was a proxy error. e: {}".format(e)})
94
+ except pynt_container.PortInUseException as e:
95
+ analytics.emit(analytics.ERROR, {"error": "port in use. e: {}".format(e)})
96
+ except SomeFindingsOrWarningsException as e:
90
97
  exit(1)
91
98
  except Exception as e:
92
99
  analytics.emit(analytics.ERROR, {"error": "{}".format(e)})
@@ -0,0 +1,7 @@
1
+
2
+ import socket
3
+
4
+
5
+ def is_port_in_use(port: int) -> bool:
6
+ with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
7
+ return s.connect_ex(('localhost', port)) == 0
@@ -6,6 +6,8 @@ import argparse
6
6
  from typing import List
7
7
  import base64
8
8
 
9
+ from . import container_utils
10
+
9
11
  from pyntcli.ui import ui_thread
10
12
  from pyntcli.analytics import send as analytics
11
13
  from pyntcli.store import CredStore
@@ -26,6 +28,12 @@ class ImageUnavailableException(Exception):
26
28
  pass
27
29
 
28
30
 
31
+ class PortInUseException(Exception):
32
+ def __init__(self, port=""):
33
+ self.message = ui_thread.print(ui_thread.PrinterText("Port: {} already in use, please use a different one".format(port), ui_thread.PrinterText.WARNING))
34
+ super().__init__(self.message)
35
+
36
+
29
37
  def get_docker_type():
30
38
  try:
31
39
  c = docker.from_env()
@@ -60,16 +68,20 @@ class PyntDockerPort:
60
68
 
61
69
  def get_container_with_arguments(args: argparse.Namespace, *port_args: PyntDockerPort) -> PyntBaseConatiner:
62
70
  docker_arguments = []
63
- if "desktop" in get_docker_type().lower():
64
- ports = {}
65
- for p in port_args:
71
+ ports = {}
72
+ for p in port_args:
73
+ if container_utils.is_port_in_use(p.dest):
74
+ raise PortInUseException(p.dest)
75
+ if "desktop" in get_docker_type().lower():
66
76
  ports[str(p.src)] = int(p.dest)
77
+ else:
78
+ docker_arguments.append(p.name)
79
+ docker_arguments.append(str(p.dest))
80
+
81
+ if "desktop" in get_docker_type().lower():
67
82
  docker_type = PyntDockerDesktopContainer(ports=ports)
68
83
  else:
69
84
  docker_type = PyntNativeContainer(network="host")
70
- for p in port_args:
71
- docker_arguments.append(p.name)
72
- docker_arguments.append(str(p.dest))
73
85
 
74
86
  if "insecure" in args and args.insecure:
75
87
  docker_arguments.append("--insecure")
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: pyntcli
3
- Version: 0.1.74
3
+ Version: 0.1.75
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
@@ -1,5 +1,5 @@
1
- pyntcli/__init__.py,sha256=KewwZnnRMQkstdiLHG6R7ciil5WtDn_QVk-Z392irYc,23
2
- pyntcli/main.py,sha256=intiqInoRbIF_lE8ilxQBP5aloPAtAvUBdF4k0Rqfxw,4289
1
+ pyntcli/__init__.py,sha256=FJWQjdyjCSq1G0xvL-leZBsVKT8Trwi_Y3BZDT0-Bus,23
2
+ pyntcli/main.py,sha256=7ZDeG3IO04T98D2NJ1vHWVAVJVm8y719NeV2Aom7tPY,5171
3
3
  pyntcli/analytics/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
4
  pyntcli/analytics/send.py,sha256=cKvMw4HIGJGLip5OMPqTv1AJDlKlc_Uk2Sfcl0e3QLE,2845
5
5
  pyntcli/auth/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -7,19 +7,20 @@ pyntcli/auth/login.py,sha256=CosHIB1HHWa3cGjpE4uHNxsi_7SPL-I6Da0zCq3OcmU,5012
7
7
  pyntcli/commands/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
8
8
  pyntcli/commands/burp.py,sha256=tbGpKP4NEuEZYSuBxqvLJaC4kRqtv0GO6BpBfPX2DRM,10397
9
9
  pyntcli/commands/command.py,sha256=UvJEHv69iQ03R0pN2RCsi3my48xwSMoDBTvcnbg_XzE,9477
10
- pyntcli/commands/har.py,sha256=Iq0455umKvlcMxcU4l70-NIZh7Wovry3f76u68drmQ4,3654
10
+ pyntcli/commands/har.py,sha256=mSCbTUnxQrKzJd-dAWoc6Tkw6tU1LDH7Ha1w2ylrrrg,3654
11
11
  pyntcli/commands/id_command.py,sha256=UBEgMIpm4vauTCsKyixltiGUolNg_OfHEJvJ_i5BpJY,943
12
12
  pyntcli/commands/listen.py,sha256=ZfzCM8P0TVweC42NCL24_1yK48_NvRER6Vi8_oChaT0,8450
13
- pyntcli/commands/newman.py,sha256=ctq9cuEH1GnFOhGshAn6eNfyw3rrrLMaeoWIVcf9JQs,4826
14
- pyntcli/commands/postman.py,sha256=yPE8jBITEhDT7htUaa7r2jxKfHwuSKj9177HGinABCs,4938
13
+ pyntcli/commands/newman.py,sha256=y0KolwMgsvoqPz2mp0QRug_qNr-ftOZbu_tN7h4bH7I,4826
14
+ pyntcli/commands/postman.py,sha256=GWq4NJJ_9WdFiXk5rv2nTyMM27w50XLh4LKkuuWpw4I,4721
15
15
  pyntcli/commands/pynt_cmd.py,sha256=KOl9guUtesO2JcMM5nPKKkjnK6F9HV4jHHcoUk4KVhw,2825
16
16
  pyntcli/commands/root.py,sha256=GijCi8hqe8sXEo6faWimlCmT8d782yjrw1IWJT5RAMk,3320
17
17
  pyntcli/commands/sub_command.py,sha256=GF3-rE_qk2L4jGPFqHLm9SdGINmu3EakhjJTFyWjRms,374
18
- pyntcli/commands/util.py,sha256=IREZvHYJ7wEth8ujOkk5ZXZ4UrUA7jDv134_UueED4s,2995
18
+ pyntcli/commands/util.py,sha256=mi9c6Ex0ftpdY0jvI5BiBD2zwJD6RhrPQ2VyfxBZlA8,2793
19
19
  pyntcli/log/__init__.py,sha256=cOGwOYzMoshEbZiiasBGkj6wF0SBu3Jdpl-AuakDesw,19
20
20
  pyntcli/log/log.py,sha256=cWCdWmUaAwePwdhYDcgNMEG9d9RM34sGahxBCYEdv2Y,1069
21
21
  pyntcli/pynt_docker/__init__.py,sha256=PQIOVxc7XXtMLfEX7ojgwf_Z3mmTllO3ZvzUZTPOxQY,30
22
- pyntcli/pynt_docker/pynt_container.py,sha256=rMHdTOace-hJjhKbY8u9VxrVG6J5ymfEYiCGBGrIiEI,8332
22
+ pyntcli/pynt_docker/container_utils.py,sha256=_Onn7loInzyJAG2-Uk6CGpsuRyelmUFHOvtJj4Uzi9A,175
23
+ pyntcli/pynt_docker/pynt_container.py,sha256=y4m8wZU16gqFPaMzEJKKHut4DbjPxr_du8g7I4-AcHk,8761
23
24
  pyntcli/store/__init__.py,sha256=xuS9OB21F6B1sUx5XPGxz_6WpG6-KTMbuq50RrZS5OY,29
24
25
  pyntcli/store/json_connector.py,sha256=UGs3uORw3iyn0YJ8kzab-veEZToA6d-ByXYuqEleWsA,560
25
26
  pyntcli/store/store.py,sha256=Kf4IFCAu0i0DPVGgntrSYUiwz6kmW9HvItKnCT-MosE,1905
@@ -34,8 +35,8 @@ pyntcli/ui/ui_thread.py,sha256=OVTbiIFMg2KgxAvHf7yy86xGm4RVS2vj_VYZkMi-SRY,4956
34
35
  tests/conftest.py,sha256=gToq5K74GtgeGQXjFvXSzMaE6axBYxAzcFG5XJPOXjI,427
35
36
  tests/auth/test_login.py,sha256=juYxYZWfNmAuwm-ygGEF5gjzaR9LcimonDr7pN5vgLI,3209
36
37
  tests/store/test_cred_store.py,sha256=_7-917EtNC9eKEumO2_lt-7KuDmCwOZFaowCm7DbA_A,254
37
- pyntcli-0.1.74.dist-info/METADATA,sha256=mEvK3_PCXXcU-hNBhwdEsB5ZHWkf6doTvEtYCeSXZxw,463
38
- pyntcli-0.1.74.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
39
- pyntcli-0.1.74.dist-info/entry_points.txt,sha256=kcGmqAxXDttNk2EPRcqunc_LTVp61gzakz0v-GEE2SY,43
40
- pyntcli-0.1.74.dist-info/top_level.txt,sha256=u9MDStwVHB7UG8PUcODeWCul_NvzL2EzoLvSlgwLHFs,30
41
- pyntcli-0.1.74.dist-info/RECORD,,
38
+ pyntcli-0.1.75.dist-info/METADATA,sha256=RC4dmb_LHLW2n3oSNK5--zOSaOJBC2Hcm-7LQrUakiU,463
39
+ pyntcli-0.1.75.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
40
+ pyntcli-0.1.75.dist-info/entry_points.txt,sha256=kcGmqAxXDttNk2EPRcqunc_LTVp61gzakz0v-GEE2SY,43
41
+ pyntcli-0.1.75.dist-info/top_level.txt,sha256=u9MDStwVHB7UG8PUcODeWCul_NvzL2EzoLvSlgwLHFs,30
42
+ pyntcli-0.1.75.dist-info/RECORD,,