package main import ( "encoding/json" "fmt" "log" "time" "github.com/gofiber/fiber/v2" ) const UserKey = "github.com/aziis98/lupus-lite/user" func requestUser(c *fiber.Ctx) *User { return c.Locals(UserKey).(*User) } func RequireLoggedMiddleware(auth Auth) fiber.Handler { return func(c *fiber.Ctx) error { token := c.Cookies("sid") if token == "" { return fmt.Errorf(`request has no session token`) } username, err := auth.UserForSession(token) if err != nil { return err } user, err := auth.GetUser(username) if err != nil { return err } c.Locals(UserKey, &user) return c.Next() } } func mountApiRoutes(api fiber.Router) { db, err := NewInMemoryDB() if err != nil { log.Fatal(err) } auth := NewInMemoryAuth(db) requireLogged := RequireLoggedMiddleware(auth) api.Get("/status", func(c *fiber.Ctx) error { s, err := json.MarshalIndent(db, "", " ") if err != nil { return err } log.Println(string(s)) return c.SendString("ok") }) api.Post("/login", func(c *fiber.Ctx) error { var loginForm struct { Username string `form:"username"` Password string `form:"password"` } if err := c.BodyParser(&loginForm); err != nil { return err } token, err := auth.Login(loginForm.Username, loginForm.Password) if err != nil { return err } c.Cookie(&fiber.Cookie{ Name: "sid", Value: token, Path: "/", Expires: time.Now().Add(3 * 24 * time.Hour), }) return c.Redirect("/") }) api.Post("/logout", func(c *fiber.Ctx) error { c.Cookie(&fiber.Cookie{ Name: "sid", Value: "", Path: "/", Expires: time.Now(), }) return c.SendString("ok") }) api.Post("/register", func(c *fiber.Ctx) error { var loginForm struct { Username string `form:"username"` Password string `form:"password"` Password2 string `form:"password2"` } if err := c.BodyParser(&loginForm); err != nil { return err } if err := validateUsername(loginForm.Username); err != nil { return err } if err := validatePasswords(loginForm.Password, loginForm.Password2); err != nil { return err } if err := auth.Register(loginForm.Username, loginForm.Password); err != nil { return err } return c.Redirect("/login") }) api.Get("/user", requireLogged, func(c *fiber.Ctx) error { return c.JSON(requestUser(c).PublicUser()) }) }