From 4629f39e998882516193954afc85b063e5719f7d Mon Sep 17 00:00:00 2001 From: Jackson Date: Mon, 27 Nov 2023 14:55:45 +0100 Subject: [PATCH] implement admin form to change a user's password --- admin/admin.go | 43 +++++++++++++++++++++++++++++++++++++++ admin/view.go | 5 +++++ admin/view_edit_user.html | 20 ++++++++++++++++++ 3 files changed, 68 insertions(+) diff --git a/admin/admin.go b/admin/admin.go index ef05f05..ef5ac3d 100644 --- a/admin/admin.go +++ b/admin/admin.go @@ -93,6 +93,49 @@ func handlerAdminUserEdit(w http.ResponseWriter, rq *http.Request) { viewEditUser(viewutil.MetaFrom(w, rq), f, u) } +func handlerAdminUserChangePassword(w http.ResponseWriter, rq *http.Request) { + vars := mux.Vars(rq) + u := user.ByName(vars["username"]) + if u == nil { + util.HTTP404Page(w, "404 page not found") + return + } + + f := util.FormDataFromRequest(rq, []string{"password", "password_confirm"}) + + password := f.Get("password") + passwordConfirm := f.Get("password_confirm") + // server side validation + if password == "" { + err := fmt.Errorf("passwords should not be empty") + f = f.WithError(err) + } + if password == passwordConfirm { + previousPassword := u.Password // for rollback + if err := u.ChangePassword(password); err != nil { + f = f.WithError(err) + } else { + if err := user.SaveUserDatabase(); err != nil { + u.Password = previousPassword + f = f.WithError(err) + } else { + http.Redirect(w, rq, "/admin/users/", http.StatusSeeOther) + return + } + } + } else { + err := fmt.Errorf("passwords do not match") + f = f.WithError(err) + } + + if f.HasError() { + w.WriteHeader(http.StatusBadRequest) + } + w.Header().Set("Content-Type", mime.TypeByExtension(".html")) + + viewEditUser(viewutil.MetaFrom(w, rq), f, u) +} + func handlerAdminUserDelete(w http.ResponseWriter, rq *http.Request) { vars := mux.Vars(rq) u := user.ByName(vars["username"]) diff --git a/admin/view.go b/admin/view.go index d3ce063..e7537c9 100644 --- a/admin/view.go +++ b/admin/view.go @@ -10,6 +10,7 @@ import ( "net/http" ) +// TODO: translate some untranslated strings const adminTranslationRu = ` {{define "panel title"}}Панель админстратора{{end}} {{define "panel safe section title"}}Безопасная секция{{end}} @@ -33,6 +34,9 @@ const adminTranslationRu = ` {{define "new user"}}Новый пользователь{{end}} {{define "password"}}Пароль{{end}} +{{define "confirm password"}}Confirm password{{end}} +{{define "change password"}}Change password{{end}} +{{define "non local password change"}}Non-local accounts cannot have their passwords changed.{{end}} {{define "create"}}Создать{{end}} {{define "change group"}}Изменить группу{{end}} @@ -57,6 +61,7 @@ func Init(rtr *mux.Router) { rtr.HandleFunc("/new-user", handlerAdminUserNew).Methods(http.MethodGet, http.MethodPost) rtr.HandleFunc("/users/{username}/edit", handlerAdminUserEdit).Methods(http.MethodGet, http.MethodPost) + rtr.HandleFunc("/users/{username}/change-password", handlerAdminUserChangePassword).Methods(http.MethodPost) rtr.HandleFunc("/users/{username}/delete", handlerAdminUserDelete).Methods(http.MethodGet, http.MethodPost) rtr.HandleFunc("/users", handlerAdminUsers) diff --git a/admin/view_edit_user.html b/admin/view_edit_user.html index c6d6993..63d99f4 100644 --- a/admin/view_edit_user.html +++ b/admin/view_edit_user.html @@ -33,6 +33,26 @@ +

{{block "change password" .}}Change password{{end}}

+ + {{if eq .U.Source "local"}} +
+
+ + +
+ + +
+ +
+ +
+
+ {{else}} +

{{block "non local password change" .}}Non-local accounts cannot have their passwords changed.{{end}}

+ {{end}} +

{{block "delete user" .}}Delete user{{end}}

{{block "delete user tip" .}}Remove the user from the database. Changes made by the user will be preserved. It will be possible to take this username later.{{end}}

{{template "delete"}}