// 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) { if !ctx.LoggedOn() { ctx.UnsetUdata() } 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.CheckToken(nil) { return } if user == "" || password == "" || submit != "Login" { ctx.Data.Msg = "wrong inputs" ctx.Exec() return } err := ctx.Srv.DB.Login(user, password) if err != nil { ctx.Data.Msg = err.Error() ctx.Exec() return } ctx.SetUdata(user, ctx.Srv.DB.UserIsAdmin(user)) 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.CheckToken(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.CheckToken(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.CheckToken(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.CheckToken(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.CheckToken(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.CheckToken(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.UnsetUdata() ctx.Redirect("/wiki/Index", 302) }