Class: AppIdentity::RackMiddleware

Inherits:
Object
  • Object
show all
Defined in:
lib/app_identity/rack_middleware.rb

Overview

A Rack middleware that verifies App Identity proofs provided via one or more HTTP headers.

When multiple proof values are provided in the request, all must be successfully verified. If any of the proof values cannot be verified, request processing halts with ‘403 Forbidden`. Should no proof headers are included, the request is considered invalid.

All of the above behaviours can be modified through configuration (see below).

The results of completed proof validations can be found at env, regardless of success or failure.

### Configuration

The Rack middlware can be configured with the following options:

  • ‘apps`: A list of AppIdentity::App objects or objects that can be converted into AppIdentity::App objects to be used for proof validation. Duplicate values will be ignored.

  • ‘disallowed`: A list of algorithm versions that are not allowed when processing received identity proofs. See AppIdentity::Versions.allowed?.

  • ‘finder`: A 1-arity callable function that will load an input to AppIdentity::App.new from an external source given a parsed proof.

  • ‘headers`: A list of HTTP header names.

  • ‘on_failure`: The behaviour of the Rack middleware when proof validation fails. Must be one of the following values:

    - `:forbidden`: Halt request processing and respond with a `403`
      (forbidden) status. This is the same as `[:halt, :forbidden]`. This is
      the default `on_failure` behaviour.
    
    - `[:halt, status]`: Halt request processing and return the specified
      status code. An empty body is emitted.
    
    - `[:halt, status, body]`: Halt request processing and return the
      specified status code. The body value is included in the response.
    
    - `:continue`: Continue processing, ensuring that failure states are
      recorded for the application to act on at a later point. This could be
      used to implement a distinction between *validating* a proof and
      *requiring* that the proof is valid.
    
    - A 1-arity callable accepting the Rack `env` value and returns one of the
      above values.
    

At least one of ‘apps` or `finder` must be supplied. If both are present, apps are looked up in the `apps` list first.

“‘ruby use AppIdentity::RackMiddleware, header: “application-identity”,

finder: ->(proof) { ApplicationModel.find(proof[:id]) }

“‘

Instance Method Summary collapse

Constructor Details

#initialize(app, options = {}) ⇒ RackMiddleware

:nodoc:



66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
# File 'lib/app_identity/rack_middleware.rb', line 66

def initialize(app, options = {}) # :nodoc:
  @app = app

  if !options.has_key?(:apps) && !options.has_key?(:finder)
    raise AppIdentity::Error, :plug_missing_apps_or_finder
  end

  @apps = get_apps(options)
  @finder = options[:finder]

  if @apps.empty? && @finder.nil?
    raise "One of `apps` or `finder` options is required."
  end

  @disallowed = get_disallowed(options)
  @headers = get_headers(options)
  @on_failure = get_on_failure(options)
end

Instance Method Details

#call(env) ⇒ Object

:nodoc:



85
86
87
88
89
90
91
92
93
94
95
# File 'lib/app_identity/rack_middleware.rb', line 85

def call(env) # :nodoc:
  headers = verify_headers(Hash[*@headers.flat_map { |h| [h, env[h]] }])

  env["app_identity"] = headers

  if has_errors?(headers)
    dispatch_on_failure(@on_failure, env)
  else
    @app.call(env)
  end
end