Class: M2mKeygen::RackValidator

Inherits:
Object
  • Object
show all
Extended by:
T::Sig
Defined in:
lib/m2m_keygen/rack_validator.rb

Constant Summary collapse

DEFAULT_WINDOW_SECONDS =
120
NONCE_TTL_MARGIN_SECONDS =
5
MAX_NONCE_BYTES =
256

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(secret, nonce_store:, algorithm: 'sha512', header_name: 'X-Signature', window: DEFAULT_WINDOW_SECONDS, expiry_header: 'X-M2M-Expiry', nonce_header: 'X-M2M-Nonce') ⇒ RackValidator

Returns a new instance of RackValidator.



30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# File 'lib/m2m_keygen/rack_validator.rb', line 30

def initialize(
  secret,
  nonce_store:,
  algorithm: 'sha512',
  header_name: 'X-Signature',
  window: DEFAULT_WINDOW_SECONDS,
  expiry_header: 'X-M2M-Expiry',
  nonce_header: 'X-M2M-Nonce'
)
  @signature = T.let(Signature.new(secret, algorithm: algorithm), Signature)
  @nonce_store = T.let(nonce_store, NonceStore)
  @window = T.let(window, Integer)
  @header_name = T.let(env_key_for(header_name), String)
  @expiry_header = T.let(env_key_for(expiry_header), String)
  @nonce_header = T.let(env_key_for(nonce_header), String)
end

Instance Attribute Details

#header_nameObject (readonly)

Returns the value of attribute header_name.



17
18
19
# File 'lib/m2m_keygen/rack_validator.rb', line 17

def header_name
  @header_name
end

#signatureObject (readonly)

Returns the value of attribute signature.



14
15
16
# File 'lib/m2m_keygen/rack_validator.rb', line 14

def signature
  @signature
end

Instance Method Details

#validate(req) ⇒ Object



48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
# File 'lib/m2m_keygen/rack_validator.rb', line 48

def validate(req)
  request = Rack::Request.new(req.env)
  nonce = request.env[@nonce_header].to_s
  return false if nonce.empty? && nonce_required?
  return false if nonce.bytesize > MAX_NONCE_BYTES

  expiry = request.env[@expiry_header].to_i
  body = read_body(request)

  valid_signature =
    @signature.validate(
      signature: request.env[@header_name].to_s,
      verb: request.request_method || 'GET',
      path: request.path || '/',
      expiry: expiry,
      nonce: nonce,
      query: request.query_string || '',
      body: body,
    )

  !!(
    valid_signature && expiry_within_window?(expiry) &&
      @nonce_store.add(nonce, ttl: nonce_ttl(expiry))
  )
end