aboutsummaryrefslogtreecommitdiff
path: root/controllers/login.go
blob: aa02e0c5df710ddfd76df9428cb2bbf3081f1bee (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
package controllers

import (
	"imageboard/config"
	"imageboard/database"
	"imageboard/session"
	"imageboard/utils/auth"
	"imageboard/utils/shortcuts"

	"github.com/gofiber/fiber/v2"
)

type LoginForm struct {
	Username string `json:"username" form:"username"`
	Password string `json:"password" form:"password"`
}

func renderLoginError(ctx *fiber.Ctx, errorMsg string, statusCode int) error {
	return shortcuts.RenderWithStatus(ctx, config.TEMPLATE_LOGIN, fiber.Map{
		"Error":    errorMsg,
		"Username": ctx.FormValue("username"), // Preserve username in form
	}, statusCode)
}

func LoginPageController(ctx *fiber.Ctx) error {
	ctx.Locals("Title", config.PT_LOGIN)

	if auth.IsAuthenticated(ctx) {
		return ctx.Redirect(auth.GetRedirectURL(ctx), fiber.StatusSeeOther)
	}

	next := ctx.Query("next")
	return shortcuts.Render(ctx, config.TEMPLATE_LOGIN, fiber.Map{
		"Next": next,
	})
}

func LoginPostController(ctx *fiber.Ctx) error {
	ctx.Locals("Title", config.PT_LOGIN)

	var form LoginForm
	var err error
	if err = ctx.BodyParser(&form); err != nil {
		return renderLoginError(ctx, config.ERR_INVALID_FORM_DATA, fiber.StatusBadRequest)
	}

	user, err := database.GetUserByUsername(form.Username)
	if err != nil {
		return renderLoginError(ctx, config.ERR_USER_NOT_FOUND, fiber.StatusUnauthorized)
	}

	if !user.CheckPassword(form.Password) {
		return renderLoginError(ctx, config.ERR_LOGIN_INVALID_CREDENTIALS, fiber.StatusUnauthorized)
	}

	if !user.IsActive() {
		return renderLoginError(ctx, config.ERR_ACCOUNT_DISABLED, fiber.StatusForbidden)
	}

	if !user.CanLogin() {
		return renderLoginError(ctx, config.ERR_ACCOUNT_UNABLE_TO_LOGIN, fiber.StatusForbidden)
	}

	sess, err := session.Store.Get(ctx)
	if err != nil {
		return renderLoginError(ctx, config.ERR_SESSION_FAILED_TO_CREATE, fiber.StatusInternalServerError)
	}
	sess.Set("user_id", user.ID)
	sess.Set("username", user.Username)
	if err := sess.Save(); err != nil {
		return renderLoginError(ctx, config.ERR_SESSION_FAILED_TO_SAVE, fiber.StatusInternalServerError)
	}

	user.UpdateLastUserLogin(database.DB)
	user.UpdateLastUserActivity(database.DB)

	return ctx.Redirect(auth.GetRedirectURL(ctx), fiber.StatusSeeOther)
}