package formats12import (3"errors"4"io"5"os"6"strings"78"github.com/projectdiscovery/nuclei/v3/pkg/input/types"9"github.com/projectdiscovery/retryablehttp-go"10fileutil "github.com/projectdiscovery/utils/file"11"gopkg.in/yaml.v3"12)1314// ParseReqRespCallback is a callback function for discovered raw requests15type ParseReqRespCallback func(rr *types.RequestResponse) bool1617// InputFormatOptions contains options for the input18// this can be variables that can be passed or19// overrides or some other options20type InputFormatOptions struct {21// Variables is list of variables that can be used22// while generating requests in given format23Variables map[string]interface{}24// SkipFormatValidation is used to skip format validation25// while debugging or testing if format is invalid then26// requests are skipped instead of creating invalid requests27SkipFormatValidation bool28// RequiredOnly only uses required fields when generating requests29// instead of all fields30RequiredOnly bool31// VarsTextTemplating uses Variables and inject it into the input32// this is used for text templating of variables based on carvel ytt33// Only available for Yaml formats34VarsTextTemplating bool35// VarsFilePaths is the path to the file containing variables36VarsFilePaths []string37}3839// Format is an interface implemented by all input formats40type Format interface {41// Name returns the name of the format42Name() string43// Parse parses the input and calls the provided callback44// function for each RawRequest it discovers.45Parse(input io.Reader, resultsCb ParseReqRespCallback, filePath string) error46// SetOptions sets the options for the input format47SetOptions(options InputFormatOptions)48}4950// SpecDownloader is an interface for downloading API specifications from URLs51type SpecDownloader interface {52// Download downloads the spec from the given URL and saves it to tmpDir53// Returns the path to the downloaded file54// httpClient is a retryablehttp.Client instance (can be nil for fallback)55Download(url, tmpDir string, httpClient *retryablehttp.Client) (string, error)56// SupportedExtensions returns the list of supported file extensions57SupportedExtensions() []string58}5960var (61DefaultVarDumpFileName = "required_openapi_params.yaml"62ErrNoVarsDumpFile = errors.New("no required params file found")63)6465// == OpenAPIParamsCfgFile ==66// this file is meant to be used in CLI mode67// to be more interactive and user-friendly when68// running nuclei with openapi format6970// OpenAPIParamsCfgFile is the structure of the required vars dump file71type OpenAPIParamsCfgFile struct {72Var []string `yaml:"var"`73OptionalVars []string `yaml:"-"` // this will be written to the file as comments74}7576// ReadOpenAPIVarDumpFile reads the required vars dump file77func ReadOpenAPIVarDumpFile() (*OpenAPIParamsCfgFile, error) {78var vars OpenAPIParamsCfgFile79if !fileutil.FileExists(DefaultVarDumpFileName) {80return nil, ErrNoVarsDumpFile81}82bin, err := os.ReadFile(DefaultVarDumpFileName)83if err != nil {84return nil, err85}86err = yaml.Unmarshal(bin, &vars)87if err != nil {88return nil, err89}90filtered := []string{}91for _, v := range vars.Var {92v = strings.TrimSpace(v)93if !strings.HasSuffix(v, "=") {94filtered = append(filtered, v)95}96}97vars.Var = filtered98return &vars, nil99}100101// WriteOpenAPIVarDumpFile writes the required vars dump file102func WriteOpenAPIVarDumpFile(vars *OpenAPIParamsCfgFile) error {103f, err := os.OpenFile(DefaultVarDumpFileName, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0644)104if err != nil {105return err106}107defer func() {108_ = f.Close()109}()110bin, err := yaml.Marshal(vars)111if err != nil {112return err113}114_, _ = f.Write(bin)115if len(vars.OptionalVars) > 0 {116_, _ = f.WriteString("\n # Optional parameters\n")117for _, v := range vars.OptionalVars {118_, _ = f.WriteString(" # - " + v + "=\n")119}120}121return f.Sync()122}123124125