xenon-routing 0.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
 - data/.codeclimate.yml +18 -0
 - data/.gitignore +25 -0
 - data/.rspec +3 -0
 - data/.travis.yml +6 -0
 - data/Gemfile +20 -0
 - data/Guardfile +16 -0
 - data/LICENSE +22 -0
 - data/README.md +116 -0
 - data/Rakefile +40 -0
 - data/VERSION +1 -0
 - data/examples/hello_world/config.ru +3 -0
 - data/examples/hello_world/hello_world.rb +27 -0
 - data/xenon-http/lib/xenon/auth.rb +63 -0
 - data/xenon-http/lib/xenon/errors.rb +5 -0
 - data/xenon-http/lib/xenon/etag.rb +48 -0
 - data/xenon-http/lib/xenon/headers.rb +112 -0
 - data/xenon-http/lib/xenon/headers/accept.rb +34 -0
 - data/xenon-http/lib/xenon/headers/accept_charset.rb +59 -0
 - data/xenon-http/lib/xenon/headers/accept_encoding.rb +63 -0
 - data/xenon-http/lib/xenon/headers/accept_language.rb +59 -0
 - data/xenon-http/lib/xenon/headers/authorization.rb +50 -0
 - data/xenon-http/lib/xenon/headers/cache_control.rb +56 -0
 - data/xenon-http/lib/xenon/headers/content_type.rb +23 -0
 - data/xenon-http/lib/xenon/headers/if_match.rb +53 -0
 - data/xenon-http/lib/xenon/headers/if_modified_since.rb +22 -0
 - data/xenon-http/lib/xenon/headers/if_none_match.rb +53 -0
 - data/xenon-http/lib/xenon/headers/if_range.rb +45 -0
 - data/xenon-http/lib/xenon/headers/if_unmodified_since.rb +22 -0
 - data/xenon-http/lib/xenon/headers/user_agent.rb +65 -0
 - data/xenon-http/lib/xenon/headers/www_authenticate.rb +71 -0
 - data/xenon-http/lib/xenon/http.rb +7 -0
 - data/xenon-http/lib/xenon/http_version.rb +3 -0
 - data/xenon-http/lib/xenon/media_type.rb +162 -0
 - data/xenon-http/lib/xenon/parsers/basic_rules.rb +86 -0
 - data/xenon-http/lib/xenon/parsers/header_rules.rb +60 -0
 - data/xenon-http/lib/xenon/parsers/media_type.rb +53 -0
 - data/xenon-http/lib/xenon/quoted_string.rb +20 -0
 - data/xenon-http/spec/spec_helper.rb +94 -0
 - data/xenon-http/spec/xenon/etag_spec.rb +19 -0
 - data/xenon-http/spec/xenon/headers/accept_charset_spec.rb +31 -0
 - data/xenon-http/spec/xenon/headers/accept_encoding_spec.rb +40 -0
 - data/xenon-http/spec/xenon/headers/accept_language_spec.rb +33 -0
 - data/xenon-http/spec/xenon/headers/accept_spec.rb +54 -0
 - data/xenon-http/spec/xenon/headers/authorization_spec.rb +47 -0
 - data/xenon-http/spec/xenon/headers/cache_control_spec.rb +64 -0
 - data/xenon-http/spec/xenon/headers/if_match_spec.rb +73 -0
 - data/xenon-http/spec/xenon/headers/if_modified_since_spec.rb +19 -0
 - data/xenon-http/spec/xenon/headers/if_none_match_spec.rb +79 -0
 - data/xenon-http/spec/xenon/headers/if_range_spec.rb +45 -0
 - data/xenon-http/spec/xenon/headers/if_unmodified_since_spec.rb +19 -0
 - data/xenon-http/spec/xenon/headers/user_agent_spec.rb +67 -0
 - data/xenon-http/spec/xenon/headers/www_authenticate_spec.rb +43 -0
 - data/xenon-http/spec/xenon/media_type_spec.rb +267 -0
 - data/xenon-http/xenon-http.gemspec +25 -0
 - data/xenon-routing/lib/xenon/api.rb +118 -0
 - data/xenon-routing/lib/xenon/marshallers.rb +48 -0
 - data/xenon-routing/lib/xenon/request.rb +40 -0
 - data/xenon-routing/lib/xenon/response.rb +29 -0
 - data/xenon-routing/lib/xenon/routing.rb +6 -0
 - data/xenon-routing/lib/xenon/routing/context.rb +35 -0
 - data/xenon-routing/lib/xenon/routing/directives.rb +14 -0
 - data/xenon-routing/lib/xenon/routing/header_directives.rb +32 -0
 - data/xenon-routing/lib/xenon/routing/method_directives.rb +26 -0
 - data/xenon-routing/lib/xenon/routing/param_directives.rb +22 -0
 - data/xenon-routing/lib/xenon/routing/path_directives.rb +37 -0
 - data/xenon-routing/lib/xenon/routing/route_directives.rb +51 -0
 - data/xenon-routing/lib/xenon/routing/security_directives.rb +34 -0
 - data/xenon-routing/lib/xenon/routing_version.rb +3 -0
 - data/xenon-routing/spec/spec_helper.rb +94 -0
 - data/xenon-routing/xenon-routing.gemspec +25 -0
 - data/xenon.gemspec +26 -0
 - metadata +145 -0
 
| 
         @@ -0,0 +1,48 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'xenon/media_type'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module Xenon
         
     | 
| 
      
 4 
     | 
    
         
            +
              class JsonMarshaller
         
     | 
| 
      
 5 
     | 
    
         
            +
                def media_type
         
     | 
| 
      
 6 
     | 
    
         
            +
                  MediaType::JSON
         
     | 
| 
      
 7 
     | 
    
         
            +
                end
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
                def content_type
         
     | 
| 
      
 10 
     | 
    
         
            +
                  media_type.with_charset(Encoding::UTF_8)
         
     | 
| 
      
 11 
     | 
    
         
            +
                end
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
                def marshal_to?(media_range)
         
     | 
| 
      
 14 
     | 
    
         
            +
                  media_range =~ media_type
         
     | 
| 
      
 15 
     | 
    
         
            +
                end
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
                def marshal(obj)
         
     | 
| 
      
 18 
     | 
    
         
            +
                  [obj.to_json]
         
     | 
| 
      
 19 
     | 
    
         
            +
                end
         
     | 
| 
      
 20 
     | 
    
         
            +
              end
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
              class XmlMarshaller
         
     | 
| 
      
 23 
     | 
    
         
            +
                def initialize
         
     | 
| 
      
 24 
     | 
    
         
            +
                  gem 'builder'
         
     | 
| 
      
 25 
     | 
    
         
            +
                  require 'active_support/core_ext/array/conversions'
         
     | 
| 
      
 26 
     | 
    
         
            +
                  require 'active_support/core_ext/hash/conversions'
         
     | 
| 
      
 27 
     | 
    
         
            +
                rescue Gem::LoadError
         
     | 
| 
      
 28 
     | 
    
         
            +
                  raise 'Install the "builder" gem to enable XML.'
         
     | 
| 
      
 29 
     | 
    
         
            +
                end
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
                def media_type
         
     | 
| 
      
 32 
     | 
    
         
            +
                  MediaType::XML
         
     | 
| 
      
 33 
     | 
    
         
            +
                end
         
     | 
| 
      
 34 
     | 
    
         
            +
             
     | 
| 
      
 35 
     | 
    
         
            +
                def content_type
         
     | 
| 
      
 36 
     | 
    
         
            +
                  media_type.with_charset(Encoding::UTF_8)
         
     | 
| 
      
 37 
     | 
    
         
            +
                end
         
     | 
| 
      
 38 
     | 
    
         
            +
             
     | 
| 
      
 39 
     | 
    
         
            +
                def marshal_to?(media_range)
         
     | 
| 
      
 40 
     | 
    
         
            +
                  media_range =~ media_type
         
     | 
| 
      
 41 
     | 
    
         
            +
                end
         
     | 
| 
      
 42 
     | 
    
         
            +
             
     | 
| 
      
 43 
     | 
    
         
            +
                def marshal(obj)
         
     | 
| 
      
 44 
     | 
    
         
            +
                  raise "#{obj.class} does not support #to_xml" unless obj.respond_to?(:to_xml)
         
     | 
| 
      
 45 
     | 
    
         
            +
                  [obj.to_xml]
         
     | 
| 
      
 46 
     | 
    
         
            +
                end
         
     | 
| 
      
 47 
     | 
    
         
            +
              end
         
     | 
| 
      
 48 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,40 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'xenon/headers'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module Xenon
         
     | 
| 
      
 4 
     | 
    
         
            +
              class Request
         
     | 
| 
      
 5 
     | 
    
         
            +
                attr_accessor :unmatched_path
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
                def initialize(rack_req)
         
     | 
| 
      
 8 
     | 
    
         
            +
                  @rack_req = rack_req
         
     | 
| 
      
 9 
     | 
    
         
            +
                  @unmatched_path = rack_req.path.freeze
         
     | 
| 
      
 10 
     | 
    
         
            +
                end
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
                def request_method
         
     | 
| 
      
 13 
     | 
    
         
            +
                  @rack_req.request_method.downcase.to_sym
         
     | 
| 
      
 14 
     | 
    
         
            +
                end
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
                def form_hash
         
     | 
| 
      
 17 
     | 
    
         
            +
                  @form_hash ||= @rack_req.POST.with_indifferent_access.freeze
         
     | 
| 
      
 18 
     | 
    
         
            +
                end
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
                def param_hash
         
     | 
| 
      
 21 
     | 
    
         
            +
                  puts "GET = #{@rack_req.GET.inspect}"
         
     | 
| 
      
 22 
     | 
    
         
            +
                  @param_hash ||= @rack_req.GET.with_indifferent_access.freeze
         
     | 
| 
      
 23 
     | 
    
         
            +
                end
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
                def header(name)
         
     | 
| 
      
 26 
     | 
    
         
            +
                  snake_name = name.to_s.tr('-', '_')
         
     | 
| 
      
 27 
     | 
    
         
            +
                  value = @rack_req.env['HTTP_' + snake_name.upcase]
         
     | 
| 
      
 28 
     | 
    
         
            +
                  return nil if value.nil?
         
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
      
 30 
     | 
    
         
            +
                  klass = Xenon::Headers.header_class(name)
         
     | 
| 
      
 31 
     | 
    
         
            +
                  klass ? klass.parse(value) : Xenon::Headers::Raw.new(name, value)
         
     | 
| 
      
 32 
     | 
    
         
            +
                end
         
     | 
| 
      
 33 
     | 
    
         
            +
             
     | 
| 
      
 34 
     | 
    
         
            +
                def copy(changes = {})
         
     | 
| 
      
 35 
     | 
    
         
            +
                  r = dup
         
     | 
| 
      
 36 
     | 
    
         
            +
                  changes.each { |k, v| r.instance_variable_set("@#{k}", v.freeze) }
         
     | 
| 
      
 37 
     | 
    
         
            +
                  r
         
     | 
| 
      
 38 
     | 
    
         
            +
                end
         
     | 
| 
      
 39 
     | 
    
         
            +
              end
         
     | 
| 
      
 40 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,29 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'xenon/headers'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module Xenon
         
     | 
| 
      
 4 
     | 
    
         
            +
              class Response
         
     | 
| 
      
 5 
     | 
    
         
            +
                attr_reader :status, :headers, :body
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
                def initialize
         
     | 
| 
      
 8 
     | 
    
         
            +
                  @headers = Headers.new
         
     | 
| 
      
 9 
     | 
    
         
            +
                  @complete = false
         
     | 
| 
      
 10 
     | 
    
         
            +
                  freeze
         
     | 
| 
      
 11 
     | 
    
         
            +
                end
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
                def complete?
         
     | 
| 
      
 14 
     | 
    
         
            +
                  @complete
         
     | 
| 
      
 15 
     | 
    
         
            +
                end
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
                def copy(changes = {})
         
     | 
| 
      
 18 
     | 
    
         
            +
                  r = dup
         
     | 
| 
      
 19 
     | 
    
         
            +
                  changes.each { |k, v| r.instance_variable_set("@#{k}", v) }
         
     | 
| 
      
 20 
     | 
    
         
            +
                  r.freeze
         
     | 
| 
      
 21 
     | 
    
         
            +
                end
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
                def freeze
         
     | 
| 
      
 24 
     | 
    
         
            +
                  @headers.freeze
         
     | 
| 
      
 25 
     | 
    
         
            +
                  @body.freeze
         
     | 
| 
      
 26 
     | 
    
         
            +
                  super
         
     | 
| 
      
 27 
     | 
    
         
            +
                end
         
     | 
| 
      
 28 
     | 
    
         
            +
              end
         
     | 
| 
      
 29 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,35 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module Xenon
         
     | 
| 
      
 2 
     | 
    
         
            +
              module Routing
         
     | 
| 
      
 3 
     | 
    
         
            +
                class Rejection
         
     | 
| 
      
 4 
     | 
    
         
            +
                  attr_reader :reason, :info
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
                  def initialize(reason, info = {})
         
     | 
| 
      
 7 
     | 
    
         
            +
                    @reason = reason
         
     | 
| 
      
 8 
     | 
    
         
            +
                    @info = info
         
     | 
| 
      
 9 
     | 
    
         
            +
                  end
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
                  def [](name)
         
     | 
| 
      
 12 
     | 
    
         
            +
                    @info[name]
         
     | 
| 
      
 13 
     | 
    
         
            +
                  end
         
     | 
| 
      
 14 
     | 
    
         
            +
                end
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
                class Context
         
     | 
| 
      
 17 
     | 
    
         
            +
                  attr_accessor :request, :response, :rejections
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
                  def initialize(request, response)
         
     | 
| 
      
 20 
     | 
    
         
            +
                    @request = request
         
     | 
| 
      
 21 
     | 
    
         
            +
                    @response = response
         
     | 
| 
      
 22 
     | 
    
         
            +
                    @rejections = []
         
     | 
| 
      
 23 
     | 
    
         
            +
                  end
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
                  def branch
         
     | 
| 
      
 26 
     | 
    
         
            +
                    original_request = @request
         
     | 
| 
      
 27 
     | 
    
         
            +
                    original_response = @response
         
     | 
| 
      
 28 
     | 
    
         
            +
                    yield
         
     | 
| 
      
 29 
     | 
    
         
            +
                  ensure
         
     | 
| 
      
 30 
     | 
    
         
            +
                    @request = original_request
         
     | 
| 
      
 31 
     | 
    
         
            +
                    @response = original_response unless @response.complete?
         
     | 
| 
      
 32 
     | 
    
         
            +
                  end
         
     | 
| 
      
 33 
     | 
    
         
            +
                end
         
     | 
| 
      
 34 
     | 
    
         
            +
              end
         
     | 
| 
      
 35 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,14 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            Dir[File.join(__dir__, '*_directives.rb')].each { |f| require f }
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module Xenon
         
     | 
| 
      
 4 
     | 
    
         
            +
              module Routing
         
     | 
| 
      
 5 
     | 
    
         
            +
                module Directives
         
     | 
| 
      
 6 
     | 
    
         
            +
                  include RouteDirectives
         
     | 
| 
      
 7 
     | 
    
         
            +
                  include HeaderDirectives
         
     | 
| 
      
 8 
     | 
    
         
            +
                  include MethodDirectives
         
     | 
| 
      
 9 
     | 
    
         
            +
                  include ParamDirectives
         
     | 
| 
      
 10 
     | 
    
         
            +
                  include PathDirectives
         
     | 
| 
      
 11 
     | 
    
         
            +
                  include SecurityDirectives
         
     | 
| 
      
 12 
     | 
    
         
            +
                end
         
     | 
| 
      
 13 
     | 
    
         
            +
              end
         
     | 
| 
      
 14 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,32 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'xenon/routing/route_directives'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module Xenon
         
     | 
| 
      
 4 
     | 
    
         
            +
              module Routing
         
     | 
| 
      
 5 
     | 
    
         
            +
                module HeaderDirectives
         
     | 
| 
      
 6 
     | 
    
         
            +
                  include RouteDirectives
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
                  def optional_header(name)
         
     | 
| 
      
 9 
     | 
    
         
            +
                    extract_request do |request|
         
     | 
| 
      
 10 
     | 
    
         
            +
                      yield request.header(name)
         
     | 
| 
      
 11 
     | 
    
         
            +
                    end
         
     | 
| 
      
 12 
     | 
    
         
            +
                  end
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
                  def header(name)
         
     | 
| 
      
 15 
     | 
    
         
            +
                    optional_header(name) do |value|
         
     | 
| 
      
 16 
     | 
    
         
            +
                      if value
         
     | 
| 
      
 17 
     | 
    
         
            +
                        yield value
         
     | 
| 
      
 18 
     | 
    
         
            +
                      else
         
     | 
| 
      
 19 
     | 
    
         
            +
                        reject Rejection.new(:header, { required: name })
         
     | 
| 
      
 20 
     | 
    
         
            +
                      end
         
     | 
| 
      
 21 
     | 
    
         
            +
                    end
         
     | 
| 
      
 22 
     | 
    
         
            +
                  end
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
                  def respond_with_header(header)
         
     | 
| 
      
 25 
     | 
    
         
            +
                    map_response -> r { r.copy(headers: r.headers.add(header)) } do
         
     | 
| 
      
 26 
     | 
    
         
            +
                      yield
         
     | 
| 
      
 27 
     | 
    
         
            +
                    end
         
     | 
| 
      
 28 
     | 
    
         
            +
                  end
         
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
      
 30 
     | 
    
         
            +
                end
         
     | 
| 
      
 31 
     | 
    
         
            +
              end
         
     | 
| 
      
 32 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,26 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'xenon/routing/route_directives'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module Xenon
         
     | 
| 
      
 4 
     | 
    
         
            +
              module Routing
         
     | 
| 
      
 5 
     | 
    
         
            +
                module MethodDirectives
         
     | 
| 
      
 6 
     | 
    
         
            +
                  include RouteDirectives
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
                  def request_method(method)
         
     | 
| 
      
 9 
     | 
    
         
            +
                    extract_request do |request|
         
     | 
| 
      
 10 
     | 
    
         
            +
                      if request.request_method == method
         
     | 
| 
      
 11 
     | 
    
         
            +
                        yield
         
     | 
| 
      
 12 
     | 
    
         
            +
                      else
         
     | 
| 
      
 13 
     | 
    
         
            +
                        reject Rejection.new(:method, { supported: method })
         
     | 
| 
      
 14 
     | 
    
         
            +
                      end
         
     | 
| 
      
 15 
     | 
    
         
            +
                    end
         
     | 
| 
      
 16 
     | 
    
         
            +
                  end
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
                  %i(delete get head options patch post put).each do |method|
         
     | 
| 
      
 19 
     | 
    
         
            +
                    define_method(method) do |&inner|
         
     | 
| 
      
 20 
     | 
    
         
            +
                      request_method(method, &inner)
         
     | 
| 
      
 21 
     | 
    
         
            +
                    end
         
     | 
| 
      
 22 
     | 
    
         
            +
                  end
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
                end
         
     | 
| 
      
 25 
     | 
    
         
            +
              end
         
     | 
| 
      
 26 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,22 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'xenon/routing/route_directives'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module Xenon
         
     | 
| 
      
 4 
     | 
    
         
            +
              module Routing
         
     | 
| 
      
 5 
     | 
    
         
            +
                module ParamDirectives
         
     | 
| 
      
 6 
     | 
    
         
            +
                  include RouteDirectives
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
                  def param_hash
         
     | 
| 
      
 9 
     | 
    
         
            +
                    extract_request do |request|
         
     | 
| 
      
 10 
     | 
    
         
            +
                      yield request.param_hash
         
     | 
| 
      
 11 
     | 
    
         
            +
                    end
         
     | 
| 
      
 12 
     | 
    
         
            +
                  end
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
                  def params(*names)
         
     | 
| 
      
 15 
     | 
    
         
            +
                    param_hash do |hash|
         
     | 
| 
      
 16 
     | 
    
         
            +
                      yield *hash.slice(*names).values
         
     | 
| 
      
 17 
     | 
    
         
            +
                    end
         
     | 
| 
      
 18 
     | 
    
         
            +
                  end
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
                end
         
     | 
| 
      
 21 
     | 
    
         
            +
              end
         
     | 
| 
      
 22 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,37 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'xenon/routing/route_directives'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module Xenon
         
     | 
| 
      
 4 
     | 
    
         
            +
              module Routing
         
     | 
| 
      
 5 
     | 
    
         
            +
                module PathDirectives
         
     | 
| 
      
 6 
     | 
    
         
            +
                  include RouteDirectives
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
                  def path_prefix(pattern)
         
     | 
| 
      
 9 
     | 
    
         
            +
                    extract_request do |request|
         
     | 
| 
      
 10 
     | 
    
         
            +
                      match = request.unmatched_path.match(pattern)
         
     | 
| 
      
 11 
     | 
    
         
            +
                      if match && match.pre_match == ''
         
     | 
| 
      
 12 
     | 
    
         
            +
                        map_request unmatched_path: match.post_match do
         
     | 
| 
      
 13 
     | 
    
         
            +
                          yield *match.captures
         
     | 
| 
      
 14 
     | 
    
         
            +
                        end
         
     | 
| 
      
 15 
     | 
    
         
            +
                      else
         
     | 
| 
      
 16 
     | 
    
         
            +
                        reject nil # path rejections are nil to allow more specific rejections to be seen
         
     | 
| 
      
 17 
     | 
    
         
            +
                      end
         
     | 
| 
      
 18 
     | 
    
         
            +
                    end
         
     | 
| 
      
 19 
     | 
    
         
            +
                  end
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
                  def path_end
         
     | 
| 
      
 22 
     | 
    
         
            +
                    path_prefix(/\Z/) do
         
     | 
| 
      
 23 
     | 
    
         
            +
                      yield
         
     | 
| 
      
 24 
     | 
    
         
            +
                    end
         
     | 
| 
      
 25 
     | 
    
         
            +
                  end
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
                  def path(pattern)
         
     | 
| 
      
 28 
     | 
    
         
            +
                    path_prefix(pattern) do |*captures|
         
     | 
| 
      
 29 
     | 
    
         
            +
                      path_end do
         
     | 
| 
      
 30 
     | 
    
         
            +
                        yield *captures
         
     | 
| 
      
 31 
     | 
    
         
            +
                      end
         
     | 
| 
      
 32 
     | 
    
         
            +
                    end
         
     | 
| 
      
 33 
     | 
    
         
            +
                  end
         
     | 
| 
      
 34 
     | 
    
         
            +
             
     | 
| 
      
 35 
     | 
    
         
            +
                end
         
     | 
| 
      
 36 
     | 
    
         
            +
              end
         
     | 
| 
      
 37 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,51 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'rack/utils'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module Xenon
         
     | 
| 
      
 4 
     | 
    
         
            +
              module Routing
         
     | 
| 
      
 5 
     | 
    
         
            +
                module RouteDirectives
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
                  def map_request(map)
         
     | 
| 
      
 8 
     | 
    
         
            +
                    context.branch do
         
     | 
| 
      
 9 
     | 
    
         
            +
                      context.request = map.respond_to?(:call) ? map.call(context.request) : context.request.copy(map)
         
     | 
| 
      
 10 
     | 
    
         
            +
                      yield
         
     | 
| 
      
 11 
     | 
    
         
            +
                    end
         
     | 
| 
      
 12 
     | 
    
         
            +
                  end
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
                  def map_response(map)
         
     | 
| 
      
 15 
     | 
    
         
            +
                    context.branch do
         
     | 
| 
      
 16 
     | 
    
         
            +
                      context.response = map.respond_to?(:call) ? map.call(context.response) : context.response.copy(map)
         
     | 
| 
      
 17 
     | 
    
         
            +
                      yield
         
     | 
| 
      
 18 
     | 
    
         
            +
                    end
         
     | 
| 
      
 19 
     | 
    
         
            +
                  end
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
                  def complete(status, body)
         
     | 
| 
      
 22 
     | 
    
         
            +
                    map_response complete: true, status: Rack::Utils.status_code(status), body: body do
         
     | 
| 
      
 23 
     | 
    
         
            +
                      throw :complete
         
     | 
| 
      
 24 
     | 
    
         
            +
                    end
         
     | 
| 
      
 25 
     | 
    
         
            +
                  end
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
                  def reject(rejection, info = {})
         
     | 
| 
      
 28 
     | 
    
         
            +
                    return if rejection.nil?
         
     | 
| 
      
 29 
     | 
    
         
            +
                    rejection = Rejection.new(rejection, info) unless rejection.is_a?(Rejection)
         
     | 
| 
      
 30 
     | 
    
         
            +
                    context.rejections << rejection
         
     | 
| 
      
 31 
     | 
    
         
            +
                  end
         
     | 
| 
      
 32 
     | 
    
         
            +
             
     | 
| 
      
 33 
     | 
    
         
            +
                  def fail(status, developer_message = nil)
         
     | 
| 
      
 34 
     | 
    
         
            +
                    body = {
         
     | 
| 
      
 35 
     | 
    
         
            +
                      status: status,
         
     | 
| 
      
 36 
     | 
    
         
            +
                      developer_message: developer_message || Rack::Utils::HTTP_STATUS_CODES[status]
         
     | 
| 
      
 37 
     | 
    
         
            +
                    }
         
     | 
| 
      
 38 
     | 
    
         
            +
                    complete status, body
         
     | 
| 
      
 39 
     | 
    
         
            +
                  end
         
     | 
| 
      
 40 
     | 
    
         
            +
             
     | 
| 
      
 41 
     | 
    
         
            +
                  def extract(lambda)
         
     | 
| 
      
 42 
     | 
    
         
            +
                    yield lambda.call(context)
         
     | 
| 
      
 43 
     | 
    
         
            +
                  end
         
     | 
| 
      
 44 
     | 
    
         
            +
             
     | 
| 
      
 45 
     | 
    
         
            +
                  def extract_request(lambda = nil)
         
     | 
| 
      
 46 
     | 
    
         
            +
                    yield lambda ? lambda.call(context.request) : context.request
         
     | 
| 
      
 47 
     | 
    
         
            +
                  end
         
     | 
| 
      
 48 
     | 
    
         
            +
             
     | 
| 
      
 49 
     | 
    
         
            +
                end
         
     | 
| 
      
 50 
     | 
    
         
            +
              end
         
     | 
| 
      
 51 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,34 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'xenon/routing/route_directives'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module Xenon
         
     | 
| 
      
 4 
     | 
    
         
            +
              module Routing
         
     | 
| 
      
 5 
     | 
    
         
            +
                module SecurityDirectives
         
     | 
| 
      
 6 
     | 
    
         
            +
                  include RouteDirectives
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
                  def authenticate(authenticator)
         
     | 
| 
      
 9 
     | 
    
         
            +
                    extract_request(authenticator) do |user|
         
     | 
| 
      
 10 
     | 
    
         
            +
                      if user
         
     | 
| 
      
 11 
     | 
    
         
            +
                        yield user
         
     | 
| 
      
 12 
     | 
    
         
            +
                      else
         
     | 
| 
      
 13 
     | 
    
         
            +
                        reject :unauthorized, { scheme: authenticator.scheme }.merge(authenticator.auth_params)
         
     | 
| 
      
 14 
     | 
    
         
            +
                      end
         
     | 
| 
      
 15 
     | 
    
         
            +
                    end
         
     | 
| 
      
 16 
     | 
    
         
            +
                  end
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
                  def authorize(check)
         
     | 
| 
      
 19 
     | 
    
         
            +
                    if check.respond_to?(:call)
         
     | 
| 
      
 20 
     | 
    
         
            +
                      extract_request(check) do |authorized|
         
     | 
| 
      
 21 
     | 
    
         
            +
                        authorize(authorized) do
         
     | 
| 
      
 22 
     | 
    
         
            +
                          yield
         
     | 
| 
      
 23 
     | 
    
         
            +
                        end
         
     | 
| 
      
 24 
     | 
    
         
            +
                      end
         
     | 
| 
      
 25 
     | 
    
         
            +
                    elsif check
         
     | 
| 
      
 26 
     | 
    
         
            +
                      yield
         
     | 
| 
      
 27 
     | 
    
         
            +
                    else
         
     | 
| 
      
 28 
     | 
    
         
            +
                      reject :forbidden
         
     | 
| 
      
 29 
     | 
    
         
            +
                    end
         
     | 
| 
      
 30 
     | 
    
         
            +
                  end
         
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
      
 32 
     | 
    
         
            +
                end
         
     | 
| 
      
 33 
     | 
    
         
            +
              end
         
     | 
| 
      
 34 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,94 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require "codeclimate-test-reporter"
         
     | 
| 
      
 2 
     | 
    
         
            +
            CodeClimate::TestReporter.start
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            # This file was generated by the `rspec --init` command. Conventionally, all
         
     | 
| 
      
 5 
     | 
    
         
            +
            # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
         
     | 
| 
      
 6 
     | 
    
         
            +
            # The generated `.rspec` file contains `--require spec_helper` which will cause
         
     | 
| 
      
 7 
     | 
    
         
            +
            # this file to always be loaded, without a need to explicitly require it in any
         
     | 
| 
      
 8 
     | 
    
         
            +
            # files.
         
     | 
| 
      
 9 
     | 
    
         
            +
            #
         
     | 
| 
      
 10 
     | 
    
         
            +
            # Given that it is always loaded, you are encouraged to keep this file as
         
     | 
| 
      
 11 
     | 
    
         
            +
            # light-weight as possible. Requiring heavyweight dependencies from this file
         
     | 
| 
      
 12 
     | 
    
         
            +
            # will add to the boot time of your test suite on EVERY test run, even for an
         
     | 
| 
      
 13 
     | 
    
         
            +
            # individual file that may not need all of that loaded. Instead, consider making
         
     | 
| 
      
 14 
     | 
    
         
            +
            # a separate helper file that requires the additional dependencies and performs
         
     | 
| 
      
 15 
     | 
    
         
            +
            # the additional setup, and require it from the spec files that actually need
         
     | 
| 
      
 16 
     | 
    
         
            +
            # it.
         
     | 
| 
      
 17 
     | 
    
         
            +
            #
         
     | 
| 
      
 18 
     | 
    
         
            +
            # The `.rspec` file also contains a few flags that are not defaults but that
         
     | 
| 
      
 19 
     | 
    
         
            +
            # users commonly want.
         
     | 
| 
      
 20 
     | 
    
         
            +
            #
         
     | 
| 
      
 21 
     | 
    
         
            +
            # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
         
     | 
| 
      
 22 
     | 
    
         
            +
            RSpec.configure do |config|
         
     | 
| 
      
 23 
     | 
    
         
            +
              # rspec-expectations config goes here. You can use an alternate
         
     | 
| 
      
 24 
     | 
    
         
            +
              # assertion/expectation library such as wrong or the stdlib/minitest
         
     | 
| 
      
 25 
     | 
    
         
            +
              # assertions if you prefer.
         
     | 
| 
      
 26 
     | 
    
         
            +
              config.expect_with :rspec do |expectations|
         
     | 
| 
      
 27 
     | 
    
         
            +
                # This option will default to `true` in RSpec 4. It makes the `description`
         
     | 
| 
      
 28 
     | 
    
         
            +
                # and `failure_message` of custom matchers include text for helper methods
         
     | 
| 
      
 29 
     | 
    
         
            +
                # defined using `chain`, e.g.:
         
     | 
| 
      
 30 
     | 
    
         
            +
                #     be_bigger_than(2).and_smaller_than(4).description
         
     | 
| 
      
 31 
     | 
    
         
            +
                #     # => "be bigger than 2 and smaller than 4"
         
     | 
| 
      
 32 
     | 
    
         
            +
                # ...rather than:
         
     | 
| 
      
 33 
     | 
    
         
            +
                #     # => "be bigger than 2"
         
     | 
| 
      
 34 
     | 
    
         
            +
                expectations.include_chain_clauses_in_custom_matcher_descriptions = true
         
     | 
| 
      
 35 
     | 
    
         
            +
              end
         
     | 
| 
      
 36 
     | 
    
         
            +
             
     | 
| 
      
 37 
     | 
    
         
            +
              # rspec-mocks config goes here. You can use an alternate test double
         
     | 
| 
      
 38 
     | 
    
         
            +
              # library (such as bogus or mocha) by changing the `mock_with` option here.
         
     | 
| 
      
 39 
     | 
    
         
            +
              config.mock_with :rspec do |mocks|
         
     | 
| 
      
 40 
     | 
    
         
            +
                # Prevents you from mocking or stubbing a method that does not exist on
         
     | 
| 
      
 41 
     | 
    
         
            +
                # a real object. This is generally recommended, and will default to
         
     | 
| 
      
 42 
     | 
    
         
            +
                # `true` in RSpec 4.
         
     | 
| 
      
 43 
     | 
    
         
            +
                mocks.verify_partial_doubles = true
         
     | 
| 
      
 44 
     | 
    
         
            +
              end
         
     | 
| 
      
 45 
     | 
    
         
            +
             
     | 
| 
      
 46 
     | 
    
         
            +
            # The settings below are suggested to provide a good initial experience
         
     | 
| 
      
 47 
     | 
    
         
            +
            # with RSpec, but feel free to customize to your heart's content.
         
     | 
| 
      
 48 
     | 
    
         
            +
            =begin
         
     | 
| 
      
 49 
     | 
    
         
            +
              # These two settings work together to allow you to limit a spec run
         
     | 
| 
      
 50 
     | 
    
         
            +
              # to individual examples or groups you care about by tagging them with
         
     | 
| 
      
 51 
     | 
    
         
            +
              # `:focus` metadata. When nothing is tagged with `:focus`, all examples
         
     | 
| 
      
 52 
     | 
    
         
            +
              # get run.
         
     | 
| 
      
 53 
     | 
    
         
            +
              config.filter_run :focus
         
     | 
| 
      
 54 
     | 
    
         
            +
              config.run_all_when_everything_filtered = true
         
     | 
| 
      
 55 
     | 
    
         
            +
             
     | 
| 
      
 56 
     | 
    
         
            +
              # Limits the available syntax to the non-monkey patched syntax that is
         
     | 
| 
      
 57 
     | 
    
         
            +
              # recommended. For more details, see:
         
     | 
| 
      
 58 
     | 
    
         
            +
              #   - http://myronmars.to/n/dev-blog/2012/06/rspecs-new-expectation-syntax
         
     | 
| 
      
 59 
     | 
    
         
            +
              #   - http://teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/
         
     | 
| 
      
 60 
     | 
    
         
            +
              #   - http://myronmars.to/n/dev-blog/2014/05/notable-changes-in-rspec-3#new__config_option_to_disable_rspeccore_monkey_patching
         
     | 
| 
      
 61 
     | 
    
         
            +
              config.disable_monkey_patching!
         
     | 
| 
      
 62 
     | 
    
         
            +
             
     | 
| 
      
 63 
     | 
    
         
            +
              # This setting enables warnings. It's recommended, but in some cases may
         
     | 
| 
      
 64 
     | 
    
         
            +
              # be too noisy due to issues in dependencies.
         
     | 
| 
      
 65 
     | 
    
         
            +
              config.warnings = true
         
     | 
| 
      
 66 
     | 
    
         
            +
             
     | 
| 
      
 67 
     | 
    
         
            +
              # Many RSpec users commonly either run the entire suite or an individual
         
     | 
| 
      
 68 
     | 
    
         
            +
              # file, and it's useful to allow more verbose output when running an
         
     | 
| 
      
 69 
     | 
    
         
            +
              # individual spec file.
         
     | 
| 
      
 70 
     | 
    
         
            +
              if config.files_to_run.one?
         
     | 
| 
      
 71 
     | 
    
         
            +
                # Use the documentation formatter for detailed output,
         
     | 
| 
      
 72 
     | 
    
         
            +
                # unless a formatter has already been configured
         
     | 
| 
      
 73 
     | 
    
         
            +
                # (e.g. via a command-line flag).
         
     | 
| 
      
 74 
     | 
    
         
            +
                config.default_formatter = 'doc'
         
     | 
| 
      
 75 
     | 
    
         
            +
              end
         
     | 
| 
      
 76 
     | 
    
         
            +
             
     | 
| 
      
 77 
     | 
    
         
            +
              # Print the 10 slowest examples and example groups at the
         
     | 
| 
      
 78 
     | 
    
         
            +
              # end of the spec run, to help surface which specs are running
         
     | 
| 
      
 79 
     | 
    
         
            +
              # particularly slow.
         
     | 
| 
      
 80 
     | 
    
         
            +
              config.profile_examples = 10
         
     | 
| 
      
 81 
     | 
    
         
            +
             
     | 
| 
      
 82 
     | 
    
         
            +
              # Run specs in random order to surface order dependencies. If you find an
         
     | 
| 
      
 83 
     | 
    
         
            +
              # order dependency and want to debug it, you can fix the order by providing
         
     | 
| 
      
 84 
     | 
    
         
            +
              # the seed, which is printed after each run.
         
     | 
| 
      
 85 
     | 
    
         
            +
              #     --seed 1234
         
     | 
| 
      
 86 
     | 
    
         
            +
              config.order = :random
         
     | 
| 
      
 87 
     | 
    
         
            +
             
     | 
| 
      
 88 
     | 
    
         
            +
              # Seed global randomization in this process using the `--seed` CLI option.
         
     | 
| 
      
 89 
     | 
    
         
            +
              # Setting this allows you to use `--seed` to deterministically reproduce
         
     | 
| 
      
 90 
     | 
    
         
            +
              # test failures related to randomization by passing the same `--seed` value
         
     | 
| 
      
 91 
     | 
    
         
            +
              # as the one that triggered the failure.
         
     | 
| 
      
 92 
     | 
    
         
            +
              Kernel.srand config.seed
         
     | 
| 
      
 93 
     | 
    
         
            +
            =end
         
     | 
| 
      
 94 
     | 
    
         
            +
            end
         
     |