package index12import (3"os"4"slices"5"time"67"github.com/projectdiscovery/nuclei/v3/pkg/model/types/severity"8"github.com/projectdiscovery/nuclei/v3/pkg/templates"9"github.com/projectdiscovery/nuclei/v3/pkg/templates/types"10)1112// Metadata contains lightweight metadata extracted from a template.13type Metadata struct {14// ID is the unique identifier of the template.15ID string `gob:"id"`1617// FilePath is the path to the template file.18FilePath string `gob:"file_path"`1920// ModTime is the modification time of the template file.21ModTime time.Time `gob:"mod_time"`2223// Name is the name of the template.24Name string `gob:"name"`2526// Authors are the authors of the template.27Authors []string `gob:"authors"`2829// Tags are the tags associated with the template.30Tags []string `gob:"tags"`3132// Severity is the severity level of the template.33Severity string `gob:"severity"`3435// ProtocolType is the primary protocol type of the template.36ProtocolType string `gob:"protocol_type"`3738// Verified indicates whether the template is verified.39Verified bool `gob:"verified"`4041// TemplateVerifier is the verifier used for the template.42TemplateVerifier string `gob:"verifier,omitempty"`4344// NOTE(dwisiswant0): Consider adding more fields here in the future to45// enhance filtering caps w/o loading full templates, such as:46// `has_{code,headless,file}` to indicate presence of protocol-based47// requests, and/or classification fields (CVE, CWE, CVSS, EPSS), if needed.48//49// For maintainers: when adding new fields, don't forget to update the50// Weigher logic in [NewIndex] to account for the new fields in cache weight51// calculation, because it affects cache eviction behavior. Also, consider52// the impact on existing cached data and whether a [IndexVersion] bump is53// needed.54}5556// NewMetadataFromTemplate creates a new metadata object from a template.57func NewMetadataFromTemplate(path string, tpl *templates.Template) *Metadata {58return &Metadata{59ID: tpl.ID,60FilePath: path,6162Name: tpl.Info.Name,63Authors: tpl.Info.Authors.ToSlice(),64Tags: tpl.Info.Tags.ToSlice(),65Severity: tpl.Info.SeverityHolder.Severity.String(),6667ProtocolType: tpl.Type().String(),6869Verified: tpl.Verified,70TemplateVerifier: tpl.TemplateVerifier,71}72}7374// IsValid checks if the cached metadata is still valid by comparing the file75// modification time.76func (m *Metadata) IsValid() bool {77info, err := os.Stat(m.FilePath)78if err != nil {79return false80}8182return m.ModTime.Equal(info.ModTime())83}8485// MatchesSeverity checks if the metadata matches the given severity.86func (m *Metadata) MatchesSeverity(sev severity.Severity) bool {87return m.Severity == sev.String()88}8990// MatchesProtocol checks if the metadata matches the given protocol type.91func (m *Metadata) MatchesProtocol(protocolType types.ProtocolType) bool {92return m.ProtocolType == protocolType.String()93}9495// HasTag checks if the metadata contains the given tag.96func (m *Metadata) HasTag(tag string) bool {97return slices.Contains(m.Tags, tag)98}99100// HasAuthor checks if the metadata contains the given author.101func (m *Metadata) HasAuthor(author string) bool {102return slices.Contains(m.Authors, author)103}104105106