package httpapp import ( "encoding/json" "log" "net/http" "strings" "gitea.avt.data-center.id/othman.suseno/atlas/internal/models" ) // handleUserOpsWithAuth routes user operations with auth func (a *App) handleUserOpsWithAuth(w http.ResponseWriter, r *http.Request) { if strings.HasSuffix(r.URL.Path, "/password") { // Password change endpoint (requires auth, can change own password) if r.Method == http.MethodPut { a.handleChangePassword(w, r) return } http.Error(w, "method not allowed", http.StatusMethodNotAllowed) return } // Regular user operations (admin-only) methodHandler( func(w http.ResponseWriter, r *http.Request) { a.requireRole(models.RoleAdministrator)(http.HandlerFunc(a.handleGetUser)).ServeHTTP(w, r) }, nil, func(w http.ResponseWriter, r *http.Request) { a.requireRole(models.RoleAdministrator)(http.HandlerFunc(a.handleUpdateUser)).ServeHTTP(w, r) }, func(w http.ResponseWriter, r *http.Request) { a.requireRole(models.RoleAdministrator)(http.HandlerFunc(a.handleDeleteUser)).ServeHTTP(w, r) }, nil, )(w, r) } // handleChangePassword allows users to change their own password func (a *App) handleChangePassword(w http.ResponseWriter, r *http.Request) { user, ok := getUserFromContext(r) if !ok { writeJSON(w, http.StatusUnauthorized, map[string]string{"error": "unauthorized"}) return } var req struct { OldPassword string `json:"old_password"` NewPassword string `json:"new_password"` } if err := json.NewDecoder(r.Body).Decode(&req); err != nil { writeJSON(w, http.StatusBadRequest, map[string]string{"error": "invalid request body"}) return } if req.NewPassword == "" { writeJSON(w, http.StatusBadRequest, map[string]string{"error": "new password is required"}) return } // Verify old password _, err := a.userStore.Authenticate(user.Username, req.OldPassword) if err != nil { writeJSON(w, http.StatusUnauthorized, map[string]string{"error": "invalid current password"}) return } // Update password if err := a.userStore.UpdatePassword(user.ID, req.NewPassword); err != nil { log.Printf("update password error: %v", err) writeJSON(w, http.StatusInternalServerError, map[string]string{"error": err.Error()}) return } writeJSON(w, http.StatusOK, map[string]string{"message": "password updated"}) }