Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sherlock-project
GitHub Repository: sherlock-project/sherlock
Path: blob/master/sherlock_project/notify.py
761 views
1
"""Sherlock Notify Module
2
3
This module defines the objects for notifying the caller about the
4
results of queries.
5
"""
6
from sherlock_project.result import QueryStatus
7
from colorama import Fore, Style
8
import webbrowser
9
10
# Global variable to count the number of results.
11
globvar = 0
12
13
14
class QueryNotify:
15
"""Query Notify Object.
16
17
Base class that describes methods available to notify the results of
18
a query.
19
It is intended that other classes inherit from this base class and
20
override the methods to implement specific functionality.
21
"""
22
23
def __init__(self, result=None):
24
"""Create Query Notify Object.
25
26
Contains information about a specific method of notifying the results
27
of a query.
28
29
Keyword Arguments:
30
self -- This object.
31
result -- Object of type QueryResult() containing
32
results for this query.
33
34
Return Value:
35
Nothing.
36
"""
37
38
self.result = result
39
40
41
def start(self, message=None):
42
"""Notify Start.
43
44
Notify method for start of query. This method will be called before
45
any queries are performed. This method will typically be
46
overridden by higher level classes that will inherit from it.
47
48
Keyword Arguments:
49
self -- This object.
50
message -- Object that is used to give context to start
51
of query.
52
Default is None.
53
54
Return Value:
55
Nothing.
56
"""
57
58
59
def update(self, result):
60
"""Notify Update.
61
62
Notify method for query result. This method will typically be
63
overridden by higher level classes that will inherit from it.
64
65
Keyword Arguments:
66
self -- This object.
67
result -- Object of type QueryResult() containing
68
results for this query.
69
70
Return Value:
71
Nothing.
72
"""
73
74
self.result = result
75
76
77
def finish(self, message=None):
78
"""Notify Finish.
79
80
Notify method for finish of query. This method will be called after
81
all queries have been performed. This method will typically be
82
overridden by higher level classes that will inherit from it.
83
84
Keyword Arguments:
85
self -- This object.
86
message -- Object that is used to give context to start
87
of query.
88
Default is None.
89
90
Return Value:
91
Nothing.
92
"""
93
94
95
def __str__(self):
96
"""Convert Object To String.
97
98
Keyword Arguments:
99
self -- This object.
100
101
Return Value:
102
Nicely formatted string to get information about this object.
103
"""
104
return str(self.result)
105
106
107
class QueryNotifyPrint(QueryNotify):
108
"""Query Notify Print Object.
109
110
Query notify class that prints results.
111
"""
112
113
def __init__(self, result=None, verbose=False, print_all=False, browse=False):
114
"""Create Query Notify Print Object.
115
116
Contains information about a specific method of notifying the results
117
of a query.
118
119
Keyword Arguments:
120
self -- This object.
121
result -- Object of type QueryResult() containing
122
results for this query.
123
verbose -- Boolean indicating whether to give verbose output.
124
print_all -- Boolean indicating whether to only print all sites, including not found.
125
browse -- Boolean indicating whether to open found sites in a web browser.
126
127
Return Value:
128
Nothing.
129
"""
130
131
super().__init__(result)
132
self.verbose = verbose
133
self.print_all = print_all
134
self.browse = browse
135
136
137
def start(self, message):
138
"""Notify Start.
139
140
Will print the title to the standard output.
141
142
Keyword Arguments:
143
self -- This object.
144
message -- String containing username that the series
145
of queries are about.
146
147
Return Value:
148
Nothing.
149
"""
150
151
title = "Checking username"
152
153
print(Style.BRIGHT + Fore.GREEN + "[" +
154
Fore.YELLOW + "*" +
155
Fore.GREEN + f"] {title}" +
156
Fore.WHITE + f" {message}" +
157
Fore.GREEN + " on:")
158
# An empty line between first line and the result(more clear output)
159
print('\r')
160
161
162
def countResults(self):
163
"""This function counts the number of results. Every time the function is called,
164
the number of results is increasing.
165
166
Keyword Arguments:
167
self -- This object.
168
169
Return Value:
170
The number of results by the time we call the function.
171
"""
172
global globvar
173
globvar += 1
174
return globvar
175
176
def update(self, result):
177
"""Notify Update.
178
179
Will print the query result to the standard output.
180
181
Keyword Arguments:
182
self -- This object.
183
result -- Object of type QueryResult() containing
184
results for this query.
185
186
Return Value:
187
Nothing.
188
"""
189
self.result = result
190
191
response_time_text = ""
192
if self.result.query_time is not None and self.verbose is True:
193
response_time_text = f" [{round(self.result.query_time * 1000)}ms]"
194
195
# Output to the terminal is desired.
196
if result.status == QueryStatus.CLAIMED:
197
self.countResults()
198
print(Style.BRIGHT + Fore.WHITE + "[" +
199
Fore.GREEN + "+" +
200
Fore.WHITE + "]" +
201
response_time_text +
202
Fore.GREEN +
203
f" {self.result.site_name}: " +
204
Style.RESET_ALL +
205
f"{self.result.site_url_user}")
206
if self.browse:
207
webbrowser.open(self.result.site_url_user, 2)
208
209
elif result.status == QueryStatus.AVAILABLE:
210
if self.print_all:
211
print(Style.BRIGHT + Fore.WHITE + "[" +
212
Fore.RED + "-" +
213
Fore.WHITE + "]" +
214
response_time_text +
215
Fore.GREEN + f" {self.result.site_name}:" +
216
Fore.YELLOW + " Not Found!")
217
218
elif result.status == QueryStatus.UNKNOWN:
219
if self.print_all:
220
print(Style.BRIGHT + Fore.WHITE + "[" +
221
Fore.RED + "-" +
222
Fore.WHITE + "]" +
223
Fore.GREEN + f" {self.result.site_name}:" +
224
Fore.RED + f" {self.result.context}" +
225
Fore.YELLOW + " ")
226
227
elif result.status == QueryStatus.ILLEGAL:
228
if self.print_all:
229
msg = "Illegal Username Format For This Site!"
230
print(Style.BRIGHT + Fore.WHITE + "[" +
231
Fore.RED + "-" +
232
Fore.WHITE + "]" +
233
Fore.GREEN + f" {self.result.site_name}:" +
234
Fore.YELLOW + f" {msg}")
235
236
elif result.status == QueryStatus.WAF:
237
if self.print_all:
238
print(Style.BRIGHT + Fore.WHITE + "[" +
239
Fore.RED + "-" +
240
Fore.WHITE + "]" +
241
Fore.GREEN + f" {self.result.site_name}:" +
242
Fore.RED + " Blocked by bot detection" +
243
Fore.YELLOW + " (proxy may help)")
244
245
else:
246
# It should be impossible to ever get here...
247
raise ValueError(
248
f"Unknown Query Status '{result.status}' for site '{self.result.site_name}'"
249
)
250
251
252
def finish(self, message="The processing has been finished."):
253
"""Notify Finish.
254
Will print the last line to the standard output.
255
Keyword Arguments:
256
self -- This object.
257
message -- The 2 last phrases.
258
Return Value:
259
Nothing.
260
"""
261
NumberOfResults = self.countResults() - 1
262
263
print(Style.BRIGHT + Fore.GREEN + "[" +
264
Fore.YELLOW + "*" +
265
Fore.GREEN + "] Search completed with" +
266
Fore.WHITE + f" {NumberOfResults} " +
267
Fore.GREEN + "results" + Style.RESET_ALL
268
)
269
270
def __str__(self):
271
"""Convert Object To String.
272
273
Keyword Arguments:
274
self -- This object.
275
276
Return Value:
277
Nicely formatted string to get information about this object.
278
"""
279
return str(self.result)
280
281