package main import ( "fmt" "html/template" "log" "time" "git.phc.dm.unipi.it/phc/website/articles" "git.phc.dm.unipi.it/phc/website/auth" "git.phc.dm.unipi.it/phc/website/config" "git.phc.dm.unipi.it/phc/website/model" "git.phc.dm.unipi.it/phc/website/templates" "git.phc.dm.unipi.it/phc/website/util" "github.com/gofiber/fiber/v2" "github.com/gofiber/fiber/v2/middleware/logger" "github.com/gofiber/fiber/v2/middleware/recover" "github.com/gofiber/redirect/v2" ) func UserMiddleware(as auth.Service) fiber.Handler { return func(c *fiber.Ctx) error { token := c.Cookies("session-token") user, _ := auth.UserForSession(as, token) c.Locals("user", user) return c.Next() } } func main() { config.Load() app := fiber.New() app.Use(logger.New()) app.Use(recover.New()) // Remove trailing slash from URLs app.Use(redirect.New(redirect.Config{ Rules: map[string]string{ "/*/": "/$1", }, })) // Serve content statically from "./public", mounted on the "/public/" route app.Static("/public/", "./public") authService := auth.NewDefaultService(config.AuthServiceHost) app.Use(UserMiddleware(authService)) // Templates & Renderer renderer := templates.NewRenderer( "./views/", "./views/base.html", "./views/partials/*.html", ) newsArticlesRegistry := articles.NewRegistry("./news") // Routes actuallyStaticRoutes := map[string]string{ "/": "home.html", "/link": "link.html", "/login": "login.html", "/utenti": "utenti.html", } for route, view := range actuallyStaticRoutes { localView := view app.Get(route, func(c *fiber.Ctx) error { c.Type("html") return renderer.Render(c, localView, util.H{ "User": c.Locals("user"), }) }) } app.Get("/api/utenti", func(c *fiber.Ctx) error { utenti, err := authService.GetUsers() if err != nil { return err } return c.JSON(utenti) }) app.Get("/api/profilo", func(c *fiber.Ctx) error { user := c.Locals("user") if user == nil { return fmt.Errorf(`user not logged in`) } return c.JSON(user) }) app.Get("/storia", func(c *fiber.Ctx) error { storia, err := GetStoria() if err != nil { return err } c.Type("html") return renderer.Render(c, "storia.html", util.H{ "User": c.Locals("user"), "Storia": storia, }) }) app.Get("/appunti", func(c *fiber.Ctx) error { searchQuery := c.Query("q", "") c.Type("html") return renderer.Render(c, "appunti.html", util.H{ "User": c.Locals("user"), "Query": searchQuery, }) }) app.Get("/news", func(c *fiber.Ctx) error { articles, err := newsArticlesRegistry.GetArticles() if err != nil { return err } c.Type("html") return renderer.Render(c, "news.html", util.H{ "User": c.Locals("user"), "Articles": articles, }) }) app.Post("/login", func(c *fiber.Ctx) error { var loginForm struct { Provider string `form:"provider"` Username string `form:"username"` Password string `form:"password"` } if err := c.BodyParser(&loginForm); err != nil { return err } session, err := authService.Login(loginForm.Username, loginForm.Password) if err != nil { return err } inThreeDays := time.Now().Add(3 * 24 * time.Hour) c.Cookie(&fiber.Cookie{ Name: "session-token", Path: "/", Value: session.Token, Expires: inThreeDays, }) return c.Redirect("/profilo") }) app.Get("/profilo", func(c *fiber.Ctx) error { user, ok := c.Locals("user").(*model.User) if !ok || user == nil { return fmt.Errorf(`user not logged in`) } c.Type("html") return renderer.Render(c, "profilo.html", util.H{ "User": c.Locals("user"), }) }) app.Get("/logout", func(c *fiber.Ctx) error { c.Cookie(&fiber.Cookie{ Name: "session-token", Path: "/", Value: "", Expires: time.Now(), }) return c.Redirect("/") }) app.Get("/news/:article", func(c *fiber.Ctx) error { articleID := c.Params("article") article, err := newsArticlesRegistry.GetArticle(articleID) if err != nil { return err } html, err := article.Render() if err != nil { return err } c.Type("html") return renderer.Render(c, "news-base.html", util.H{ "User": c.Locals("user"), "Article": article, "ContentHTML": template.HTML(html), }) }) log.Printf("Starting server on host %q", config.Host) err := app.Listen(config.Host) if err != nil { log.Fatal(err) } }