gowiki/pkg/server/handler.go
2018-09-12 00:37:13 +02:00

440 lines
8.5 KiB
Go

// Copyright (C) 2017 Marius Schellenberger
package server
import (
"git.giftfish.de/ston1th/gowiki/pkg/core"
"git.giftfish.de/ston1th/gowiki/pkg/log"
"html/template"
"net/http"
"time"
)
type notFoundHandler struct {
s *HTTPServer
}
func (nf *notFoundHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
newContext(w, r, nf.s).NotFound()
}
func adminAuthHandler(h ctxHandler) ctxHandler {
return func(ctx *Context) {
if ctx.GetAdmin() {
h(ctx)
return
}
ctx.NotFound()
}
}
func userAuthHandler(h ctxHandler) ctxHandler {
return func(ctx *Context) {
if ctx.GetAdmin() {
h(ctx)
return
}
if ctx.GetUser() == ctx.Var("user") {
h(ctx)
return
}
ctx.NotFound()
}
}
func authHandler(h ctxHandler) ctxHandler {
return func(ctx *Context) {
if ctx.LoggedOn() {
h(ctx)
return
}
ctx.NotFound()
}
}
func staticHandler(ctx *Context) {
var err error
ctx.SetHeader("Content-Type", "text/css; charset=utf-8")
ctx.SetHeader("Expires", time.Now().Add(time.Hour*12).Format(http.TimeFormat))
switch ctx.Path() {
case "/bootstrap.css":
err = ctx.Write(ctx.Srv.res["bootstrap.css"])
case "/custom.css":
err = ctx.Write(ctx.Srv.res["custom.css"])
}
if err != nil {
log.Println("static:", err)
}
}
func indexHandler(ctx *Context) {
ctx.Redirect("/wiki/Index", 302)
}
func loginHandler(ctx *Context) {
if ctx.LoggedOn() {
ctx.Redirect("/wiki/Index", 302)
return
}
ctx.Template("loginHandler")
ctx.Data = webData{
Title: "Login",
BodyTitle: "Login",
}
switch ctx.Method() {
case "GET":
ctx.Exec()
case "POST":
user := ctx.Form("user")
password := ctx.Form("password")
submit := ctx.Form("submit")
if !ctx.CheckXsrf(nil) {
return
}
if user == "" || password == "" || submit != "Login" {
ctx.Data.Msg = "wrong inputs"
ctx.Exec()
return
}
u, err := ctx.Srv.DB.Login(user, password)
if err != nil {
ctx.Data.Msg = err.Error()
ctx.Exec()
return
}
ctx.SetCookie(map[string]interface{}{"username": u.Username, "admin": u.Admin})
ctx.Redirect("/wiki/Index", 302)
}
}
func searchHandler(ctx *Context) {
ctx.Template("searchHandler")
ctx.Data = webData{
Title: "Search",
BodyTitle: "Search",
}
switch ctx.Method() {
case "GET":
ctx.Exec()
case "POST":
search := ctx.Form("search")
submit := ctx.Form("submit")
if !ctx.CheckXsrf(nil) {
return
}
if submit != "Search" {
ctx.Data.Msg = "wrong inputs"
ctx.Exec()
return
}
res, err := ctx.Srv.DB.Index.Search(search)
if err != nil {
ctx.Data.Msg = err.Error()
ctx.Exec()
return
}
ctx.Data.Search = search
ctx.Data.Data = template.HTML(res)
ctx.Exec()
}
}
func allHandler(ctx *Context) {
ctx.Template("allHandler")
ctx.Data = webData{
Title: "All Articles",
BodyTitle: "All Articles",
Admin: ctx.GetAdmin(),
}
all, err := ctx.Srv.DB.Index.GetAll(!ctx.LoggedOn())
if err != nil {
ctx.Data.Msg = err.Error()
}
ctx.Data.Data = all
ctx.Exec()
}
func wikiNewHandler(ctx *Context) {
ctx.Template("wikiNewHandler")
ctx.Data = webData{Title: "New Article"}
switch ctx.Method() {
case "GET":
ctx.Exec()
case "POST":
title := ctx.Form("title")
text := ctx.Form("text")
public := ctx.Form("public")
pub := false
if public == "0" {
pub = true
}
submit := ctx.Form("submit")
p := core.Page{
Title: title,
MD: text,
}
ctx.Data.Data = p
if !ctx.CheckXsrf(nil) {
return
}
if submit != "Submit" {
ctx.Data.Msg = "wrong inputs"
ctx.Exec()
return
}
newTitle, err := ctx.Srv.DB.Index.Index(title, text, ctx.GetUser(), pub)
if err != nil {
ctx.Data.Msg = err.Error()
ctx.Exec()
return
}
ctx.Redirect("/wiki/"+newTitle, 302)
}
}
func wikiHandler(ctx *Context) {
if ctx.T == nil {
ctx.Template("wikiHandler")
}
ctx.Data = webData{
Admin: ctx.GetAdmin(),
}
title := ctx.Var("title")
art, err := ctx.Srv.DB.Index.Get(!ctx.LoggedOn(), title)
if err != nil {
ctx.NotFound()
return
}
art.LinkTitle = title
ctx.Data.Data = art
ctx.Data.Title = art.Title
ctx.Data.BodyTitle = art.Title
ctx.Exec()
}
func wikiMDHandler(f ctxHandler) ctxHandler {
return func(ctx *Context) {
ctx.Template("wikiMDHandler")
f(ctx)
}
}
func wikiEditHandler(ctx *Context) {
ctx.Template("wikiEditHandler")
ctx.Data = webData{}
title := ctx.Var("title")
switch ctx.Method() {
case "GET":
art, err := ctx.Srv.DB.Index.Get(!ctx.LoggedOn(), title)
if err != nil {
ctx.NotFound()
return
}
art.LinkTitle = title
ctx.Data.Data = art
ctx.Data.Title = art.Title
ctx.Data.BodyTitle = art.Title
ctx.Exec()
case "POST":
ftitle := ctx.Form("title")
text := ctx.Form("text")
public := ctx.Form("public")
pub := false
if public == "0" {
pub = true
}
submit := ctx.Form("submit")
ctx.Data.Data = core.Page{
Title: ftitle,
LinkTitle: title,
MD: text,
Public: pub,
}
ctx.Data.Title = ftitle
ctx.Data.BodyTitle = ftitle
if !ctx.CheckXsrf(nil) {
return
}
if submit != "Submit" {
ctx.Data.Msg = "wrong inputs"
ctx.Exec()
return
}
err := ctx.Srv.DB.Index.Update(title, text, ctx.GetUser(), pub)
if err != nil {
ctx.Data.Msg = err.Error()
ctx.Exec()
return
}
ctx.Srv.Editors.Remove(title)
ctx.Redirect("/wiki/"+title, 302)
}
}
func wikiDelHandler(ctx *Context) {
title := ctx.Var("title")
submit := ctx.Form("submit")
f := func() {
ctx.Redirect("/wiki/"+title, 302)
}
if !ctx.CheckXsrf(f) {
return
}
if submit != "Delete" {
f()
return
}
if err := ctx.Srv.Index.Delete(title); err != nil {
log.Println("delete:", err)
f()
}
ctx.Redirect("/wiki/Index", 302)
}
func usersHandler(ctx *Context) {
if !ctx.LoggedOn() {
ctx.NotFound()
return
}
ctx.Template("usersHandler")
ctx.Data = webData{
Title: "Users",
BodyTitle: "Users",
User: ctx.GetUser(),
}
us, err := ctx.Srv.BS.GetUsers()
if err != nil {
ctx.Data.Msg = err.Error()
}
ctx.Data.Data = us
ctx.Exec()
}
func userNewHandler(ctx *Context) {
ctx.Template("userNewHandler")
ctx.Data = webData{
Title: "New User",
BodyTitle: "New User",
}
switch ctx.Method() {
case "GET":
ctx.Exec()
case "POST":
user := ctx.Form("user")
password := ctx.Form("password")
repeat := ctx.Form("repeat")
admin := ctx.Form("admin")
adm := false
if admin == "0" {
adm = true
}
submit := ctx.Form("submit")
if !ctx.CheckXsrf(nil) {
return
}
if user == "" || password == "" || password != repeat || submit != "Submit" {
ctx.Data.Msg = "wrong inputs"
ctx.Exec()
return
}
if err := ctx.Srv.BS.CreateUser(user, password, adm); err != nil {
ctx.Data.Msg = err.Error()
ctx.Exec()
return
}
ctx.Redirect("/users", 302)
}
}
func userEditHandler(ctx *Context) {
ctx.Template("userEditHandler")
ctx.Data = webData{
Title: "Edit User",
BodyTitle: "Edit User",
}
switch ctx.Method() {
case "GET":
u, err := ctx.Srv.BS.GetUserWithoutPassword(ctx.Var("user"))
if err != nil {
ctx.Data.Msg = err.Error()
ctx.Exec()
return
}
ctx.Data.Data = u
ctx.Exec()
case "POST":
user := ctx.Var("user")
password := ctx.Form("password")
repeat := ctx.Form("repeat")
admin := ctx.Form("admin")
adm := false
if admin == "0" {
adm = true
}
submit := ctx.Form("submit")
if !ctx.CheckXsrf(nil) {
return
}
if user == "" || password != repeat || submit != "Submit" {
ctx.Data.Msg = "wrong inputs"
ctx.Exec()
return
}
if ctx.GetAdmin() {
if err := ctx.Srv.BS.AdminUpdateUser(user, password, adm); err != nil {
ctx.Data.Msg = err.Error()
ctx.Exec()
return
}
} else {
if user == ctx.GetUser() {
if err := ctx.Srv.BS.UpdateUserPassword(user, password); err != nil {
ctx.Data.Msg = err.Error()
ctx.Exec()
return
}
ctx.Redirect("/wiki/Index", 302)
return
}
}
ctx.Redirect("/users", 302)
}
}
func userUnlockHandler(ctx *Context) {
user := ctx.Var("user")
if err := ctx.Srv.BS.UnlockUser(user); err != nil {
log.Println("unlock:", err)
}
ctx.Redirect("/users", 302)
}
func userDelHandler(ctx *Context) {
ctx.Template("userDelHandler")
ctx.Data = webData{
Title: "Delete User",
BodyTitle: "Delete User",
}
switch ctx.Method() {
case "GET":
user, err := ctx.Srv.BS.GetUserWithoutPassword(ctx.Var("user"))
if err != nil {
ctx.Data.Msg = err.Error()
ctx.Exec()
return
}
ctx.Data.Data = user
ctx.Exec()
case "POST":
if err := ctx.Srv.BS.DeleteUser(ctx.Var("user")); err != nil {
log.Println("delete:", err)
}
ctx.Redirect("/users", 302)
}
}
func logoutHandler(ctx *Context) {
ctx.SetCookie(nil)
ctx.Redirect("/wiki/Index", 302)
}