jmoses_api-auth 1.0.4

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.
@@ -0,0 +1,129 @@
1
+ module ApiAuth
2
+
3
+ # Integration with Rails
4
+ #
5
+ class Rails # :nodoc:
6
+
7
+ module ControllerMethods # :nodoc:
8
+
9
+ module InstanceMethods # :nodoc:
10
+
11
+ def get_api_access_id_from_request
12
+ ApiAuth.access_id(request)
13
+ end
14
+
15
+ def api_authenticated?(secret_key)
16
+ ApiAuth.authentic?(request, secret_key)
17
+ 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
+ end
32
+
33
+ if defined?(ActionController::Base)
34
+ ActionController::Base.send(:include, ControllerMethods::InstanceMethods)
35
+ end
36
+
37
+ end # ControllerMethods
38
+
39
+ module ActiveResourceExtension # :nodoc:
40
+
41
+ module ActiveResourceApiAuth # :nodoc:
42
+
43
+ def self.included(base)
44
+ base.extend(ClassMethods)
45
+
46
+ if base.respond_to?('class_attribute')
47
+ base.class_attribute :hmac_access_id
48
+ base.class_attribute :hmac_secret_key
49
+ base.class_attribute :use_hmac
50
+ else
51
+ base.class_inheritable_accessor :hmac_access_id
52
+ base.class_inheritable_accessor :hmac_secret_key
53
+ base.class_inheritable_accessor :use_hmac
54
+ end
55
+
56
+ end
57
+
58
+ module ClassMethods
59
+
60
+ def with_api_auth(access_id, secret_key)
61
+ self.hmac_access_id = access_id
62
+ self.hmac_secret_key = secret_key
63
+ self.use_hmac = true
64
+
65
+ class << self
66
+ alias_method_chain :connection, :auth
67
+ end
68
+ end
69
+
70
+ def connection_with_auth(refresh = false)
71
+ c = connection_without_auth(refresh)
72
+ c.hmac_access_id = self.hmac_access_id
73
+ c.hmac_secret_key = self.hmac_secret_key
74
+ c.use_hmac = self.use_hmac
75
+ c
76
+ end
77
+
78
+ end # class methods
79
+
80
+ module InstanceMethods
81
+ end
82
+
83
+ end # BaseApiAuth
84
+
85
+ module Connection
86
+
87
+ def self.included(base)
88
+ base.send :alias_method_chain, :request, :auth
89
+ base.class_eval do
90
+ attr_accessor :hmac_secret_key, :hmac_access_id, :use_hmac
91
+ end
92
+ end
93
+
94
+ def request_with_auth(method, path, *arguments)
95
+ if use_hmac && hmac_access_id && hmac_secret_key
96
+ h = arguments.last
97
+ tmp = "Net::HTTP::#{method.to_s.capitalize}".constantize.new(path, h)
98
+ tmp.body = arguments[0] if arguments.length > 1
99
+ ApiAuth.sign!(tmp, hmac_access_id, hmac_secret_key)
100
+ arguments.last['Content-MD5'] = tmp['Content-MD5'] if tmp['Content-MD5']
101
+ arguments.last['DATE'] = tmp['DATE']
102
+ arguments.last['Authorization'] = tmp['Authorization']
103
+ end
104
+
105
+ request_without_auth(method, path, *arguments)
106
+ end
107
+
108
+ end # Connection
109
+
110
+ unless defined?(ActiveResource)
111
+ begin
112
+ require 'rubygems'
113
+ gem 'activeresource'
114
+ require 'active_resource'
115
+ rescue LoadError
116
+ nil
117
+ end
118
+ end
119
+
120
+ if defined?(ActiveResource)
121
+ ActiveResource::Base.send(:include, ActiveResourceApiAuth)
122
+ ActiveResource::Connection.send(:include, Connection)
123
+ end
124
+
125
+ end # ActiveResourceExtension
126
+
127
+ end # Rails
128
+
129
+ end # ApiAuth
@@ -0,0 +1,85 @@
1
+ module ApiAuth
2
+
3
+ module RequestDrivers # :nodoc:
4
+
5
+ class ActionControllerRequest # :nodoc:
6
+
7
+ include ApiAuth::Helpers
8
+
9
+ def initialize(request)
10
+ @request = request
11
+ @headers = fetch_headers
12
+ true
13
+ end
14
+
15
+ def set_auth_header(header)
16
+ @request.env["Authorization"] = header
17
+ @headers = fetch_headers
18
+ @request
19
+ end
20
+
21
+ def calculated_md5
22
+ if @request.body
23
+ body = @request.raw_post
24
+ else
25
+ body = ''
26
+ end
27
+ Digest::MD5.base64digest(body)
28
+ end
29
+
30
+ def populate_content_md5
31
+ if @request.put? || @request.post?
32
+ @request.env["Content-MD5"] = calculated_md5
33
+ end
34
+ end
35
+
36
+ def md5_mismatch?
37
+ if @request.put? || @request.post?
38
+ calculated_md5 != content_md5
39
+ else
40
+ false
41
+ end
42
+ end
43
+
44
+ def fetch_headers
45
+ capitalize_keys @request.env
46
+ end
47
+
48
+ def content_type
49
+ value = find_header(%w(CONTENT-TYPE CONTENT_TYPE HTTP_CONTENT_TYPE))
50
+ value.nil? ? "" : value
51
+ end
52
+
53
+ def content_md5
54
+ value = find_header(%w(CONTENT-MD5 CONTENT_MD5 HTTP_CONTENT_MD5))
55
+ value.nil? ? "" : value
56
+ end
57
+
58
+ def request_uri
59
+ @request.request_uri
60
+ end
61
+
62
+ def set_date
63
+ @request.env['DATE'] = Time.now.utc.httpdate
64
+ end
65
+
66
+ def timestamp
67
+ value = find_header(%w(DATE HTTP_DATE))
68
+ value.nil? ? "" : value
69
+ end
70
+
71
+ def authorization_header
72
+ find_header %w(Authorization AUTHORIZATION HTTP_AUTHORIZATION)
73
+ end
74
+
75
+ private
76
+
77
+ def find_header(keys)
78
+ keys.map {|key| @headers[key] }.compact.first
79
+ end
80
+
81
+ end
82
+
83
+ end
84
+
85
+ end
@@ -0,0 +1,15 @@
1
+ module ApiAuth
2
+
3
+ module RequestDrivers # :nodoc:
4
+
5
+ class ActionDispatchRequest < ActionControllerRequest # :nodoc:
6
+
7
+ def request_uri
8
+ @request.fullpath
9
+ end
10
+
11
+ end
12
+
13
+ end
14
+
15
+ end
@@ -0,0 +1,70 @@
1
+ module ApiAuth
2
+
3
+ module RequestDrivers # :nodoc:
4
+
5
+ class CurbRequest # :nodoc:
6
+
7
+ include ApiAuth::Helpers
8
+
9
+ def initialize(request)
10
+ @request = request
11
+ @headers = fetch_headers
12
+ true
13
+ end
14
+
15
+ def set_auth_header(header)
16
+ @request.headers.merge!({ "Authorization" => header })
17
+ @headers = fetch_headers
18
+ @request
19
+ end
20
+
21
+ def populate_content_md5
22
+ nil #doesn't appear to be possible
23
+ end
24
+
25
+ def md5_mismatch?
26
+ false
27
+ end
28
+
29
+ def fetch_headers
30
+ capitalize_keys @request.headers
31
+ end
32
+
33
+ def content_type
34
+ value = find_header(%w(CONTENT-TYPE CONTENT_TYPE HTTP_CONTENT_TYPE))
35
+ value.nil? ? "" : value
36
+ end
37
+
38
+ def content_md5
39
+ value = find_header(%w(CONTENT-MD5 CONTENT_MD5))
40
+ value.nil? ? "" : value
41
+ end
42
+
43
+ def request_uri
44
+ @request.url
45
+ end
46
+
47
+ def set_date
48
+ @request.headers.merge!({ "DATE" => Time.now.utc.httpdate })
49
+ end
50
+
51
+ def timestamp
52
+ value = find_header(%w(DATE HTTP_DATE))
53
+ value.nil? ? "" : value
54
+ end
55
+
56
+ def authorization_header
57
+ find_header %w(Authorization AUTHORIZATION HTTP_AUTHORIZATION)
58
+ end
59
+
60
+ private
61
+
62
+ def find_header(keys)
63
+ keys.map {|key| @headers[key] }.compact.first
64
+ end
65
+
66
+ end
67
+
68
+ end
69
+
70
+ end
@@ -0,0 +1,78 @@
1
+ module ApiAuth
2
+
3
+ module RequestDrivers # :nodoc:
4
+
5
+ class NetHttpRequest # :nodoc:
6
+
7
+ def initialize(request)
8
+ @request = request
9
+ @headers = fetch_headers
10
+ true
11
+ end
12
+
13
+ def set_auth_header(header)
14
+ @request["Authorization"] = header
15
+ @headers = fetch_headers
16
+ @request
17
+ end
18
+
19
+ def calculated_md5
20
+ Digest::MD5.base64digest(@request.body || '')
21
+ end
22
+
23
+ def populate_content_md5
24
+ if @request.class::REQUEST_HAS_BODY
25
+ @request["Content-MD5"] = calculated_md5
26
+ end
27
+ end
28
+
29
+ def md5_mismatch?
30
+ if @request.class::REQUEST_HAS_BODY
31
+ calculated_md5 != content_md5
32
+ else
33
+ false
34
+ end
35
+ end
36
+
37
+ def fetch_headers
38
+ @request
39
+ end
40
+
41
+ def content_type
42
+ value = find_header(%w(CONTENT-TYPE CONTENT_TYPE HTTP_CONTENT_TYPE))
43
+ value.nil? ? "" : value
44
+ end
45
+
46
+ def content_md5
47
+ value = find_header(%w(CONTENT-MD5 CONTENT_MD5))
48
+ value.nil? ? "" : value
49
+ end
50
+
51
+ def request_uri
52
+ @request.path
53
+ end
54
+
55
+ def set_date
56
+ @request["DATE"] = Time.now.utc.httpdate
57
+ end
58
+
59
+ def timestamp
60
+ value = find_header(%w(DATE HTTP_DATE))
61
+ value.nil? ? "" : value
62
+ end
63
+
64
+ def authorization_header
65
+ find_header %w(Authorization AUTHORIZATION HTTP_AUTHORIZATION)
66
+ end
67
+
68
+ private
69
+
70
+ def find_header(keys)
71
+ keys.map {|key| @headers[key] }.compact.first
72
+ end
73
+
74
+ end
75
+
76
+ end
77
+
78
+ end
@@ -0,0 +1,85 @@
1
+ module ApiAuth
2
+
3
+ module RequestDrivers # :nodoc:
4
+
5
+ class RackRequest # :nodoc:
6
+
7
+ include ApiAuth::Helpers
8
+
9
+ def initialize(request)
10
+ @request = request
11
+ @headers = fetch_headers
12
+ true
13
+ end
14
+
15
+ def set_auth_header(header)
16
+ @request.env.merge!({ "Authorization" => header })
17
+ @headers = fetch_headers
18
+ @request
19
+ end
20
+
21
+ def calculated_md5
22
+ if @request.body
23
+ body = @request.body.read
24
+ else
25
+ body = ''
26
+ end
27
+ Digest::MD5.base64digest(body)
28
+ end
29
+
30
+ def populate_content_md5
31
+ if ['POST', 'PUT'].include?(@request.request_method)
32
+ @request.env["Content-MD5"] = calculated_md5
33
+ end
34
+ end
35
+
36
+ def md5_mismatch?
37
+ if ['POST', 'PUT'].include?(@request.request_method)
38
+ calculated_md5 != content_md5
39
+ else
40
+ false
41
+ end
42
+ end
43
+
44
+ def fetch_headers
45
+ capitalize_keys @request.env
46
+ end
47
+
48
+ def content_type
49
+ value = find_header(%w(CONTENT-TYPE CONTENT_TYPE HTTP_CONTENT_TYPE))
50
+ value.nil? ? "" : value
51
+ end
52
+
53
+ def content_md5
54
+ value = find_header(%w(CONTENT-MD5 CONTENT_MD5))
55
+ value.nil? ? "" : value
56
+ end
57
+
58
+ def request_uri
59
+ @request.url
60
+ end
61
+
62
+ def set_date
63
+ @request.env.merge!({ "DATE" => Time.now.utc.httpdate })
64
+ end
65
+
66
+ def timestamp
67
+ value = find_header(%w(DATE HTTP_DATE))
68
+ value.nil? ? "" : value
69
+ end
70
+
71
+ def authorization_header
72
+ find_header %w(Authorization AUTHORIZATION HTTP_AUTHORIZATION)
73
+ end
74
+
75
+ private
76
+
77
+ def find_header(keys)
78
+ keys.map {|key| @headers[key] }.compact.first
79
+ end
80
+
81
+ end
82
+
83
+ end
84
+
85
+ end
@@ -0,0 +1,93 @@
1
+ # give access to RestClient @processed_headers
2
+ module RestClient;class Request;attr_accessor :processed_headers;end;end
3
+
4
+ module ApiAuth
5
+
6
+ module RequestDrivers # :nodoc:
7
+
8
+ class RestClientRequest # :nodoc:
9
+
10
+ include ApiAuth::Helpers
11
+
12
+ def initialize(request)
13
+ @request = request
14
+ @headers = fetch_headers
15
+ true
16
+ end
17
+
18
+ def set_auth_header(header)
19
+ @request.headers.merge!({ "Authorization" => header })
20
+ @headers = fetch_headers
21
+ save_headers # enforce update of processed_headers based on last updated headers
22
+ @request
23
+ end
24
+
25
+ def calculated_md5
26
+ if @request.payload
27
+ body = @request.payload.read
28
+ else
29
+ body = ''
30
+ end
31
+ Digest::MD5.base64digest(body)
32
+ end
33
+
34
+ def populate_content_md5
35
+ if [:post, :put].include?(@request.method)
36
+ @request.headers["Content-MD5"] = calculated_md5
37
+ end
38
+ end
39
+
40
+ def md5_mismatch?
41
+ if [:post, :put].include?(@request.method)
42
+ calculated_md5 != content_md5
43
+ else
44
+ false
45
+ end
46
+ end
47
+
48
+ def fetch_headers
49
+ capitalize_keys @request.headers
50
+ end
51
+
52
+ def content_type
53
+ value = find_header(%w(CONTENT-TYPE CONTENT_TYPE HTTP_CONTENT_TYPE))
54
+ value.nil? ? "" : value
55
+ end
56
+
57
+ def content_md5
58
+ value = find_header(%w(CONTENT-MD5 CONTENT_MD5))
59
+ value.nil? ? "" : value
60
+ end
61
+
62
+ def request_uri
63
+ @request.url
64
+ end
65
+
66
+ def set_date
67
+ @request.headers.merge!({ "DATE" => Time.now.utc.httpdate })
68
+ end
69
+
70
+ def timestamp
71
+ value = find_header(%w(DATE HTTP_DATE))
72
+ value.nil? ? "" : value
73
+ end
74
+
75
+ def authorization_header
76
+ find_header %w(Authorization AUTHORIZATION HTTP_AUTHORIZATION)
77
+ end
78
+
79
+ private
80
+
81
+ def find_header(keys)
82
+ keys.map {|key| @headers[key] }.compact.first
83
+ end
84
+
85
+ def save_headers
86
+ @request.processed_headers = @request.make_headers(@headers)
87
+ end
88
+
89
+ end
90
+
91
+ end
92
+
93
+ end
data/lib/api_auth.rb ADDED
@@ -0,0 +1,16 @@
1
+ require 'openssl'
2
+ require 'base64'
3
+
4
+ require 'api_auth/errors'
5
+ require 'api_auth/helpers'
6
+
7
+ require 'api_auth/request_drivers/net_http'
8
+ require 'api_auth/request_drivers/curb'
9
+ require 'api_auth/request_drivers/rest_client'
10
+ require 'api_auth/request_drivers/action_controller'
11
+ require 'api_auth/request_drivers/action_dispatch'
12
+ require 'api_auth/request_drivers/rack'
13
+
14
+ require 'api_auth/headers'
15
+ require 'api_auth/base'
16
+ require 'api_auth/railtie'