defmodule Paraxial.Scan do @moduledoc false @derive Jason.Encoder defstruct [:timestamp, :findings, :api_key] alias Paraxial.Finding def get_timestamp() do DateTime.utc_now() end def make_sobelow(raw_scan) do # Input: The raw json output from a sobelow scan # Action: Use :jason (it's already in project) to parse, construct findings # Returns a list of findings scan_map = Jason.decode!(raw_scan)["findings"] Enum.map(scan_map, fn {confidence, findings} -> Enum.map(findings, fn finding -> %Finding{ source: "sobelow", content: Map.put(finding, "confidence", confidence) } end) end) |> List.flatten() end def make_deps(raw_deps) do raw_deps |> String.split("\n\n") |> Enum.map(&dep_to_finding/1) |> List.flatten() end def fpart_to_tuple(fpart) do fpart |> String.split(":", parts: 2) |> List.to_tuple() end def dep_to_finding(dep_string) do finding = String.split(dep_string, "\n", trim: true) if length(finding) <= 2 do [] else fmap = finding |> Enum.map(&fpart_to_tuple/1) |> Map.new() %Finding{ source: "deps.audit", content: fmap } end end # Input: Raw output from mix hex.audit # Returns a list of findings def make_hex("No retired packages found\n"), do: [] def make_hex(raw_hex) do raw_lines = String.split(raw_hex, "\n", trim: true) raw_findings = tl(raw_lines) Enum.map(raw_findings, fn finding -> [dep, ver | reason] = String.split(finding, " ", trim: true) %Finding{ source: "hex.audit", content: %{ "dependency" => dep, "version" => ver, "reason" => Enum.join(reason, " ") } } end) end end