chldapasswd/reset.go
Pierre-Olivier Mercier 439dc2cd07 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 <noreply@anthropic.com>
2026-03-08 11:48:34 +07:00

93 lines
2.6 KiB
Go

package main
import (
"log"
"net/http"
)
func resetPassword(w http.ResponseWriter, r *http.Request) {
if r.Method == "POST" && !resetLimiter.Allow(remoteIP(r)) {
http.Error(w, "Too many requests. Please try again later.", http.StatusTooManyRequests)
return
}
if len(r.URL.Query().Get("l")) == 0 || len(r.URL.Query().Get("t")) == 0 {
http.Redirect(w, r, "lost", http.StatusFound)
return
}
base := map[string]any{
"login": r.URL.Query().Get("l"),
"token": r.URL.Query().Get("t"),
}
if r.Method != "POST" {
csrfToken, err := setCSRFToken(w)
if err != nil {
http.Error(w, "Internal server error", http.StatusInternalServerError)
return
}
base["csrf_token"] = csrfToken
displayTmpl(w, "reset.html", base)
return
}
renderError := func(status int, msg string) {
csrfToken, _ := setCSRFToken(w)
base["error"] = msg
base["csrf_token"] = csrfToken
displayTmplError(w, status, "reset.html", base)
}
if !validateCSRF(r) {
renderError(http.StatusForbidden, "Invalid or missing CSRF token. Please try again.")
return
}
if !validateAltcha(r) {
renderError(http.StatusForbidden, "Invalid or missing altcha response. Please try again.")
return
}
// Check the two new passwords are identical
if r.PostFormValue("newpassword") != r.PostFormValue("new2password") {
renderError(http.StatusNotAcceptable, "New passwords are not identical. Please retry.")
return
} else if err := checkPasswdConstraint(r.PostFormValue("newpassword")); err != nil {
renderError(http.StatusNotAcceptable, "The password you chose doesn't respect all constraints: "+err.Error())
return
}
// Validate and consume the token (single-use, server-side)
token := r.PostFormValue("token")
dn, ok := consumeResetToken(token)
if !ok {
renderError(http.StatusNotAcceptable, "Token invalid or expired, please retry the lost password procedure. Tokens expire after 1 hour.")
return
}
// Connect to the LDAP server
conn, err := myLDAP.Connect()
if err != nil || conn == nil {
log.Println(err)
renderError(http.StatusInternalServerError, "Unable to process your request. Please try again later.")
return
}
// Bind as service to perform the password change
err = conn.ServiceBind()
if err != nil {
log.Println(err)
renderError(http.StatusInternalServerError, "Unable to process your request. Please try again later.")
return
}
// Replace the password by the new given
if err := conn.ChangePassword(dn, r.PostFormValue("newpassword")); err != nil {
log.Println(err)
renderError(http.StatusInternalServerError, "Unable to process your request. Please try again later.")
return
}
displayMsg(w, "Password successfully changed!", http.StatusOK)
}