api-auth 1.5.0 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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