Initial commit on Forgejo
Fresh repository history for elektrine/tarakan hosted at https://git.elektrine.com/elektrine/tarakan.
This commit is contained in:
commit
af6077b9c3
455 changed files with 78366 additions and 0 deletions
420
test/tarakan_web/live/finding_live_test.exs
Normal file
420
test/tarakan_web/live/finding_live_test.exs
Normal file
|
|
@ -0,0 +1,420 @@
|
|||
defmodule TarakanWeb.FindingLiveTest do
|
||||
use TarakanWeb.ConnCase
|
||||
|
||||
import Phoenix.LiveViewTest
|
||||
|
||||
setup do
|
||||
submitter = github_account_fixture()
|
||||
repository = listed_github_repository_fixture(submitter)
|
||||
%{repository: repository, submitter: submitter}
|
||||
end
|
||||
|
||||
test "renders a publicly disclosed finding", %{
|
||||
conn: conn,
|
||||
repository: repository,
|
||||
submitter: submitter
|
||||
} do
|
||||
scan =
|
||||
repository
|
||||
|> scan_fixture(submitter, %{"findings_json" => findings_json_fixture(1)})
|
||||
|> publish_scan("public")
|
||||
|
||||
[finding] = scan.findings
|
||||
|
||||
{:ok, view, html} = live(conn, ~p"/findings/#{finding.public_id}")
|
||||
|
||||
assert has_element?(view, "#finding-title", finding.title)
|
||||
assert has_element?(view, "#finding-severity", "high")
|
||||
assert has_element?(view, "#finding-description", "String-built SQL")
|
||||
assert has_element?(view, "#finding-canonical-memory", "detected in 1 run")
|
||||
assert has_element?(view, "#finding-source-link[href='/findings/#{finding.public_id}/code']")
|
||||
assert has_element?(view, "#finding-verified-badge")
|
||||
assert has_element?(view, "#finding-disclosure-badge")
|
||||
assert has_element?(view, "#finding-copy-link")
|
||||
assert has_element?(view, "#finding-cite", "/findings/#{finding.public_id}")
|
||||
assert has_element?(view, "#finding-verdict-counts", "2 confirmed · 0 disputed")
|
||||
assert html =~ scan.commit_sha
|
||||
assert html =~ "Public"
|
||||
assert has_element?(view, "#finding-record-link[href='/github.com/openai/codex/security']")
|
||||
end
|
||||
|
||||
test "shows the raw model report exactly as submitted", %{
|
||||
conn: conn,
|
||||
repository: repository,
|
||||
submitter: submitter
|
||||
} do
|
||||
scan = scan_fixture(repository, submitter, %{"findings_json" => findings_json_fixture(1)})
|
||||
[finding] = scan.findings
|
||||
|
||||
assert scan.raw_document == findings_json_fixture(1)
|
||||
|
||||
{:ok, view, html} = live(conn, ~p"/findings/#{finding.public_id}")
|
||||
|
||||
assert has_element?(view, "#finding-raw-report")
|
||||
assert html =~ "tarakan_scan_format"
|
||||
end
|
||||
|
||||
test "a qualified contributor records a verdict from the finding page", %{
|
||||
conn: conn,
|
||||
repository: repository,
|
||||
submitter: submitter
|
||||
} do
|
||||
scan = scan_fixture(repository, submitter, %{"findings_json" => findings_json_fixture(1)})
|
||||
[finding] = scan.findings
|
||||
|
||||
reviewer =
|
||||
account_fixture()
|
||||
|> Tarakan.Accounts.Account.authorization_changeset(%{
|
||||
state: "active",
|
||||
platform_role: "member",
|
||||
trust_tier: "reviewer"
|
||||
})
|
||||
|> Tarakan.Repo.update!()
|
||||
|
||||
conn = log_in_account(conn, reviewer)
|
||||
{:ok, view, _html} = live(conn, ~p"/findings/#{finding.public_id}")
|
||||
|
||||
assert has_element?(view, "#finding-verdict-counts", "0 confirmed · 0 disputed")
|
||||
|
||||
view
|
||||
|> form("#finding-verdict-form", %{
|
||||
"notes" => "Reproduced against the pinned commit with the documented payload."
|
||||
})
|
||||
|> render_submit(%{"verdict" => "confirmed"})
|
||||
|
||||
assert has_element?(view, "#finding-verdict-counts", "1 confirmed · 0 disputed")
|
||||
assert has_element?(view, "#finding-checks", "@#{reviewer.handle}")
|
||||
|
||||
assert has_element?(
|
||||
view,
|
||||
"#finding-checks",
|
||||
"Reproduced against the pinned commit with the documented payload."
|
||||
)
|
||||
|
||||
assert has_element?(view, "#finding-checks", "counts toward quorum")
|
||||
refute has_element?(view, "#finding-verdict-form")
|
||||
|
||||
{:ok, public_view, _html} =
|
||||
live(Phoenix.ConnTest.build_conn(), ~p"/findings/#{finding.public_id}")
|
||||
|
||||
assert has_element?(public_view, "#finding-checks", "@#{reviewer.handle}")
|
||||
assert has_element?(public_view, "#finding-checks", "documented payload")
|
||||
end
|
||||
|
||||
test "the submitter cannot verify their own finding", %{
|
||||
conn: conn,
|
||||
repository: repository,
|
||||
submitter: submitter
|
||||
} do
|
||||
scan = scan_fixture(repository, submitter, %{"findings_json" => findings_json_fixture(1)})
|
||||
[finding] = scan.findings
|
||||
|
||||
conn = log_in_account(conn, submitter)
|
||||
{:ok, view, _html} = live(conn, ~p"/findings/#{finding.public_id}")
|
||||
|
||||
refute has_element?(view, "#finding-verdict-form")
|
||||
end
|
||||
|
||||
test "the dead render carries the meta description and canonical URL", %{
|
||||
conn: conn,
|
||||
repository: repository,
|
||||
submitter: submitter
|
||||
} do
|
||||
scan =
|
||||
repository
|
||||
|> scan_fixture(submitter, %{"findings_json" => findings_json_fixture(1)})
|
||||
|> publish_scan("public")
|
||||
|
||||
[finding] = scan.findings
|
||||
|
||||
html = conn |> get(~p"/findings/#{finding.public_id}") |> html_response(200)
|
||||
|
||||
assert html =~ ~s(rel="canonical")
|
||||
assert html =~ "/findings/#{finding.public_id}"
|
||||
assert html =~ "High in openai/codex"
|
||||
assert get_resp_header(get(conn, ~p"/findings/#{finding.public_id}"), "x-robots-tag") == []
|
||||
end
|
||||
|
||||
test "fresh submissions resolve for anonymous visitors immediately", %{
|
||||
conn: conn,
|
||||
repository: repository,
|
||||
submitter: submitter
|
||||
} do
|
||||
scan = scan_fixture(repository, submitter, %{"findings_json" => findings_json_fixture(1)})
|
||||
[finding] = scan.findings
|
||||
|
||||
{:ok, view, _html} = live(conn, ~p"/findings/#{finding.public_id}")
|
||||
|
||||
assert has_element?(view, "#finding-title", finding.title)
|
||||
refute has_element?(view, "#finding-verified-badge")
|
||||
end
|
||||
|
||||
test "restricted findings do not resolve for anonymous visitors", %{
|
||||
conn: conn,
|
||||
repository: repository,
|
||||
submitter: submitter
|
||||
} do
|
||||
scan = scan_fixture(repository, submitter, %{"findings_json" => findings_json_fixture(1)})
|
||||
[finding] = scan.findings
|
||||
|
||||
{:ok, _restricted} =
|
||||
Tarakan.Scans.update_visibility(
|
||||
Tarakan.Accounts.Scope.for_account(moderator_account_fixture()),
|
||||
scan,
|
||||
"restricted",
|
||||
%{
|
||||
"moderation_reason" => "takedown_review",
|
||||
"moderation_notes" =>
|
||||
"Deliberately restricted in this test to exercise the takedown boundary."
|
||||
}
|
||||
)
|
||||
|
||||
assert_error_sent 404, fn -> get(conn, ~p"/findings/#{finding.public_id}") end
|
||||
end
|
||||
|
||||
test "public-summary findings do not resolve for anonymous visitors", %{
|
||||
conn: conn,
|
||||
repository: repository,
|
||||
submitter: submitter
|
||||
} do
|
||||
scan = scan_fixture(repository, submitter, %{"findings_json" => findings_json_fixture(1)})
|
||||
[finding] = scan.findings
|
||||
publish_scan(scan, "public_summary")
|
||||
|
||||
assert_error_sent 404, fn -> get(conn, ~p"/findings/#{finding.public_id}") end
|
||||
end
|
||||
|
||||
test "the submitter can still open their own restricted finding", %{
|
||||
conn: conn,
|
||||
repository: repository,
|
||||
submitter: submitter
|
||||
} do
|
||||
scan = scan_fixture(repository, submitter, %{"findings_json" => findings_json_fixture(1)})
|
||||
[finding] = scan.findings
|
||||
|
||||
{:ok, _restricted} =
|
||||
Tarakan.Scans.update_visibility(
|
||||
Tarakan.Accounts.Scope.for_account(moderator_account_fixture()),
|
||||
scan,
|
||||
"restricted",
|
||||
%{
|
||||
"moderation_reason" => "takedown_review",
|
||||
"moderation_notes" =>
|
||||
"Deliberately restricted in this test to exercise submitter access."
|
||||
}
|
||||
)
|
||||
|
||||
conn = log_in_account(conn, submitter)
|
||||
{:ok, view, _html} = live(conn, ~p"/findings/#{finding.public_id}")
|
||||
|
||||
assert has_element?(view, "#finding-title", finding.title)
|
||||
end
|
||||
|
||||
test "the lifecycle timeline lists first-seen and check events", %{
|
||||
conn: conn,
|
||||
repository: repository,
|
||||
submitter: submitter
|
||||
} do
|
||||
scan = scan_fixture(repository, submitter, %{"findings_json" => findings_json_fixture(1)})
|
||||
[finding] = scan.findings
|
||||
|
||||
reviewer = reviewer_account_fixture()
|
||||
conn = log_in_account(conn, reviewer)
|
||||
{:ok, view, _html} = live(conn, ~p"/findings/#{finding.public_id}")
|
||||
|
||||
assert has_element?(view, "#finding-timeline-first-seen", "First seen")
|
||||
refute has_element?(view, "li[id^='finding-timeline-check-']")
|
||||
refute has_element?(view, "#finding-timeline-verified")
|
||||
refute has_element?(view, "#finding-timeline-vendor-notified")
|
||||
|
||||
view
|
||||
|> form("#finding-verdict-form", %{
|
||||
"notes" => "Reproduced against the pinned commit with the documented payload."
|
||||
})
|
||||
|> render_submit(%{"verdict" => "confirmed"})
|
||||
|
||||
assert has_element?(view, "#finding-timeline li[id^='finding-timeline-check-']")
|
||||
assert has_element?(view, "#finding-timeline", "@#{reviewer.handle}")
|
||||
assert has_element?(view, "#finding-timeline", "confirmed")
|
||||
end
|
||||
|
||||
test "the lifecycle timeline shows verified and vendor events when set", %{
|
||||
conn: conn,
|
||||
repository: repository,
|
||||
submitter: submitter
|
||||
} do
|
||||
scan =
|
||||
repository
|
||||
|> scan_fixture(submitter, %{"findings_json" => findings_json_fixture(1)})
|
||||
|> publish_scan("public")
|
||||
|
||||
[finding] = scan.findings
|
||||
|
||||
conn = log_in_account(conn, reviewer_account_fixture())
|
||||
{:ok, view, _html} = live(conn, ~p"/findings/#{finding.public_id}")
|
||||
|
||||
assert has_element?(view, "#finding-timeline-first-seen")
|
||||
assert has_element?(view, "#finding-timeline li[id^='finding-timeline-check-']")
|
||||
assert has_element?(view, "#finding-timeline-verified", "Verified")
|
||||
refute has_element?(view, "#finding-timeline-vendor-notified")
|
||||
|
||||
view
|
||||
|> form("#finding-vendor-form", %{
|
||||
"vendor_notification" => %{"notified_on" => "2026-01-15"}
|
||||
})
|
||||
|> render_submit()
|
||||
|
||||
assert has_element?(view, "#finding-timeline-vendor-notified", "Vendor notified")
|
||||
|
||||
canonical =
|
||||
Tarakan.Repo.get_by!(Tarakan.Scans.CanonicalFinding, repository_id: repository.id)
|
||||
|
||||
assert canonical.vendor_notified_at == ~U[2026-01-15 00:00:00.000000Z]
|
||||
|
||||
view
|
||||
|> form("#finding-vendor-form", %{"vendor_notification" => %{"notified_on" => ""}})
|
||||
|> render_submit()
|
||||
|
||||
refute has_element?(view, "#finding-timeline-vendor-notified")
|
||||
|
||||
assert Tarakan.Repo.get!(Tarakan.Scans.CanonicalFinding, canonical.id).vendor_notified_at ==
|
||||
nil
|
||||
end
|
||||
|
||||
test "CWE and CVE badges link out and disclosure metadata renders", %{
|
||||
conn: conn,
|
||||
repository: repository,
|
||||
submitter: submitter
|
||||
} do
|
||||
scan =
|
||||
scan_fixture(repository, submitter, %{
|
||||
"findings_json" => findings_json_with_disclosure_fixture()
|
||||
})
|
||||
|
||||
[finding] = scan.findings
|
||||
|
||||
{:ok, view, _html} = live(conn, ~p"/findings/#{finding.public_id}")
|
||||
|
||||
assert has_element?(
|
||||
view,
|
||||
"#finding-cwe-badge[href='https://cwe.mitre.org/data/definitions/89.html']",
|
||||
"CWE-89"
|
||||
)
|
||||
|
||||
assert has_element?(
|
||||
view,
|
||||
"#finding-cve-badge[href='https://nvd.nist.gov/vuln/detail/CVE-2026-12345']",
|
||||
"CVE-2026-12345"
|
||||
)
|
||||
|
||||
assert has_element?(view, "#finding-reproduction", "Run the payload")
|
||||
assert has_element?(view, "#finding-affected-versions", ">= 1.0, < 2.0")
|
||||
end
|
||||
|
||||
test "CWE and CVE badges and disclosure metadata are absent when unset", %{
|
||||
conn: conn,
|
||||
repository: repository,
|
||||
submitter: submitter
|
||||
} do
|
||||
scan = scan_fixture(repository, submitter, %{"findings_json" => findings_json_fixture(1)})
|
||||
[finding] = scan.findings
|
||||
|
||||
{:ok, view, _html} = live(conn, ~p"/findings/#{finding.public_id}")
|
||||
|
||||
refute has_element?(view, "#finding-cwe-badge")
|
||||
refute has_element?(view, "#finding-cve-badge")
|
||||
refute has_element?(view, "#finding-reproduction")
|
||||
refute has_element?(view, "#finding-affected-versions")
|
||||
end
|
||||
|
||||
test "the vendor notification form is hidden from ordinary members", %{
|
||||
conn: conn,
|
||||
repository: repository,
|
||||
submitter: submitter
|
||||
} do
|
||||
scan = scan_fixture(repository, submitter, %{"findings_json" => findings_json_fixture(1)})
|
||||
[finding] = scan.findings
|
||||
|
||||
{:ok, anonymous_view, _html} = live(conn, ~p"/findings/#{finding.public_id}")
|
||||
refute has_element?(anonymous_view, "#finding-vendor-form")
|
||||
|
||||
conn = log_in_account(conn, submitter)
|
||||
{:ok, view, _html} = live(conn, ~p"/findings/#{finding.public_id}")
|
||||
refute has_element?(view, "#finding-vendor-form")
|
||||
end
|
||||
|
||||
test "an unauthorized vendor notification event is rejected", %{
|
||||
conn: conn,
|
||||
repository: repository,
|
||||
submitter: submitter
|
||||
} do
|
||||
scan = scan_fixture(repository, submitter, %{"findings_json" => findings_json_fixture(1)})
|
||||
[finding] = scan.findings
|
||||
|
||||
conn = log_in_account(conn, submitter)
|
||||
{:ok, view, _html} = live(conn, ~p"/findings/#{finding.public_id}")
|
||||
|
||||
render_hook(view, "record_vendor_notification", %{
|
||||
"vendor_notification" => %{"notified_on" => "2026-01-15"}
|
||||
})
|
||||
|
||||
assert has_element?(view, "#flash-group", "not authorized")
|
||||
|
||||
canonical =
|
||||
Tarakan.Repo.get_by!(Tarakan.Scans.CanonicalFinding, repository_id: repository.id)
|
||||
|
||||
assert canonical.vendor_notified_at == nil
|
||||
end
|
||||
|
||||
defp findings_json_with_disclosure_fixture do
|
||||
Jason.encode!(%{
|
||||
"tarakan_scan_format" => 1,
|
||||
"findings" => [
|
||||
%{
|
||||
"file" => "lib/example/module_1.ex",
|
||||
"line_start" => 10,
|
||||
"line_end" => 15,
|
||||
"severity" => "high",
|
||||
"title" => "Unsanitized input reaches interpolated query (1)",
|
||||
"description" => "String-built SQL executed with request parameters.",
|
||||
"reproduction" => "1. Check out the pinned commit\n2. Run the payload",
|
||||
"affected_versions" => ">= 1.0, < 2.0",
|
||||
"cwe" => "CWE-89",
|
||||
"cve" => "CVE-2026-12345"
|
||||
}
|
||||
]
|
||||
})
|
||||
end
|
||||
|
||||
defp publish_scan(scan, visibility) do
|
||||
scan = confirmation_fixture(scan, reviewer_account_fixture())
|
||||
scan = confirmation_fixture(scan, reviewer_account_fixture())
|
||||
|
||||
scope = Tarakan.Accounts.Scope.for_account(moderator_account_fixture())
|
||||
|
||||
if visibility == "public" do
|
||||
scan.repository
|
||||
|> Tarakan.Repositories.Repository.participation_changeset(%{
|
||||
participation_mode: "maintainer_verified"
|
||||
})
|
||||
|> Tarakan.Repo.update!()
|
||||
end
|
||||
|
||||
{:ok, scan} =
|
||||
Tarakan.Scans.accept_scan(scope, scan, %{
|
||||
"moderation_reason" => "evidence_reviewed",
|
||||
"moderation_notes" =>
|
||||
"Two independent reviewers supplied reproducible evidence for the pinned commit."
|
||||
})
|
||||
|
||||
{:ok, scan} =
|
||||
Tarakan.Scans.update_visibility(scope, scan, visibility, %{
|
||||
"moderation_reason" => "disclosure_reviewed",
|
||||
"moderation_notes" =>
|
||||
"Disclosure was separately reviewed for scope, secrets, and personal data.",
|
||||
"sensitive_data_reviewed" => "true"
|
||||
})
|
||||
|
||||
scan
|
||||
end
|
||||
end
|
||||
Loading…
Add table
Add a link
Reference in a new issue