authorize('update', $investigation); $type = $request->validate([ 'type' => ['required', 'string', 'in:'.implode(',', Target::TYPES)], ])['type']; $data = $request->validate([ 'value' => Target::valueRulesFor($type), 'notes' => ['nullable', 'string', 'max:5000'], ]); $investigation->targets()->create([ ...$data, 'type' => $type, 'created_by' => $request->user()->id, ]); return redirect()->route('investigations.show', $investigation); } public function destroy(Investigation $investigation, Target $target): RedirectResponse { $this->authorize('update', $investigation); abort_if($target->investigation_id !== $investigation->id, 404); $target->delete(); return redirect()->route('investigations.show', $investigation); } public function run(Request $request, Investigation $investigation, Target $target, RunnerRegistry $registry): RedirectResponse { $this->authorize('update', $investigation); abort_if($target->investigation_id !== $investigation->id, 404); $data = $request->validate([ 'source_id' => ['required', 'integer', 'exists:sources,id'], ]); $source = Source::findOrFail($data['source_id']); if (! in_array($target->type, $source->target_types, true) || ! $registry->has($source->key)) { return back()->withErrors(['source_id' => "{$source->name} can't be run against this target."]); } $finding = Finding::create([ 'target_id' => $target->id, 'source_id' => $source->id, 'run_by' => $request->user()->id, 'status' => 'pending', ]); RunFinding::dispatch($finding->id); return redirect()->route('investigations.show', $investigation) ->with('status', "Running {$source->name} against {$target->value}..."); } }