diff options
Diffstat (limited to 'internal/api')
-rw-r--r-- | internal/api/handlers.go | 110 |
1 files changed, 110 insertions, 0 deletions
diff --git a/internal/api/handlers.go b/internal/api/handlers.go new file mode 100644 index 0000000..8d328a6 --- /dev/null +++ b/internal/api/handlers.go @@ -0,0 +1,110 @@ +package api + +import ( + "encoding/json" + "fmt" + "io" + "net/http" + "net" + "strings" + "regexp" + "time" +) + +var fs http.Handler + +func init() { + fs = http.FileServer(http.Dir("static")) +} + +const log_length = 100 + +type accessLog struct { + ClientAddr string `json:"clientAddr"` + RequestedPath string `json:"requestedPath"` + RequestTime time.Time `json:"requestTime"` + HttpMethod string `json:"httpMethod"` +} + +func CreateFilesHandler(logs *[log_length]string, n *int, logChan chan string) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + jsonData, _ := json.Marshal(accessLog{ + ClientAddr: redactIP(r.RemoteAddr), + RequestedPath: r.URL.Path, + RequestTime: time.Now().UTC(), + HttpMethod: r.Method, + }) + addRotLog(logs, n, logChan, string(jsonData)) + // Serve the index.html file from the static directory + http.StripPrefix("/", fs).ServeHTTP(w, r) + } +} + +func CreateGetLogs(logs *[log_length]string) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + for _, s := range logs { + fmt.Fprintln(w, s) + } + } +} + +func CreateLoginHandler(logs *[log_length]string, n *int, logChan chan string) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + body, err := io.ReadAll(r.Body) + if err != nil { + http.Error(w, "Bad Request", http.StatusBadRequest) + return + } + defer r.Body.Close() + + var data map[string]any + if json.Unmarshal(body, &data) != nil { + addRotLog(logs, n, logChan, fmt.Sprintf(`{"authRequest": %s}`, string(body))) + http.Error(w, "Forbidden", http.StatusForbidden) + return + } + + if email, ok := data["email"].(string); ok { + if rememberMe, ok := data["rememberMe"].(bool); ok { + addRotLog(logs, n, logChan, fmt.Sprintf(`{"authRequest": {"email": "%s", "password": "XXXXXXXX", "loginTime": "%s", "success": false, "rememberMe": %t}}`, email, time.Now().UTC(), rememberMe)) + } + } + http.Error(w, "Forbidden", http.StatusForbidden) + } +} + +func redactIP(input string) string { + ipRegex := `\b(?:\d{1,3}\.){3}\d{1,3}\b` + re := regexp.MustCompile(ipRegex) + + return re.ReplaceAllStringFunc(input, func(match string) string { + if ip := net.ParseIP(match); ip != nil { + parts := strings.Split(match, ".") + if len(parts) == 4 { + parts[3] = "XXX" + return strings.Join(parts, ".") + } + } + return match + }) +} + +func addRotLog(logs *[log_length]string, last *int, parser chan string, value string) { + if strings.Contains(value, "\n") { + for _, v := range strings.Split(value, "\n") { + addRotLog(logs, last, parser, v) + } + } else { + if *last == log_length { + for i := 0; i < log_length-1; i++ { + logs[i] = logs[i+1] + } + logs[log_length-1] = value + parser <- value + } else { + logs[*last] = value + *last++ + parser <- value + } + } +} |