-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.go
194 lines (176 loc) · 5.5 KB
/
main.go
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
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
package main
import (
"encoding/json"
"fmt"
"io"
"log/slog"
"net/http"
"os"
"regexp"
"strconv"
"strings"
"time"
)
type EzpaarseLog struct {
Date string `json:"date"`
Datetime string `json:"datetime"`
Domain string `json:"domain"`
City string `json:"geoip-city"`
Coordinates string `json:"geoip-coordinates"`
Country string `json:"geoip-country"`
Latitude string `json:"geoip-latitude"`
Longitude string `json:"geoip-longitude"`
Region string `json:"geoip-region"`
Host string `json:"host"`
Identd string `json:"identd"`
LogID string `json:"log_id"`
Login string `json:"login"`
Middlewares string `json:"middlewares"`
MiddlewaresDate string `json:"middlewares_date"`
MiddlewaresVersion string `json:"middlewares_version"`
OnCampus string `json:"on_campus"`
Platform string `json:"platform"`
PlatformName string `json:"platform_name"`
PlatformsDate string `json:"platforms_date"`
PlatformsVersion string `json:"platforms_version"`
PublisherName string `json:"publisher_name"`
Robot string `json:"robot"`
Size string `json:"size"`
Status string `json:"status"`
Timestamp int `json:"timestamp"`
URL string `json:"url"`
}
type Quicksight struct {
Date string `json:"date"`
Domain string `json:"domain"`
City string `json:"city"`
Country string `json:"country"`
Latitude string `json:"lat"`
Longitude string `json:"lng"`
Region string `json:"region"`
Platform string `json:"platform"`
PlatformName string `json:"platform_name"`
PublisherName string `json:"publisher_name"`
Department string `json:"department"`
Role string `json:"role"`
}
// Function to check if a file exists
func fileExists(filename string) bool {
_, err := os.Stat(filename)
return !os.IsNotExist(err)
}
// Function to save the response body to a file
func saveToFile(filename string, data io.Reader) error {
file, err := os.Create(filename)
if err != nil {
return err
}
defer file.Close()
_, err = io.Copy(file, data)
return err
}
// Function to extract description
func extractDescription(filename string) (string, string, error) {
data, err := os.ReadFile(filename)
if err != nil {
return "", "", err
}
// Use regex to capture everything in the second <td> tag
re := regexp.MustCompile(`<tr><td>Description</td><td>([^<]+)</td></tr>`)
matches := re.FindStringSubmatch(string(data))
if len(matches) < 2 {
return "", "", fmt.Errorf("description not found")
}
// Now, we have everything inside the second <td>
fullDescription := matches[1]
// Try to split it on " - " to separate category and description
parts := strings.SplitN(fullDescription, " - ", 2)
category := parts[0]
description := "unknown"
if len(parts) == 2 {
description = parts[1]
}
return category, description, nil
}
func main() {
ldapSearchServer := os.Getenv("LDAP_SEARCH_SERVER")
file, err := os.Open("logs/ezpaarse.json")
if err != nil {
slog.Error("Failed to open ezpaarse JSON. Did you run process.sh?", "err", err)
os.Exit(1)
}
defer file.Close()
// Decode the JSON file into a slice of EzpaarseLog
var logs []EzpaarseLog
if err := json.NewDecoder(file).Decode(&logs); err != nil {
slog.Error("Failed to decode JSON", "err", err)
os.Exit(1)
}
// Iterate over the logs and print some fields
visitors := []Quicksight{}
for _, log := range logs {
visitor := Quicksight{
Date: log.Date,
Domain: log.Domain,
City: log.City,
Country: log.Country,
Region: log.Region,
Platform: log.Platform,
PlatformName: log.PlatformName,
PublisherName: log.PublisherName,
}
lat, err := strconv.ParseFloat(log.Latitude, 64)
if err != nil {
slog.Warn("Error converting string to float", "err", err, "lng", log.Latitude)
continue
}
lng, err := strconv.ParseFloat(log.Longitude, 64)
if err != nil {
slog.Warn("Error converting string to float", "err", err, "lat", log.Latitude)
continue
}
visitor.Latitude = fmt.Sprintf("%.6f", lat)
visitor.Longitude = fmt.Sprintf("%.6f", lng)
email := fmt.Sprintf("%[email protected]", strings.ToLower(log.Login))
filename := fmt.Sprintf("/tmp/%s.html", log.Login)
// Check if the file already exists
if !fileExists(filename) {
slog.Info("Querying LDAP")
// If not, make the HTTP POST request
resp, err := http.PostForm(ldapSearchServer, map[string][]string{
"cn": {email},
})
if err != nil {
slog.Error("Error making request", "err", err)
return
}
defer resp.Body.Close()
// Save response to STR.html
err = saveToFile(filename, resp.Body)
if err != nil {
slog.Error("Error saving file", "err", err)
return
}
time.Sleep(2 * time.Second)
}
// Extract and parse the description
role, department, err := extractDescription(filename)
if err != nil {
slog.Warn("Error extracting description", "login", log.Login, "err", err)
}
// Output the extracted values
visitor.Department = department
visitor.Role = role
visitors = append(visitors, visitor)
}
f, err := os.Create("ezproxy.json")
if err != nil {
slog.Error("failed to create ezproxy JSON", "err", err)
}
defer f.Close()
// Marshal the logs slice into JSON
encoder := json.NewEncoder(f)
if err := encoder.Encode(visitors); err != nil {
slog.Error("failed to encode JSON", "err", err)
}
}