package main import ( "crypto/sha512" "encoding/hex" "errors" "html/template" "io" "net/http" "strconv" "time" "muse/storage" "github.com/labstack/echo" "github.com/labstack/echo/middleware" ) type ( Response struct { Ok bool `json:"ok"` Message string `json:"message"` } TemplateRenderer struct { template *template.Template } Template string ) const ( adminUsername = "danolo" adminPassword = "bd4cad796950f50352225de3c773d8f3c39622bc17f34ad661eabe615cdf6d32751c5751e0648dc17d890f40330018334a2ae899878f200f6dc80121ddb70cc9" ) var ( list *storage.EntryList = &storage.EntryList{ Filename: "/var/lib/muse.json", ModTime: time.Unix(0, 0), } ) // TemplateRenderer func (renderer *TemplateRenderer) Render(w io.Writer, name string, data interface{}, c echo.Context) error { return renderer.template.ExecuteTemplate(w, name, data) } func (template Template) TemplateController(c echo.Context) (err error) { entries, err := list.GetEntries() if err == nil { err = c.Render(http.StatusOK, string(template), struct { Entries []*storage.Entry Today storage.JSTime }{ Entries: entries, Today: storage.JSTime(time.Now()), }) } return } func AddController(c echo.Context) (err error) { entry := new(storage.Entry) err = c.Bind(entry) if err == nil { if c.FormValue("date") == "" { entry.Date = storage.JSTime(time.Now()) } err = list.AddEntry(entry) } if err == nil { err = c.Redirect(http.StatusFound, "..") } return } func DelController(c echo.Context) error { var url string var status int var pos int pos, err := strconv.Atoi(c.Param("index")) if err == nil { err = list.DeleteElement(pos) } if err == nil { url = "../.." status = http.StatusFound } else { status = http.StatusInternalServerError } return c.Redirect(status, url) } func DelConfirmController(c echo.Context) error { var entries []*storage.Entry failed := c.QueryParam("failed") indexStr := c.Param("index") index, err := strconv.Atoi(indexStr) if err == nil { entries, err = list.GetEntries() } if index >= len(entries) { err = errors.New("Index out of range") } if err == nil { err = c.Render(http.StatusOK, "del.html", struct { Index int Elem *storage.Entry Failed string }{ Index: index, Elem: entries[index], Failed: failed, }) } return err } func auth(username, password string, c echo.Context) (bool, error) { hash := sha512.Sum512([]byte(password)) hashString := hex.EncodeToString(hash[:]) if username == adminUsername && hashString == adminPassword { return true, nil } return false, nil } func RSSController(c echo.Context) (err error) { if blob, err := list.GetFeed().ToRss(); err == nil { c.Blob(http.StatusOK, "application/xml", []byte(blob)) } return } func main() { e := echo.New() e.Renderer = &TemplateRenderer{ template: template.Must(template.ParseGlob("templates/*.html")), } e.GET("/", Template("index.html").TemplateController) e.GET("/rss", RSSController) e.Static("/static", "static") admin := e.Group("/admin", middleware.BasicAuth(auth)) admin.POST("/add", AddController) admin.POST("/del/:index", DelController) admin.GET("/del/:index", DelConfirmController) admin.GET("/", Template("admin.html").TemplateController) admin.Static("/static", "admin/static") e.Logger.Fatal(e.Start(":30303")) }