package dav import ( "errors" "net/http" "strconv" "strings" sdk "git.happydns.org/checker-sdk-go/checker" ) func UserOptions() []sdk.CheckerOptionDocumentation { return []sdk.CheckerOptionDocumentation{ { Id: "username", Type: "string", Label: "Username", Description: "Optional. Supplying credentials unlocks authenticated checks (principal, home-set, collections, report probe).", }, { Id: "password", Type: "string", Label: "Password or token", Description: "Optional. Paired with the username for HTTP Basic authentication.", Secret: true, }, { Id: "context_url", Type: "string", Label: "Explicit context URL", Description: "Optional. Bypasses /.well-known and SRV discovery. Use for servers with a non-standard layout.", Placeholder: "https://dav.example.com/caldav/", }, } } func DomainOptions() []sdk.CheckerOptionDocumentation { return []sdk.CheckerOptionDocumentation{ { Id: "domain_name", Label: "Domain name", AutoFill: sdk.AutoFillDomainName, }, } } func RunOptions() []sdk.CheckerOptionDocumentation { return []sdk.CheckerOptionDocumentation{ { Id: "timeout_seconds", Type: "number", Label: "Timeout (seconds)", Description: "Per-request HTTP timeout.", Default: float64(10), }, } } // InteractiveForm mirrors UserOptions+DomainOptions+RunOptions for the // standalone /check page. Discovery happens inside Collect, so all the // human owes us is the domain. func InteractiveForm() []sdk.CheckerOptionField { return []sdk.CheckerOptionField{ { Id: "domain_name", Type: "string", Label: "Domain name", Placeholder: "example.com", Required: true, }, { Id: "username", Type: "string", Label: "Username", Description: "Optional. Supplying credentials unlocks authenticated checks.", }, { Id: "password", Type: "string", Label: "Password or token", Description: "Optional. Paired with the username for HTTP Basic auth.", Secret: true, }, { Id: "context_url", Type: "string", Label: "Explicit context URL", Description: "Optional. Bypasses /.well-known and SRV discovery.", Placeholder: "https://dav.example.com/caldav/", }, { Id: "timeout_seconds", Type: "number", Label: "Timeout (seconds)", Description: "Per-request HTTP timeout.", Default: float64(10), }, } } func ParseInteractiveForm(r *http.Request) (sdk.CheckerOptions, error) { domain := strings.TrimSpace(r.FormValue("domain_name")) if domain == "" { return nil, errors.New("domain name is required") } opts := sdk.CheckerOptions{"domain_name": domain} if v := strings.TrimSpace(r.FormValue("username")); v != "" { opts["username"] = v } if v := r.FormValue("password"); v != "" { opts["password"] = v } if v := strings.TrimSpace(r.FormValue("context_url")); v != "" { opts["context_url"] = v } if v := strings.TrimSpace(r.FormValue("timeout_seconds")); v != "" { f, err := strconv.ParseFloat(v, 64) if err != nil { return nil, errors.New("timeout must be a number") } opts["timeout_seconds"] = f } return opts, nil }