1
0
mirror of https://github.com/osmarks/mycorrhiza.git synced 2024-12-13 14:00:25 +00:00
mycorrhiza/admin/admin.go

184 lines
4.6 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package admin
import (
"fmt"
"github.com/bouncepaw/mycorrhiza/viewutil"
"github.com/gorilla/mux"
"log"
"mime"
"net/http"
"os"
"sort"
"github.com/bouncepaw/mycorrhiza/cfg"
"github.com/bouncepaw/mycorrhiza/user"
"github.com/bouncepaw/mycorrhiza/util"
)
// handlerAdmin provides the admin panel.
func handlerAdmin(w http.ResponseWriter, rq *http.Request) {
w.Header().Set("Content-Type", "text/html;charset=utf-8")
w.WriteHeader(http.StatusOK)
viewPanel(viewutil.MetaFrom(w, rq))
}
// handlerAdminShutdown kills the wiki.
func handlerAdminShutdown(w http.ResponseWriter, rq *http.Request) {
if user.CanProceed(rq, "admin/shutdown") {
log.Println("An admin commanded the wiki to shutdown")
os.Exit(0)
}
}
// handlerAdminReindexUsers reinitialises the user system.
func handlerAdminReindexUsers(w http.ResponseWriter, rq *http.Request) {
user.ReadUsersFromFilesystem()
redirectTo := rq.Referer()
if redirectTo == "" {
redirectTo = "/hypha/" + cfg.UserHypha
}
http.Redirect(w, rq, redirectTo, http.StatusSeeOther)
}
func handlerAdminUsers(w http.ResponseWriter, rq *http.Request) {
// Get a sorted list of users
var users []*user.User
for u := range user.YieldUsers() {
users = append(users, u)
}
sort.Slice(users, func(i, j int) bool {
less := users[i].RegisteredAt.Before(users[j].RegisteredAt)
return less
})
viewList(viewutil.MetaFrom(w, rq), users)
}
func handlerAdminUserEdit(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{"group"})
if rq.Method == http.MethodPost {
oldGroup := u.Group
newGroup := f.Get("group")
if user.ValidGroup(newGroup) {
u.Group = newGroup
if err := user.SaveUserDatabase(); err != nil {
u.Group = oldGroup
log.Println(err)
f = f.WithError(err)
} else {
http.Redirect(w, rq, "/admin/users/", http.StatusSeeOther)
return
}
} else {
f = f.WithError(fmt.Errorf("invalid group %s", newGroup))
}
}
f.Put("group", u.Group)
if f.HasError() {
w.WriteHeader(http.StatusBadRequest)
}
w.Header().Set("Content-Type", mime.TypeByExtension(".html"))
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"])
if u == nil {
util.HTTP404Page(w, "404 page not found")
return
}
f := util.NewFormData()
if rq.Method == http.MethodPost {
f = f.WithError(user.DeleteUser(u.Name))
if !f.HasError() {
http.Redirect(w, rq, "/admin/users/", http.StatusSeeOther)
} else {
log.Println(f.Error())
}
}
if f.HasError() {
w.WriteHeader(http.StatusBadRequest)
}
w.Header().Set("Content-Type", mime.TypeByExtension(".html"))
viewDeleteUser(viewutil.MetaFrom(w, rq), f, u)
}
func handlerAdminUserNew(w http.ResponseWriter, rq *http.Request) {
if rq.Method == http.MethodGet {
w.Header().Set("Content-Type", mime.TypeByExtension(".html"))
viewNewUser(viewutil.MetaFrom(w, rq), util.NewFormData())
} else if rq.Method == http.MethodPost {
// Create a user
f := util.FormDataFromRequest(rq, []string{"name", "password", "group"})
err := user.Register(f.Get("name"), f.Get("password"), f.Get("group"), "local", true)
if err != nil {
w.WriteHeader(http.StatusBadRequest)
w.Header().Set("Content-Type", mime.TypeByExtension(".html"))
viewNewUser(viewutil.MetaFrom(w, rq), f.WithError(err))
} else {
http.Redirect(w, rq, "/admin/users/", http.StatusSeeOther)
}
}
}