Class: Rack::SimpleAuth::HMAC

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

Overview

HMAC Middleware uses HMAC Authorization for Securing an REST API

Instance Method Summary collapse

Constructor Details

#initialize(app, signature, secret, config) ⇒ HMAC

Constructor for Rack Middleware (passing the rack stack)

Parameters:

  • app (Rack Application)
    next middleware or rack app which gets called
  • signature (String)
    Public Signature
  • secret (String)
    Secret used for Message Encryption


10
11
12
13
14
15
# File 'lib/rack/simple_auth/hmac.rb', line 10

def initialize(app, signature, secret, config)
  @app = app
  @signature = signature
  @secret = secret
  @config = config
end

Instance Method Details

#call(env) ⇒ Object

call Method for Rack Middleware/Application

Parameters:

  • env (Hash)
    Rack Env Hash which contains headers etc..


19
20
21
22
23
24
25
26
27
# File 'lib/rack/simple_auth/hmac.rb', line 19

def call(env)
  request = Rack::Request.new(env)
  if valid?(request)
    @app.call(env)
  else
    response = Rack::Response.new('Unauthorized', 401, 'Content-Type' => 'text/html')
    response.finish
  end
end

#message(request) ⇒ Hash

Get Message for current Request

Parameters:

  • request (Rack::Request)
    current Request

Returns:

  • (Hash)

    message [message which will be encrypted]



54
55
56
57
58
59
60
61
62
63
64
65
66
67
# File 'lib/rack/simple_auth/hmac.rb', line 54

def message(request)
  case request.request_method
  when 'GET'
    return { 'method' => request.request_method, 'data' => request_data(request, @config) }.to_json
  when 'POST'
    return { 'method' => request.request_method, 'data' => request_data(request, @config) }.to_json
  when 'DELETE'
    return { 'method' => request.request_method, 'data' => request_data(request, @config) }.to_json
  when 'PUT'
    return { 'method' => request.request_method, 'data' => request_data(request, @config) }.to_json
  when 'PATCH'
    return { 'method' => request.request_method, 'data' => request_data(request, @config) }.to_json
  end
end

#request_data(request, config) ⇒ String|Hash

Get Request Data specified by Config

Parameters:

  • request (Rack::Request)
    current Request
  • config (Hash)
    Config Hash containing what type of info is data for each request

Returns:

  • (String|Hash)

    data [Data for each request]



73
74
75
76
77
78
79
# File 'lib/rack/simple_auth/hmac.rb', line 73

def request_data(request, config)
  if config[request.request_method] == 'path' || config[request.request_method] == 'params'
    request.send(config[request.request_method].to_sym)
  else
    fail "Not a valid option #{config[request.request_method]} - Use either params or path"
  end
end

#valid?(request) ⇒ boolean

checks for valid HMAC Request

Parameters:

  • request (Rack::Request)
    current Request

Returns:

  • (boolean)

    ValidationStatus [If authorized returns true, else false]



32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
# File 'lib/rack/simple_auth/hmac.rb', line 32

def valid?(request)
  return false if request.env['HTTP_AUTHORIZATION'].nil?

  auth_array = request.env['HTTP_AUTHORIZATION'].split(':')
  message_hash = auth_array[0]
  signature = auth_array[1]

  hash = OpenSSL::HMAC.hexdigest(OpenSSL::Digest::Digest.new('sha256'), @secret, message(request))
  # puts request.request_method
  # puts "Hash to Check: #{hash}"
  # puts "Message Hash: #{message_hash}"

  if signature == @signature && hash == message_hash
    true
  else
    false
  end
end