Initial commit on Forgejo
All checks were successful
CI and deploy / Test (push) Successful in 4m52s
CI and deploy / Deploy production (push) Successful in 23s

Fresh repository history for elektrine/tarakan hosted at
https://git.elektrine.com/elektrine/tarakan.
This commit is contained in:
Maxfield Luke 2026-07-29 04:43:40 -04:00
commit af6077b9c3
455 changed files with 78366 additions and 0 deletions

View file

@ -0,0 +1,85 @@
defmodule TarakanWeb.Plugs.ApiRateLimitTest do
use Tarakan.DataCase, async: true
import Plug.Conn
import Plug.Test
alias Tarakan.Accounts.Scope
alias TarakanWeb.Plugs.ApiRateLimit
defp call_ip(conn, opts) do
ApiRateLimit.call(conn, ApiRateLimit.init([mode: :ip] ++ opts))
end
defp call_actor(conn, scope, opts) do
conn
|> assign(:current_scope, scope)
|> ApiRateLimit.call(ApiRateLimit.init([mode: :actor] ++ opts))
end
defp credential_scope(account, token_id) do
Scope.for_account(account, token_id: token_id, authentication_method: :api_credential)
end
test "requests carrying a Bearer token count against the IP bucket" do
opts = [request_limit: 2, mutation_limit: 2, window_seconds: 60]
for _ <- 1..2 do
conn =
conn(:get, "/api/repositories")
|> put_req_header("authorization", "Bearer garbage-token")
|> call_ip(opts)
refute conn.halted
end
conn =
conn(:get, "/api/repositories")
|> put_req_header("authorization", "Bearer garbage-token")
|> call_ip(opts)
assert conn.halted
assert conn.status == 429
assert Jason.decode!(conn.resp_body)["error"] == "rate limit exceeded"
end
test "IPv6 clients in the same /64 share one IP bucket" do
opts = [request_limit: 1, mutation_limit: 1, window_seconds: 60]
first =
conn(:get, "/api/repositories")
|> Map.put(:remote_ip, {0x2001, 0x0DB8, 0, 0, 0, 0, 0, 1})
|> call_ip(opts)
refute first.halted
second =
conn(:get, "/api/repositories")
|> Map.put(:remote_ip, {0x2001, 0x0DB8, 0, 0, 0xAAAA, 0xBBBB, 0xCCCC, 0xDDDD})
|> call_ip(opts)
assert second.halted
assert second.status == 429
end
test "plain requests still count against the IP bucket" do
opts = [request_limit: 1, mutation_limit: 1, window_seconds: 60]
refute conn(:get, "/api/repositories") |> call_ip(opts) |> Map.fetch!(:halted)
assert conn(:get, "/api/repositories") |> call_ip(opts) |> Map.fetch!(:halted)
end
test "authenticated actors get the multiplied actor budget" do
opts = [request_limit: 2, mutation_limit: 2, window_seconds: 60]
scope = credential_scope(account_fixture(), 11_001)
# 2 × @actor_multiplier (4) = 8 requests fit; the 9th is rejected.
for _ <- 1..8 do
refute conn(:get, "/api/jobs") |> call_actor(scope, opts) |> Map.fetch!(:halted)
end
limited = conn(:get, "/api/jobs") |> call_actor(scope, opts)
assert limited.halted
assert limited.status == 429
end
end