99 lines
2.2 KiB
Go
99 lines
2.2 KiB
Go
// Package validation provides utilities for parsing and validating request data
|
|
package validation
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"net/http"
|
|
|
|
"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"
|
|
)
|
|
|
|
type ValidationRule struct {
|
|
Condition bool // Condition on which to fail validation
|
|
Title string // Title for warning message
|
|
Message string // Warning message
|
|
}
|
|
|
|
// Getter abstracts getting values from either form or query
|
|
type Getter interface {
|
|
Get(key string) string
|
|
GetList(key string) []string
|
|
AddCheck(check *ValidationRule)
|
|
String(key string) *StringField
|
|
Int(key string) *IntField
|
|
Time(key string, format *timefmt.Format) *TimeField
|
|
StringList(key string) *StringList
|
|
IntList(key string) *IntList
|
|
ValidateChecks() []*ValidationRule
|
|
Validate() bool
|
|
ValidateAndNotify(s *hws.Server, w http.ResponseWriter, r *http.Request) bool
|
|
ValidateAndError(s *hws.Server, w http.ResponseWriter, r *http.Request) bool
|
|
|
|
getChecks() []*ValidationRule
|
|
}
|
|
type FieldBase struct {
|
|
Key string
|
|
optional bool
|
|
getter Getter
|
|
}
|
|
|
|
func newField(key string, g Getter) FieldBase {
|
|
return FieldBase{
|
|
Key: key,
|
|
getter: g,
|
|
}
|
|
}
|
|
|
|
func newFailedCheck(title, message string) *ValidationRule {
|
|
return &ValidationRule{
|
|
Condition: true,
|
|
Title: title,
|
|
Message: message,
|
|
}
|
|
}
|
|
|
|
func validate(g Getter) []*ValidationRule {
|
|
failed := []*ValidationRule{}
|
|
for _, check := range g.getChecks() {
|
|
if check != nil && check.Condition {
|
|
failed = append(failed, check)
|
|
}
|
|
}
|
|
return failed
|
|
}
|
|
|
|
func validateAndNotify(
|
|
s *hws.Server,
|
|
w http.ResponseWriter,
|
|
r *http.Request,
|
|
g Getter,
|
|
) bool {
|
|
failedChecks := g.ValidateChecks()
|
|
for _, check := range failedChecks {
|
|
notify.Warn(s, w, r, check.Title, check.Message, nil)
|
|
}
|
|
return len(failedChecks) == 0
|
|
}
|
|
|
|
func validateAndError(
|
|
s *hws.Server,
|
|
w http.ResponseWriter,
|
|
r *http.Request,
|
|
g Getter,
|
|
) bool {
|
|
failedChecks := g.ValidateChecks()
|
|
var err error
|
|
for _, check := range failedChecks {
|
|
err_ := fmt.Errorf("%s: %s", check.Title, check.Message)
|
|
err = errors.Join(err, err_)
|
|
}
|
|
if len(failedChecks) > 0 {
|
|
throw.BadRequest(s, w, r, "Invalid form data", err)
|
|
}
|
|
return len(failedChecks) == 0
|
|
}
|