Added ability to delete other users

This commit is contained in:
Jason Streifling 2024-04-12 08:46:34 +02:00
parent 0f0471b84c
commit 21fd3403b2
7 changed files with 92 additions and 21 deletions

View File

@ -53,6 +53,7 @@ func main() {
mux.HandleFunc("GET /create-user", view.CreateUser(config)) mux.HandleFunc("GET /create-user", view.CreateUser(config))
mux.HandleFunc("GET /edit-self", view.EditSelf(config, db, store)) mux.HandleFunc("GET /edit-self", view.EditSelf(config, db, store))
mux.HandleFunc("GET /edit-user/{id}", view.EditUser(config, db)) mux.HandleFunc("GET /edit-user/{id}", view.EditUser(config, db))
mux.HandleFunc("GET /delete-user/{id}", view.DeleteUser(config, db, store))
mux.HandleFunc("GET /hub", view.ShowHub(config, db, store)) mux.HandleFunc("GET /hub", view.ShowHub(config, db, store))
mux.HandleFunc("GET /logout", view.Logout(config, store)) mux.HandleFunc("GET /logout", view.Logout(config, store))
mux.HandleFunc("GET /pics/{pic}", view.ServeImage(config, store)) mux.HandleFunc("GET /pics/{pic}", view.ServeImage(config, store))
@ -65,7 +66,8 @@ func main() {
mux.HandleFunc("GET /rss", func(w http.ResponseWriter, r *http.Request) { mux.HandleFunc("GET /rss", func(w http.ResponseWriter, r *http.Request) {
http.ServeFile(w, r, config.RSSFile) http.ServeFile(w, r, config.RSSFile)
}) })
mux.HandleFunc("GET /show-all-users", view.ShowAllUsers(config, db)) mux.HandleFunc("GET /show-all-users-edit", view.ShowAllUsers(config, db, store, "edit-user"))
mux.HandleFunc("GET /show-all-users-delete", view.ShowAllUsers(config, db, store, "delete-user"))
mux.HandleFunc("GET /this-issue", view.ShowCurrentArticles(config, db)) mux.HandleFunc("GET /this-issue", view.ShowCurrentArticles(config, db))
mux.HandleFunc("GET /unpublished-articles", view.ShowUnpublishedArticles(config, db)) mux.HandleFunc("GET /unpublished-articles", view.ShowUnpublishedArticles(config, db))
mux.HandleFunc("GET /write-article", view.WriteArticle(config, db)) mux.HandleFunc("GET /write-article", view.WriteArticle(config, db))

View File

@ -14,6 +14,7 @@ const (
Publisher Publisher
Editor Editor
Author Author
NonExistent
) )
type User struct { type User struct {
@ -269,7 +270,7 @@ func (db *DB) AddFirstUser(u *User, pass string) (int64, error) {
return 0, fmt.Errorf("error: %v unsuccessful retries for DB operation, aborting", TxMaxRetries) return 0, fmt.Errorf("error: %v unsuccessful retries for DB operation, aborting", TxMaxRetries)
} }
func (db *DB) GetAllUsers() ([]*User, error) { func (db *DB) GetAllUsers() (map[int64]*User, error) {
query := "SELECT id, username, first_name, last_name, role FROM users" query := "SELECT id, username, first_name, last_name, role FROM users"
rows, err := db.Query(query) rows, err := db.Query(query)
@ -277,14 +278,14 @@ func (db *DB) GetAllUsers() ([]*User, error) {
return nil, fmt.Errorf("error getting all users from DB: %v", err) return nil, fmt.Errorf("error getting all users from DB: %v", err)
} }
users := make([]*User, 0) users := make(map[int64]*User, 0)
for rows.Next() { for rows.Next() {
user := new(User) user := new(User)
if err = rows.Scan(&user.ID, &user.UserName, &user.FirstName, if err = rows.Scan(&user.ID, &user.UserName, &user.FirstName,
&user.LastName, &user.Role); err != nil { &user.LastName, &user.Role); err != nil {
return nil, fmt.Errorf("error getting user info: %v", err) return nil, fmt.Errorf("error getting user info: %v", err)
} }
users = append(users, user) users[user.ID] = user
} }
return users, nil return users, nil
@ -299,11 +300,7 @@ func (tx *Tx) SetPassword(id int64, newPass string) error {
return fmt.Errorf("error creating password hash: %v", err) return fmt.Errorf("error creating password hash: %v", err)
} }
setQuery := ` setQuery := "UPDATE users SET password = ? WHERE id = ?"
UPDATE users
SET password = ?
WHERE id = ?
`
if _, err = tx.Exec(setQuery, string(hashedPass), id); err != nil { if _, err = tx.Exec(setQuery, string(hashedPass), id); err != nil {
if rollbackErr := tx.Rollback(); rollbackErr != nil { if rollbackErr := tx.Rollback(); rollbackErr != nil {
log.Fatalf("transaction error: %v, rollback error: %v", err, rollbackErr) log.Fatalf("transaction error: %v, rollback error: %v", err, rollbackErr)
@ -370,3 +367,14 @@ func (db *DB) UpdateUserAttributes(id int64, user, first, last, newPass, newPass
return fmt.Errorf("error: %v unsuccessful retries for DB operation, aborting", TxMaxRetries) return fmt.Errorf("error: %v unsuccessful retries for DB operation, aborting", TxMaxRetries)
} }
func (db *DB) DeleteUser(id int64) error {
query := "DELETE FROM users WHERE id = ?"
_, err := db.Exec(query, id)
if err != nil {
return fmt.Errorf("error deleting user %v from DB: %v", id, err)
}
return nil
}

View File

@ -95,8 +95,16 @@ func AddUser(c *control.Config, db *model.DB, s *control.CookieStore) http.Handl
return return
} }
session, err := s.Get(r, "cookie")
if err != nil {
tmpl, err := template.ParseFiles(c.WebDir + "/templates/login.html")
msg := "Session nicht mehr gültig. Bitte erneut anmelden."
template.Must(tmpl, err).ExecuteTemplate(w, "page-content", msg)
}
tmpl, err := template.ParseFiles(c.WebDir + "/templates/hub.html") tmpl, err := template.ParseFiles(c.WebDir + "/templates/hub.html")
template.Must(tmpl, err).ExecuteTemplate(w, "page-content", 0) tmpl = template.Must(tmpl, err)
tmpl.ExecuteTemplate(w, "page-content", session.Values["role"].(int))
} }
} }
@ -266,17 +274,32 @@ func AddFirstUser(c *control.Config, db *model.DB, s *control.CookieStore) http.
} }
} }
func ShowAllUsers(c *control.Config, db *model.DB) http.HandlerFunc { func ShowAllUsers(c *control.Config, db *model.DB, s *control.CookieStore, action string) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) { return func(w http.ResponseWriter, r *http.Request) {
users, err := db.GetAllUsers() var err error
type htmlData struct {
Users map[int64]*model.User
Action string
}
data := &htmlData{Action: action}
data.Users, err = db.GetAllUsers()
if err != nil { if err != nil {
log.Println(err) log.Println(err)
http.Error(w, err.Error(), http.StatusInternalServerError) http.Error(w, err.Error(), http.StatusInternalServerError)
return return
} }
session, err := s.Get(r, "cookie")
if err != nil {
tmpl, err := template.ParseFiles(c.WebDir + "/templates/login.html")
msg := "Session nicht mehr gültig. Bitte erneut anmelden."
template.Must(tmpl, err).ExecuteTemplate(w, "page-content", msg)
}
delete(data.Users, session.Values["id"].(int64))
tmpl, err := template.ParseFiles(c.WebDir + "/templates/show-all-users.html") tmpl, err := template.ParseFiles(c.WebDir + "/templates/show-all-users.html")
template.Must(tmpl, err).ExecuteTemplate(w, "page-content", users) template.Must(tmpl, err).ExecuteTemplate(w, "page-content", data)
} }
} }
@ -372,8 +395,43 @@ func UpdateUser(c *control.Config, db *model.DB, s *control.CookieStore) http.Ha
template.Must(tmpl, err).ExecuteTemplate(w, "page-content", userData) template.Must(tmpl, err).ExecuteTemplate(w, "page-content", userData)
} }
session, err := s.Get(r, "cookie")
if err != nil {
tmpl, err := template.ParseFiles(c.WebDir + "/templates/login.html")
msg := "Session nicht mehr gültig. Bitte erneut anmelden."
template.Must(tmpl, err).ExecuteTemplate(w, "page-content", msg)
}
tmpl, err := template.ParseFiles(c.WebDir + "/templates/hub.html") tmpl, err := template.ParseFiles(c.WebDir + "/templates/hub.html")
tmpl = template.Must(tmpl, err) tmpl = template.Must(tmpl, err)
tmpl.ExecuteTemplate(w, "page-content", 0) tmpl.ExecuteTemplate(w, "page-content", session.Values["role"].(int))
}
}
func DeleteUser(c *control.Config, db *model.DB, s *control.CookieStore) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
id, err := strconv.ParseInt(r.PathValue("id"), 10, 64)
if err != nil {
log.Println(err)
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
if err = db.DeleteUser(id); err != nil {
log.Println(err)
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
session, err := s.Get(r, "cookie")
if err != nil {
tmpl, err := template.ParseFiles(c.WebDir + "/templates/login.html")
msg := "Session nicht mehr gültig. Bitte erneut anmelden."
template.Must(tmpl, err).ExecuteTemplate(w, "page-content", msg)
}
tmpl, err := template.ParseFiles(c.WebDir + "/templates/hub.html")
tmpl = template.Must(tmpl, err)
tmpl.ExecuteTemplate(w, "page-content", session.Values["role"].(int))
} }
} }

View File

@ -40,7 +40,7 @@
</div> </div>
<div> <div>
<input required id="admin" name="role" type="radio" value="0" {{if eq .Role 0 }}checked{{end}} /> <input required id="admin" name="role" type="radio" value="0" {{if eq .Role 0 }}checked{{end}} />
<label for="admin">Admin</label> <label for="admin">Administrator</label>
</div> </div>
</div> </div>

View File

@ -44,7 +44,7 @@
</div> </div>
<div> <div>
<input required id="admin" name="role" type="radio" value="0" {{if eq .Role 0 }}checked{{end}} /> <input required id="admin" name="role" type="radio" value="0" {{if eq .Role 0 }}checked{{end}} />
<label for="admin">Admin</label> <label for="admin">Administrator</label>
</div> </div>
</div> </div>

View File

@ -2,6 +2,7 @@
<div class="flex flex-col gap-4"> <div class="flex flex-col gap-4">
<button class="btn" hx-get="/logout" hx-target="#page-content">Abmelden</button> <button class="btn" hx-get="/logout" hx-target="#page-content">Abmelden</button>
{{if lt . 4}}
<div class="mb-3"> <div class="mb-3">
<h2>Autor</h2> <h2>Autor</h2>
<div class="grid grid-cols-2 gap-x-4 gap-y-2"> <div class="grid grid-cols-2 gap-x-4 gap-y-2">
@ -11,6 +12,7 @@
<button class="btn" hx-get="/edit-self" hx-target="#page-content">Profil bearbeiten</button> <button class="btn" hx-get="/edit-self" hx-target="#page-content">Profil bearbeiten</button>
</div> </div>
</div> </div>
{{end}}
{{if lt . 3}} {{if lt . 3}}
<div class="mb-3"> <div class="mb-3">
@ -36,9 +38,10 @@
{{if eq . 0}} {{if eq . 0}}
<div class="mb-3"> <div class="mb-3">
<h2>Administrator</h2> <h2>Administrator</h2>
<div class="grid grid-cols-2 gap-4"> <div class="grid grid-cols-3 gap-4">
<button class="btn" hx-get="/create-user" hx-target="#page-content">Benutzer hinzufügen</button> <button class="btn" hx-get="/create-user" hx-target="#page-content">Benutzer hinzufügen</button>
<button class="btn" hx-get="/show-all-users" hx-target="#page-content">Benutzer bearbeiten</button> <button class="btn" hx-get="/show-all-users-edit" hx-target="#page-content">Benutzer bearbeiten</button>
<button class="btn" hx-get="/show-all-users-delete" hx-target="#page-content">Benutzer löschen</button>
</div> </div>
</div> </div>
{{end}} {{end}}

View File

@ -2,12 +2,12 @@
<h2>Alle Benutzer</h2> <h2>Alle Benutzer</h2>
<div class="flex flex-col gap-4"> <div class="flex flex-col gap-4">
{{range .}} {{range .Users}}
<button class="btn" hx-get="/edit-user/{{.ID}}" hx-target="#page-content"> <button class="btn" hx-get="/{{$.Action}}/{{.ID}}" hx-target="#page-content">
<h1 class="font-bold text-2xl"> <h1 class="font-bold text-2xl">
{{.UserName}} {{.UserName}}
({{if eq .Role 0}} ({{if eq .Role 0}}
Admin Administrator
{{else if eq .Role 1}} {{else if eq .Role 1}}
Herausgeber Herausgeber
{{else if eq .Role 2}} {{else if eq .Role 2}}