From 439dc2cd07fdac27ed2e3c6230fd10c8b561b783 Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Sun, 8 Mar 2026 10:56:58 +0700 Subject: [PATCH] refactor: modernize Go idioms across codebase Replace map[string]interface{} with map[string]any, ioutil.ReadAll with io.ReadAll, and simplify redundant fmt.Sprintf/w.Write calls. Co-Authored-By: Claude Sonnet 4.6 --- addy.go | 10 ++-------- change.go | 10 +++++----- login.go | 12 ++++++------ lost.go | 14 +++++++------- main.go | 8 ++++---- reset.go | 2 +- static.go | 6 +++--- 7 files changed, 28 insertions(+), 34 deletions(-) diff --git a/addy.go b/addy.go index c2878e1..7a01e9a 100644 --- a/addy.go +++ b/addy.go @@ -12,6 +12,7 @@ import ( "log" "net/http" "os" + "slices" "strings" ) @@ -134,14 +135,7 @@ func addyAliasAPI(w http.ResponseWriter, r *http.Request) { http.Error(w, "Alias creation is not configured", http.StatusServiceUnavailable) return } - domainAllowed := false - for _, d := range allowedAliasDomains { - if body.Domain == d { - domainAllowed = true - break - } - } - if !domainAllowed { + if !slices.Contains(allowedAliasDomains, body.Domain) { http.Error(w, "Domain not allowed", http.StatusBadRequest) return } diff --git a/change.go b/change.go index 0a9e7e6..d915aba 100644 --- a/change.go +++ b/change.go @@ -33,7 +33,7 @@ func checkPasswdConstraint(password string) error { func changePassword(w http.ResponseWriter, r *http.Request) { if r.Method == "POST" && !changeLimiter.Allow(remoteIP(r)) { csrfToken, _ := setCSRFToken(w) - displayTmplError(w, http.StatusTooManyRequests, "change.html", map[string]interface{}{"error": "Too many requests. Please try again later.", "csrf_token": csrfToken}) + displayTmplError(w, http.StatusTooManyRequests, "change.html", map[string]any{"error": "Too many requests. Please try again later.", "csrf_token": csrfToken}) return } @@ -43,25 +43,25 @@ func changePassword(w http.ResponseWriter, r *http.Request) { http.Error(w, "Internal server error", http.StatusInternalServerError) return } - displayTmpl(w, "change.html", map[string]interface{}{"csrf_token": csrfToken}) + displayTmpl(w, "change.html", map[string]any{"csrf_token": csrfToken}) return } if !validateCSRF(r) { csrfToken, _ := setCSRFToken(w) - displayTmplError(w, http.StatusForbidden, "change.html", map[string]interface{}{"error": "Invalid or missing CSRF token. Please try again.", "csrf_token": csrfToken}) + displayTmplError(w, http.StatusForbidden, "change.html", map[string]any{"error": "Invalid or missing CSRF token. Please try again.", "csrf_token": csrfToken}) return } if !validateAltcha(r) { csrfToken, _ := setCSRFToken(w) - displayTmplError(w, http.StatusForbidden, "change.html", map[string]interface{}{"error": "Invalid or missing altcha response. Please try again.", "csrf_token": csrfToken}) + displayTmplError(w, http.StatusForbidden, "change.html", map[string]any{"error": "Invalid or missing altcha response. Please try again.", "csrf_token": csrfToken}) return } renderError := func(status int, msg string) { csrfToken, _ := setCSRFToken(w) - displayTmplError(w, status, "change.html", map[string]interface{}{"error": msg, "csrf_token": csrfToken}) + displayTmplError(w, status, "change.html", map[string]any{"error": msg, "csrf_token": csrfToken}) } // Check the two new passwords are identical diff --git a/login.go b/login.go index 44ffe66..af883d7 100644 --- a/login.go +++ b/login.go @@ -44,23 +44,23 @@ func login(login string, password string) ([]*ldap.EntryAttribute, error) { func tryLogin(w http.ResponseWriter, r *http.Request) { if r.Method != "POST" { - displayTmpl(w, "login.html", map[string]interface{}{}) + displayTmpl(w, "login.html", map[string]any{}) return } if !authLimiter.Allow(remoteIP(r)) { - displayTmplError(w, http.StatusTooManyRequests, "login.html", map[string]interface{}{"error": "Too many login attempts. Please try again later."}) + displayTmplError(w, http.StatusTooManyRequests, "login.html", map[string]any{"error": "Too many login attempts. Please try again later."}) return } if !validateAltcha(r) { - displayTmplError(w, http.StatusForbidden, "login.html", map[string]interface{}{"error": "Invalid or missing altcha response. Please try again."}) + displayTmplError(w, http.StatusForbidden, "login.html", map[string]any{"error": "Invalid or missing altcha response. Please try again."}) return } if entries, err := login(r.PostFormValue("login"), r.PostFormValue("password")); err != nil { log.Println(err) - displayTmplError(w, http.StatusInternalServerError, "login.html", map[string]interface{}{"error": err.Error()}) + displayTmplError(w, http.StatusInternalServerError, "login.html", map[string]any{"error": err.Error()}) } else { apiToken := AddyAPIToken(r.PostFormValue("login")) @@ -83,7 +83,7 @@ func tryLogin(w http.ResponseWriter, r *http.Request) { } } } - displayTmpl(w, "message.html", map[string]interface{}{"details": template.HTML(`Login ok

Here are the information we have about you:` + cnt + "

To use our Addy.io compatible API, use the following token: " + html.EscapeString(apiToken) + "

")}) + displayTmpl(w, "message.html", map[string]any{"details": template.HTML(`Login ok

Here are the information we have about you:` + cnt + "

To use our Addy.io compatible API, use the following token: " + html.EscapeString(apiToken) + "

")}) } } @@ -107,7 +107,7 @@ func httpBasicAuth(w http.ResponseWriter, r *http.Request) { for _, e := range entries { for _, v := range e.Values { if e.Name != "userPassword" { - w.Write([]byte(fmt.Sprintf("%s: %s", e.Name, v))) + fmt.Fprintf(w, "%s: %s", e.Name, v) } } } diff --git a/lost.go b/lost.go index 1e4c9d3..7afe093 100644 --- a/lost.go +++ b/lost.go @@ -88,7 +88,7 @@ func lostPasswordToken(conn *LDAPConn, login string) (string, string, error) { func lostPassword(w http.ResponseWriter, r *http.Request) { if r.Method == "POST" && !lostLimiter.Allow(remoteIP(r)) { - displayTmplError(w, http.StatusTooManyRequests, "lost.html", map[string]interface{}{"error": "Too many requests. Please try again later."}) + displayTmplError(w, http.StatusTooManyRequests, "lost.html", map[string]any{"error": "Too many requests. Please try again later."}) return } @@ -98,17 +98,17 @@ func lostPassword(w http.ResponseWriter, r *http.Request) { http.Error(w, "Internal server error", http.StatusInternalServerError) return } - displayTmpl(w, "lost.html", map[string]interface{}{"csrf_token": csrfToken}) + displayTmpl(w, "lost.html", map[string]any{"csrf_token": csrfToken}) return } if !validateCSRF(r) { - displayTmplError(w, http.StatusForbidden, "lost.html", map[string]interface{}{"error": "Invalid or missing CSRF token. Please try again."}) + displayTmplError(w, http.StatusForbidden, "lost.html", map[string]any{"error": "Invalid or missing CSRF token. Please try again."}) return } if !validateAltcha(r) { - displayTmplError(w, http.StatusForbidden, "lost.html", map[string]interface{}{"error": "Invalid or missing altcha response. Please try again."}) + displayTmplError(w, http.StatusForbidden, "lost.html", map[string]any{"error": "Invalid or missing altcha response. Please try again."}) return } @@ -116,7 +116,7 @@ func lostPassword(w http.ResponseWriter, r *http.Request) { conn, err := myLDAP.Connect() if err != nil || conn == nil { log.Println(err) - displayTmplError(w, http.StatusInternalServerError, "lost.html", map[string]interface{}{"error": "Unable to process your request. Please try again later."}) + displayTmplError(w, http.StatusInternalServerError, "lost.html", map[string]any{"error": "Unable to process your request. Please try again later."}) return } @@ -167,7 +167,7 @@ func lostPassword(w http.ResponseWriter, r *http.Request) { s, err = d.Dial() if err != nil { log.Println("Unable to connect to email server: " + err.Error()) - displayTmplError(w, http.StatusInternalServerError, "lost.html", map[string]interface{}{"error": "Unable to send password recovery email. Please try again later."}) + displayTmplError(w, http.StatusInternalServerError, "lost.html", map[string]any{"error": "Unable to send password recovery email. Please try again later."}) return } } else { @@ -202,7 +202,7 @@ func lostPassword(w http.ResponseWriter, r *http.Request) { if err := gomail.Send(s, m); err != nil { log.Println("Unable to send email: " + err.Error()) - displayTmplError(w, http.StatusInternalServerError, "lost.html", map[string]interface{}{"error": "Unable to send password recovery email. Please try again later."}) + displayTmplError(w, http.StatusInternalServerError, "lost.html", map[string]any{"error": "Unable to send password recovery email. Please try again later."}) return } diff --git a/main.go b/main.go index 36ab61d..42c2ef9 100644 --- a/main.go +++ b/main.go @@ -5,7 +5,7 @@ import ( "encoding/json" "flag" "fmt" - "io/ioutil" + "io" "log" "net/http" "net/url" @@ -104,7 +104,7 @@ func main() { if configfile != nil && *configfile != "" { if fd, err := os.Open(*configfile); err != nil { log.Fatal(err) - } else if cnt, err := ioutil.ReadAll(fd); err != nil { + } else if cnt, err := io.ReadAll(fd); err != nil { log.Fatal(err) } else if err := json.Unmarshal(cnt, &myLDAP); err != nil { log.Fatal(err) @@ -137,7 +137,7 @@ func main() { if val, ok := os.LookupEnv("LDAP_SERVICE_PASSWORD_FILE"); ok { if fd, err := os.Open(val); err != nil { log.Fatal(err) - } else if cnt, err := ioutil.ReadAll(fd); err != nil { + } else if cnt, err := io.ReadAll(fd); err != nil { log.Fatal(err) } else { myLDAP.ServicePassword = string(cnt) @@ -239,7 +239,7 @@ func main() { go func() { log.Fatal(srv.ListenAndServe()) }() - log.Println(fmt.Sprintf("Ready, listening on %s", *bind)) + log.Printf("Ready, listening on %s", *bind) // Wait shutdown signal <-interrupt diff --git a/reset.go b/reset.go index a37f99d..a65c27c 100644 --- a/reset.go +++ b/reset.go @@ -16,7 +16,7 @@ func resetPassword(w http.ResponseWriter, r *http.Request) { return } - base := map[string]interface{}{ + base := map[string]any{ "login": r.URL.Query().Get("l"), "token": r.URL.Query().Get("t"), } diff --git a/static.go b/static.go index aa8b8a2..7713995 100644 --- a/static.go +++ b/static.go @@ -23,7 +23,7 @@ func securityHeaders(next http.Handler) http.Handler { //go:embed all:static var assets embed.FS -func displayTmpl(w http.ResponseWriter, page string, vars map[string]interface{}) { +func displayTmpl(w http.ResponseWriter, page string, vars map[string]any) { data, err := assets.ReadFile("static/" + page) if err != nil { log.Fatalf("Unable to find %q: %s", page, err.Error()) @@ -45,7 +45,7 @@ func displayTmpl(w http.ResponseWriter, page string, vars map[string]interface{} tpl.ExecuteTemplate(w, "page", vars) } -func displayTmplError(w http.ResponseWriter, statusCode int, page string, vars map[string]interface{}) { +func displayTmplError(w http.ResponseWriter, statusCode int, page string, vars map[string]any) { w.WriteHeader(statusCode) displayTmpl(w, page, vars) } @@ -58,5 +58,5 @@ func displayMsg(w http.ResponseWriter, msg string, statusCode int) { label = "message" } - displayTmpl(w, "message.html", map[string]interface{}{label: msg}) + displayTmpl(w, "message.html", map[string]any{label: msg}) }