Files
oslstats/internal/validation/forms.go
2026-02-15 12:27:36 +11:00

115 lines
2.8 KiB
Go

package validation
import (
"net/http"
"strings"
"git.haelnorr.com/h/golib/hws"
"git.haelnorr.com/h/oslstats/internal/notify"
"git.haelnorr.com/h/oslstats/internal/throw"
"git.haelnorr.com/h/timefmt"
"github.com/pkg/errors"
)
// FormGetter wraps http.Request to get form values
type FormGetter struct {
r *http.Request
checks []*ValidationRule
}
func NewFormGetter(r *http.Request) *FormGetter {
return &FormGetter{r: r, checks: []*ValidationRule{}}
}
func (f *FormGetter) Get(key string) string {
return f.r.FormValue(key)
}
func (f *FormGetter) GetList(key string) []string {
return strings.Split(f.Get(key), ",")
}
func (f *FormGetter) getChecks() []*ValidationRule {
return f.checks
}
func (f *FormGetter) AddCheck(check *ValidationRule) {
f.checks = append(f.checks, check)
}
func (f *FormGetter) ValidateChecks() []*ValidationRule {
return validate(f)
}
func (f *FormGetter) String(key string) *StringField {
return newStringField(key, f)
}
func (f *FormGetter) Int(key string) *IntField {
return newIntField(key, f)
}
func (f *FormGetter) Time(key string, format *timefmt.Format) *TimeField {
return newTimeField(key, format, f)
}
func (f *FormGetter) StringList(key string) *StringList {
return newStringList(key, f)
}
func (f *FormGetter) IntList(key string) *IntList {
return newIntList(key, f)
}
func ParseForm(r *http.Request) (*FormGetter, error) {
err := r.ParseForm()
if err != nil {
return nil, errors.Wrap(err, "r.ParseForm")
}
return NewFormGetter(r), nil
}
// ParseFormOrNotify attempts to parse the form data and notifies the user on fail
func ParseFormOrNotify(s *hws.Server, w http.ResponseWriter, r *http.Request) (*FormGetter, bool) {
getter, err := ParseForm(r)
if err != nil {
notify.Warn(s, w, r, "Invalid Form", "Please check your input and try again.", nil)
return nil, false
}
return getter, true
}
// ParseFormOrError attempts to parse the form data and renders an error page on fail
func ParseFormOrError(s *hws.Server, w http.ResponseWriter, r *http.Request) (*FormGetter, bool) {
getter, err := ParseForm(r)
if err != nil {
throw.BadRequest(s, w, r, "Invalid form data", err)
return nil, false
}
return getter, true
}
func (f *FormGetter) Validate() bool {
return len(validate(f)) == 0
}
// ValidateAndNotify runs the provided validation checks and sends a notification for each failed check
// Returns true if all checks passed
func (f *FormGetter) ValidateAndNotify(
s *hws.Server,
w http.ResponseWriter,
r *http.Request,
) bool {
return validateAndNotify(s, w, r, f)
}
// ValidateAndError runs the provided validation checks and renders an error page with all the error messages
// Returns true if all checks passed
func (f *FormGetter) ValidateAndError(
s *hws.Server,
w http.ResponseWriter,
r *http.Request,
) bool {
return validateAndError(s, w, r, f)
}