Class: HerokuLockdown::SecureAccess

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

Constant Summary collapse

DEFAULT_ALLOWED_PATHS =
[
  # Allow status checker
  %r{\A/status.json\z}i,
  %r{\A/status_all.json\z}i
].freeze

Instance Method Summary collapse

Constructor Details

#initialize(app, x_api_secret, version = "1.4", service_allowed_paths = []) ⇒ SecureAccess



12
13
14
15
16
17
# File 'lib/heroku_lockdown.rb', line 12

def initialize app, x_api_secret, version = "1.4", service_allowed_paths = []
  @app = app
  @x_api_secret = x_api_secret
  @version = version
  @allowed_paths = (DEFAULT_ALLOWED_PATHS + service_allowed_paths).freeze
end

Instance Method Details

#auth_key_present?(env) ⇒ Boolean



36
37
38
# File 'lib/heroku_lockdown.rb', line 36

def auth_key_present? env
  env.has_key?('HTTP_X_WF.API_SECRET')
end

#authorized?(env) ⇒ Boolean



32
33
34
# File 'lib/heroku_lockdown.rb', line 32

def authorized? env
  @x_api_secret ? (env['HTTP_X_WF.API_SECRET'] == @x_api_secret) : true
end

#call(env) ⇒ Object



40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
# File 'lib/heroku_lockdown.rb', line 40

def call env
  return @app.call(env) if authorized? env

  # Make these check separately to optimize the common path.
  # Defaults allow health check to not require a key.
  request = Rack::Request.new(env)

  @allowed_paths.each do |path|
    return @app.call(env) if request.path =~ path
  end

  suffix = auth_key_present?(env) ? 'invalid' : 'missing'
  body = return_401("header is #{suffix}")

  headers =
    {
      'Content-Type' => 'application/json',
    }
  [401, headers, [body]]
end

#return_401(message) ⇒ Object



19
20
21
22
23
24
25
26
27
28
29
30
# File 'lib/heroku_lockdown.rb', line 19

def return_401 message
  {
    data: { },
    errors: {
      "x-wf.api-secret": [ message ],
    },
    meta: {
      api_version: @version,
      deprecation_information: { },
    }
  }.to_json
end