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
This commit is contained in:
75
pkg/dorks/executor.go
Normal file
75
pkg/dorks/executor.go
Normal file
@@ -0,0 +1,75 @@
|
||||
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)
|
||||
}
|
||||
Reference in New Issue
Block a user