pyntcli 0.1.111__py3-none-any.whl → 0.1.113__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.
- ignoreTests/auth/login.py +1 -1
- pyntcli/__init__.py +1 -1
- pyntcli/auth/login.py +33 -19
- pyntcli/commands/burp.py +1 -0
- pyntcli/commands/command.py +1 -0
- pyntcli/commands/har.py +1 -0
- pyntcli/commands/listen.py +1 -0
- pyntcli/commands/newman.py +1 -0
- pyntcli/commands/postman.py +1 -0
- pyntcli/commands/root.py +9 -0
- pyntcli/commands/template.py +1 -0
- pyntcli/pynt_docker/pynt_container.py +4 -0
- {pyntcli-0.1.111.dist-info → pyntcli-0.1.113.dist-info}/METADATA +2 -2
- {pyntcli-0.1.111.dist-info → pyntcli-0.1.113.dist-info}/RECORD +17 -17
- {pyntcli-0.1.111.dist-info → pyntcli-0.1.113.dist-info}/WHEEL +1 -1
- {pyntcli-0.1.111.dist-info → pyntcli-0.1.113.dist-info}/entry_points.txt +0 -0
- {pyntcli-0.1.111.dist-info → pyntcli-0.1.113.dist-info}/top_level.txt +0 -0
ignoreTests/auth/login.py
CHANGED
pyntcli/__init__.py
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
__version__ = "0.1.
|
|
1
|
+
__version__ = "0.1.113"
|
pyntcli/auth/login.py
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
+
import random
|
|
2
|
+
import string
|
|
1
3
|
from base64 import b64decode
|
|
2
4
|
import webbrowser
|
|
3
|
-
import uuid
|
|
4
5
|
import urllib.parse
|
|
5
6
|
import datetime
|
|
6
7
|
import time
|
|
@@ -28,6 +29,8 @@ PYNT_ID = "PYNT_ID"
|
|
|
28
29
|
PYNT_CREDENTIALS = "PYNT_CREDENTIALS"
|
|
29
30
|
PYNT_SAAS = os.environ.get("PYNT_SAAS_URL") if os.environ.get(
|
|
30
31
|
"PYNT_SAAS_URL") else "https://api.pynt.io/v1"
|
|
32
|
+
PYNT_APP_URL = os.environ.get("PYNT_APP_URL") if os.environ.get(
|
|
33
|
+
"PYNT_APP_URL") else "https://app.pynt.io"
|
|
31
34
|
PYNT_BUCKET_NAME = os.environ.get(
|
|
32
35
|
"PYNT_BUCKET_NAME") if os.environ.get("PYNT_BUCKET_NAME") else ""
|
|
33
36
|
PYNT_PARAM1 = os.environ.get(
|
|
@@ -36,41 +39,47 @@ PYNT_PARAM2 = os.environ.get(
|
|
|
36
39
|
"PYNT_PARAM2") if os.environ.get("PYNT_PARAM2") else ""
|
|
37
40
|
|
|
38
41
|
|
|
42
|
+
def generate_device_code() -> str:
|
|
43
|
+
"""
|
|
44
|
+
Generates a random 8 alphanumeric string of pattern `XXXX-XXXX`
|
|
45
|
+
"""
|
|
46
|
+
part_one = ''.join(random.choice(string.ascii_uppercase + string.digits) for _ in range(4))
|
|
47
|
+
part_two = ''.join(random.choice(string.ascii_uppercase + string.digits) for _ in range(4))
|
|
48
|
+
return f"{part_one}-{part_two}"
|
|
49
|
+
|
|
50
|
+
|
|
39
51
|
class Login():
|
|
40
52
|
def __init__(self) -> None:
|
|
41
53
|
self.delay = 5
|
|
42
|
-
self.base_authorization_url = "https://pynt.io/login?"
|
|
43
|
-
self.poll_url = "https://n592meacjj.execute-api.us-east-1.amazonaws.com/default/cli_validate_login"
|
|
44
54
|
self.login_wait_period = (60 * 3) # 3 minutes
|
|
45
55
|
|
|
46
|
-
def create_login_request(self):
|
|
47
|
-
|
|
48
|
-
request_url =
|
|
49
|
-
|
|
50
|
-
{"request_id": request_id, "utm_source": "cli"})
|
|
56
|
+
def create_login_request(self) -> str:
|
|
57
|
+
device_code = generate_device_code()
|
|
58
|
+
request_url = f"{PYNT_APP_URL}/login?" + urllib.parse.urlencode(
|
|
59
|
+
{"device_code": device_code, "utm_source": "cli"})
|
|
51
60
|
webbrowser.open(request_url)
|
|
52
61
|
|
|
53
62
|
ui_thread.print(ui_thread.PrinterText("To continue, you need to log in to your account.")
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
return
|
|
59
|
-
|
|
60
|
-
def
|
|
63
|
+
.with_line("You will now be redirected to the login page.")
|
|
64
|
+
.with_line("")
|
|
65
|
+
.with_line("If you are not automatically redirected, please click on the link provided below (or copy to your web browser)")
|
|
66
|
+
.with_line(request_url))
|
|
67
|
+
return device_code
|
|
68
|
+
|
|
69
|
+
def claim_token_using_device_code(self, device_code: str):
|
|
70
|
+
poll_url = f"{PYNT_SAAS}/auth/device-code/{device_code}"
|
|
61
71
|
with ui_thread.spinner("Waiting...", "point"):
|
|
62
72
|
start = time.time()
|
|
63
73
|
while start + self.login_wait_period > time.time():
|
|
64
|
-
response = pynt_requests.get(
|
|
65
|
-
"request_id": request_id})
|
|
74
|
+
response = pynt_requests.get(poll_url)
|
|
66
75
|
if response.status_code == 200:
|
|
67
76
|
return response.json()
|
|
68
77
|
time.sleep(self.delay)
|
|
69
78
|
raise Timeout()
|
|
70
79
|
|
|
71
80
|
def login(self):
|
|
72
|
-
|
|
73
|
-
token = self.
|
|
81
|
+
device_code = self.create_login_request()
|
|
82
|
+
token = self.claim_token_using_device_code(device_code)
|
|
74
83
|
with CredStore() as store:
|
|
75
84
|
store.put("token", token)
|
|
76
85
|
|
|
@@ -85,6 +94,7 @@ def refresh_token():
|
|
|
85
94
|
token = store.get("token")
|
|
86
95
|
|
|
87
96
|
if not token:
|
|
97
|
+
ui_thread.print_verbose("Token not found, logging in")
|
|
88
98
|
Login().login()
|
|
89
99
|
|
|
90
100
|
access_token = token.get("access_token")
|
|
@@ -93,11 +103,13 @@ def refresh_token():
|
|
|
93
103
|
|
|
94
104
|
refresh = token.get("refresh_token", None)
|
|
95
105
|
if not refresh:
|
|
106
|
+
ui_thread.print_verbose("Refresh token not found, logging in")
|
|
96
107
|
Login().login()
|
|
97
108
|
return
|
|
98
109
|
|
|
99
110
|
refresh_response = refresh_request(refresh)
|
|
100
111
|
if refresh_response.status_code != 200:
|
|
112
|
+
ui_thread.print_verbose("Failed to refresh token, logging in")
|
|
101
113
|
Login().login()
|
|
102
114
|
return
|
|
103
115
|
|
|
@@ -172,9 +184,11 @@ def should_login():
|
|
|
172
184
|
token = store.get("token")
|
|
173
185
|
|
|
174
186
|
if not token or token == store.connector.default_value:
|
|
187
|
+
ui_thread.print_verbose("Token is default or not found")
|
|
175
188
|
return True
|
|
176
189
|
|
|
177
190
|
if not token.get("refresh_token"):
|
|
191
|
+
ui_thread.print_verbose("Refresh token not found")
|
|
178
192
|
return True
|
|
179
193
|
|
|
180
194
|
return False
|
pyntcli/commands/burp.py
CHANGED
|
@@ -151,6 +151,7 @@ def burp_usage():
|
|
|
151
151
|
.with_line("\t--application-id - Attach the scan to an application, you can find the ID in your applications area at app.pynt.io")
|
|
152
152
|
.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.")
|
|
153
153
|
.with_line("\t--severity-level - 'all', 'medium', 'high', 'critical', 'none' (default) ")
|
|
154
|
+
.with_line("\t--tag - Tag the scan. Repeat for multiple tags")
|
|
154
155
|
.with_line("\t--verbose - Use to get more detailed information about the run")
|
|
155
156
|
)
|
|
156
157
|
|
pyntcli/commands/command.py
CHANGED
|
@@ -40,6 +40,7 @@ def command_usage():
|
|
|
40
40
|
.with_line("\t--application-id - Attach the scan to an application, you can find the ID in your applications area at app.pynt.io")
|
|
41
41
|
.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.")
|
|
42
42
|
.with_line("\t--severity-level - 'all', 'medium', 'high', 'critical', 'none' (default) ")
|
|
43
|
+
.with_line("\t--tag - Tag the scan. Repeat for multiple tags")
|
|
43
44
|
.with_line("\t--verbose - Use to get more detailed information about the run")
|
|
44
45
|
)
|
|
45
46
|
|
pyntcli/commands/har.py
CHANGED
|
@@ -29,6 +29,7 @@ def har_usage():
|
|
|
29
29
|
"\t--host-ca - Path to the CA file in PEM format to enable SSL certificate verification for pynt when running through a VPN."
|
|
30
30
|
)
|
|
31
31
|
.with_line("\t--severity-level - 'all', 'medium', 'high', 'critical', 'none' (default) ")
|
|
32
|
+
.with_line("\t--tag - Tag the scan. Repeat for multiple tags")
|
|
32
33
|
.with_line("\t--verbose - Use to get more detailed information about the run")
|
|
33
34
|
.with_line("")
|
|
34
35
|
)
|
pyntcli/commands/listen.py
CHANGED
|
@@ -34,6 +34,7 @@ def listen_usage():
|
|
|
34
34
|
.with_line("\t--insecure - use when target uses self signed certificates")
|
|
35
35
|
.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.")
|
|
36
36
|
.with_line("\t--severity-level - 'all', 'medium', 'high', 'critical', 'none' (default) ")
|
|
37
|
+
.with_line("\t--tag - Tag the scan. Repeat for multiple tags")
|
|
37
38
|
.with_line("\t--verbose - Use to get more detailed information about the run")
|
|
38
39
|
)
|
|
39
40
|
|
pyntcli/commands/newman.py
CHANGED
|
@@ -29,6 +29,7 @@ def newman_usage():
|
|
|
29
29
|
"\t--application-id - Attach the scan to an application, you can find the ID in your applications area at app.pynt.io"
|
|
30
30
|
)
|
|
31
31
|
.with_line("\t--severity-level - 'all', 'medium', 'high', 'critical', 'none' (default) ")
|
|
32
|
+
.with_line("\t--tag - Tag the scan. Repeat for multiple tags")
|
|
32
33
|
.with_line("\t--verbose - Use to get more detailed information about the run")
|
|
33
34
|
)
|
|
34
35
|
|
pyntcli/commands/postman.py
CHANGED
|
@@ -36,6 +36,7 @@ def postman_usage():
|
|
|
36
36
|
.with_line("\t--port - set the port pynt will listen to (DEFAULT: 5001)") \
|
|
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--tag - Tag the scan. Repeat for multiple tags") \
|
|
39
40
|
.with_line("\t--verbose - Use to get more detailed information about the run")
|
|
40
41
|
|
|
41
42
|
|
pyntcli/commands/root.py
CHANGED
|
@@ -96,6 +96,14 @@ class BaseCommand:
|
|
|
96
96
|
type=str,
|
|
97
97
|
help=argparse.SUPPRESS,
|
|
98
98
|
)
|
|
99
|
+
parser.add_argument(
|
|
100
|
+
"--tag",
|
|
101
|
+
default=[],
|
|
102
|
+
required=False,
|
|
103
|
+
nargs="+",
|
|
104
|
+
action="append",
|
|
105
|
+
help=argparse.SUPPRESS,
|
|
106
|
+
)
|
|
99
107
|
|
|
100
108
|
def get_subparser(self) -> argparse._SubParsersAction:
|
|
101
109
|
if self.subparser is None:
|
|
@@ -107,6 +115,7 @@ class BaseCommand:
|
|
|
107
115
|
analytics.emit(analytics.LOGIN_START)
|
|
108
116
|
|
|
109
117
|
if login.should_login():
|
|
118
|
+
ui_thread.print_verbose("User should login")
|
|
110
119
|
l = login.Login().login()
|
|
111
120
|
else:
|
|
112
121
|
login.refresh_token()
|
pyntcli/commands/template.py
CHANGED
|
@@ -26,6 +26,7 @@ def template_usage():
|
|
|
26
26
|
.with_line("\t--urls - Path to the file containing the base URLs (with new line separator) for the attacks")
|
|
27
27
|
.with_line("\t--reporters - Output results to json")
|
|
28
28
|
.with_line("\t--severity-level - 'all', 'medium', 'high', 'critical', 'none' (default)")
|
|
29
|
+
.with_line("\t--tag - Tag the scan. Repeat for multiple tags")
|
|
29
30
|
.with_line("\t--verbose - Use to get more detailed information about the run")
|
|
30
31
|
.with_line("")
|
|
31
32
|
)
|
|
@@ -167,6 +167,10 @@ def build_docker_args(integration_name: str, args: argparse.Namespace, port_args
|
|
|
167
167
|
if "verbose" in args and args.verbose:
|
|
168
168
|
docker_arguments.append("--verbose")
|
|
169
169
|
|
|
170
|
+
if "tag" in args and args.tag:
|
|
171
|
+
for tag in args.tag:
|
|
172
|
+
docker_arguments += ["--tag", tag[0]]
|
|
173
|
+
|
|
170
174
|
for port_arg in port_args:
|
|
171
175
|
docker_arguments += [port_arg.name, str(port_arg.port)]
|
|
172
176
|
|
|
@@ -1,31 +1,31 @@
|
|
|
1
1
|
ignoreTests/conftest.py,sha256=gToq5K74GtgeGQXjFvXSzMaE6axBYxAzcFG5XJPOXjI,427
|
|
2
|
-
ignoreTests/auth/login.py,sha256=
|
|
2
|
+
ignoreTests/auth/login.py,sha256=7GeBirHTD9t6EassLYsegCw1FZHkfjvVW1Z5uybHzgM,3801
|
|
3
3
|
ignoreTests/store/cred_store.py,sha256=_7-917EtNC9eKEumO2_lt-7KuDmCwOZFaowCm7DbA_A,254
|
|
4
|
-
pyntcli/__init__.py,sha256=
|
|
4
|
+
pyntcli/__init__.py,sha256=j3sjtalrZ7qzajUh_46Une0yUZprSFiTpVECCQnsaGI,24
|
|
5
5
|
pyntcli/main.py,sha256=RD0W2_0ogYBCXubo-YewxHYkiIXxNv6NkZOh3n1VujE,5964
|
|
6
6
|
pyntcli/analytics/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
7
7
|
pyntcli/analytics/send.py,sha256=0hJ0WJNFHLqyohtRr_xOg5WEXzxHrUOlcePPg-k65Hk,3846
|
|
8
8
|
pyntcli/auth/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
9
|
-
pyntcli/auth/login.py,sha256=
|
|
9
|
+
pyntcli/auth/login.py,sha256=Oz1DtEZje0afgJcHSwEFHcH78X-QD5Mjn0CQ9ZgCfQU,5844
|
|
10
10
|
pyntcli/commands/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
11
|
-
pyntcli/commands/burp.py,sha256=
|
|
12
|
-
pyntcli/commands/command.py,sha256=
|
|
13
|
-
pyntcli/commands/har.py,sha256=
|
|
11
|
+
pyntcli/commands/burp.py,sha256=AUJU2cIJ-PSUATxYoHRwDy0K5feqCs-mGdkGle2WcDw,14173
|
|
12
|
+
pyntcli/commands/command.py,sha256=3egvDDr68sTUnyJpUE0bO9TfVy_rgeuM2C4zkMA-9GQ,10903
|
|
13
|
+
pyntcli/commands/har.py,sha256=FKWgTOWwvYFJGazeuttsTJTFjP6g_PUJxzzNoDl8v28,4273
|
|
14
14
|
pyntcli/commands/id_command.py,sha256=UBEgMIpm4vauTCsKyixltiGUolNg_OfHEJvJ_i5BpJY,943
|
|
15
|
-
pyntcli/commands/listen.py,sha256=
|
|
16
|
-
pyntcli/commands/newman.py,sha256=
|
|
17
|
-
pyntcli/commands/postman.py,sha256=
|
|
15
|
+
pyntcli/commands/listen.py,sha256=18D9OdW1EakkK1u54hiOjwAuT5J6nsYb2vqlP1nw8p4,8898
|
|
16
|
+
pyntcli/commands/newman.py,sha256=ssMXY7VvYdMCXS38uLftF7uQ4HmDMYYHra4GvZhcR-g,5116
|
|
17
|
+
pyntcli/commands/postman.py,sha256=kN1PkzPpcUnsbirg17AN9JwJZu6VBt6OeKYrLGrvtFc,4964
|
|
18
18
|
pyntcli/commands/pynt_cmd.py,sha256=AeXxKy8dtZTdwWhTirHVvkPkeFUSoZNb3FRyuwkL6kg,7103
|
|
19
|
-
pyntcli/commands/root.py,sha256=
|
|
19
|
+
pyntcli/commands/root.py,sha256=Lr31nsx2sgM-o3OYEbfqakaxzXHY6irr9uj-X6QWiqk,4325
|
|
20
20
|
pyntcli/commands/static_file_extensions.py,sha256=PZJb02BI-64tbU-j3rdCNsXzTh7gkIDGxGKbKNw3h5k,1995
|
|
21
21
|
pyntcli/commands/sub_command.py,sha256=GF3-rE_qk2L4jGPFqHLm9SdGINmu3EakhjJTFyWjRms,374
|
|
22
|
-
pyntcli/commands/template.py,sha256=
|
|
22
|
+
pyntcli/commands/template.py,sha256=wl-0GhIUUqdO39fyoO7mMsEKXnYqG32XkQdUJhLkdiA,8047
|
|
23
23
|
pyntcli/commands/util.py,sha256=ev06aUlJ9tCSw1eAGVIsGlVVY4u0H6AJG9b5MB_bAzs,4594
|
|
24
24
|
pyntcli/log/__init__.py,sha256=cOGwOYzMoshEbZiiasBGkj6wF0SBu3Jdpl-AuakDesw,19
|
|
25
25
|
pyntcli/log/log.py,sha256=YXCvcCzuhQ5QUT2L02uQEdN_lTCzLEuet4OnLuEnjlM,112
|
|
26
26
|
pyntcli/pynt_docker/__init__.py,sha256=PQIOVxc7XXtMLfEX7ojgwf_Z3mmTllO3ZvzUZTPOxQY,30
|
|
27
27
|
pyntcli/pynt_docker/container_utils.py,sha256=_Onn7loInzyJAG2-Uk6CGpsuRyelmUFHOvtJj4Uzi9A,175
|
|
28
|
-
pyntcli/pynt_docker/pynt_container.py,sha256=
|
|
28
|
+
pyntcli/pynt_docker/pynt_container.py,sha256=u87rBT52rxDYNg8gc0NAs3GhTDS1MFwKLpShJkPlKbA,13861
|
|
29
29
|
pyntcli/store/__init__.py,sha256=1fP8cEAQCF_myja3gnhHH9FEqtBiOJ-2aBmUXSKBdFA,41
|
|
30
30
|
pyntcli/store/json_connector.py,sha256=UGs3uORw3iyn0YJ8kzab-veEZToA6d-ByXYuqEleWsA,560
|
|
31
31
|
pyntcli/store/store.py,sha256=Kl_HT9FJFdKlAH7SwAt3g4-bW-r-1ve_u13OPggQai0,2529
|
|
@@ -40,8 +40,8 @@ pyntcli/ui/report.py,sha256=W-icPSZrGLOubXgam0LpOvHLl_aZg9Zx9qIkL8Ym5PE,1930
|
|
|
40
40
|
pyntcli/ui/ui_thread.py,sha256=XUBgLpYQjVhrilU-ofw7VSXgTiwneSdTxm61EvC3x4Q,5091
|
|
41
41
|
tests/test_utils.py,sha256=t5fTQUk1U_Js6iMxcGYGqt4C-crzOJ0CqCKtLkRtUi0,2050
|
|
42
42
|
tests/commands/test_pynt_cmd.py,sha256=BjGFCFACcSziLrNA6_27t6TjSmvdu54wx9njwLpRSJY,8379
|
|
43
|
-
pyntcli-0.1.
|
|
44
|
-
pyntcli-0.1.
|
|
45
|
-
pyntcli-0.1.
|
|
46
|
-
pyntcli-0.1.
|
|
47
|
-
pyntcli-0.1.
|
|
43
|
+
pyntcli-0.1.113.dist-info/METADATA,sha256=8sdhJod-t85esbW4yJ0okltq4ljGEX1_4sQ2u5p5Mhg,427
|
|
44
|
+
pyntcli-0.1.113.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
|
|
45
|
+
pyntcli-0.1.113.dist-info/entry_points.txt,sha256=kcGmqAxXDttNk2EPRcqunc_LTVp61gzakz0v-GEE2SY,43
|
|
46
|
+
pyntcli-0.1.113.dist-info/top_level.txt,sha256=64XSgBzSpgwjYjEKHZE7q3JH2a816zEeyZBXfJi3AKI,42
|
|
47
|
+
pyntcli-0.1.113.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|