Files
keyhunter/pkg/dorks/executor.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

76 lines
2.6 KiB
Go

package dorks
import (
"context"
"errors"
"fmt"
)
// ErrSourceNotImplemented is returned by Runner.Run when no executor has
// been registered for a dork's source. Most sources arrive in Phase 9-16
// (OSINT) — this phase only wires the GitHub executor live (Plan 08-05).
var ErrSourceNotImplemented = errors.New("dork source not yet implemented")
// ErrMissingAuth is returned by an Executor when the source requires
// credentials (e.g. GITHUB_TOKEN) that are not configured.
var ErrMissingAuth = errors.New("dork source requires auth credentials")
// Match is a single hit produced by an Executor. Downstream code feeds
// Snippet into the engine detection pipeline.
type Match struct {
DorkID string
Source string
URL string
Snippet string // content chunk forwarded to the detector
Path string // file path inside the source (repo, URL, etc.)
}
// Executor runs a single dork against its source backend. Implementations
// live in per-source files (executor_github.go, executor_shodan.go, ...).
// All executors except GitHub are stubs in Phase 8 and return
// ErrSourceNotImplemented.
type Executor interface {
// Source returns the dork source identifier this executor handles,
// e.g. "github". Must match one of ValidSources.
Source() string
// Execute runs the dork and returns matches. limit bounds the number
// of results to request from the backend (zero means backend default).
Execute(ctx context.Context, d Dork, limit int) ([]Match, error)
}
// Runner dispatches dorks to the correct per-source Executor.
type Runner struct {
executors map[string]Executor
}
// NewRunner returns an empty Runner. Call Register to wire in per-source
// executors. In Phase 8, only the GitHub executor is registered by
// Plan 08-05; every other source returns ErrSourceNotImplemented.
func NewRunner() *Runner {
return &Runner{executors: make(map[string]Executor)}
}
// Register installs an Executor, replacing any prior executor for the same
// source.
func (r *Runner) Register(e Executor) {
r.executors[e.Source()] = e
}
// Executor returns the registered Executor for the given source along with a
// boolean indicating whether one was found.
func (r *Runner) Executor(source string) (Executor, bool) {
e, ok := r.executors[source]
return e, ok
}
// Run locates the Executor for the dork's source and invokes it. If no
// Executor has been registered, it returns an error wrapping
// ErrSourceNotImplemented.
func (r *Runner) Run(ctx context.Context, d Dork, limit int) ([]Match, error) {
ex, ok := r.executors[d.Source]
if !ok {
return nil, fmt.Errorf("%w: %s (coming Phase 9-16)", ErrSourceNotImplemented, d.Source)
}
return ex.Execute(ctx, d, limit)
}