Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sundowndev
GitHub Repository: sundowndev/phoneinfoga
Path: blob/master/web/v2/api/handlers/scanners.go
994 views
1
package handlers
2
3
import (
4
"github.com/gin-gonic/gin"
5
"github.com/sundowndev/phoneinfoga/v2/lib/number"
6
"github.com/sundowndev/phoneinfoga/v2/lib/remote"
7
"github.com/sundowndev/phoneinfoga/v2/web/v2/api"
8
"net/http"
9
)
10
11
type Scanner struct {
12
Name string `json:"name"`
13
Description string `json:"description"`
14
}
15
16
type GetAllScannersResponse struct {
17
Scanners []Scanner `json:"scanners"`
18
}
19
20
// GetAllScanners is an HTTP handler
21
// @ID GetAllScanners
22
// @Tags Numbers
23
// @Summary Get all available scanners.
24
// @Description This route returns all available scanners.
25
// @Produce json
26
// @Success 200 {object} GetAllScannersResponse
27
// @Router /v2/scanners [get]
28
func GetAllScanners(*gin.Context) *api.Response {
29
var scanners []Scanner
30
for _, s := range RemoteLibrary.GetAllScanners() {
31
scanners = append(scanners, Scanner{
32
Name: s.Name(),
33
Description: s.Description(),
34
})
35
}
36
37
return &api.Response{
38
Code: http.StatusOK,
39
JSON: true,
40
Data: GetAllScannersResponse{
41
Scanners: scanners,
42
},
43
}
44
}
45
46
type DryRunScannerInput struct {
47
Number string `json:"number" binding:"number,required"`
48
Options remote.ScannerOptions `json:"options" validate:"dive,required"`
49
}
50
51
type DryRunScannerResponse struct {
52
Success bool `json:"success"`
53
Error string `json:"error,omitempty"`
54
}
55
56
// DryRunScanner is an HTTP handler
57
// @ID DryRunScanner
58
// @Tags Numbers
59
// @Summary Dry run a single scanner
60
// @Description This route performs a dry run with the given phone number. This doesn't perform an actual scan.
61
// @Accept json
62
// @Produce json
63
// @Param request body DryRunScannerInput true "Request body"
64
// @Success 200 {object} DryRunScannerResponse
65
// @Success 404 {object} api.ErrorResponse
66
// @Success 500 {object} api.ErrorResponse
67
// @Router /v2/scanners/{scanner}/dryrun [post]
68
// @Param scanner path string true "Scanner name" validate(required)
69
func DryRunScanner(ctx *gin.Context) *api.Response {
70
var input DryRunScannerInput
71
if err := ctx.ShouldBindJSON(&input); err != nil {
72
return &api.Response{
73
Code: http.StatusBadRequest,
74
JSON: true,
75
Data: api.ErrorResponse{Error: "Invalid phone number: please provide an integer without any special chars"},
76
}
77
}
78
79
if input.Options == nil {
80
input.Options = make(remote.ScannerOptions)
81
}
82
83
scanner := RemoteLibrary.GetScanner(ctx.Param("scanner"))
84
if scanner == nil {
85
return &api.Response{
86
Code: http.StatusNotFound,
87
JSON: true,
88
Data: api.ErrorResponse{Error: "Scanner not found"},
89
}
90
}
91
92
num, err := number.NewNumber(input.Number)
93
if err != nil {
94
return &api.Response{
95
Code: http.StatusBadRequest,
96
JSON: true,
97
Data: api.ErrorResponse{Error: err.Error()},
98
}
99
}
100
101
err = scanner.DryRun(*num, input.Options)
102
if err != nil {
103
return &api.Response{
104
Code: http.StatusBadRequest,
105
JSON: true,
106
Data: DryRunScannerResponse{
107
Success: false,
108
Error: err.Error(),
109
},
110
}
111
}
112
113
return &api.Response{
114
Code: http.StatusOK,
115
JSON: true,
116
Data: DryRunScannerResponse{
117
Success: true,
118
},
119
}
120
}
121
122
type RunScannerInput struct {
123
Number string `json:"number" binding:"number,required"`
124
Options remote.ScannerOptions `json:"options" validate:"dive,required"`
125
}
126
127
type RunScannerResponse struct {
128
Result interface{} `json:"result"`
129
}
130
131
// RunScanner is an HTTP handler
132
// @ID RunScanner
133
// @Tags Numbers
134
// @Summary Run a single scanner
135
// @Description This route runs a single scanner with the given phone number
136
// @Accept json
137
// @Produce json
138
// @Param request body RunScannerInput true "Request body"
139
// @Success 200 {object} RunScannerResponse
140
// @Success 404 {object} api.ErrorResponse
141
// @Success 500 {object} api.ErrorResponse
142
// @Router /v2/scanners/{scanner}/run [post]
143
// @Param scanner path string true "Scanner name" validate(required)
144
func RunScanner(ctx *gin.Context) *api.Response {
145
var input RunScannerInput
146
if err := ctx.ShouldBindJSON(&input); err != nil {
147
return &api.Response{
148
Code: http.StatusBadRequest,
149
JSON: true,
150
Data: api.ErrorResponse{Error: "Invalid phone number: please provide an integer without any special chars"},
151
}
152
}
153
154
if input.Options == nil {
155
input.Options = make(remote.ScannerOptions)
156
}
157
158
scanner := RemoteLibrary.GetScanner(ctx.Param("scanner"))
159
if scanner == nil {
160
return &api.Response{
161
Code: http.StatusNotFound,
162
JSON: true,
163
Data: api.ErrorResponse{Error: "Scanner not found"},
164
}
165
}
166
167
num, err := number.NewNumber(input.Number)
168
if err != nil {
169
return &api.Response{
170
Code: http.StatusBadRequest,
171
JSON: true,
172
Data: api.ErrorResponse{Error: err.Error()},
173
}
174
}
175
176
result, err := scanner.Run(*num, input.Options)
177
if err != nil {
178
return &api.Response{
179
Code: http.StatusInternalServerError,
180
JSON: true,
181
Data: api.ErrorResponse{Error: err.Error()},
182
}
183
}
184
185
return &api.Response{
186
Code: http.StatusOK,
187
JSON: true,
188
Data: RunScannerResponse{
189
Result: result,
190
},
191
}
192
}
193
194