66 lines
2.1 KiB
Go
66 lines
2.1 KiB
Go
package auth
|
|
|
|
import (
|
|
"encoding/json"
|
|
"net/http"
|
|
|
|
"gitea.perlbach24.de/scripte/nexarch/internal/user"
|
|
)
|
|
|
|
// ChangePasswordHandler stellt die Passwortaenderung fuer den bereits
|
|
// angemeldeten Benutzer bereit (IAM-08 Akzeptanzkriterium 2). Getrennt von
|
|
// Handler (Login/Logout), weil hier zusaetzlich der TenantUserStore fuer das
|
|
// Aktualisieren des Hashes gebraucht wird.
|
|
type ChangePasswordHandler struct {
|
|
users *user.TenantUserStore
|
|
}
|
|
|
|
func NewChangePasswordHandler(users *user.TenantUserStore) *ChangePasswordHandler {
|
|
return &ChangePasswordHandler{users: users}
|
|
}
|
|
|
|
type changePasswordRequest struct {
|
|
CurrentPassword string `json:"current_password"`
|
|
NewPassword string `json:"new_password"`
|
|
}
|
|
|
|
// ChangePassword verlangt das aktuelle Passwort, bevor ein neues gesetzt wird
|
|
// — ohne diese Pruefung koennte ein gekapertes, noch gueltiges Session-Cookie
|
|
// allein zur vollstaendigen Kontoübernahme reichen (Passwort setzen, alte
|
|
// Session unbrauchbar machen). Muss hinter RequireAuth haengen.
|
|
func (h *ChangePasswordHandler) ChangePassword(w http.ResponseWriter, r *http.Request) {
|
|
claims, ok := ClaimsFromContext(r.Context())
|
|
if !ok {
|
|
http.Error(w, "nicht angemeldet", http.StatusUnauthorized)
|
|
return
|
|
}
|
|
|
|
var req changePasswordRequest
|
|
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
|
|
http.Error(w, "ungueltige Anfrage", http.StatusBadRequest)
|
|
return
|
|
}
|
|
|
|
creds, err := h.users.GetByIDForAuth(r.Context(), claims.UserID)
|
|
if err != nil {
|
|
http.Error(w, "Aktuelles Passwort oder neues Passwort ungültig.", http.StatusBadRequest)
|
|
return
|
|
}
|
|
if !VerifyPassword(creds.PasswordHash, req.CurrentPassword) {
|
|
http.Error(w, "Aktuelles Passwort oder neues Passwort ungültig.", http.StatusBadRequest)
|
|
return
|
|
}
|
|
|
|
newHash, err := HashPassword(req.NewPassword)
|
|
if err != nil {
|
|
http.Error(w, "Aktuelles Passwort oder neues Passwort ungültig.", http.StatusBadRequest)
|
|
return
|
|
}
|
|
if err := h.users.SetPasswordHash(r.Context(), claims.UserID, newHash); err != nil {
|
|
http.Error(w, "Passwort konnte nicht gespeichert werden.", http.StatusInternalServerError)
|
|
return
|
|
}
|
|
|
|
w.WriteHeader(http.StatusOK)
|
|
}
|