You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
website/server/fiber.go

226 lines
5.3 KiB
Go

2 years ago
package server
import (
"log"
2 years ago
"time"
"git.phc.dm.unipi.it/phc/website/config"
2 years ago
"git.phc.dm.unipi.it/phc/website/handler"
"git.phc.dm.unipi.it/phc/website/model"
"github.com/gofiber/fiber/v2"
"github.com/gofiber/fiber/v2/middleware/etag"
2 years ago
"github.com/gofiber/fiber/v2/middleware/logger"
"github.com/gofiber/fiber/v2/middleware/recover"
"github.com/gofiber/redirect/v2"
)
func UserMiddleware(h handler.Service) fiber.Handler {
return func(c *fiber.Ctx) error {
token := c.Cookies("session-token")
user := h.HandleUser(token)
c.Locals("user", user)
return c.Next()
}
}
func CreateContext(ctx *fiber.Ctx) handler.Context {
// the "_" here is required because Go cannot cast <nil> of type interface{} to *model.User, in other words <nil> of type *model.User and <nil> of type interface{} are different type. In this case the "_" returns a boolean that tells whether the cast succeeded or not, if it is false the user variable gets assigned its default zero value that is <nil> of type *model.User
user, _ := ctx.Locals("user").(*model.User)
context := handler.Context{}
handler.SetContextValue(context, handler.UserKey, user)
return context
}
func NewFiberServer(h handler.Service) *fiber.App {
app := fiber.New()
routes(h, app)
return app
}
2 years ago
// routes defines routes under "/"
2 years ago
func routes(h handler.Service, r fiber.Router) {
//
// Initial setup
//
r.Use(logger.New())
r.Use(recover.New())
// Remove trailing slash from URLs
r.Use(redirect.New(redirect.Config{
Rules: map[string]string{
"/*/": "/$1",
},
}))
// Better static file serving setup
r.Route("/public", func(r fiber.Router) {
// Cache client side files based on checksum
r.Use(etag.New())
staticConfig := fiber.Static{}
if config.Mode == "development" {
log.Printf("Disabling Cache-Control in development mode")
// if no "Cache-Control" is present the browser will cache heuristically (and we don't want that)
r.Use(func(c *fiber.Ctx) error {
c.Set("Cache-Control", "no-cache")
return c.Next()
})
staticConfig.CacheDuration = 1 * time.Millisecond
}
r.Static("/", "./_frontend/out", staticConfig)
r.Static("/", "./_public", staticConfig)
})
// Serve generated css and js files and the static "./_public" folder
2 years ago
// Process all request and add user to the request context if there is a session cookie
r.Use(UserMiddleware(h))
//
// Pages
//
r.Get("/", func(c *fiber.Ctx) error {
c.Type("html")
return h.HandleStaticPage(c, "home.html", CreateContext(c))
})
r.Get("/link", func(c *fiber.Ctx) error {
c.Type("html")
return h.HandleStaticPage(c, "link.html", CreateContext(c))
})
r.Get("/login", func(c *fiber.Ctx) error {
c.Type("html")
return h.HandleStaticPage(c, "login.html", CreateContext(c))
})
r.Get("/utenti", func(c *fiber.Ctx) error {
c.Type("html")
return h.HandleStaticPage(c, "utenti.html", CreateContext(c))
})
r.Get("/storia", func(c *fiber.Ctx) error {
c.Type("html")
return h.HandleStoriaPage(c, CreateContext(c))
})
r.Get("/appunti", func(c *fiber.Ctx) error {
query := c.Query("q", "")
c.Type("html")
return h.HandleQueryAppunti(c, query, CreateContext(c))
})
r.Get("/appunti/condivisi", func(c *fiber.Ctx) error {
c.Type("html")
return h.HandleAppuntiCondivisiPage(c, CreateContext(c))
})
2 years ago
r.Get("/news", func(c *fiber.Ctx) error {
c.Type("html")
return h.HandleNewsPage(c, CreateContext(c))
})
r.Get("/guide", func(c *fiber.Ctx) error {
c.Type("html")
return h.HandleGuidePage(c, CreateContext(c))
})
r.Get("/news/rss", func(c *fiber.Ctx) error {
c.Type("xml")
return h.HandleNewsFeedPage(c)
})
r.Get("/guide/rss", func(c *fiber.Ctx) error {
c.Type("xml")
return h.HandleGuideFeedPage(c)
})
2 years ago
r.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 := h.HandleLogin(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")
})
r.Get("/profilo", func(c *fiber.Ctx) error {
c.Type("html")
return h.HandleProfilePage(c, CreateContext(c))
})
r.Get("/logout", func(c *fiber.Ctx) error {
c.Cookie(&fiber.Cookie{
Name: "session-token",
Path: "/",
Value: "",
Expires: time.Now(),
})
return c.Redirect("/")
})
r.Get("/news/:article", func(c *fiber.Ctx) error {
articleID := c.Params("article")
c.Type("html")
return h.HandleNewsArticlePage(c, articleID, CreateContext(c))
})
r.Get("/guide/:article", func(c *fiber.Ctx) error {
articleID := c.Params("article")
c.Type("html")
return h.HandleGuideArticlePage(c, articleID, CreateContext(c))
2 years ago
})
routesApi(h, r.Group("/api"))
}
2 years ago
// routesApi defines routes under "/api"
2 years ago
func routesApi(h handler.Service, r fiber.Router) {
2 years ago
r.Get("/utenti", func(c *fiber.Ctx) error {
utenti, err := h.HandleListaUtenti()
2 years ago
if err != nil {
return err
}
return c.JSON(utenti)
})
2 years ago
r.Get("/profilo", func(c *fiber.Ctx) error {
2 years ago
user, err := h.HandleRequiredUser(CreateContext(c))
if err != nil {
return err
}
return c.JSON(user)
})
}