package validation import ( "fmt" "net/http" "strconv" ) // ValidatePathUUID validates a UUID path parameter // CWE-20: Improper Input Validation func ValidatePathUUID(r *http.Request, paramName string) (string, error) { value := r.PathValue(paramName) if value == "" { return "", fmt.Errorf("%s is required", paramName) } validator := NewValidator() if err := validator.ValidateUUID(value, paramName); err != nil { return "", err } return value, nil } // ValidatePathSlug validates a slug path parameter // CWE-20: Improper Input Validation func ValidatePathSlug(r *http.Request, paramName string) (string, error) { value := r.PathValue(paramName) if value == "" { return "", fmt.Errorf("%s is required", paramName) } validator := NewValidator() if err := validator.ValidateSlug(value, paramName); err != nil { return "", err } return value, nil } // ValidatePathInt validates an integer path parameter // CWE-20: Improper Input Validation func ValidatePathInt(r *http.Request, paramName string) (int64, error) { valueStr := r.PathValue(paramName) if valueStr == "" { return 0, fmt.Errorf("%s is required", paramName) } value, err := strconv.ParseInt(valueStr, 10, 64) if err != nil { return 0, fmt.Errorf("%s must be a valid integer", paramName) } if value <= 0 { return 0, fmt.Errorf("%s must be greater than 0", paramName) } return value, nil } // ValidatePagination validates pagination query parameters // Returns limit and offset with defaults and bounds checking func ValidatePagination(r *http.Request, defaultLimit int) (limit int, offset int, err error) { limit = defaultLimit offset = 0 // Validate limit if limitStr := r.URL.Query().Get("limit"); limitStr != "" { parsedLimit, err := strconv.Atoi(limitStr) if err != nil || parsedLimit <= 0 || parsedLimit > 100 { return 0, 0, fmt.Errorf("limit must be between 1 and 100") } limit = parsedLimit } // Validate offset if offsetStr := r.URL.Query().Get("offset"); offsetStr != "" { parsedOffset, err := strconv.Atoi(offsetStr) if err != nil || parsedOffset < 0 { return 0, 0, fmt.Errorf("offset must be >= 0") } offset = parsedOffset } return limit, offset, nil } // ValidateSortField validates sort field against whitelist // CWE-89: SQL Injection prevention via whitelist func ValidateSortField(r *http.Request, allowedFields []string) (string, error) { sortBy := r.URL.Query().Get("sort_by") if sortBy == "" { return "", nil // Optional field } for _, allowed := range allowedFields { if sortBy == allowed { return sortBy, nil } } return "", fmt.Errorf("invalid sort_by field (allowed: %v)", allowedFields) } // ValidateQueryEmail validates an email query parameter // CWE-20: Improper Input Validation func ValidateQueryEmail(r *http.Request, paramName string) (string, error) { email := r.URL.Query().Get(paramName) if email == "" { return "", fmt.Errorf("%s is required", paramName) } emailValidator := NewEmailValidator() normalizedEmail, err := emailValidator.ValidateAndNormalize(email, paramName) if err != nil { return "", err } return normalizedEmail, nil }