skeleton/internal/web/handlers_auth.go

134 lines
3.3 KiB
Go
Raw Normal View History

2019-08-22 00:48:27 +02:00
package web
import (
2020-07-19 15:52:08 +02:00
"context"
2019-08-22 00:48:27 +02:00
"net/http"
"strconv"
"golang.org/x/crypto/bcrypt"
"bitmask.me/skeleton/internal/database"
2019-12-14 07:28:33 +01:00
ldap "github.com/go-ldap/ldap/v3"
2019-08-22 00:48:27 +02:00
"github.com/jmoiron/sqlx"
"github.com/pkg/errors"
)
// ErrNotImplemented is returned whenever a feature is not implemented yet.
var ErrNotImplemented = errors.New("Not implemented")
// User interface is provided by all data types that are returned from a
// User store.
type User interface {
GetID() string
GetDisplayName() string
}
// UserRow wraps a user row from the database.
type UserRow struct {
*database.User
}
// GetDisplayName implements User interface by returning the display name.
func (u UserRow) GetDisplayName() string {
return u.GetID()
}
// GetID implements the User interface by returning the user ID.
func (u UserRow) GetID() string {
return strconv.FormatInt(u.ID, 10)
}
2019-12-14 07:28:33 +01:00
// NewLDAPAuthenticator returns a authable function from a LDAP Database.
func NewLDAPAuthenticator(lc *ldap.Conn) func(user, pass string) (User, error) {
return func(user, pass string) (User, error) {
return nil, ErrNotImplemented
}
}
// NewSQLAuthenticator returns a authable function from a Database.
func NewSQLAuthenticator(db *sqlx.DB) func(user, pass string) (User, error) {
2019-08-22 00:48:27 +02:00
return func(user, pass string) (User, error) {
// Fetch email used for login
2020-07-19 15:52:08 +02:00
q := database.New(db)
email, err := q.GetEmailByAddress(context.TODO(), user)
2019-08-22 00:48:27 +02:00
if err != nil {
return nil, err
}
2020-07-19 15:52:08 +02:00
row, err := q.GetUserByID(context.TODO(), email.UserID)
2019-08-22 00:48:27 +02:00
if err != nil {
return nil, err
}
//u.Password
err = bcrypt.CompareHashAndPassword(row.Password, []byte(pass))
if err != nil {
return nil, err
}
2020-07-19 15:52:08 +02:00
u := UserRow{&row}
2019-08-22 00:48:27 +02:00
return u, nil
}
}
// LoginPageHandler renders the login page, and sets session cookies
// on successful authentication.
func (h *Handlers) LoginPageHandler(w http.ResponseWriter, r *http.Request) {
if r.Method == http.MethodPost {
type LoginForm struct {
Login string
Password string
}
loginForm := LoginForm{
Login: r.PostFormValue("login"),
Password: r.PostFormValue("password"),
}
2019-12-14 07:28:33 +01:00
authenticate := NewSQLAuthenticator(h.App.Database())
2019-08-22 00:48:27 +02:00
user, err := authenticate(loginForm.Login, loginForm.Password)
if err != nil {
context := h.commonRenderContext(r)
context["Errors"] = []string{"Wrong username or password"}
h.Templates().Get("auth_login.tmpl").Execute(w, context)
return
}
sess := h.Session()
sess.Put(r.Context(), SessKeyUserID, user.GetID())
sess.Put(r.Context(), SessKeyUserName, user.GetDisplayName())
http.Redirect(w, r, "/app", http.StatusFound)
return
}
h.Templates().Get("auth_login.tmpl").Execute(w, h.commonRenderContext(r))
}
2020-07-19 11:52:26 +02:00
// RegisterPageHandler renders the login page, and sets session cookies
// on successful authentication.
func (h *Handlers) RegisterPageHandler(w http.ResponseWriter, r *http.Request) {
if r.Method == http.MethodPost {
type RegisterForm struct {
Email string
}
registerForm := RegisterForm{
Email: r.PostFormValue("email"),
}
_ = registerForm
{
context := h.commonRenderContext(r)
context["Errors"] = []string{"registration disabled"}
h.Templates().Get("auth_register.tmpl").Execute(w, context)
return
}
}
h.Templates().Get("auth_register.tmpl").Execute(w, h.commonRenderContext(r))
}