Skip to content

feat: preview draft job policy, scope, and unit probe budget #1267

Closed

Description

@crypt0rr

Result

Before saving a monitor, a unit administrator/operator can validate its configuration and see the scanner scope and budget consequences. Add POST /api/v1/jobs/preview without creating a job or starting work.

Parent: #1266. No implementation prerequisite; coordinate the response contract with the shared-draft task.

API contract

Request: the existing new-job JobForm JSON payload (create semantics, not an update to a job ID). Response: job (normalized public job payload with selected profile revision), scan_estimate (existing WorkEstimate shape), scan_budget (existing budget outcome), and a bounded warnings array of {code, field?, message} describing estimate limitations and configuration choices. Document examples and field meanings. Do not echo arbitrary unknown input or credentials.

  • Missing timezone follows current create defaults. An unspecified TCP scanner follows defaultNewScannerProfile; explicitly chosen Nmap ports must not become full-range Naabu implicitly.
  • Invalid input uses current field-validation responses. Unavailable resources and profile conflicts use the same semantics as creation. Missing policy/budget data must return a clear unavailable response, not a fabricated fit.
  • Report syntactically valid work that exceeds the unit budget as a preview outcome, so the UI can explain and revise scope. Saving remains compatible with existing behavior; the guided start action must not promise an over-budget run will execute.
  • Preview does not reserve a name, lease, profile revision, or budget. Create/run revalidate, including races after preview. Do not add hidden snapshot or token state.

Implementation

  1. Extract only the creation preparation needed for defaults, payload conversion, permission checks, selected-profile resolution, and notification selection from internal/web/job_handlers.go. Reuse it for create and preview, preserving audited creation and existing error contracts.
  2. Reuse the store-installed target exclusion validator (internal/store/store.go), including the distinction between nil and explicitly empty policy. If a new exported TenantStore validation method is necessary, register and test it under the existing tenancy contract. Do not bypass scoped stores or inspect another unit's records.
  3. Reuse internal/config/config.go and App.CheckScanWorkBudget. Keep DNS expansion and data-dependent Naabu→Nmap enrichment explicit; no elapsed-time promise. Estimate arithmetic remains bounded even for huge CIDRs and expressions.
  4. Register/dispatch preview before /jobs/{id} matching in internal/web/server.go and internal/web/permissions.go. Require jobs.write, existing POST session/CSRF/origin protections, and existing high-cost approval rules. Deny anonymous, viewer, and platform-admin requests.
  5. Add response types in src/types.ts and a cancelable previewJob(draft, signal?) API helper in src/api.ts. Follow existing API error and CSRF behavior.

Acceptance and tests

  • Valid full-range Naabu, selected-port Nmap, optional UDP, timezone/default normalization, exclusions, malformed targets/durations/ports, large CIDRs, and DNS uncertainty are covered.
  • Preview and create prepare equivalent public configuration/profile revision for a representative table of inputs; advanced editing/rebaseline validation remains intact.
  • Another unit's custom profile or destination is indistinguishable from an unknown ID; stale/archived profile revisions follow current create rules.
  • Administrator/operator/viewer/platform-admin/anonymous, CSRF/origin, high-cost override, and disabled-unit cases pass TestIsolationMatrix and route-permission coverage.
  • Unit budget exceeded/approval-would-fit/unavailable results are truthful and tested for both scanner engines and the absolute ceiling.
  • Instrumented fixtures demonstrate no DNS, scanner/notifier process, monitoring-domain writes (jobs, baselines, scans, outbox, or audit), schedule refresh, or SSE event during preview; ordinary authentication/session bookkeeping remains unchanged. Use fresh migrated-template databases.
  • API client tests cover JSON, cancellation, validation/conflict/unavailable responses, and credential absence.
  • Update docs/src/content/docs/reference/api-compatibility.md with the additive endpoint and limitation semantics; update relevant security guidance if the documented boundary changes, build docs, and verify deployment.

Likely files: internal/web/job_handlers.go, internal/web/server.go, internal/web/permissions.go, internal/web/scanner_profiles.go, a narrow store validation adapter if required, nearby backend permission/isolation tests, src/api.ts, src/types.ts, and API tests. Existing estimator changes should be minimal and justified.

Checks: gofmt, go vet ./..., go test -race -timeout=25m ./...; frontend lint/build/coverage; docs build/deployment and normal CI/security/diff coverage. Estimated effort: 6–10 hours.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions