From fc553d277f5bcadb0a6f75d40dbd5f28a0a8d8c1 Mon Sep 17 00:00:00 2001 From: Rob Loranger Date: Tue, 5 Nov 2019 10:44:06 -0800 Subject: [PATCH 1/3] add admin user account deletion this adds a section to the admin user view to delete the account and a handler to process the request. --- admin.go | 33 +++++++++++++++++++++++++++++ routes.go | 1 + templates/user/admin/users.tmpl | 6 ++++++ templates/user/admin/view-user.tmpl | 12 +++++++++++ 4 files changed, 52 insertions(+) diff --git a/admin.go b/admin.go index fdbb82f..ec40c6c 100644 --- a/admin.go +++ b/admin.go @@ -123,6 +123,7 @@ func handleViewAdminUsers(app *App, u *User, w http.ResponseWriter, r *http.Requ *UserPage Config config.AppCfg Message string + Flashes []string Users *[]User CurPage int @@ -134,6 +135,7 @@ func handleViewAdminUsers(app *App, u *User, w http.ResponseWriter, r *http.Requ Message: r.FormValue("m"), } + p.Flashes, _ = getSessionFlashes(app, w, r, nil) p.TotalUsers = app.db.GetAllUsersCount() ttlPages := p.TotalUsers / adminUsersPerPage p.TotalPages = []int{} @@ -230,6 +232,37 @@ func handleViewAdminUser(app *App, u *User, w http.ResponseWriter, r *http.Reque return nil } +func handleAdminDeleteUser(app *App, u *User, w http.ResponseWriter, r *http.Request) error { + if !u.IsAdmin() { + return impart.HTTPError{http.StatusForbidden, "Administrator privileges required for this action"} + } + + vars := mux.Vars(r) + username := vars["username"] + confirmUsername := r.PostFormValue("confirm-username") + + if confirmUsername != username { + return impart.HTTPError{http.StatusBadRequest, "Username was not confirmed"} + } + + user, err := app.db.GetUserForAuth(username) + if err == ErrUserNotFound { + return impart.HTTPError{http.StatusNotFound, fmt.Sprintf("User '%s' was not found", username)} + } else if err != nil { + log.Error("get user for deletion: %v", err) + return impart.HTTPError{http.StatusInternalServerError, fmt.Sprintf("Could not get user with username '%s': %v", username, err)} + } + + err = app.db.DeleteAccount(user.ID) + if err != nil { + log.Error("delete user %s: %v", user.Username, err) + return impart.HTTPError{http.StatusInternalServerError, fmt.Sprintf("Could not delete user account for '%s': %v", username, err)} + } + + _ = addSessionFlash(app, w, r, fmt.Sprintf("Account for user \"%s\" was deleted successfully.", username), nil) + return impart.HTTPError{http.StatusFound, "/admin/users"} +} + func handleViewAdminPages(app *App, u *User, w http.ResponseWriter, r *http.Request) error { p := struct { *UserPage diff --git a/routes.go b/routes.go index 0113e93..3d2a714 100644 --- a/routes.go +++ b/routes.go @@ -144,6 +144,7 @@ func InitRoutes(apper Apper, r *mux.Router) *mux.Router { write.HandleFunc("/admin", handler.Admin(handleViewAdminDash)).Methods("GET") write.HandleFunc("/admin/users", handler.Admin(handleViewAdminUsers)).Methods("GET") write.HandleFunc("/admin/user/{username}", handler.Admin(handleViewAdminUser)).Methods("GET") + write.HandleFunc("/admin/user/{username}/delete", handler.Admin(handleAdminDeleteUser)).Methods("POST") write.HandleFunc("/admin/pages", handler.Admin(handleViewAdminPages)).Methods("GET") write.HandleFunc("/admin/page/{slug}", handler.Admin(handleViewAdminPage)).Methods("GET") write.HandleFunc("/admin/update/config", handler.AdminApper(handleAdminUpdateConfig)).Methods("POST") diff --git a/templates/user/admin/users.tmpl b/templates/user/admin/users.tmpl index b59104c..8476f78 100644 --- a/templates/user/admin/users.tmpl +++ b/templates/user/admin/users.tmpl @@ -4,6 +4,12 @@
{{template "admin-header" .}} + + {{if .Flashes}} +

+ {{range .Flashes}}{{.}}{{end}} +

+ {{end}}

Users {{.TotalUsers}} total

diff --git a/templates/user/admin/view-user.tmpl b/templates/user/admin/view-user.tmpl index 2a74e5b..e457889 100644 --- a/templates/user/admin/view-user.tmpl +++ b/templates/user/admin/view-user.tmpl @@ -81,6 +81,18 @@ h3 { {{end}}
{{end}} + + {{ if not .User.IsAdmin }} +
+

Delete Account

+

Danger Zone - This cannot be undone

+

This will delete the user {{.User.Username}} and all their blogs AND posts.

+
+

Type their username to confirm deletion.

+ + +

+ {{end}}
{{template "footer" .}} From e4164cbf67132355697fa2b3d6465d63914e612f Mon Sep 17 00:00:00 2001 From: Matt Baer Date: Thu, 22 Apr 2021 10:08:05 -0400 Subject: [PATCH 2/3] Move admin user deletion confirmation to modal Ref T319 --- less/core.less | 13 ++++++ less/pad.less | 9 +++++ static/js/modals.js | 24 +++++++++++ templates/user/admin/view-user.tmpl | 62 ++++++++++++++++++++++++----- templates/user/collection.tmpl | 17 +------- 5 files changed, 100 insertions(+), 25 deletions(-) create mode 100644 static/js/modals.js diff --git a/less/core.less b/less/core.less index 9d2e1ab..6401ceb 100644 --- a/less/core.less +++ b/less/core.less @@ -1044,6 +1044,19 @@ li { background-color: #dff0d8; border-color: #d6e9c6; } + &.danger { + border-color: #856404; + background-color: white; + h3 { + margin: 0 0 0.5em 0; + font-size: 1em; + font-weight: bold; + color: black !important; + } + h3 + p, button { + font-size: 0.86em; + } + } p { margin: 0; diff --git a/less/pad.less b/less/pad.less index 6cdd383..486e2ea 100644 --- a/less/pad.less +++ b/less/pad.less @@ -340,6 +340,15 @@ body#pad { } } + .body { + line-height: 1.5; + + input[type=text].confirm { + width: 100%; + box-sizing: border-box; + } + } + .short { text-align: center; } diff --git a/static/js/modals.js b/static/js/modals.js new file mode 100644 index 0000000..6705afa --- /dev/null +++ b/static/js/modals.js @@ -0,0 +1,24 @@ +/* + * Copyright © 2016-2021 A Bunch Tell LLC. + * + * This file is part of WriteFreely. + * + * WriteFreely is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License, included + * in the LICENSE file in this source code package. + */ + +function showModal(id) { + document.getElementById('overlay').style.display = 'block'; + document.getElementById('modal-'+id).style.display = 'block'; +} + +var closeModals = function(e) { + e.preventDefault(); + document.getElementById('overlay').style.display = 'none'; + var modals = document.querySelectorAll('.modal'); + for (var i=0; i
+
+ {{template "admin-header" .}}

{{.User.Username}}

@@ -141,19 +146,58 @@ input.copy-text { {{end}} {{ if not .User.IsAdmin }} -
-

Delete Account

-

Danger Zone - This cannot be undone

-

This will delete the user {{.User.Username}} and all their blogs AND posts.

-
-

Type their username to confirm deletion.

- - -

+

Incinerator

+
+
+
+

Delete this user

+

Permanently erase all user data, with no way to recover it.

+
+ +
+
{{end}}
+ + + + +