Class: HmacRequest
- Inherits:
-
Object
- Object
- HmacRequest
- Defined in:
- lib/hmac_request.rb
Constant Summary collapse
- HTTP_HEADER_TO_ENV_MAP =
{ 'Content-Type' => 'CONTENT_TYPE', 'Content-MD5' => 'CONTENT_MD5', 'Date' => 'HTTP_DATE', 'Method' => 'REQUEST_METHOD', 'Authorization' => 'HTTP_AUTHORIZATION' }
- @@valid_date_window =
seconds
600
Instance Attribute Summary collapse
-
#body ⇒ Object
Returns the value of attribute body.
-
#env ⇒ Object
Returns the value of attribute env.
-
#hmac_hash ⇒ Object
Returns the value of attribute hmac_hash.
-
#hmac_id ⇒ Object
Returns the value of attribute hmac_id.
-
#request ⇒ Object
Returns the value of attribute request.
Class Method Summary collapse
Instance Method Summary collapse
- #[](key) ⇒ Object
- #date_is_recent? ⇒ Boolean
- #get_hmac_vals ⇒ Object
-
#get_xreferer_auth_headers ⇒ Object
these are the X-Referer-Headers that get passed along to lockbox from the middleware for authentication.
- #has_body?(method) ⇒ Boolean
- #hmac_auth(credential_store) ⇒ Object
-
#initialize(env) ⇒ HmacRequest
constructor
A new instance of HmacRequest.
- #log(msg) ⇒ Object
- #log_auth_error(key) ⇒ Object
- #path ⇒ Object
Constructor Details
#initialize(env) ⇒ HmacRequest
Returns a new instance of HmacRequest.
33 34 35 36 37 |
# File 'lib/hmac_request.rb', line 33 def initialize(env) @request = Rack::Request.new(env) @env = @request.env @body = @request.body if has_body?(@env['REQUEST_METHOD']) end |
Instance Attribute Details
#body ⇒ Object
Returns the value of attribute body.
7 8 9 |
# File 'lib/hmac_request.rb', line 7 def body @body end |
#env ⇒ Object
Returns the value of attribute env.
7 8 9 |
# File 'lib/hmac_request.rb', line 7 def env @env end |
#hmac_hash ⇒ Object
Returns the value of attribute hmac_hash.
7 8 9 |
# File 'lib/hmac_request.rb', line 7 def hmac_hash @hmac_hash end |
#hmac_id ⇒ Object
Returns the value of attribute hmac_id.
7 8 9 |
# File 'lib/hmac_request.rb', line 7 def hmac_id @hmac_id end |
#request ⇒ Object
Returns the value of attribute request.
7 8 9 |
# File 'lib/hmac_request.rb', line 7 def request @request end |
Class Method Details
.new_from_rack_env(env) ⇒ Object
18 19 20 21 |
# File 'lib/hmac_request.rb', line 18 def self.new_from_rack_env(env) r = self.new(env) return r end |
.new_from_rails_request(request) ⇒ Object
23 24 25 26 27 28 29 30 31 |
# File 'lib/hmac_request.rb', line 23 def self.new_from_rails_request(request) r = self.new(request.headers) #pull stuff out of X-Referer, which is where the middleware sticks it HTTP_HEADER_TO_ENV_MAP.each_pair do |h,e| r.env[e] = r.env["X-Referer-#{h}"] unless r.env["X-Referer-#{h}"].blank? end return r end |
Instance Method Details
#[](key) ⇒ Object
39 40 41 |
# File 'lib/hmac_request.rb', line 39 def [](key) @request[key] end |
#date_is_recent? ⇒ Boolean
83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 |
# File 'lib/hmac_request.rb', line 83 def date_is_recent?() req_date = nil begin req_date = Time.httpdate(@env['HTTP_DATE']) rescue Exception => ex if ex. =~ /not RFC 2616 compliant/ # try rfc2822 req_date = Time.rfc2822(@env['HTTP_DATE']) else raise ex end end if Time.now.to_i - req_date.to_i >= @@valid_date_window log "Request date #{req_date} is more than #{@@valid_date_window} seconds old" return false else return true end end |
#get_hmac_vals ⇒ Object
66 67 68 69 70 |
# File 'lib/hmac_request.rb', line 66 def get_hmac_vals @env['HTTP_AUTHORIZATION'].to_s =~ /^AuthHMAC ([^:]+):(.*)$/ @hmac_id = $1 @hmac_hash = $2 end |
#get_xreferer_auth_headers ⇒ Object
these are the X-Referer-Headers that get passed along to lockbox from the middleware for authentication
106 107 108 109 110 111 112 113 114 115 116 |
# File 'lib/hmac_request.rb', line 106 def get_xreferer_auth_headers() headers = {} headers['Referer'] = "#{@env['rack.url_scheme']}://#{@env['SERVER_NAME']}#{@env['PATH_INFO']}" headers['Referer'] << "?#{@env['QUERY_STRING']}" unless @env['QUERY_STRING'].blank? HTTP_HEADER_TO_ENV_MAP.each_pair do |h,e| headers["X-Referer-#{h}"] = @env[e] unless @env[e].blank? end headers['X-Referer-Content-MD5'] = Digest::MD5.hexdigest(@request.body.read) if @env['CONTENT_TYPE'] headers["X-Referer-Date"] = @env['HTTP_X_AUTHHMAC_REQUEST_DATE'] unless @env['HTTP_X_AUTHHMAC_REQUEST_DATE'].blank? headers end |
#has_body?(method) ⇒ Boolean
52 53 54 |
# File 'lib/hmac_request.rb', line 52 def has_body?(method) ["PUT","POST"].include?(method) end |
#hmac_auth(credential_store) ⇒ Object
73 74 75 76 77 78 79 80 81 |
# File 'lib/hmac_request.rb', line 73 def hmac_auth(credential_store) authhmac = AuthHMAC.new(credential_store) if authhmac.authenticated?(self) && (@env['HTTP_DATE'].blank? || self.date_is_recent? ) credential_store[self.hmac_id] else log_auth_error(credential_store[self.hmac_id]) return false end end |
#log(msg) ⇒ Object
136 137 138 139 140 141 142 143 |
# File 'lib/hmac_request.rb', line 136 def log(msg) logger = nil if defined?(Rails.logger) Rails.logger.error msg else $stdout.puts msg end end |
#log_auth_error(key) ⇒ Object
118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 |
# File 'lib/hmac_request.rb', line 118 def log_auth_error(key) log "Logging Lockbox HMAC authorization error:" log "Path: #{self.path}" HTTP_HEADER_TO_ENV_MAP.values.each do |header| log "#{header}: #{@env[header]}" end log "HMAC Canonical String: #{ AuthHMAC::CanonicalString.new(self).inspect}" if self.hmac_id.nil? log("HMAC failed because request is not signed") elsif key log("HMAC failed - expected #{AuthHMAC.signature(self,key)} but was #{self.hmac_hash}") end end |
#path ⇒ Object
43 44 45 46 47 48 49 50 |
# File 'lib/hmac_request.rb', line 43 def path #use Referer if it's there, which it will be when this gets called while hitting the AuthenticationController if @env['Referer'].to_s =~ /^(?:http:\/\/)?[^\/]*(\/.*)$/ return $1 end #if we're in the middleware, it won't be there but we can use the request's path to the same effect return @request.path end |