lavender/auth/providers/password.go

76 lines
1.8 KiB
Go
Raw Normal View History

package providers
2024-10-06 21:30:39 +01:00
import (
"context"
"database/sql"
"errors"
"github.com/1f349/lavender/auth"
2025-01-19 12:04:25 +00:00
"github.com/1f349/lavender/auth/authContext"
"github.com/1f349/lavender/auth/process"
2024-10-06 21:30:39 +01:00
"github.com/1f349/lavender/database"
"net/http"
)
2025-01-25 19:49:57 +00:00
type passwordLoginDB interface {
2025-03-13 22:41:57 +00:00
GetUser(ctx context.Context, subject string) (database.User, error)
2024-10-06 21:30:39 +01:00
CheckLogin(ctx context.Context, un, pw string) (database.CheckLoginResult, error)
}
2025-01-25 19:49:57 +00:00
var (
_ auth.Provider = (*PasswordLogin)(nil)
_ auth.Form = (*PasswordLogin)(nil)
)
2024-10-06 21:30:39 +01:00
2025-01-25 19:49:57 +00:00
type PasswordLogin struct {
DB passwordLoginDB
2024-10-06 21:30:39 +01:00
}
2025-03-13 23:05:05 +00:00
func (p *PasswordLogin) AccessState() process.State { return process.StateBase }
2024-10-06 21:30:39 +01:00
2025-03-13 23:05:05 +00:00
func (p *PasswordLogin) Name() string { return "password" }
2024-10-06 21:30:39 +01:00
2025-03-13 23:05:05 +00:00
func (p *PasswordLogin) RenderTemplate(ctx authContext.TemplateContext) error {
2024-12-09 18:40:18 +00:00
// TODO(melon): rewrite this
2025-01-19 12:04:25 +00:00
req := ctx.Request()
redirect := req.FormValue("redirect")
if redirect == "" {
redirect = "/"
}
ctx.Render(struct {
UserEmail string
Redirect string
}{
2025-03-13 23:05:05 +00:00
UserEmail: ctx.LoginProcessData().Email,
2025-01-19 12:04:25 +00:00
Redirect: redirect,
})
return nil
2024-10-06 21:30:39 +01:00
}
2025-03-13 23:05:05 +00:00
func (p *PasswordLogin) AttemptLogin(ctx authContext.FormContext) error {
2025-01-19 12:04:25 +00:00
req := ctx.Request()
2025-03-13 23:05:05 +00:00
un := req.FormValue("email")
2024-10-06 21:30:39 +01:00
pw := req.FormValue("password")
if len(pw) < 8 {
return auth.BasicUserSafeError(http.StatusBadRequest, "Password too short")
2024-10-06 21:30:39 +01:00
}
2025-03-13 23:05:05 +00:00
login, err := p.DB.CheckLogin(ctx.Context(), un, pw)
2024-10-06 21:30:39 +01:00
switch {
case err == nil:
2025-03-13 23:05:05 +00:00
user, err := p.DB.GetUser(ctx.Context(), login.Subject)
2025-03-13 22:41:57 +00:00
if err != nil {
return err
}
ctx.SetUser(&user)
ctx.UpdateSession(process.LoginProcessData{
State: process.StateBasic,
Email: un,
})
return nil
2024-10-06 21:30:39 +01:00
case errors.Is(err, sql.ErrNoRows):
return auth.BasicUserSafeError(http.StatusForbidden, "Username or password is invalid")
2024-10-06 21:30:39 +01:00
default:
return err
}
}