feat: add user password management

This commit is contained in:
OpenClaw Agent
2026-09-22 01:20:24 +08:00
parent 77572e610b
commit eafc6c6499
3 changed files with 74 additions and 4 deletions
+55 -1
View File
@@ -77,6 +77,7 @@ func (s *Server) Handler() http.Handler {
mux.HandleFunc("/chfs/session", s.session)
mux.HandleFunc("/chfs/me", s.me)
mux.HandleFunc("/chfs/users", s.users)
mux.HandleFunc("/chfs/password", s.password)
mux.HandleFunc("/chfs/newtext", s.newtext)
mux.HandleFunc("/chfs/updatetext", s.updatetext)
mux.HandleFunc("/chfs/upload", s.upload)
@@ -464,7 +465,41 @@ func (s *Server) me(w http.ResponseWriter, r *http.Request) {
writeJSONError(w, http.StatusUnauthorized, "not authenticated")
return
}
writeJSON(w, map[string]any{"username": a.Username, "home": a.Home, "admin": a.Admin, "mask": permString(a.MaskFor(a.Home))})
writeJSON(w, map[string]any{"username": a.Username, "home": a.Home, "admin": a.Admin, "mask": permString(a.MaskFor(a.Home)), "managed": a.PasswordHash != ""})
}
func (s *Server) password(w http.ResponseWriter, r *http.Request) {
a := account(r, s)
if a == nil || a.Username == "" {
writeJSONError(w, http.StatusUnauthorized, "not authenticated")
return
}
if r.Method != http.MethodPost {
w.WriteHeader(http.StatusMethodNotAllowed)
return
}
var req struct {
CurrentPassword string `json:"currentPassword"`
Password string `json:"password"`
}
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
writeJSONError(w, http.StatusBadRequest, "invalid json")
return
}
if a.Password != req.CurrentPassword && a.PasswordHash != auth.PasswordHash(req.CurrentPassword) {
writeJSONError(w, http.StatusBadRequest, "current password incorrect")
return
}
if s.UserStore == nil {
writeJSONError(w, http.StatusNotImplemented, "user management disabled")
return
}
if err := s.UserStore.UpdatePassword(s.Auth, a.Username, req.Password); err != nil {
writeJSONError(w, http.StatusBadRequest, err.Error())
return
}
s.logOp(r, "changed password")
writeJSON(w, map[string]any{"ok": true})
}
func (s *Server) users(w http.ResponseWriter, r *http.Request) {
@@ -513,6 +548,25 @@ func (s *Server) users(w http.ResponseWriter, r *http.Request) {
}
s.logOp(r, fmt.Sprintf("created user '%s'", u.Username))
writeJSON(w, map[string]any{"username": u.Username, "home": u.Home})
case http.MethodPut:
var req struct {
Username string `json:"username"`
Password string `json:"password"`
}
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
writeJSONError(w, http.StatusBadRequest, "invalid json")
return
}
if err := auth.ValidateUsername(req.Username); err != nil {
writeJSONError(w, http.StatusBadRequest, "invalid username")
return
}
if err := s.UserStore.UpdatePassword(s.Auth, req.Username, req.Password); err != nil {
writeJSONError(w, http.StatusBadRequest, err.Error())
return
}
s.logOp(r, fmt.Sprintf("reset password for '%s'", req.Username))
writeJSON(w, map[string]any{"ok": true})
case http.MethodDelete:
username := r.URL.Query().Get("username")
if err := auth.ValidateUsername(username); err != nil {