travis-api/lib/travis/api/attack.rb
2015-10-05 18:16:29 +02:00

64 lines
1.7 KiB
Ruby

require 'rack/attack'
class Rack::Attack
class Request
TOKEN = 'travis.access_token'.freeze
def travis_token
env.fetch(TOKEN)
end
def authenticated?
env.include? TOKEN
end
def identifier
authenticated? ? travis_token.to_s : ip
end
end
####
# Ban based on: IP address
# Ban time: indefinite
# Ban after: manually banned
blacklist('block client requesting from redis') do |request|
Travis.redis.sismember(:api_blacklisted_ips, request.ip)
end
####
# Ban based on: IP address or access token
# Ban time: 5 hours
# Ban after: 10 POST requests within five minutes to /auth/github
blacklist('hammering /auth/github') do |request|
Rack::Attack::Allow2Ban.filter(request.identifier, maxretry: 10, findtime: 5.minutes, bantime: 5.hours) do
request.post? and request.path == '/auth/github'
end
end
###
# Throttle: unauthenticated requests - 50 per minute
# Scoped by: IP address
throttle('req/ip/1min', limit: 50, period: 1.minute) do |request|
request.ip unless request.authenticated?
end
###
# Throttle: authenticated requests - 200 per minute
# Scoped by: access token
throttle('req/token/1min', limit: 200, period: 1.minute) do |request|
request.identifier
end
if ENV["MEMCACHIER_SERVERS"]
cache.store = Dalli::Client.new(
ENV["MEMCACHIER_SERVERS"].split(","),
username: ENV["MEMCACHIER_USERNAME"],
password: ENV["MEMCACHIER_PASSWORD"],
failover: true,
socket_timeout: 1.5,
socket_failure_delay: 0.2)
else
cache.store = ActiveSupport::Cache::MemoryStore.new
end
end