1
0
mirror of https://github.com/volatiletech/authboss.git synced 2024-11-24 08:42:17 +02:00
authboss/defaults/values.go
Aaron L d4f4f6c443 Rewrite auth module
Discovered many problems with the abstractions along the way
and did small fixes to get to the end of the auth module.

- Use more constants for random strings
- Create forcing functions to deal with the upgrades to different
  interfaces
2018-02-04 21:24:55 -08:00

130 lines
2.7 KiB
Go

package defaults
import (
"net/http"
"net/url"
"regexp"
"github.com/pkg/errors"
"github.com/volatiletech/authboss"
)
// FormValue types
const (
FormValueEmail = "email"
FormValuePassword = "password"
FormValueUsername = "username"
)
// UserValues from the login form
type UserValues struct {
HTTPFormValidator
PID string
Password string
}
// GetPID from the values
func (u UserValues) GetPID() string {
return u.PID
}
// GetPassword from the values
func (u UserValues) GetPassword() string {
return u.Password
}
// HTTPFormReader reads forms from various pages and decodes
// them.
type HTTPFormReader struct {
UseUsername bool
Rulesets map[string][]Rules
}
// NewHTTPFormReader creates a form reader with default validation rules
// for each page.
func NewHTTPFormReader(useUsernameNotEmail bool) *HTTPFormReader {
var pid string
var pidRules Rules
if useUsernameNotEmail {
pid = "username"
pidRules = Rules{
FieldName: pid, Required: true,
MatchError: "Usernames must only start with letters, and contain letters and numbers",
MustMatch: regexp.MustCompile(`(?i)[a-z][a-z0-9]?`),
}
} else {
pid = "email"
pidRules = Rules{
FieldName: pid, Required: true,
MatchError: "Must be a valid e-mail address",
MustMatch: regexp.MustCompile(`.*@.*\.[a-z]{1,}`),
}
}
passwordRule := Rules{
FieldName: "password",
MinLength: 8,
MinNumeric: 1,
MinSymbols: 1,
MinUpper: 1,
MinLower: 1,
}
return &HTTPFormReader{
UseUsername: useUsernameNotEmail,
Rulesets: map[string][]Rules{
"login": []Rules{pidRules, passwordRule},
},
}
}
// Read the form pages
func (h HTTPFormReader) Read(page string, r *http.Request) (authboss.Validator, error) {
if err := r.ParseForm(); err != nil {
return nil, errors.Wrapf(err, "failed to parse form on page: %s", page)
}
rules := h.Rulesets[page]
values := URLValuesToMap(r.Form)
switch page {
case "login":
var pid string
if h.UseUsername {
pid = values[FormValueUsername]
} else {
pid = values[FormValueEmail]
}
validator := HTTPFormValidator{
Values: values,
Ruleset: rules,
ConfirmFields: []string{FormValuePassword, authboss.ConfirmPrefix + FormValuePassword},
}
password := values[FormValuePassword]
return UserValues{
HTTPFormValidator: validator,
PID: pid,
Password: password,
}, nil
default:
return nil, errors.Errorf("failed to parse unknown page's form: %s", page)
}
}
// URLValuesToMap helps create a map from url.Values
func URLValuesToMap(form url.Values) map[string]string {
values := make(map[string]string)
for k, v := range form {
if len(v) != 0 {
values[k] = v[0]
}
}
return values
}