Skip to content

Instantly share code, notes, and snippets.

@carpodaster
Last active August 29, 2015 13:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save carpodaster/8807139 to your computer and use it in GitHub Desktop.
Save carpodaster/8807139 to your computer and use it in GitHub Desktop.
Spec'ing a Rack middleware-based firewall/blacklist
class Firewall < Struct.new(:app)
class << self
def blacklist
@blacklist ||= ['192.0.2.1'].freeze # Example IP, see RFC 5735
end
end
def call(env)
if self.class.blacklist.include? env['HTTP_X_FORWARDED_FOR']
message = 'Your IP-address has been banned for security reasons.' +
'If you feel this is a mistake, please contact ' +
'support@absolventa.de'
[403, {}, [message]]
else
app.call(env)
end
end
end
require 'spec_helper'
describe Firewall do
let(:app) { ->(env) { [200, env, 'app'] } }
subject { described_class.new(app) }
describe '.blacklist' do
it 'returns a frozen list' do
expect(described_class.blacklist).not_to be_empty
expect(described_class.blacklist).to be_frozen
end
end
it 'passes request down the middleware stack' do
allowed_ip = '1.2.3.4'
code, _, _ = subject.call rackenv.merge('HTTP_X_FORWARDED_FOR' => allowed_ip)
expect(code).to eql 200 # calls the fake app above
end
it 'blocks the ip' do
banned_ip = '1.2.3.4'
described_class.stub(:blacklist).and_return([banned_ip])
code, _, body = subject.call rackenv.merge('HTTP_X_FORWARDED_FOR' => banned_ip)
expect(code).to eql 403 # forbidden
expect(body.to_s).to match 'banned'
end
def rackenv(*args)
Rack::MockRequest.env_for(*args)
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment