//go:build standalone package checker import ( "errors" "net/http" "strconv" "strings" sdk "git.happydns.org/checker-sdk-go/checker" ) // RenderForm builds the standalone form by aggregating each registered // source's option fields. The "domain" field is hard-coded since it // applies to every source; everything else is contributed by sources. func (p *blacklistProvider) RenderForm() []sdk.CheckerOptionField { fields := []sdk.CheckerOptionField{ { Id: "domain", Type: "string", Label: "Domain", Placeholder: "example.com", Description: "Domain to test against the configured reputation sources.", Required: true, }, } for _, s := range Sources() { o := s.Options() fields = append(fields, o.Admin...) fields = append(fields, o.User...) } return fields } // ParseForm walks every option field declared by the sources and reads // it from the form. The generic loop means a new source's fields // appear in /check automatically. func (p *blacklistProvider) ParseForm(r *http.Request) (sdk.CheckerOptions, error) { domain := strings.TrimSpace(r.FormValue("domain")) if domain == "" { return nil, errors.New("a domain is required") } opts := sdk.CheckerOptions{ "domain": domain, "domain_name": domain, } for _, s := range Sources() { o := s.Options() for _, f := range append(append([]sdk.CheckerOptionField{}, o.Admin...), o.User...) { raw := strings.TrimSpace(r.FormValue(f.Id)) if raw == "" { if f.Type == "bool" { opts[f.Id] = boolDefault(f.Default) } continue } switch f.Type { case "bool": opts[f.Id] = parseFormBool(raw, true) case "number", "uint": if n, err := strconv.ParseFloat(raw, 64); err == nil { opts[f.Id] = n } default: opts[f.Id] = raw } } } return opts, nil } func parseFormBool(s string, defaultVal bool) bool { switch strings.ToLower(strings.TrimSpace(s)) { case "": return defaultVal case "true", "on", "1", "yes": return true default: return false } } func boolDefault(v any) bool { if b, ok := v.(bool); ok { return b } return false }