package web import ( "errors" "net/http" "github.com/go-chi/chi/v5" "plumber/internal/store" ) type adminUsersPage struct { page Users []store.User Error string } func (s *Server) requireAdmin(w http.ResponseWriter, r *http.Request) *store.User { u := currentUser(r) if !u.Admin() { http.Error(w, "forbidden", http.StatusForbidden) return nil } return u } func (s *Server) handleAdminUsers(w http.ResponseWriter, r *http.Request) { if s.requireAdmin(w, r) == nil { return } users, err := s.store.ListUsers(r.Context()) if err != nil { http.Error(w, "could not load users", http.StatusInternalServerError) return } s.exec(w, "admin-users", adminUsersPage{ page: s.basePage(r, "Users"), Users: users, }) } func (s *Server) handleAdminSetRole(w http.ResponseWriter, r *http.Request) { if !s.requireCSRF(w, r) { return } if s.requireAdmin(w, r) == nil { return } id := chi.URLParam(r, "id") role := store.Role(r.PostFormValue("role")) err := s.store.SetUserRole(r.Context(), id, role) if errors.Is(err, store.ErrLastAdmin) { users, listErr := s.store.ListUsers(r.Context()) if listErr != nil { http.Error(w, "could not demote last admin", http.StatusBadRequest) return } s.exec(w, "admin-users", adminUsersPage{ page: s.basePage(r, "Users"), Users: users, Error: "Cannot demote the last admin.", }) return } if err != nil { http.Error(w, "could not update role", http.StatusBadRequest) return } http.Redirect(w, r, "/admin/users", http.StatusSeeOther) }