opengist/internal/web/auth.go

113 lines
2.6 KiB
Go

package web
import (
"errors"
"github.com/labstack/echo/v4"
"github.com/rs/zerolog/log"
"gorm.io/gorm"
"opengist/internal/models"
)
func register(ctx echo.Context) error {
setData(ctx, "title", "New account")
setData(ctx, "htmlTitle", "New account")
return html(ctx, "auth_form.html")
}
func processRegister(ctx echo.Context) error {
if getData(ctx, "signupDisabled") == true {
return errorRes(403, "Signing up is disabled", nil)
}
setData(ctx, "title", "New account")
setData(ctx, "htmlTitle", "New account")
sess := getSession(ctx)
var dto = new(models.UserDTO)
if err := ctx.Bind(dto); err != nil {
return errorRes(400, "Cannot bind data", err)
}
if err := ctx.Validate(dto); err != nil {
addFlash(ctx, validationMessages(&err), "error")
return html(ctx, "auth_form.html")
}
if exists, err := models.UserExists(dto.Username); err != nil || exists {
addFlash(ctx, "Username already exists", "error")
return html(ctx, "auth_form.html")
}
user := dto.ToUser()
password, err := argon2id.hash(user.Password)
if err != nil {
return errorRes(500, "Cannot hash password", err)
}
user.Password = password
if err = user.Create(); err != nil {
return errorRes(500, "Cannot create user", err)
}
if user.ID == 1 {
if err = user.SetAdmin(); err != nil {
return errorRes(500, "Cannot set user admin", err)
}
}
sess.Values["user"] = user.ID
saveSession(sess, ctx)
return redirect(ctx, "/")
}
func login(ctx echo.Context) error {
setData(ctx, "title", "Login")
setData(ctx, "htmlTitle", "Login")
return html(ctx, "auth_form.html")
}
func processLogin(ctx echo.Context) error {
var err error
sess := getSession(ctx)
dto := &models.UserDTO{}
if err = ctx.Bind(dto); err != nil {
return errorRes(400, "Cannot bind data", err)
}
password := dto.Password
var user *models.User
if user, err = models.GetUserByUsername(dto.Username); err != nil {
if !errors.Is(err, gorm.ErrRecordNotFound) {
return errorRes(500, "Cannot get user", err)
}
log.Warn().Msg("Invalid HTTP authentication attempt from " + ctx.RealIP())
addFlash(ctx, "Invalid credentials", "error")
return redirect(ctx, "/login")
}
if ok, err := argon2id.verify(password, user.Password); !ok {
if err != nil {
return errorRes(500, "Cannot check for password", err)
}
log.Warn().Msg("Invalid HTTP authentication attempt from " + ctx.RealIP())
addFlash(ctx, "Invalid credentials", "error")
return redirect(ctx, "/login")
}
sess.Values["user"] = user.ID
saveSession(sess, ctx)
deleteCsrfCookie(ctx)
return redirect(ctx, "/")
}
func logout(ctx echo.Context) error {
deleteSession(ctx)
deleteCsrfCookie(ctx)
return redirect(ctx, "/all")
}