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
411
test/tarakan_web/live/repository_code_live_test.exs
Normal file
411
test/tarakan_web/live/repository_code_live_test.exs
Normal file
|
|
@ -0,0 +1,411 @@
|
|||
defmodule TarakanWeb.RepositoryCodeLiveTest do
|
||||
use TarakanWeb.ConnCase, async: false
|
||||
|
||||
import Phoenix.LiveViewTest
|
||||
|
||||
alias Tarakan.Accounts.Scope
|
||||
alias Tarakan.RepositoryCode.Cache
|
||||
alias Tarakan.Scans
|
||||
|
||||
@default_commit_sha String.duplicate("7", 40)
|
||||
# develop branch tip in the GitHub stub (must remain a real branch tip).
|
||||
@develop_commit_sha String.duplicate("8", 40)
|
||||
# A fetchable commit that is not the tip of any published branch (and not a
|
||||
# special-cased stub SHA such as all-c truncated trees).
|
||||
@historical_commit_sha String.duplicate("b", 40)
|
||||
|
||||
setup do
|
||||
Cache.clear()
|
||||
repository = listed_github_repository_fixture()
|
||||
%{repository: repository}
|
||||
end
|
||||
|
||||
test "repository roots open the code browser by default", %{conn: conn} do
|
||||
{:ok, view, _html} = live(conn, ~p"/github.com/openai/codex")
|
||||
render_async(view, 1_000)
|
||||
|
||||
assert has_element?(view, "#repository-navigation")
|
||||
assert has_element?(view, "#repository-code-tab[aria-current='page']", "Code")
|
||||
|
||||
assert has_element?(
|
||||
view,
|
||||
"#repository-overview-tab[href='/github.com/openai/codex/security']"
|
||||
)
|
||||
|
||||
assert has_element?(view, "#code-tree")
|
||||
end
|
||||
|
||||
test "the legacy code entry route still opens the default tree", %{conn: conn} do
|
||||
{:ok, view, _html} = live(conn, ~p"/github.com/openai/codex/code")
|
||||
render_async(view, 1_000)
|
||||
|
||||
assert has_element?(view, "#code-tree")
|
||||
assert has_element?(view, "#code-commit-sha", String.slice(@default_commit_sha, 0, 7))
|
||||
end
|
||||
|
||||
test "browses directories at the freshly resolved default commit", %{conn: conn} do
|
||||
{:ok, view, _html} =
|
||||
live(conn, ~p"/github.com/openai/codex/code/#{@default_commit_sha}")
|
||||
|
||||
render_async(view, 1_000)
|
||||
|
||||
assert has_element?(view, "#code-tree")
|
||||
assert has_element?(view, "#code-tree-entries [id^='code-entry-']", "lib")
|
||||
|
||||
assert has_element?(
|
||||
view,
|
||||
"#code-tree-entries a[href='/github.com/openai/codex/code/#{@default_commit_sha}/README.md']"
|
||||
)
|
||||
end
|
||||
|
||||
test "round-trips encoded spaces, percent signs, fragments, and Unicode filenames", %{
|
||||
conn: conn
|
||||
} do
|
||||
root = "/github.com/openai/codex/code/#{@default_commit_sha}"
|
||||
{:ok, tree_view, _html} = live(conn, root)
|
||||
render_async(tree_view, 1_000)
|
||||
|
||||
assert has_element?(
|
||||
tree_view,
|
||||
"a[href='#{root}/space%20%23%20100%25.txt']",
|
||||
"space # 100%.txt"
|
||||
)
|
||||
|
||||
assert has_element?(tree_view, "a[href='#{root}/%CE%BB.ex']", "λ.ex")
|
||||
|
||||
{:ok, encoded_view, _html} = live(conn, root <> "/space%20%23%20100%25.txt")
|
||||
render_async(encoded_view, 1_000)
|
||||
assert has_element?(encoded_view, "#code-file", "space # 100%.txt")
|
||||
assert has_element?(encoded_view, "#L1 code", "# Codex")
|
||||
|
||||
{:ok, unicode_view, _html} = live(conn, root <> "/%CE%BB.ex")
|
||||
render_async(unicode_view, 1_000)
|
||||
assert has_element?(unicode_view, "#code-file", "λ.ex")
|
||||
assert has_element?(unicode_view, "#L1 code", "defmodule Codex")
|
||||
end
|
||||
|
||||
test "folder and file rows show findings for the pinned commit", %{
|
||||
conn: conn,
|
||||
repository: repository
|
||||
} do
|
||||
scan = finding_scan_fixture(repository, account_fixture(), @default_commit_sha)
|
||||
_scan = publish_full_scan(repository, scan)
|
||||
|
||||
{:ok, root_view, _html} = live(conn, ~p"/github.com/openai/codex")
|
||||
render_async(root_view, 1_000)
|
||||
|
||||
assert has_element?(root_view, "#code-entry-bGli-findings", "1 finding")
|
||||
assert has_element?(root_view, "#code-reference", "1 finding")
|
||||
|
||||
{:ok, lib_view, _html} =
|
||||
live(conn, ~p"/github.com/openai/codex/code/#{@default_commit_sha}/lib")
|
||||
|
||||
render_async(lib_view, 1_000)
|
||||
|
||||
assert has_element?(lib_view, "#code-entry-bGliL2NvZGV4LmV4-findings", "1 finding")
|
||||
end
|
||||
|
||||
test "public summaries do not leak file paths through code-row badges", %{
|
||||
conn: conn,
|
||||
repository: repository
|
||||
} do
|
||||
scan = finding_scan_fixture(repository, account_fixture(), @default_commit_sha)
|
||||
scan = confirmation_fixture(scan, reviewer_account_fixture())
|
||||
scan = confirmation_fixture(scan, reviewer_account_fixture())
|
||||
moderator_scope = Scope.for_account(moderator_account_fixture())
|
||||
|
||||
{:ok, accepted} = Scans.accept_scan(moderator_scope, scan, moderation_attributes())
|
||||
|
||||
{:ok, _summary} =
|
||||
Scans.update_visibility(
|
||||
moderator_scope,
|
||||
accepted,
|
||||
"public_summary",
|
||||
moderation_attributes()
|
||||
)
|
||||
|
||||
{:ok, view, _html} = live(conn, ~p"/github.com/openai/codex")
|
||||
render_async(view, 1_000)
|
||||
html = render(view)
|
||||
|
||||
refute has_element?(view, "[id$='-findings']")
|
||||
refute html =~ "lib/codex.ex"
|
||||
end
|
||||
|
||||
test "renders escaped plain-text lines with stable anchors and selection", %{conn: conn} do
|
||||
{:ok, view, _html} =
|
||||
live(
|
||||
conn,
|
||||
~p"/github.com/openai/codex/code/#{@default_commit_sha}/README.md?lines=1"
|
||||
)
|
||||
|
||||
render_async(view, 1_000)
|
||||
|
||||
assert has_element?(view, "#code-file")
|
||||
assert has_element?(view, "#L1.bg-panel")
|
||||
assert has_element?(view, "#L1 code", "# Codex")
|
||||
|
||||
assert has_element?(
|
||||
view,
|
||||
"#L1 a[href='/github.com/openai/codex/code/#{@default_commit_sha}/README.md?lines=1#L1']"
|
||||
)
|
||||
end
|
||||
|
||||
test "rejects an out-of-range single-line selection", %{conn: conn} do
|
||||
{:ok, view, _html} =
|
||||
live(
|
||||
conn,
|
||||
~p"/github.com/openai/codex/code/#{@default_commit_sha}/README.md?lines=1000001"
|
||||
)
|
||||
|
||||
render_async(view, 1_000)
|
||||
|
||||
assert has_element?(view, "#invalid-line-selection")
|
||||
refute has_element?(view, "#code-lines .bg-panel")
|
||||
end
|
||||
|
||||
test "renders hostile source as escaped text rather than executable markup", %{conn: conn} do
|
||||
{:ok, view, _html} =
|
||||
live(
|
||||
conn,
|
||||
~p"/github.com/openai/codex/code/#{@default_commit_sha}/unsafe.html"
|
||||
)
|
||||
|
||||
render_async(view, 1_000)
|
||||
html = render(view)
|
||||
|
||||
assert has_element?(view, "#L1 code", "</code><script id=\"source-xss\">alert(1)</script>")
|
||||
refute has_element?(view, "script#source-xss")
|
||||
assert html =~ "</code><script id="source-xss">"
|
||||
end
|
||||
|
||||
test "rejects guessed historical SHAs on the generic browser", %{conn: conn} do
|
||||
paths = [
|
||||
~p"/github.com/openai/codex/code/#{@historical_commit_sha}",
|
||||
~p"/github.com/openai/codex/code/#{@historical_commit_sha}/README.md"
|
||||
]
|
||||
|
||||
for path <- paths do
|
||||
{:ok, view, _html} = live(conn, path)
|
||||
render_async(view, 1_000)
|
||||
|
||||
assert has_element?(view, "#code-browser-error")
|
||||
assert has_element?(view, "#code-browser-error", "Source not found")
|
||||
refute has_element?(view, "#code-tree")
|
||||
refute has_element?(view, "#code-file")
|
||||
end
|
||||
end
|
||||
|
||||
test "branch switch opens another published branch tip", %{conn: conn} do
|
||||
{:ok, view, _html} = live(conn, ~p"/github.com/openai/codex/code/#{@default_commit_sha}")
|
||||
render_async(view, 1_000)
|
||||
|
||||
assert has_element?(view, "#code-branch-select")
|
||||
assert has_element?(view, "#code-tree")
|
||||
|
||||
view
|
||||
|> form("#code-branch-form", %{branch: "develop"})
|
||||
|> render_change()
|
||||
|
||||
path = ~p"/github.com/openai/codex/code/#{@develop_commit_sha}"
|
||||
assert_redirect(view, path)
|
||||
|
||||
{:ok, switched, _html} = live(conn, path)
|
||||
render_async(switched, 1_000)
|
||||
|
||||
assert has_element?(switched, "#code-tree")
|
||||
assert has_element?(switched, "#code-commit-sha", String.slice(@develop_commit_sha, 0, 7))
|
||||
assert has_element?(switched, ~s(#code-branch-select option[value="develop"][selected]))
|
||||
end
|
||||
|
||||
test "deep link to a non-default branch tip works", %{conn: conn} do
|
||||
{:ok, view, _html} =
|
||||
live(conn, ~p"/github.com/openai/codex/code/#{@develop_commit_sha}/README.md")
|
||||
|
||||
render_async(view, 1_000)
|
||||
|
||||
assert has_element?(view, "#code-file")
|
||||
assert has_element?(view, "#code-commit-sha", String.slice(@develop_commit_sha, 0, 7))
|
||||
assert has_element?(view, ~s(#code-branch-select option[value="develop"][selected]))
|
||||
end
|
||||
|
||||
test "rejects encoded traversal and backslash paths at the route boundary", %{conn: conn} do
|
||||
unsafe_paths = [
|
||||
"/github.com/openai/codex/code/#{@default_commit_sha}/lib/%2E%2E/README.md",
|
||||
"/github.com/openai/codex/code/#{@default_commit_sha}/lib/%5C..%5Csecret"
|
||||
]
|
||||
|
||||
for path <- unsafe_paths do
|
||||
{:ok, view, _html} = live(conn, path)
|
||||
|
||||
assert has_element?(view, "#code-browser-error", "Invalid path")
|
||||
refute has_element?(view, "#code-file")
|
||||
end
|
||||
end
|
||||
|
||||
test "an authorized opaque finding route opens historical source without leaking path in links",
|
||||
%{
|
||||
conn: conn,
|
||||
repository: repository
|
||||
} do
|
||||
submitter = account_fixture()
|
||||
scan = finding_scan_fixture(repository, submitter, @historical_commit_sha)
|
||||
finding = hd(scan.findings)
|
||||
|
||||
{:ok, view, _html} =
|
||||
live(log_in_account(conn, submitter), ~p"/findings/#{finding.public_id}/code")
|
||||
|
||||
render_async(view, 1_000)
|
||||
|
||||
assert has_element?(view, "#finding-code-context")
|
||||
assert has_element?(view, "#code-file")
|
||||
assert has_element?(view, "#L2.bg-panel")
|
||||
refute has_element?(view, "#source-breadcrumbs a")
|
||||
assert has_element?(view, "#L2 a[href='/findings/#{finding.public_id}/code#L2']")
|
||||
end
|
||||
|
||||
test "the opaque route does not reveal a moderator-restricted finding to anonymous visitors",
|
||||
%{
|
||||
conn: conn,
|
||||
repository: repository
|
||||
} do
|
||||
scan = finding_scan_fixture(repository, account_fixture(), @historical_commit_sha)
|
||||
finding = hd(scan.findings)
|
||||
|
||||
moderator_scope = Scope.for_account(moderator_account_fixture())
|
||||
|
||||
{:ok, _restricted} =
|
||||
Scans.update_visibility(moderator_scope, scan, "restricted", moderation_attributes())
|
||||
|
||||
assert_raise Ecto.NoResultsError, fn ->
|
||||
live(conn, ~p"/findings/#{finding.public_id}/code")
|
||||
end
|
||||
end
|
||||
|
||||
test "marks a reported line range that does not exist at the pinned commit", %{
|
||||
conn: conn,
|
||||
repository: repository
|
||||
} do
|
||||
submitter = account_fixture()
|
||||
scan = finding_scan_fixture(repository, submitter, @historical_commit_sha, 99)
|
||||
finding = hd(scan.findings)
|
||||
|
||||
{:ok, view, _html} =
|
||||
live(log_in_account(conn, submitter), ~p"/findings/#{finding.public_id}/code")
|
||||
|
||||
render_async(view, 1_000)
|
||||
|
||||
assert has_element?(view, "#finding-line-outside-file")
|
||||
refute has_element?(view, "#code-lines .bg-panel")
|
||||
end
|
||||
|
||||
test "finding source routes reject enumerable integer identifiers", %{conn: conn} do
|
||||
assert_raise Ecto.NoResultsError, fn ->
|
||||
live(conn, "/findings/1/code")
|
||||
end
|
||||
end
|
||||
|
||||
test "a connected finding view is evicted when a moderator restricts the scan", %{
|
||||
conn: conn,
|
||||
repository: repository
|
||||
} do
|
||||
scan = finding_scan_fixture(repository, account_fixture(), @historical_commit_sha)
|
||||
scan = publish_full_scan(repository, scan)
|
||||
finding = hd(scan.findings)
|
||||
|
||||
{:ok, view, _html} = live(conn, ~p"/findings/#{finding.public_id}/code")
|
||||
render_async(view, 1_000)
|
||||
assert has_element?(view, "#code-file")
|
||||
|
||||
moderator_scope = Scope.for_account(moderator_account_fixture())
|
||||
|
||||
assert {:ok, _restricted} =
|
||||
Scans.update_visibility(moderator_scope, scan, "restricted", moderation_attributes())
|
||||
|
||||
assert_redirect(view, ~p"/github.com/openai/codex")
|
||||
end
|
||||
|
||||
test "the default code page is uncached but remains indexable", %{conn: conn} do
|
||||
conn = get(conn, ~p"/github.com/openai/codex")
|
||||
|
||||
assert html_response(conn, 200)
|
||||
assert get_resp_header(conn, "cache-control") == ["no-store"]
|
||||
assert get_resp_header(conn, "x-robots-tag") == []
|
||||
end
|
||||
|
||||
test "commit-pinned code routes prohibit caches and search indexing", %{conn: conn} do
|
||||
conn = get(conn, ~p"/github.com/openai/codex/code/#{@default_commit_sha}")
|
||||
|
||||
assert html_response(conn, 200)
|
||||
assert get_resp_header(conn, "cache-control") == ["no-store"]
|
||||
assert get_resp_header(conn, "x-robots-tag") == ["noindex, nofollow"]
|
||||
end
|
||||
|
||||
test "opaque finding routes prohibit caches and search indexing", %{
|
||||
conn: conn,
|
||||
repository: repository
|
||||
} do
|
||||
scan = finding_scan_fixture(repository, account_fixture(), @historical_commit_sha)
|
||||
finding = repository |> publish_full_scan(scan) |> Map.fetch!(:findings) |> hd()
|
||||
|
||||
conn = get(conn, ~p"/findings/#{finding.public_id}/code")
|
||||
|
||||
assert html_response(conn, 200)
|
||||
assert get_resp_header(conn, "cache-control") == ["no-store"]
|
||||
assert get_resp_header(conn, "x-robots-tag") == ["noindex, nofollow"]
|
||||
end
|
||||
|
||||
defp finding_scan_fixture(repository, submitter, commit_sha, line_start \\ 2) do
|
||||
document =
|
||||
Jason.encode!(%{
|
||||
"tarakan_scan_format" => 1,
|
||||
"findings" => [
|
||||
%{
|
||||
"file" => "lib/codex.ex",
|
||||
"line_start" => line_start,
|
||||
"line_end" => line_start,
|
||||
"severity" => "high",
|
||||
"title" => "Authorization is not checked",
|
||||
"description" => "A request reaches a privileged operation without a policy check."
|
||||
}
|
||||
]
|
||||
})
|
||||
|
||||
scan_fixture(repository, submitter, %{
|
||||
"commit_sha" => commit_sha,
|
||||
"findings_json" => document
|
||||
})
|
||||
end
|
||||
|
||||
defp publish_full_scan(repository, scan) do
|
||||
repository
|
||||
|> Tarakan.Repositories.Repository.participation_changeset(%{
|
||||
participation_mode: "maintainer_verified"
|
||||
})
|
||||
|> Tarakan.Repo.update!()
|
||||
|
||||
scan = confirmation_fixture(scan, reviewer_account_fixture())
|
||||
scan = confirmation_fixture(scan, reviewer_account_fixture())
|
||||
moderator_scope = Scope.for_account(moderator_account_fixture())
|
||||
|
||||
{:ok, accepted} = Scans.accept_scan(moderator_scope, scan, moderation_attributes())
|
||||
|
||||
{:ok, disclosed} =
|
||||
Scans.update_visibility(
|
||||
moderator_scope,
|
||||
accepted,
|
||||
"public",
|
||||
moderation_attributes(%{"sensitive_data_reviewed" => "true"})
|
||||
)
|
||||
|
||||
disclosed
|
||||
end
|
||||
|
||||
defp moderation_attributes(overrides \\ %{}) do
|
||||
Enum.into(overrides, %{
|
||||
"moderation_reason" => "evidence_reviewed",
|
||||
"moderation_notes" =>
|
||||
"Independent evidence and disclosure boundaries were reviewed for this exact commit."
|
||||
})
|
||||
end
|
||||
end
|
||||
Loading…
Add table
Add a link
Reference in a new issue