otwarchive-symphonyarchive/spec/requests/rack_attack_spec.rb
2026-03-11 22:22:11 +00:00

193 lines
7.6 KiB
Ruby

require "spec_helper"
describe "Rack::Attack" do
around do |example|
default_store = Rack::Attack.cache.store
Rack::Attack.cache.store = ActiveSupport::Cache::MemoryStore.new
example.run
Rack::Attack.cache.store = default_store
end
before { freeze_time }
def unique_ip_env
{ "REMOTE_ADDR" => Faker::Internet.unique.public_ip_v4_address }
end
def unique_user_params
{ user: { login: generate(:login), password: "secret" } }
end
def unique_admin_params
{ admin: { login: generate(:login), password: "secretpassword" } }
end
it "test utility returns valid parameters for successful user login attempts" do
params = unique_user_params
create(:user, login: params[:user][:login], password: params[:user][:password])
post user_session_path, params: params.to_query
expect(response).to have_http_status(:redirect)
end
it "test utility returns valid parameters for successful admin login attempts" do
params = unique_admin_params
create(:admin, login: params[:admin][:login], password: params[:admin][:password])
post admin_session_path, params: params.to_query
expect(response).to have_http_status(:redirect)
end
it "successful response does not include retry-after header" do
get root_path, env: { "REMOTE_ADDR" => Faker::Internet.unique.public_ip_v4_address }
expect(response).to have_http_status(:ok)
expect(response.headers["Retry-After"]).to be_nil
end
context "when there have been max number of requests from an IP address" do
let(:ip) { Faker::Internet.unique.public_ip_v4_address }
before do
ArchiveConfig.RATE_LIMIT_NUMBER.times do
get root_path, env: { "REMOTE_ADDR" => ip }
end
end
it "response to the next attempt from the same IP includes retry-after header" do
get root_path, env: { "REMOTE_ADDR" => ip }
expect(response).to have_http_status(:too_many_requests)
expect(response.headers["Retry-After"].to_i).to be > 0
expect(response.headers["Retry-After"].to_i).to be <= ArchiveConfig.RATE_LIMIT_PERIOD
end
end
context "when there have been max user login attempts from an IP address" do
let(:ip) { Faker::Internet.unique.public_ip_v4_address }
before do
ArchiveConfig.RATE_LIMIT_LOGIN_ATTEMPTS.times do
post user_session_path, params: unique_user_params.to_query, env: { "REMOTE_ADDR" => ip }
end
end
it "response to the next attempt from the same IP includes retry-after header" do
post user_session_path, params: unique_user_params.to_query, env: { "REMOTE_ADDR" => ip }
expect(response).to have_http_status(:too_many_requests)
expect(response.headers["Retry-After"].to_i).to be > 0
expect(response.headers["Retry-After"].to_i).to be <= ArchiveConfig.RATE_LIMIT_LOGIN_PERIOD
end
it "throttles the next attempt from the same IP" do
post user_session_path, params: unique_user_params.to_query, env: { "REMOTE_ADDR" => ip }
expect(response).to have_http_status(:too_many_requests)
end
it "does not throttle an attempt from a different IP" do
post user_session_path, params: unique_user_params.to_query, env: unique_ip_env
expect(response).to have_http_status(:ok)
end
it "does not throttle the next attempt from the same IP after some time" do
travel ArchiveConfig.RATE_LIMIT_LOGIN_PERIOD.seconds
post user_session_path, params: unique_user_params.to_query, env: { "REMOTE_ADDR" => ip }
expect(response).to have_http_status(:ok)
end
end
context "when there have been max user login attempts for a username" do
let(:params) { unique_user_params.to_query }
before do
ArchiveConfig.RATE_LIMIT_LOGIN_ATTEMPTS.times do
post user_session_path, params: params, env: unique_ip_env
end
end
it "response to the next attempt for the same username includes retry-after header" do
post user_session_path, params: params, env: unique_ip_env
expect(response).to have_http_status(:too_many_requests)
expect(response.headers["Retry-After"].to_i).to be > 0
expect(response.headers["Retry-After"].to_i).to be <= ArchiveConfig.RATE_LIMIT_LOGIN_PERIOD
end
it "throttles the next attempt for the same username" do
post user_session_path, params: params, env: unique_ip_env
expect(response).to have_http_status(:too_many_requests)
end
it "does not throttle an attempt for a different username" do
post user_session_path, params: unique_user_params.to_query, env: unique_ip_env
expect(response).to have_http_status(:ok)
end
it "does not throttle the next attempt for the same username after some time" do
travel ArchiveConfig.RATE_LIMIT_LOGIN_PERIOD.seconds
post user_session_path, params: params, env: unique_ip_env
expect(response).to have_http_status(:ok)
end
end
context "when there have been max admin login attempts from an IP address" do
let(:ip) { Faker::Internet.unique.public_ip_v4_address }
before do
ArchiveConfig.RATE_LIMIT_ADMIN_LOGIN_ATTEMPTS.times do
post admin_session_path, params: unique_admin_params.to_query, env: { "REMOTE_ADDR" => ip }
end
end
it "response to the next attempt from the same IP includes retry-after header" do
post admin_session_path, params: unique_admin_params.to_query, env: { "REMOTE_ADDR" => ip }
expect(response).to have_http_status(:too_many_requests)
expect(response.headers["Retry-After"].to_i).to be > 0
expect(response.headers["Retry-After"].to_i).to be <= ArchiveConfig.RATE_LIMIT_ADMIN_LOGIN_PERIOD.seconds
end
it "throttles the next attempt from the same IP" do
post admin_session_path, params: unique_admin_params.to_query, env: { "REMOTE_ADDR" => ip }
expect(response).to have_http_status(:too_many_requests)
end
it "does not throttle an attempt from a different IP" do
post admin_session_path, params: unique_admin_params.to_query, env: unique_ip_env
expect(response).to have_http_status(:ok)
end
it "does not throttle the next attempt from the same IP after some time" do
travel ArchiveConfig.RATE_LIMIT_ADMIN_LOGIN_PERIOD.seconds
post admin_session_path, params: unique_admin_params.to_query, env: { "REMOTE_ADDR" => ip }
expect(response).to have_http_status(:ok)
end
end
context "when there have been max admin login attempts for a username" do
let(:params) { unique_admin_params.to_query }
before do
ArchiveConfig.RATE_LIMIT_ADMIN_LOGIN_ATTEMPTS.times do
post admin_session_path, params: params, env: unique_ip_env
end
end
it "response to the next attempt for the same username includes retry-after header" do
post admin_session_path, params: params, env: unique_ip_env
expect(response).to have_http_status(:too_many_requests)
expect(response.headers["Retry-After"].to_i).to be > 0
expect(response.headers["Retry-After"].to_i).to be <= ArchiveConfig.RATE_LIMIT_ADMIN_LOGIN_PERIOD.seconds
end
it "throttles the next attempt for the same username" do
post admin_session_path, params: params, env: unique_ip_env
expect(response).to have_http_status(:too_many_requests)
end
it "does not throttle an attempt for a different username" do
post admin_session_path, params: unique_admin_params.to_query, env: unique_ip_env
expect(response).to have_http_status(:ok)
end
it "does not throttle the next attempt for the same username after some time" do
travel ArchiveConfig.RATE_LIMIT_ADMIN_LOGIN_PERIOD.seconds
post admin_session_path, params: params, env: unique_ip_env
expect(response).to have_http_status(:ok)
end
end
end