Files
keyhunter/pkg/dorks/registry.go
salvacybersec fd6efbb4c2 feat(08-01): add pkg/dorks foundation (schema, loader, registry, executor)
- Dork schema with Validate() mirroring provider YAML pattern
- go:embed loader tolerating empty definitions tree
- Registry with List/Get/Stats/ListBySource/ListByCategory
- Executor interface + Runner dispatch + ErrSourceNotImplemented
- Placeholder definitions/.gitkeep and repo-root dorks/.gitkeep
- Full unit test coverage for registry, validation, and runner dispatch
2026-04-06 00:15:32 +03:00

93 lines
2.5 KiB
Go

package dorks
import "fmt"
// Registry is the in-memory store of loaded dork definitions. It is built
// once at startup (via NewRegistry) and is safe for concurrent reads.
type Registry struct {
dorks []Dork
byID map[string]int
bySource map[string][]int
byCategory map[string][]int
}
// NewRegistry loads every embedded dork YAML file, validates them, and
// returns a ready-to-query Registry. An empty definitions tree is tolerated
// and yields an empty (but non-nil) Registry.
func NewRegistry() (*Registry, error) {
ds, err := loadDorks()
if err != nil {
return nil, fmt.Errorf("loading dorks: %w", err)
}
return NewRegistryFromDorks(ds), nil
}
// NewRegistryFromDorks builds a Registry from an explicit slice of dorks
// without touching the embedded filesystem. Intended for tests.
func NewRegistryFromDorks(ds []Dork) *Registry {
r := &Registry{
dorks: make([]Dork, len(ds)),
byID: make(map[string]int, len(ds)),
bySource: make(map[string][]int),
byCategory: make(map[string][]int),
}
copy(r.dorks, ds)
for i, d := range r.dorks {
r.byID[d.ID] = i
r.bySource[d.Source] = append(r.bySource[d.Source], i)
r.byCategory[d.Category] = append(r.byCategory[d.Category], i)
}
return r
}
// List returns all loaded dorks. The returned slice must not be mutated.
func (r *Registry) List() []Dork {
return r.dorks
}
// Get returns the dork with the given id and a boolean indicating whether it
// was found.
func (r *Registry) Get(id string) (Dork, bool) {
idx, ok := r.byID[id]
if !ok {
return Dork{}, false
}
return r.dorks[idx], true
}
// ListBySource returns every dork declared for the given source.
func (r *Registry) ListBySource(source string) []Dork {
idxs := r.bySource[source]
out := make([]Dork, 0, len(idxs))
for _, i := range idxs {
out = append(out, r.dorks[i])
}
return out
}
// ListByCategory returns every dork tagged with the given category.
func (r *Registry) ListByCategory(category string) []Dork {
idxs := r.byCategory[category]
out := make([]Dork, 0, len(idxs))
for _, i := range idxs {
out = append(out, r.dorks[i])
}
return out
}
// Stats returns aggregate counts grouped by source and category.
func (r *Registry) Stats() Stats {
s := Stats{
Total: len(r.dorks),
BySource: make(map[string]int, len(r.bySource)),
ByCategory: make(map[string]int, len(r.byCategory)),
}
for src, idxs := range r.bySource {
s.BySource[src] = len(idxs)
}
for cat, idxs := range r.byCategory {
s.ByCategory[cat] = len(idxs)
}
return s
}