Skip to content

Commit 721ced5

Browse files
committed
refactor(prompts): enhance input validation and streamline get_input function
1 parent ffd8f2f commit 721ced5

File tree

8 files changed

+77
-136
lines changed

8 files changed

+77
-136
lines changed

bugscanx/modules/others/file_toolkit.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,8 @@ def write_lines(file_path, lines):
3434

3535

3636
def split_file():
37-
file_path = get_input("Enter filename", "file")
38-
parts = int(get_input("Number of parts", "number"))
37+
file_path = get_input("Enter filename", input_type="file", validators="file")
38+
parts = int(get_input("Number of parts", validators="number"))
3939
lines = read_lines(file_path)
4040
if not lines:
4141
return
@@ -89,7 +89,7 @@ def merge_files():
8989

9090

9191
def clean_file():
92-
input_file = get_input("Enter filename", "file")
92+
input_file = get_input("Enter filename", input_type="file", validators="file")
9393
domain_output_file = get_input("Enter domains output filename")
9494
ip_output_file = get_input("Enter IP output filename")
9595

@@ -117,7 +117,7 @@ def clean_file():
117117

118118

119119
def remove_duplicates():
120-
file_path = get_input("Enter filename", "file")
120+
file_path = get_input("Enter filename", input_type="file", validators="file")
121121
lines = read_lines(file_path)
122122
if not lines:
123123
return
@@ -135,7 +135,7 @@ def remove_duplicates():
135135

136136

137137
def filter_by_tlds():
138-
file_path = get_input("Enter filename", "file")
138+
file_path = get_input("Enter filename", input_type="file", validators="file")
139139
tlds_input = get_input("Enter TLDs ", instruction="(e.g. com, org)")
140140

141141
domains = read_lines(file_path)
@@ -172,7 +172,7 @@ def filter_by_tlds():
172172

173173

174174
def filter_by_keywords():
175-
file_path = get_input("Enter filename", "file")
175+
file_path = get_input("Enter filename", input_type="file", validators="file")
176176
keywords = [k.strip().lower() for k in get_input("Enter keyword(s)").split(',')]
177177
output_file = get_input("Enter output filename")
178178

@@ -195,7 +195,7 @@ def filter_by_keywords():
195195

196196

197197
def cidr_to_ip():
198-
cidr_input = get_input("Enter CIDR range")
198+
cidr_input = get_input("Enter CIDR range", validators="cidr")
199199
output_file = get_input("Enter output filename")
200200

201201
try:
@@ -215,7 +215,7 @@ def cidr_to_ip():
215215

216216

217217
def domains_to_ip():
218-
file_path = get_input("Enter filename", "file")
218+
file_path = get_input("Enter filename", input_type="file", validators="cidr")
219219
output_file = get_input("Enter output filename")
220220

221221
domains = read_lines(file_path)

bugscanx/modules/others/host_info.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -196,12 +196,12 @@ def scan(self):
196196

197197

198198
def main():
199-
host = get_input("Enter host")
200-
protocol = get_input("Select protocol", "choice", choices=["http", "https"])
199+
host = get_input("Enter host", validators="required")
200+
protocol = get_input("Select protocol", input_type="choice", choices=["http", "https"])
201201
available_methods = ["GET", "HEAD", "POST", "PUT", "DELETE", "OPTIONS", "TRACE", "PATCH"]
202202
method_list = get_input(
203203
"Select HTTP method(s)",
204-
"choice",
204+
input_type="choice",
205205
multiselect=True,
206206
choices=available_methods,
207207
transformer=lambda result: ', '.join(result) if isinstance(result, list) else result

bugscanx/modules/scanners/host_scanner.py

Lines changed: 18 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from bugscanx.utils.prompts import get_input, get_confirm, is_cidr
1+
from bugscanx.utils.prompts import get_input, get_confirm
22
from bugscanx.utils.cidr import read_cidrs_from_file
33

44

@@ -10,25 +10,23 @@ def get_common_inputs():
1010
default_filename = "results.txt"
1111
output = get_input(
1212
"Enter output filename",
13-
default=default_filename,
14-
validate_input=False
13+
default=default_filename
1514
)
1615
threads = get_input(
1716
"Enter threads",
18-
"number",
19-
default="50",
20-
allow_comma_separated=False
17+
validators="number",
18+
default="50"
2119
)
2220
return output, threads
2321

2422

2523
def get_host_input():
26-
filename = get_input("Enter filename", "file", mandatory=False)
24+
filename = get_input("Enter filename", input_type="file", validators="file", mandatory=False)
2725
if not filename:
28-
cidr = get_input("Enter CIDR range(s)", validators=[is_cidr], mandatory=False)
26+
cidr = get_input("Enter CIDR range(s)", validators="cidr", mandatory=False)
2927
if not cidr:
3028
cidr_file = get_input(
31-
"Enter CIDR file", "file")
29+
"Enter CIDR file", input_type="file")
3230
cidr = read_cidrs_from_file(cidr_file) if cidr_file else None
3331
return None, cidr
3432
return filename, None
@@ -39,12 +37,12 @@ def get_input_direct(no302=False):
3937
if filename is None and cidr is None:
4038
return None, None, None
4139

42-
port_list = get_input("Enter port(s)", "number", default="80").split(',')
43-
timeout = get_input("Enter timeout (seconds)", "number", default="3")
40+
port_list = get_input("Enter port(s)", validators="number", default="80").split(',')
41+
timeout = get_input("Enter timeout (seconds)", validators="number", default="3")
4442
output, threads = get_common_inputs()
4543
method_list = get_input(
4644
"Select HTTP method(s)",
47-
"choice",
45+
input_type="choice",
4846
multiselect=True,
4947
choices=[
5048
"GET", "HEAD", "POST", "PUT",
@@ -94,8 +92,8 @@ def get_input_proxy():
9492
"Upgrade: websocket[crlf][crlf]"
9593
)
9694
payload = get_input("Enter payload", default=default_payload)
97-
port_list = get_input("Enter port(s)", "number", default="80").split(',')
98-
output, threads = get_common_inputs(filename or cidr)
95+
port_list = get_input("Enter port(s)", validators="number", default="80").split(',')
96+
output, threads = get_common_inputs()
9997

10098
if cidr:
10199
try:
@@ -128,11 +126,11 @@ def get_input_proxy2():
128126
if filename is None and cidr is None:
129127
return None, None, None
130128

131-
port_list = get_input("Enter port(s)", "number", default="80").split(',')
132-
output, threads = get_common_inputs(filename or cidr)
129+
port_list = get_input("Enter port(s)", validators="number", default="80").split(',')
130+
output, threads = get_common_inputs()
133131
method_list = get_input(
134132
"Select HTTP method(s)",
135-
"choice",
133+
input_type="choice",
136134
multiselect=True,
137135
choices=[
138136
"GET", "HEAD", "POST", "PUT",
@@ -180,7 +178,7 @@ def get_input_ssl():
180178
if filename is None and cidr is None:
181179
return None, None, None
182180

183-
output, threads = get_common_inputs(filename or cidr)
181+
output, threads = get_common_inputs()
184182

185183
if cidr:
186184
try:
@@ -207,8 +205,8 @@ def get_input_ping():
207205
if filename is None and cidr is None:
208206
return None, None, None
209207

210-
port_list = get_input("Enter port(s)", "number", default="443").split(',')
211-
output, threads = get_common_inputs(filename or cidr)
208+
port_list = get_input("Enter port(s)", validators="number", default="443").split(',')
209+
output, threads = get_common_inputs()
212210

213211
if cidr:
214212
try:

bugscanx/modules/scanners/port_scanner.py

Lines changed: 3 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ def scan_port(ip, port):
3030

3131

3232
def main():
33-
target = get_input("Enter target")
33+
target = get_input("Enter target", validators="required")
3434
try:
3535
ip = socket.gethostbyname(target)
3636
except socket.gaierror:
@@ -42,7 +42,7 @@ def main():
4242

4343
scan_type = get_input(
4444
"Select scan type",
45-
"choice",
45+
input_type="choice",
4646
choices=["Common ports", "All ports (1-65535)"]
4747
)
4848
ports = COMMON_PORTS if scan_type == "Common ports" else range(1, 65535)
@@ -73,16 +73,5 @@ def main():
7373
progress.console.print(f" [green]✓[/] Port {result} is open")
7474
progress.advance(task)
7575

76-
open_ports = sorted(open_ports)
77-
78-
console.print("\n[bold green] Scan Results:[/]\n")
79-
if open_ports:
80-
console.print("[cyan] Open Ports:[/]\n")
81-
for port in open_ports:
82-
console.print(f" • Port {port}")
83-
84-
with open(f"{target}_open_ports.txt", "w") as f:
85-
f.write("\n".join(f"Port {port} is open" for port in open_ports))
86-
console.print(f"\n[dim] Results saved to {target}_open_ports.txt[/]\n")
87-
else:
76+
if not open_ports:
8877
console.print("\n[yellow] No open ports found.[/]\n")

bugscanx/modules/scrapers/iplookup/iplookup.py

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import os
22
from concurrent.futures import ThreadPoolExecutor, as_completed
33

4-
from bugscanx.utils.prompts import get_input, is_cidr
4+
from bugscanx.utils.prompts import get_input
55
from .sources import get_scrapers
66
from .utils import CursorManager, process_input, process_file
77
from .logger import IPLookupConsole
@@ -75,11 +75,9 @@ def run(self, ips, output_file, scrapers=None):
7575

7676
def main():
7777
ips = []
78-
input_type = get_input("Select input mode", "choice",
79-
choices=["Manual", "File"])
80-
78+
input_type = get_input("Select input mode", input_type="choice", choices=["Manual", "File"])
8179
if input_type == "Manual":
82-
ip_input = get_input("Enter IP or CIDR", validators=[is_cidr])
80+
ip_input = get_input("Enter IP or CIDR", validators="cidr")
8381
ips.extend(process_input(ip_input))
8482
default_output = f"{ip_input}_domains.txt".replace("/", "-")
8583
else:

bugscanx/modules/scrapers/subfinder/subfinder.py

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import os
22
from concurrent.futures import ThreadPoolExecutor, as_completed
3-
43
from bugscanx.utils.prompts import get_input
54
from .logger import SubFinderConsole
65
from .sources import get_sources
@@ -81,15 +80,13 @@ def run(self, domains, output_file, sources):
8180
def main():
8281
domains = []
8382
sources = get_sources()
84-
input_type = get_input("Select input mode", "choice",
85-
choices=["Manual", "File"])
86-
83+
input_type = get_input("Select input mode", input_type="choice", choices=["Manual", "File"])
8784
if input_type == "Manual":
88-
domain_input = get_input("Enter domain(s)")
85+
domain_input = get_input("Enter domain(s)", validators="required")
8986
domains = [d.strip() for d in domain_input.split(',') if DomainValidator.is_valid_domain(d.strip())]
9087
default_output = f"{domains[0]}_subdomains.txt" if domains else "subdomains.txt"
9188
else:
92-
file_path = get_input("Enter filename", "file")
89+
file_path = get_input("Enter filename", input_type="file", validators="file")
9390
with open(file_path, 'r') as f:
9491
domains = [d.strip() for d in f if DomainValidator.is_valid_domain(d.strip())]
9592
default_output = f"{file_path.rsplit('.', 1)[0]}_subdomains.txt"

bugscanx/utils/prompts.py

Lines changed: 24 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,12 @@
11
import os
2-
32
from InquirerPy import get_style
43
from InquirerPy.prompts import (
54
ListPrompt as select,
65
FilePathPrompt as filepath,
76
InputPrompt as text,
87
ConfirmPrompt as confirm,
98
)
10-
from .validators import create_validator, required, is_file, is_digit, is_cidr
9+
from .validators import create_validator, VALIDATORS
1110

1211

1312
DEFAULT_STYLE = get_style(
@@ -20,30 +19,6 @@
2019
)
2120

2221

23-
INPUT_VALIDATORS = {
24-
"file": [required, is_file],
25-
"number": [required, is_digit],
26-
"text": [required],
27-
}
28-
29-
30-
def strip_handler(handler, strip_input):
31-
def wrapped(params):
32-
result = handler(params)
33-
if strip_input and isinstance(result, str):
34-
return result.strip()
35-
return result
36-
return wrapped
37-
38-
39-
INPUT_HANDLERS = {
40-
"choice": lambda params: select(**params).execute(),
41-
"file": lambda params: filepath(**params).execute(),
42-
"number": lambda params: text(**params).execute(),
43-
"text": lambda params: text(**params).execute(),
44-
}
45-
46-
4722
def get_input(
4823
message,
4924
input_type="text",
@@ -53,58 +28,47 @@ def get_input(
5328
multiselect=False,
5429
transformer=None,
5530
style=DEFAULT_STYLE,
56-
validate_input=True,
5731
instruction="",
5832
mandatory=True,
59-
allow_comma_separated=True,
60-
strip_input=True,
6133
**kwargs
6234
):
63-
common_params = {
64-
"message": f" {message.strip()}" + ("" if instruction else ":"),
35+
def auto_strip(result):
36+
return result.strip() if isinstance(result, str) else result
37+
38+
params = {
39+
"message": f" {message.strip()}" + (":" if not instruction else ""),
6540
"default": "" if default is None else str(default),
66-
"qmark": kwargs.pop("qmark", ""),
67-
"amark": kwargs.pop("amark", ""),
41+
"qmark": "",
42+
"amark": "",
6843
"style": style,
6944
"instruction": instruction + (":" if instruction else ""),
7045
"mandatory": mandatory,
7146
"transformer": transformer,
7247
}
7348

74-
if validators is None and validate_input:
75-
validators = INPUT_VALIDATORS.get(input_type, [])
76-
77-
if validate_input and validators:
78-
if input_type == "number":
79-
validators = [required, lambda x: is_digit(x, allow_comma_separated)]
80-
common_params["validate"] = create_validator(validators)
49+
if validators:
50+
if isinstance(validators, str) and validators in VALIDATORS:
51+
params["validate"] = create_validator(*VALIDATORS[validators])
52+
elif isinstance(validators, (list, tuple)):
53+
params["validate"] = create_validator(*validators)
8154

82-
input_type_params = {
83-
"choice": {
55+
if input_type == "choice":
56+
params.update({
8457
"choices": choices,
8558
"multiselect": multiselect,
86-
"transformer": transformer,
87-
"show_cursor": kwargs.pop("show_cursor", False),
88-
},
89-
"file": {
90-
"only_files": kwargs.pop("only_files", True),
91-
},
92-
}
59+
"show_cursor": kwargs.get("show_cursor", False),
60+
})
61+
return select(**params).execute()
9362

94-
common_params.update(input_type_params.get(input_type, {}))
95-
common_params.update(kwargs)
63+
elif input_type == "file":
64+
params["only_files"] = kwargs.get("only_files", True)
65+
return auto_strip(filepath(**params).execute())
9666

97-
handler = INPUT_HANDLERS.get(input_type)
98-
99-
return strip_handler(handler, strip_input)(common_params)
67+
else:
68+
return auto_strip(text(**params).execute())
10069

10170

102-
def get_confirm(
103-
message,
104-
default=True,
105-
style=DEFAULT_STYLE,
106-
**kwargs
107-
):
71+
def get_confirm(message, default=True, style=DEFAULT_STYLE, **kwargs):
10872
return confirm(
10973
message=message,
11074
default=default,

0 commit comments

Comments
 (0)