mirror of
https://github.com/volatiletech/authboss.git
synced 2026-06-19 23:00:27 +02:00
129 lines
3.4 KiB
Go
129 lines
3.4 KiB
Go
// Package register allows for user registration.
|
|
package register
|
|
|
|
import (
|
|
"errors"
|
|
"net/http"
|
|
|
|
"golang.org/x/crypto/bcrypt"
|
|
"gopkg.in/authboss.v0"
|
|
"gopkg.in/authboss.v0/internal/render"
|
|
)
|
|
|
|
const (
|
|
tplRegister = "register.html.tpl"
|
|
)
|
|
|
|
// RegisterStorer must be implemented in order to satisfy the register module's
|
|
// storage requirments.
|
|
type RegisterStorer interface {
|
|
authboss.Storer
|
|
// Create is the same as put, except it refers to a non-existent key.
|
|
Create(key string, attr authboss.Attributes) error
|
|
}
|
|
|
|
func init() {
|
|
authboss.RegisterModule("register", &Register{})
|
|
}
|
|
|
|
// Register module.
|
|
type Register struct {
|
|
templates render.Templates
|
|
}
|
|
|
|
// Initialize the module.
|
|
func (r *Register) Initialize() (err error) {
|
|
if authboss.Cfg.Storer == nil {
|
|
return errors.New("register: Need a RegisterStorer")
|
|
}
|
|
|
|
if _, ok := authboss.Cfg.Storer.(RegisterStorer); !ok {
|
|
return errors.New("register: RegisterStorer required for register functionality")
|
|
}
|
|
|
|
if r.templates, err = render.LoadTemplates(authboss.Cfg.Layout, authboss.Cfg.ViewsPath, tplRegister); err != nil {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// Routes creates the routing table.
|
|
func (r *Register) Routes() authboss.RouteTable {
|
|
return authboss.RouteTable{
|
|
"/register": r.registerHandler,
|
|
}
|
|
}
|
|
|
|
// Storage returns storage requirements.
|
|
func (r *Register) Storage() authboss.StorageOptions {
|
|
return authboss.StorageOptions{
|
|
authboss.Cfg.PrimaryID: authboss.String,
|
|
authboss.StorePassword: authboss.String,
|
|
}
|
|
}
|
|
|
|
func (reg *Register) registerHandler(ctx *authboss.Context, w http.ResponseWriter, r *http.Request) error {
|
|
switch r.Method {
|
|
case "GET":
|
|
data := authboss.HTMLData{
|
|
"primaryID": authboss.Cfg.PrimaryID,
|
|
"primaryIDValue": "",
|
|
}
|
|
return reg.templates.Render(ctx, w, r, tplRegister, data)
|
|
case "POST":
|
|
return reg.registerPostHandler(ctx, w, r)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (reg *Register) registerPostHandler(ctx *authboss.Context, w http.ResponseWriter, r *http.Request) error {
|
|
key, _ := ctx.FirstPostFormValue(authboss.Cfg.PrimaryID)
|
|
password, _ := ctx.FirstPostFormValue(authboss.StorePassword)
|
|
|
|
policies := authboss.FilterValidators(authboss.Cfg.Policies, authboss.Cfg.PrimaryID, authboss.StorePassword)
|
|
validationErrs := ctx.Validate(policies, authboss.Cfg.ConfirmFields...)
|
|
|
|
if len(validationErrs) != 0 {
|
|
data := authboss.HTMLData{
|
|
"primaryID": authboss.Cfg.PrimaryID,
|
|
"primaryIDValue": key,
|
|
"errs": validationErrs.Map(),
|
|
}
|
|
|
|
return reg.templates.Render(ctx, w, r, tplRegister, data)
|
|
}
|
|
|
|
attr, err := ctx.Attributes() // Attributes from overriden forms
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
pass, err := bcrypt.GenerateFromPassword([]byte(password), authboss.Cfg.BCryptCost)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
attr[authboss.Cfg.PrimaryID] = key
|
|
attr[authboss.StorePassword] = string(pass)
|
|
ctx.User = attr
|
|
|
|
if err := authboss.Cfg.Storer.(RegisterStorer).Create(key, attr); err != nil {
|
|
return err
|
|
}
|
|
|
|
if err := authboss.Cfg.Callbacks.FireAfter(authboss.EventRegister, ctx); err != nil {
|
|
return err
|
|
}
|
|
|
|
if authboss.IsLoaded("confirm") {
|
|
render.Redirect(ctx, w, r, authboss.Cfg.RegisterOKPath, "Account successfully created, please verify your e-mail address.", "", true)
|
|
return nil
|
|
}
|
|
|
|
ctx.SessionStorer.Put(authboss.SessionKey, key)
|
|
render.Redirect(ctx, w, r, authboss.Cfg.RegisterOKPath, "Account successfully created, you are now logged in.", "", true)
|
|
|
|
return nil
|
|
}
|