-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathrun.py
146 lines (111 loc) · 4.45 KB
/
run.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
# ---------------------------------------------------------------------------------------------------------------------
# Name: run
# Created By : marataj
# Created Date: 2024-11-20
# ---------------------------------------------------------------------------------------------------------------------
"""
Module that integrates all the features and exposes CLI.
"""
import argparse
import json
from datetime import datetime
from pathlib import Path
from source.data_collector import DataCollector
from source.detector.detector import Detector
def validate_dir(path: str) -> Path:
"""
Validates directory path.
Parameters
----------
path: `str`
Path to the directory.
Raises
------
argparse.ArgumentTypeError
Raises if validation fails.
Returns
-------
`Path`
Path to the directory as a pathlib.Path object.
"""
path = Path(path)
if not path.exists():
raise argparse.ArgumentTypeError(f"Directory {path} doesn't exist")
if not path.is_dir():
raise argparse.ArgumentTypeError(f"{path} is not a valid directory.")
return path
def perform_scan(args: argparse.Namespace) -> None:
"""
Function containing logic of the command-line interface execution.
FUnction is responsible for starting scanning and saving the created report.
Parameters
----------
args: `argparse.Namespace`
Parsed arguments from command-line interface.
Raises
------
argparse.ArgumentTypeError
Raises if validation of the parameters fails.
"""
if (not any([args.input, args.auto_collect])) or all([args.input, args.auto_collect]):
raise argparse.ArgumentTypeError(
"Arguments input and auto_collect are alternatives. Only exactly one from them must be provided."
)
if args.input and any([args.phish_stats, args.open_phish]):
raise argparse.ArgumentTypeError("Source of the data can be declared only in auto collect mode.")
auto_collection_method = None
if args.phish_stats:
auto_collection_method = "get_urls_phishstats"
elif args.open_phish:
auto_collection_method = "get_urls_openphish"
if all([args.phish_stats, args.open_phish]) or not any([args.phish_stats, args.open_phish]):
auto_collection_method = "get_urls"
urls = args.input or getattr(DataCollector(), auto_collection_method)(args.auto_collect)
print("Start scanning...")
detector = Detector(args.chrome_safebrowsing_enabled)
start_time = datetime.now()
report = detector.scan(urls).to_dict()
results_dir = args.results_dir or Path(__file__).resolve().parents[0] / "results"
results_dir.mkdir(exist_ok=True)
report_name = start_time.strftime("%Y_%m_%d_%H_%M_%S_%f_phishing_scan_report.json")
report_path = results_dir / report_name
with open(report_path, "w") as file:
json.dump(report, file, indent=2)
print(f"Scanning finished. The report file stored in {report_path}.")
def argparse_config() -> argparse.Namespace:
"""
Parses arguments passed through the command-line interface.
Returns
-------
`argparse.Namespace`
Namespace containing required arguments.
"""
parser = argparse.ArgumentParser(
description="CLI client for Phishing-detector application. It allows to scan the URLs against phishing using"
"several available detector engines."
)
parser.add_argument("--input", type=str, action="extend", nargs="+", help="User defined URLs to be scanned.")
parser.add_argument(
"--auto-collect", type=int, help="Number of URLs to be automatically collected from the open sources."
)
parser.add_argument(
"--open-phish", action="store_true", help="Determines OpenPhish as a automatically collected data source."
)
parser.add_argument(
"--phish-stats", action="store_true", help="Determines PhishStats as a automatically collected data source."
)
parser.add_argument(
"--chrome-safebrowsing-enabled", action="store_true", help="Activates Chrome Safe Browser Scanning."
)
parser.add_argument(
"-r", "--results-dir", type=validate_dir, help="Path to the directory for saving the scan report."
)
return parser.parse_args()
def cli() -> None:
"""
CLI main method containing argument parsing and calling the CLI logic execution.
"""
args = argparse_config()
perform_scan(args)
if __name__ == "__main__":
cli()