Skip to content

Commit

Permalink
Merge 596f3e8 into 9bada2a
Browse files Browse the repository at this point in the history
  • Loading branch information
0exp committed Aug 12, 2018
2 parents 9bada2a + 596f3e8 commit f806c29
Show file tree
Hide file tree
Showing 13 changed files with 376 additions and 2 deletions.
5 changes: 3 additions & 2 deletions lib/blast_wave.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ module BlastWave
require_relative 'blast_wave/version'
require_relative 'blast_wave/middleware'
require_relative 'blast_wave/request_id'
require_relative 'blast_wave/request_id/extensions/request_interface'
require_relative 'blast_wave/request_id/initializer'
require_relative 'blast_wave/check_list'
require_relative 'blast_wave/white_list'
require_relative 'blast_wave/black_list'
end
end
18 changes: 18 additions & 0 deletions lib/blast_wave/black_list.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# frozen_string_literal: true

module Rack
# @api public
# @since 0.1.0
class BlastWave::BlackList < BlastWave::CheckList
BlastWave::CheckList::Builder.build(self)

# @param env [Hash]
# @return [Object]
#
# @api private
# @since 0.1.0
def call(env)
check!(env) ? generate_fail_response! : super
end
end
end
14 changes: 14 additions & 0 deletions lib/blast_wave/check_list.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# frozen_string_literal: true

module Rack
# @api public
# @since 0.1.0
BlastWave::CheckList = Class.new(BlastWave::Middleware)

require_relative 'check_list/matcher'
require_relative 'check_list/matcher_registry'
require_relative 'check_list/fail_response'
require_relative 'check_list/checkable'
require_relative 'check_list/checker'
require_relative 'check_list/builder'
end
73 changes: 73 additions & 0 deletions lib/blast_wave/check_list/builder.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
# frozen_string_literal: true

module Rack
# @api public
# @since 0.1.0
module BlastWave::CheckList::Builder
# @return [Proc]
#
# @api private
# @since 0.1.0
INSTRUCTIONS = proc do
# @since 0.1.0
include Qonfig::Configurable
# @since 0.1.0
include BlastWave::CheckList::Checkable

# @since 0.1.0
configuration do
setting :check_all, false

setting :fail_response do
setting :body, BlastWave::CheckList::FailResponse::DEFAULT_BODY
setting :status, BlastWave::CheckList::FailResponse::DEFAULT_STATUS
setting :headers, BlastWave::CheckList::FailResponse::DEFAULT_HEADERS
end
end

private

# @return [Qonfig::Settings]
#
# @api private
# @since 0.1.0
def options
self.class.config.settings
end

# @param env [Hash]
# @return [Boolean]
#
# @api private
# @since 0.1.0
def check!(env)
request = Rack::Request.new(env)
should_check_all = options.check_all?
checker.check!(request, check_all: should_check_all)
end

# @return [Rack::Response]
#
# @api private
# @since 0.1.0
def generate_fail_response!
FailResponse.build(
status: options.fail_response.status,
body: options.fail_response.body,
headers: options.fail_response.headers
)
end
end

class << self
# @param empty_middleware_klass [Class<BlastWave::MiddleWare>]
# @return [Class<BlastWave::MiddleWare>]
#
# @api public
# @since 0.1.0
def build(empty_middleware_klass = Class.new(BlastWave::Middleware))
empty_middleware_klass.class_eval(&INSTRUCTIONS)
end
end
end
end
46 changes: 46 additions & 0 deletions lib/blast_wave/check_list/checkable.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# frozen_string_literal: true

module Rack
# @api private
# @since 0.1.0
module BlastWave::CheckList::Checkable
class << self
# @param base_klass [Class]
# @return [void]
#
# @api private
# @since 0.1.0
def included(base_klass)
base_klass.extend(ClassMethods)
base_klass.include(InstanceMethods)
base_klass.instance_variable_set(:@checker, BlastWave::CheckList::Checker.new)
base_klass.singleton_class.class_eval { attr_reader :checker }
end
end

# @api private
# @since 0.1.0
module ClassMethods
# @param block [Proc]
# @return [void]
#
# @api public
# @since 0.1.0
def match_by(&block)
checker.register(&block)
end
end

# @api private
# @since 0.1.0
module InstanceMethods
# @return [BlastWave::CheckLis::Checker]
#
# @api private
# @sicne 0.1.0
def checker
self.class.checker
end
end
end
end
60 changes: 60 additions & 0 deletions lib/blast_wave/check_list/checker.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# frozen_string_literal: true

module Rack
# @api private
# @since 0.1.0
class BlastWave::CheckList::Checker
# @return [void]
#
# @api private
# @since 0.1.0
def initialize
@matcher_registry = BlastWave::CheckList::MatcherRegistry.new
end

# @param request [Rack::Request]
# @option check_all [Boolean]
# @return [Boolean]
#
# @api private
# @since 0.1.0
def check!(request, check_all: false)
check_all ? all?(request) : any?(request)
end

# @param block [Proc]
# @return [void]
#
# @api private
# @since 0.1.0
def register(&block)
matcher_registry.register(BlastWave::CheckList::Matcher.new(block))
end

private

# @return [BlastWave::CheckList::MatcherRegistry]
#
# @api private
# @since 0.1.0
attr_reader :matcher_registry

# @param request [Rack::Request]
# @return [Boolean]
#
# @api private
# @since 0.1.0
def any?(request)
matcher_registry.all?(request)
end

# @param request [Rack::Request]
# @return [Boolean]
#
# @api private
# @since 0.1.0
def all?(request)
matcher_registry.any?(request)
end
end
end
49 changes: 49 additions & 0 deletions lib/blast_wave/check_list/fail_response.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# frozen_string_literal: true

module Rack
# @api private
# @since 0.1.0
class BlastWave::CheckList::FailResponse < Rack::Response
# @return [Array<String>]
#
# @api private
# @since 0.1.0
DEFAULT_BODY = ['Forbidden'].freeze

# @return [Hash]
#
# @api private
# @since 0.1.0
DEFAULT_HEADERS = { 'Content-Type' => 'text/plain' }.freeze

# @return [Integer]
#
# @api private
# @since 0.1.0
DEFAULT_STATUS = 403

class << self
# @option status [Integer]
# @option body [Array<String>]
# @option headers [Hash]
# @return [Rack::Response]
#
# @api private
# @since 0.1.0
def build(status: DEFAULT_STATUS, body: DEFAULT_BODY, headers: DEFAULT_HEADERS)
new(body, status, headers)
end
end

# @param body [Array<String>]
# @param status [Integer]
# @param header [Hash]
# @return [void]
#
# @since 0.1.0
# @api private
def initialize(body = DEFAULT_BODY, status = DEFAULT_STATUS, header = DEFAULT_HEADERS)
super
end
end
end
31 changes: 31 additions & 0 deletions lib/blast_wave/check_list/matcher.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# frozen_string_literal: true

module Rack
# @api private
# @since 0.1.0
class BlastWave::CheckList::Matcher
# @return [Object] #call-able object
#
# @api private
# @since 0.1.0
attr_reader :matcher

# @param matcher [Object] #call-able object
# @return [void]
#
# @api private
# @since 0.1.0
def initialize(matcher)
@matcher = matcher
end

# @param request [Rack::Request]
# @return [Boolean]
#
# @api private
# @since 0.1.0
def match?(request)
!!matcher.call(request)
end
end
end
51 changes: 51 additions & 0 deletions lib/blast_wave/check_list/matcher_registry.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# frozen_string_literal: true

module Rack
# @api private
# @since 0.1.0
class BlastWave::CheckList::MatcherRegistry
# @since 0.1.0
include Enumerable

# @return [void]
#
# @api private
# @since 0.1.0
def initialize
@list = []
@lock = Mutex.new
end

# @param matcher [BlastWave::CheckList::Matcher]
# @return [void]
#
# @api private
# @since 0.1.0
def register(matcher)
lock.synchronize { list << matcher }
end

# @param block [Proc]
# @return [void]
#
# @api private
# @since 0.1.0
def each(&block)
block_given? ? list.each(&block) : list.each
end

private

# @return [Array]
#
# @api private
# @since 0.1.0
attr_reader :list

# @return [Mutex]
#
# @api private
# @since 0.1.0
attr_reader :lock
end
end
3 changes: 3 additions & 0 deletions lib/blast_wave/request_id.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ module Rack
# @api public
# @since 0.1.0
class BlastWave::RequestId < BlastWave::Middleware
require_relative 'request_id/extensions/request_interface'
require_relative 'request_id/initializer'

# @since 0.1.0
include Qonfig::Configurable

Expand Down
18 changes: 18 additions & 0 deletions lib/blast_wave/white_list.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# frozen_string_literal: true

module Rack
# @api public
# @since 0.1.0
class BlastWave::WhiteList < BlastWave::CheckList
BlastWave::CheckList::Builder.build(self)

# @param env [Hash]
# @return [Object]
#
# @api private
# @since 0.1.0
def call(env)
check!(env) ? super : generate_fail_response!
end
end
end
5 changes: 5 additions & 0 deletions spec/features/black_list_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# frozen_string_literal: true

RSpec.describe 'Rack::BlastWave::BlackList Middleware' do
let!(:app) { build_fake_rack_app(Rack::BlastWave::BlackList) }
end

0 comments on commit f806c29

Please sign in to comment.