api-auth 1.5.0 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (53) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +10 -44
  3. data/.rubocop.yml +102 -0
  4. data/.travis.yml +1 -0
  5. data/Appraisals +8 -0
  6. data/CHANGELOG.md +8 -1
  7. data/Gemfile +3 -0
  8. data/README.md +33 -5
  9. data/VERSION +1 -1
  10. data/api_auth.gemspec +17 -17
  11. data/gemfiles/rails_23.gemfile +3 -0
  12. data/gemfiles/rails_30.gemfile +3 -0
  13. data/gemfiles/rails_31.gemfile +5 -0
  14. data/gemfiles/rails_32.gemfile +5 -0
  15. data/gemfiles/rails_4.gemfile +2 -0
  16. data/gemfiles/rails_41.gemfile +2 -0
  17. data/gemfiles/rails_42.gemfile +2 -0
  18. data/lib/api-auth.rb +1 -1
  19. data/lib/api_auth/base.rb +21 -25
  20. data/lib/api_auth/errors.rb +4 -3
  21. data/lib/api_auth/headers.rb +11 -27
  22. data/lib/api_auth/helpers.rb +2 -6
  23. data/lib/api_auth/railtie.rb +5 -50
  24. data/lib/api_auth/request_drivers/action_controller.rb +7 -13
  25. data/lib/api_auth/request_drivers/action_dispatch.rb +0 -6
  26. data/lib/api_auth/request_drivers/curb.rb +8 -14
  27. data/lib/api_auth/request_drivers/faraday.rb +11 -21
  28. data/lib/api_auth/request_drivers/httpi.rb +8 -14
  29. data/lib/api_auth/request_drivers/net_http.rb +8 -14
  30. data/lib/api_auth/request_drivers/rack.rb +10 -16
  31. data/lib/api_auth/request_drivers/rest_client.rb +9 -15
  32. data/spec/api_auth_spec.rb +90 -88
  33. data/spec/headers_spec.rb +69 -84
  34. data/spec/helpers_spec.rb +7 -9
  35. data/spec/railtie_spec.rb +42 -72
  36. data/spec/request_drivers/action_controller_spec.rb +53 -55
  37. data/spec/request_drivers/action_dispatch_spec.rb +52 -55
  38. data/spec/request_drivers/curb_spec.rb +25 -28
  39. data/spec/request_drivers/faraday_spec.rb +54 -56
  40. data/spec/request_drivers/httpi_spec.rb +42 -48
  41. data/spec/request_drivers/net_http_spec.rb +51 -53
  42. data/spec/request_drivers/rack_spec.rb +58 -60
  43. data/spec/request_drivers/rest_client_spec.rb +86 -89
  44. data/spec/spec_helper.rb +9 -9
  45. metadata +4 -11
  46. data/Gemfile.lock +0 -115
  47. data/gemfiles/rails_23.gemfile.lock +0 -70
  48. data/gemfiles/rails_30.gemfile.lock +0 -92
  49. data/gemfiles/rails_31.gemfile.lock +0 -98
  50. data/gemfiles/rails_32.gemfile.lock +0 -97
  51. data/gemfiles/rails_4.gemfile.lock +0 -94
  52. data/gemfiles/rails_41.gemfile.lock +0 -98
  53. data/gemfiles/rails_42.gemfile.lock +0 -115
@@ -1,9 +1,10 @@
1
1
  module ApiAuth
2
-
3
2
  # :nodoc:
4
3
  class ApiAuthError < StandardError; end
5
-
4
+
6
5
  # Raised when the HTTP request object passed is not supported
7
6
  class UnknownHTTPRequest < ApiAuthError; end
8
-
7
+
8
+ # Raised when the client request digest is not the same as the server
9
+ class InvalidRequestDigest < ApiAuthError; end
9
10
  end
@@ -1,8 +1,6 @@
1
1
  module ApiAuth
2
-
3
2
  # Builds the canonical string given a request object.
4
3
  class Headers
5
-
6
4
  include RequestDrivers
7
5
 
8
6
  def initialize(request)
@@ -36,46 +34,32 @@ module ApiAuth
36
34
  HttpiRequest.new(request)
37
35
  when /Faraday::Request/
38
36
  FaradayRequest.new(request)
39
- else
40
- nil
41
37
  end
42
38
 
43
39
  return new_request if new_request
44
- return RackRequest.new(request) if request.kind_of?(Rack::Request)
45
- raise UnknownHTTPRequest, "#{request.class.to_s} is not yet supported."
40
+ return RackRequest.new(request) if request.is_a?(Rack::Request)
41
+ raise UnknownHTTPRequest, "#{request.class} is not yet supported."
46
42
  end
47
43
  private :initialize_request_driver
48
44
 
49
45
  # Returns the request timestamp
50
46
  def timestamp
51
- @request.timestamp
47
+ @request.timestamp
52
48
  end
53
49
 
54
- # Returns the canonical string computed from the request's headers
55
- def canonical_string_without_http_method
56
- [ @request.content_type,
57
- @request.content_md5,
58
- parse_uri(@request.request_uri),
59
- @request.timestamp
60
- ].join(",")
61
- end
62
-
63
- # temp backwards compatibility
64
- alias_method :canonical_string, :canonical_string_without_http_method
65
-
66
- def canonical_string_with_http_method(override_method = nil)
50
+ def canonical_string(override_method = nil)
67
51
  request_method = override_method || @request.http_method
68
52
 
69
53
  if request_method.nil?
70
- raise ArgumentError, "unable to determine the http method from the request, please supply an override"
54
+ raise ArgumentError, 'unable to determine the http method from the request, please supply an override'
71
55
  end
72
56
 
73
- [ request_method.upcase,
74
- @request.content_type,
75
- @request.content_md5,
76
- parse_uri(@request.request_uri),
77
- @request.timestamp
78
- ].join(",")
57
+ [request_method.upcase,
58
+ @request.content_type,
59
+ @request.content_md5,
60
+ parse_uri(@request.request_uri),
61
+ @request.timestamp
62
+ ].join(',')
79
63
  end
80
64
 
81
65
  # Returns the authorization header from the request's headers
@@ -1,13 +1,11 @@
1
1
  module ApiAuth
2
-
3
2
  module Helpers # :nodoc:
4
-
5
3
  def b64_encode(string)
6
4
  if Base64.respond_to?(:strict_encode64)
7
5
  Base64.strict_encode64(string)
8
6
  else
9
7
  # Fall back to stripping out newlines on Ruby 1.8.
10
- Base64.encode64(string).gsub(/\n/, '')
8
+ Base64.encode64(string).delete("\n")
11
9
  end
12
10
  end
13
11
 
@@ -22,10 +20,8 @@ module ApiAuth
22
20
  # Capitalizes the keys of a hash
23
21
  def capitalize_keys(hsh)
24
22
  capitalized_hash = {}
25
- hsh.each_pair {|k,v| capitalized_hash[k.to_s.upcase] = v }
23
+ hsh.each_pair { |k, v| capitalized_hash[k.to_s.upcase] = v }
26
24
  capitalized_hash
27
25
  end
28
-
29
26
  end
30
-
31
27
  end
@@ -1,13 +1,9 @@
1
1
  module ApiAuth
2
-
3
2
  # Integration with Rails
4
3
  #
5
4
  class Rails # :nodoc:
6
-
7
5
  module ControllerMethods # :nodoc:
8
-
9
6
  module InstanceMethods # :nodoc:
10
-
11
7
  def get_api_access_id_from_request
12
8
  ApiAuth.access_id(request)
13
9
  end
@@ -15,31 +11,15 @@ module ApiAuth
15
11
  def api_authenticated?(secret_key)
16
12
  ApiAuth.authentic?(request, secret_key)
17
13
  end
18
-
19
- end
20
-
21
- unless defined?(ActionController)
22
- begin
23
- require 'rubygems'
24
- gem 'actionpack'
25
- gem 'activesupport'
26
- require 'action_controller'
27
- require 'active_support'
28
- rescue LoadError
29
- nil
30
- end
31
14
  end
32
15
 
33
16
  if defined?(ActionController::Base)
34
17
  ActionController::Base.send(:include, ControllerMethods::InstanceMethods)
35
18
  end
36
-
37
19
  end # ControllerMethods
38
20
 
39
21
  module ActiveResourceExtension # :nodoc:
40
-
41
22
  module ActiveResourceApiAuth # :nodoc:
42
-
43
23
  def self.included(base)
44
24
  base.extend(ClassMethods)
45
25
 
@@ -47,24 +27,17 @@ module ApiAuth
47
27
  base.class_attribute :hmac_access_id
48
28
  base.class_attribute :hmac_secret_key
49
29
  base.class_attribute :use_hmac
50
- base.class_attribute :sign_with_http_method
51
30
  else
52
31
  base.class_inheritable_accessor :hmac_access_id
53
32
  base.class_inheritable_accessor :hmac_secret_key
54
33
  base.class_inheritable_accessor :use_hmac
55
- base.class_inheritable_accessor :sign_with_http_method
56
34
  end
57
-
58
35
  end
59
36
 
60
37
  module ClassMethods
61
-
62
38
  def with_api_auth(access_id, secret_key, options = {})
63
- sign_with_http_method = options[:sign_with_http_method] || false
64
-
65
39
  self.hmac_access_id = access_id
66
40
  self.hmac_secret_key = secret_key
67
- self.sign_with_http_method = sign_with_http_method
68
41
  self.use_hmac = true
69
42
 
70
43
  class << self
@@ -74,26 +47,22 @@ module ApiAuth
74
47
 
75
48
  def connection_with_auth(refresh = false)
76
49
  c = connection_without_auth(refresh)
77
- c.hmac_access_id = self.hmac_access_id
78
- c.hmac_secret_key = self.hmac_secret_key
79
- c.use_hmac = self.use_hmac
80
- c.sign_with_http_method = self.sign_with_http_method
50
+ c.hmac_access_id = hmac_access_id
51
+ c.hmac_secret_key = hmac_secret_key
52
+ c.use_hmac = use_hmac
81
53
  c
82
54
  end
83
-
84
55
  end # class methods
85
56
 
86
57
  module InstanceMethods
87
58
  end
88
-
89
59
  end # BaseApiAuth
90
60
 
91
61
  module Connection
92
-
93
62
  def self.included(base)
94
63
  base.send :alias_method_chain, :request, :auth
95
64
  base.class_eval do
96
- attr_accessor :hmac_secret_key, :hmac_access_id, :use_hmac, :sign_with_http_method
65
+ attr_accessor :hmac_secret_key, :hmac_access_id, :use_hmac
97
66
  end
98
67
  end
99
68
 
@@ -102,7 +71,7 @@ module ApiAuth
102
71
  h = arguments.last
103
72
  tmp = "Net::HTTP::#{method.to_s.capitalize}".constantize.new(path, h)
104
73
  tmp.body = arguments[0] if arguments.length > 1
105
- ApiAuth.sign!(tmp, hmac_access_id, hmac_secret_key, {:with_http_method => (sign_with_http_method || false)})
74
+ ApiAuth.sign!(tmp, hmac_access_id, hmac_secret_key)
106
75
  arguments.last['Content-MD5'] = tmp['Content-MD5'] if tmp['Content-MD5']
107
76
  arguments.last['DATE'] = tmp['DATE']
108
77
  arguments.last['Authorization'] = tmp['Authorization']
@@ -110,26 +79,12 @@ module ApiAuth
110
79
 
111
80
  request_without_auth(method, path, *arguments)
112
81
  end
113
-
114
82
  end # Connection
115
83
 
116
- unless defined?(ActiveResource)
117
- begin
118
- require 'rubygems'
119
- gem 'activeresource'
120
- require 'active_resource'
121
- rescue LoadError
122
- nil
123
- end
124
- end
125
-
126
84
  if defined?(ActiveResource)
127
85
  ActiveResource::Base.send(:include, ActiveResourceApiAuth)
128
86
  ActiveResource::Connection.send(:include, Connection)
129
87
  end
130
-
131
88
  end # ActiveResourceExtension
132
-
133
89
  end # Rails
134
-
135
90
  end # ApiAuth
@@ -1,9 +1,6 @@
1
1
  module ApiAuth
2
-
3
2
  module RequestDrivers # :nodoc:
4
-
5
3
  class ActionControllerRequest # :nodoc:
6
-
7
4
  include ApiAuth::Helpers
8
5
 
9
6
  def initialize(request)
@@ -13,7 +10,7 @@ module ApiAuth
13
10
  end
14
11
 
15
12
  def set_auth_header(header)
16
- @request.env["Authorization"] = header
13
+ @request.env['Authorization'] = header
17
14
  fetch_headers
18
15
  @request
19
16
  end
@@ -25,7 +22,7 @@ module ApiAuth
25
22
 
26
23
  def populate_content_md5
27
24
  if @request.put? || @request.post?
28
- @request.env["Content-MD5"] = calculated_md5
25
+ @request.env['Content-MD5'] = calculated_md5
29
26
  fetch_headers
30
27
  end
31
28
  end
@@ -48,12 +45,12 @@ module ApiAuth
48
45
 
49
46
  def content_type
50
47
  value = find_header(%w(CONTENT-TYPE CONTENT_TYPE HTTP_CONTENT_TYPE))
51
- value.nil? ? "" : value
48
+ value.nil? ? '' : value
52
49
  end
53
50
 
54
51
  def content_md5
55
52
  value = find_header(%w(CONTENT-MD5 CONTENT_MD5 HTTP_CONTENT_MD5))
56
- value.nil? ? "" : value
53
+ value.nil? ? '' : value
57
54
  end
58
55
 
59
56
  def request_uri
@@ -67,21 +64,18 @@ module ApiAuth
67
64
 
68
65
  def timestamp
69
66
  value = find_header(%w(DATE HTTP_DATE))
70
- value.nil? ? "" : value
67
+ value.nil? ? '' : value
71
68
  end
72
69
 
73
70
  def authorization_header
74
71
  find_header %w(Authorization AUTHORIZATION HTTP_AUTHORIZATION)
75
72
  end
76
73
 
77
- private
74
+ private
78
75
 
79
76
  def find_header(keys)
80
- keys.map {|key| @headers[key] }.compact.first
77
+ keys.map { |key| @headers[key] }.compact.first
81
78
  end
82
-
83
79
  end
84
-
85
80
  end
86
-
87
81
  end
@@ -1,15 +1,9 @@
1
1
  module ApiAuth
2
-
3
2
  module RequestDrivers # :nodoc:
4
-
5
3
  class ActionDispatchRequest < ActionControllerRequest # :nodoc:
6
-
7
4
  def request_uri
8
5
  @request.fullpath
9
6
  end
10
-
11
7
  end
12
-
13
8
  end
14
-
15
9
  end
@@ -1,9 +1,6 @@
1
1
  module ApiAuth
2
-
3
2
  module RequestDrivers # :nodoc:
4
-
5
3
  class CurbRequest # :nodoc:
6
-
7
4
  include ApiAuth::Helpers
8
5
 
9
6
  def initialize(request)
@@ -13,13 +10,13 @@ module ApiAuth
13
10
  end
14
11
 
15
12
  def set_auth_header(header)
16
- @request.headers.merge!({ "Authorization" => header })
13
+ @request.headers['Authorization'] = header
17
14
  fetch_headers
18
15
  @request
19
16
  end
20
17
 
21
18
  def populate_content_md5
22
- nil #doesn't appear to be possible
19
+ nil # doesn't appear to be possible
23
20
  end
24
21
 
25
22
  def md5_mismatch?
@@ -36,12 +33,12 @@ module ApiAuth
36
33
 
37
34
  def content_type
38
35
  value = find_header(%w(CONTENT-TYPE CONTENT_TYPE HTTP_CONTENT_TYPE))
39
- value.nil? ? "" : value
36
+ value.nil? ? '' : value
40
37
  end
41
38
 
42
39
  def content_md5
43
40
  value = find_header(%w(CONTENT-MD5 CONTENT_MD5))
44
- value.nil? ? "" : value
41
+ value.nil? ? '' : value
45
42
  end
46
43
 
47
44
  def request_uri
@@ -49,27 +46,24 @@ module ApiAuth
49
46
  end
50
47
 
51
48
  def set_date
52
- @request.headers.merge!({ "DATE" => Time.now.utc.httpdate })
49
+ @request.headers['DATE'] = Time.now.utc.httpdate
53
50
  fetch_headers
54
51
  end
55
52
 
56
53
  def timestamp
57
54
  value = find_header(%w(DATE HTTP_DATE))
58
- value.nil? ? "" : value
55
+ value.nil? ? '' : value
59
56
  end
60
57
 
61
58
  def authorization_header
62
59
  find_header %w(Authorization AUTHORIZATION HTTP_AUTHORIZATION)
63
60
  end
64
61
 
65
- private
62
+ private
66
63
 
67
64
  def find_header(keys)
68
- keys.map {|key| @headers[key] }.compact.first
65
+ keys.map { |key| @headers[key] }.compact.first
69
66
  end
70
-
71
67
  end
72
-
73
68
  end
74
-
75
69
  end
@@ -1,9 +1,6 @@
1
1
  module ApiAuth
2
-
3
2
  module RequestDrivers # :nodoc:
4
-
5
3
  class FaradayRequest # :nodoc:
6
-
7
4
  include ApiAuth::Helpers
8
5
 
9
6
  def initialize(request)
@@ -13,29 +10,25 @@ module ApiAuth
13
10
  end
14
11
 
15
12
  def set_auth_header(header)
16
- @request.headers.merge!({ "Authorization" => header })
13
+ @request.headers['Authorization'] = header
17
14
  fetch_headers
18
15
  @request
19
16
  end
20
17
 
21
18
  def calculated_md5
22
- if @request.body
23
- body = @request.body
24
- else
25
- body = ''
26
- end
19
+ body = @request.body ? @request.body : ''
27
20
  md5_base64digest(body)
28
21
  end
29
22
 
30
23
  def populate_content_md5
31
- if ['POST', 'PUT'].include?(@request.method.to_s.upcase)
32
- @request.headers["Content-MD5"] = calculated_md5
24
+ if %w(POST PUT).include?(@request.method.to_s.upcase)
25
+ @request.headers['Content-MD5'] = calculated_md5
33
26
  fetch_headers
34
27
  end
35
28
  end
36
29
 
37
30
  def md5_mismatch?
38
- if ['POST', 'PUT'].include?(@request.method.to_s.upcase)
31
+ if %w(POST PUT).include?(@request.method.to_s.upcase)
39
32
  calculated_md5 != content_md5
40
33
  else
41
34
  false
@@ -52,12 +45,12 @@ module ApiAuth
52
45
 
53
46
  def content_type
54
47
  value = find_header(%w(CONTENT-TYPE CONTENT_TYPE HTTP_CONTENT_TYPE))
55
- value.nil? ? "" : value
48
+ value.nil? ? '' : value
56
49
  end
57
50
 
58
51
  def content_md5
59
52
  value = find_header(%w(CONTENT-MD5 CONTENT_MD5 HTTP-CONTENT-MD5 HTTP_CONTENT_MD5))
60
- value.nil? ? "" : value
53
+ value.nil? ? '' : value
61
54
  end
62
55
 
63
56
  def request_uri
@@ -68,27 +61,24 @@ module ApiAuth
68
61
  end
69
62
 
70
63
  def set_date
71
- @request.headers.merge!({ "DATE" => Time.now.utc.httpdate })
64
+ @request.headers['DATE'] = Time.now.utc.httpdate
72
65
  fetch_headers
73
66
  end
74
67
 
75
68
  def timestamp
76
69
  value = find_header(%w(DATE HTTP_DATE))
77
- value.nil? ? "" : value
70
+ value.nil? ? '' : value
78
71
  end
79
72
 
80
73
  def authorization_header
81
74
  find_header %w(Authorization AUTHORIZATION HTTP_AUTHORIZATION)
82
75
  end
83
76
 
84
- private
77
+ private
85
78
 
86
79
  def find_header(keys)
87
- keys.map {|key| @headers[key] }.compact.first
80
+ keys.map { |key| @headers[key] }.compact.first
88
81
  end
89
-
90
82
  end
91
-
92
83
  end
93
-
94
84
  end