Class: XLock::Rack

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

Overview

Rack middleware for x-lock bot protection.

Usage:

use XLock::Rack,
site_key: ENV["XLOCK_SITE_KEY"],
protected_paths: ["/api/auth"]

Instance Method Summary collapse

Constructor Details

#initialize(app, **options) ⇒ Rack

Returns a new instance of Rack.



11
12
13
14
15
16
17
# File 'lib/xlock/rack.rb', line 11

def initialize(app, **options)
  @app = app
  @site_key = options[:site_key] || ENV["XLOCK_SITE_KEY"]
  @api_url = options[:api_url] || XLock::API_URL
  @fail_open = options.fetch(:fail_open, true)
  @protected_paths = options[:protected_paths] || []
end

Instance Method Details

#call(env) ⇒ Object



19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# File 'lib/xlock/rack.rb', line 19

def call(env)
  request = ::Rack::Request.new(env)

  unless @site_key && request.post? && matches?(request.path)
    return @app.call(env)
  end

  token = env["HTTP_X_LOCK"]
  unless token
    return [403, { "Content-Type" => "application/json" },
            ['{"error":"Blocked by x-lock: missing token"}']]
  end

  result = XLock.verify(token: token, site_key: @site_key, path: request.path, api_url: @api_url)

  if result.blocked
    return [403, { "Content-Type" => "application/json" },
            [{ error: "Blocked by x-lock", reason: result.reason }.to_json]]
  end

  if result.error && !@fail_open
    return [403, { "Content-Type" => "application/json" },
            ['{"error":"x-lock verification failed"}']]
  end

  @app.call(env)
end