From af5528f60c4d12f4e089f8b2f083e1b4d5d91a07 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?William=20Bouzour=C3=A8ne?= Date: Sat, 21 Dec 2024 18:39:09 +0100 Subject: [PATCH] Create login form & handle auth --- controllers/login.go | 68 +++++++++++++++++++++++++++++++++-- helpers/users.go | 2 +- main.go | 2 ++ middlewares/authentication.go | 16 ++++++++- static/main.css | 9 +++-- views/login.pug | 22 ++++++++++++ 6 files changed, 112 insertions(+), 7 deletions(-) create mode 100644 views/login.pug diff --git a/controllers/login.go b/controllers/login.go index 790b4a6..3e3bcf0 100644 --- a/controllers/login.go +++ b/controllers/login.go @@ -1,10 +1,72 @@ package controllers -import "github.com/gofiber/fiber/v2" +import ( + "errors" + "fmt" + "time" + + "git.readonly.ch/bouzoure/popvaud-people/helpers" + "git.readonly.ch/bouzoure/popvaud-people/models" + "github.com/gofiber/fiber/v2" + "gorm.io/gorm" +) func LoginForm(c *fiber.Ctx) error { - return c.Render("index", fiber.Map{ + return c.Render("login", fiber.Map{ "PageTitle": "Connexion", - "Title": "Hello, World!", }, "layouts/main") } + +func LoginProcess(c *fiber.Ctx) error { + sess, err := helpers.GetSessionStore(c) + if err != nil { + return err + } + + db, err := helpers.GetDatabase() + if err != nil { + return err + } + + email := c.FormValue("email") + password := c.FormValue("password") + + var user models.User + result := db.First( + &user, + "LOWER(email) = LOWER(?) AND (disabled_at IS NULL OR disabled_at <= ?)", + email, + time.Now(), + ) + + allowLogin := false + if result.Error != nil && !errors.Is(result.Error, gorm.ErrRecordNotFound) { + return err + } else { + allowLogin = helpers.CheckPasswordHash(password, user.Password) + } + + if !allowLogin { + return c.Render("login", fiber.Map{ + "PageTitle": "Connexion", + "LoginError": "Email ou mot de passe incorrect", + }, "layouts/main") + } + + sess.Set("userid", user.ID) + sess.Save() + + redirectId := c.Query("redirect") + redirectUrl := "/" + + if len(redirectId) > 0 { + redirectKey := fmt.Sprintf("redirect-%s", redirectId) + redirectVal := sess.Get(redirectKey) + + if redirectVal != nil { + redirectUrl = redirectVal.(string) + } + } + + return c.Redirect(redirectUrl) +} diff --git a/helpers/users.go b/helpers/users.go index db3a029..868874d 100644 --- a/helpers/users.go +++ b/helpers/users.go @@ -54,7 +54,7 @@ func FirstAccountCreate() error { return nil } -func UserExistsAndIsActive(id int) (bool, error) { +func UserExistsAndIsActive(id uint) (bool, error) { db, err := GetDatabase() if err != nil { return false, err diff --git a/main.go b/main.go index e5aca8c..dc8c685 100644 --- a/main.go +++ b/main.go @@ -81,10 +81,12 @@ func main() { // Middlewares app.Use(middlewares.AuthMiddleware) + app.Use("/login", middlewares.DenyAuthMiddleware) // Controllers app.Get("/", controllers.Homepage) app.Get("/login", controllers.LoginForm) + app.Post("/login", controllers.LoginProcess) listenAddr := fmt.Sprintf( "%s:%d", diff --git a/middlewares/authentication.go b/middlewares/authentication.go index 2ff373b..e10464f 100644 --- a/middlewares/authentication.go +++ b/middlewares/authentication.go @@ -24,7 +24,7 @@ func AuthMiddleware(c *fiber.Ctx) error { if userid == nil { denyAccess = true } else { - active, err := helpers.UserExistsAndIsActive(userid.(int)) + active, err := helpers.UserExistsAndIsActive(userid.(uint)) if err != nil { return err } @@ -55,3 +55,17 @@ func AuthMiddleware(c *fiber.Ctx) error { return c.Next() } + +func DenyAuthMiddleware(c *fiber.Ctx) error { + sess, err := helpers.GetSessionStore(c) + if err != nil { + return err + } + + userid := sess.Get("userid") + if userid != nil { + return fiber.NewError(fiber.StatusForbidden, "Forbidden") + } + + return c.Next() +} diff --git a/static/main.css b/static/main.css index 5830d71..cded75c 100644 --- a/static/main.css +++ b/static/main.css @@ -1,4 +1,9 @@ img#header-logo { - width: 200px; - height: 100px; + width: 60px; + height: 30px; +} + +#login-card { + margin: auto; + max-width: 600px; } \ No newline at end of file diff --git a/views/login.pug b/views/login.pug new file mode 100644 index 0000000..feff70d --- /dev/null +++ b/views/login.pug @@ -0,0 +1,22 @@ +include partials/header.pug + +.container + #login-card.my-5 + .card + .card-header + | Authentification + .card-body + if .LoginError + .alert.alert-danger + | #{.LoginError} + form#login(method="post") + .mb-3 + label.form-label(for="email") Adresse email + input#email.form-control(type="email", required, name="email") + .mb-3 + label.form-label(for="password") Mot de passe + input#password.form-control(type="password", required, name="password") + .mt-3.text-end + button.btn.btn-primary(type="submit") + i.me-2(data-feather="log-in") + | Connexion