Class: RestCore::Oauth1Header

Inherits:
Object
  • Object
show all
Includes:
Middleware
Defined in:
lib/rest-core/middleware/oauth1_header.rb

Overview

Constant Summary

Constants included from Middleware

Middleware::UNRESERVED

Constants included from RestCore

ASYNC, CLIENT, DRY, FAIL, HIJACK, LOG, PROMISE, REQUEST_HEADERS, REQUEST_METHOD, REQUEST_PATH, REQUEST_PAYLOAD, REQUEST_QUERY, REQUEST_URI, RESPONSE_BODY, RESPONSE_HEADERS, RESPONSE_KEY, RESPONSE_SOCKET, RESPONSE_STATUS, Simple, TIMER, Universal, VERSION

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Middleware

contain_binary?, #contain_binary?, escape, #escape, #fail, #id, included, #log, merge_hash, #merge_hash, #percent_encode, percent_encode, request_uri, #request_uri, #run, #string_keys, string_keys

Methods included from RestCore

eagerload, id

Class Method Details

.membersObject



10
11
12
13
14
15
# File 'lib/rest-core/middleware/oauth1_header.rb', line 10

def self.members
  [:request_token_path, :access_token_path, :authorize_path,
   :consumer_key, :consumer_secret,
   :oauth_callback, :oauth_verifier,
   :oauth_token, :oauth_token_secret, :data]
end

Instance Method Details

#attach_signature(env, oauth_params) ⇒ Object



43
44
45
46
# File 'lib/rest-core/middleware/oauth1_header.rb', line 43

def attach_signature env, oauth_params
  params = reject_blank(oauth_params)
  params.merge('oauth_signature' => signature(env, params))
end

#base_string(env, oauth_params) ⇒ Object



53
54
55
56
57
58
59
60
61
62
63
# File 'lib/rest-core/middleware/oauth1_header.rb', line 53

def base_string env, oauth_params
  method   = env[REQUEST_METHOD].to_s.upcase
  base_uri = env[REQUEST_PATH]
  payload  = payload_params(env)
  query    = reject_blank(env[REQUEST_QUERY])
  params   = reject_blank(oauth_params.merge(query.merge(payload))).
    to_a.sort.map{ |(k, v)|
      "#{escape(k.to_s)}=#{escape(v.to_s)}"}.join('&')

  "#{method}&#{escape(base_uri)}&#{escape(params)}"
end

#call(env, &k) ⇒ Object



17
18
19
20
21
22
23
24
25
26
# File 'lib/rest-core/middleware/oauth1_header.rb', line 17

def call env, &k
  start_time = Time.now
  headers = {'Authorization' => oauth_header(env)}.
              merge(env[REQUEST_HEADERS])

  event = Event::WithHeader.new(Time.now - start_time,
            "Authorization: #{headers['Authorization']}")

  app.call(log(env.merge(REQUEST_HEADERS => headers), event), &k)
end

#nonceObject



65
66
67
# File 'lib/rest-core/middleware/oauth1_header.rb', line 65

def nonce
  [OpenSSL::Random.random_bytes(32)].pack('m0').tr("+/=", '')
end

#oauth_header(env) ⇒ Object



28
29
30
31
32
33
34
35
36
37
38
39
40
41
# File 'lib/rest-core/middleware/oauth1_header.rb', line 28

def oauth_header env
  oauth = attach_signature(env,
    'oauth_consumer_key'     => consumer_key(env),
    'oauth_signature_method' => 'HMAC-SHA1',
    'oauth_timestamp'        => Time.now.to_i.to_s,
    'oauth_nonce'            => nonce,
    'oauth_version'          => '1.0',
    'oauth_callback'         => oauth_callback(env),
    'oauth_verifier'         => oauth_verifier(env),
    'oauth_token'            => oauth_token(env)).
    map{ |(k, v)| "#{k}=\"#{escape(v)}\"" }.join(', ')

  "OAuth #{oauth}"
end

#payload_params(env) ⇒ Object

according to OAuth 1.0a spec, only:

Content-Type: application/x-www-form-urlencoded

should take payload as a part of the base_string



72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
# File 'lib/rest-core/middleware/oauth1_header.rb', line 72

def payload_params env
  # if we already specified Content-Type and which is not
  # application/x-www-form-urlencoded, then we should not
  # take payload as a part of the base_string
  if env[REQUEST_HEADERS].kind_of?(Hash)  &&
     env[REQUEST_HEADERS]['Content-Type'] &&
     env[REQUEST_HEADERS]['Content-Type'] !=
       'application/x-www-form-urlencoded'
    {}

  # if it contains any binary data,
  # then it shouldn't be application/x-www-form-urlencoded either
  # the Content-Type header would be handled in our HTTP client
  elsif contain_binary?(env[REQUEST_PAYLOAD])
    {}

  # so the Content-Type header must be application/x-www-form-urlencoded
  else
    reject_blank(env[REQUEST_PAYLOAD])
  end
end

#reject_blank(params) ⇒ Object



94
95
96
97
98
99
# File 'lib/rest-core/middleware/oauth1_header.rb', line 94

def reject_blank params
  params.reject{ |k, v| v.nil? || v == false ||
                                  (v.respond_to?(:strip) &&
                                   v.respond_to?(:empty) &&
                                   v.strip.empty? == true) }
end

#signature(env, params) ⇒ Object



48
49
50
51
# File 'lib/rest-core/middleware/oauth1_header.rb', line 48

def signature env, params
  [Hmac.sha1("#{consumer_secret(env)}&#{oauth_token_secret(env)}",
             base_string(env, params))].pack('m0')
end