api-auth 0.9.1 → 0.9.2
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.
- data/.gitignore +42 -0
- data/Gemfile +2 -12
- data/Gemfile.lock +21 -20
- data/LICENSE.txt +1 -1
- data/README.md +73 -64
- data/Rakefile +4 -27
- data/VERSION +1 -1
- data/api_auth.gemspec +17 -67
- data/lib/api_auth.rb +1 -0
- data/lib/api_auth/headers.rb +2 -0
- data/lib/api_auth/request_drivers/action_controller.rb +1 -1
- data/lib/api_auth/request_drivers/action_dispatch.rb +15 -0
- data/spec/api_auth_spec.rb +35 -0
- data/spec/application_helper.rb +2 -0
- data/spec/headers_spec.rb +35 -0
- data/spec/test_helper.rb +2 -0
- metadata +75 -93
data/.gitignore
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
# rcov generated
|
2
|
+
coverage
|
3
|
+
|
4
|
+
# rdoc generated
|
5
|
+
rdoc
|
6
|
+
|
7
|
+
# yard generated
|
8
|
+
doc
|
9
|
+
.yardoc
|
10
|
+
|
11
|
+
# bundler
|
12
|
+
.bundle
|
13
|
+
|
14
|
+
# jeweler generated
|
15
|
+
pkg
|
16
|
+
|
17
|
+
# Have editor/IDE/OS specific files you need to ignore? Consider using a global gitignore:
|
18
|
+
#
|
19
|
+
# * Create a file at ~/.gitignore
|
20
|
+
# * Include files you want ignored
|
21
|
+
# * Run: git config --global core.excludesfile ~/.gitignore
|
22
|
+
#
|
23
|
+
# After doing this, these files will be ignored in all your git projects,
|
24
|
+
# saving you from having to 'pollute' every project you touch with them
|
25
|
+
#
|
26
|
+
# Not sure what to needs to be ignored for particular editors/OSes? Here's some ideas to get you started. (Remember, remove the leading # of the line)
|
27
|
+
#
|
28
|
+
# For MacOS:
|
29
|
+
#
|
30
|
+
#.DS_Store
|
31
|
+
#
|
32
|
+
# For TextMate
|
33
|
+
#*.tmproj
|
34
|
+
#tmtags
|
35
|
+
#
|
36
|
+
# For emacs:
|
37
|
+
#*~
|
38
|
+
#\#*
|
39
|
+
#.\#*
|
40
|
+
#
|
41
|
+
# For vim:
|
42
|
+
#*.swp
|
data/Gemfile
CHANGED
@@ -1,12 +1,2 @@
|
|
1
|
-
source
|
2
|
-
|
3
|
-
group :development do
|
4
|
-
gem "rspec", "~> 2.4.0"
|
5
|
-
gem "bundler", "~> 1.0.0"
|
6
|
-
gem "jeweler", "~> 1.5.2"
|
7
|
-
gem "amatch", "~> 0.2.5"
|
8
|
-
gem "curb", "~> 0.7.7"
|
9
|
-
gem "rest-client", "~> 1.6.0"
|
10
|
-
gem "actionpack", "~> 2.3.2"
|
11
|
-
gem "activeresource", "~> 2.3.2"
|
12
|
-
end
|
1
|
+
source :rubygems
|
2
|
+
gemspec
|
data/Gemfile.lock
CHANGED
@@ -1,24 +1,24 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
api_auth (0.9.2)
|
5
|
+
|
1
6
|
GEM
|
2
7
|
remote: http://rubygems.org/
|
3
8
|
specs:
|
4
|
-
actionpack (2.3.
|
5
|
-
activesupport (= 2.3.
|
9
|
+
actionpack (2.3.14)
|
10
|
+
activesupport (= 2.3.14)
|
6
11
|
rack (~> 1.1.0)
|
7
|
-
activeresource (2.3.
|
8
|
-
activesupport (= 2.3.
|
9
|
-
activesupport (2.3.
|
10
|
-
amatch (0.2.
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
rake
|
18
|
-
mime-types (1.16)
|
19
|
-
rack (1.1.0)
|
20
|
-
rake (0.8.7)
|
21
|
-
rest-client (1.6.1)
|
12
|
+
activeresource (2.3.14)
|
13
|
+
activesupport (= 2.3.14)
|
14
|
+
activesupport (2.3.14)
|
15
|
+
amatch (0.2.10)
|
16
|
+
tins (~> 0.3)
|
17
|
+
curb (0.7.18)
|
18
|
+
diff-lcs (1.1.3)
|
19
|
+
mime-types (1.17.2)
|
20
|
+
rack (1.1.3)
|
21
|
+
rest-client (1.6.7)
|
22
22
|
mime-types (>= 1.16)
|
23
23
|
rspec (2.4.0)
|
24
24
|
rspec-core (~> 2.4.0)
|
@@ -28,6 +28,7 @@ GEM
|
|
28
28
|
rspec-expectations (2.4.0)
|
29
29
|
diff-lcs (~> 1.1.2)
|
30
30
|
rspec-mocks (2.4.0)
|
31
|
+
tins (0.3.9)
|
31
32
|
|
32
33
|
PLATFORMS
|
33
34
|
ruby
|
@@ -35,9 +36,9 @@ PLATFORMS
|
|
35
36
|
DEPENDENCIES
|
36
37
|
actionpack (~> 2.3.2)
|
37
38
|
activeresource (~> 2.3.2)
|
38
|
-
|
39
|
-
|
39
|
+
activesupport (~> 2.3.2)
|
40
|
+
amatch (~> 0.2.10)
|
41
|
+
api_auth!
|
40
42
|
curb (~> 0.7.7)
|
41
|
-
jeweler (~> 1.5.2)
|
42
43
|
rest-client (~> 1.6.0)
|
43
44
|
rspec (~> 2.4.0)
|
data/LICENSE.txt
CHANGED
data/README.md
CHANGED
@@ -1,66 +1,63 @@
|
|
1
|
-
ApiAuth
|
2
|
-
=======
|
1
|
+
# ApiAuth #
|
3
2
|
|
4
|
-
Logins and passwords are for humans. Communication between applications need to
|
3
|
+
Logins and passwords are for humans. Communication between applications need to
|
5
4
|
be protected through different means.
|
6
5
|
|
7
6
|
ApiAuth is a Ruby gem designed to be used both in your client and server
|
8
|
-
HTTP-based applications. It implements the same authentication methods (HMAC-SHA1)
|
7
|
+
HTTP-based applications. It implements the same authentication methods (HMAC-SHA1)
|
9
8
|
used by Amazon Web Services.
|
10
9
|
|
11
|
-
The gem will sign your requests on the client side and authenticate that
|
12
|
-
signature on the server side. If your server resources are implemented as a
|
13
|
-
Rails ActiveResource, it will integrate with that. It will even generate the
|
10
|
+
The gem will sign your requests on the client side and authenticate that
|
11
|
+
signature on the server side. If your server resources are implemented as a
|
12
|
+
Rails ActiveResource, it will integrate with that. It will even generate the
|
14
13
|
secret keys necessary for your clients to sign their requests.
|
15
14
|
|
16
|
-
Since it operates entirely using HTTP headers, the server component does not
|
15
|
+
Since it operates entirely using HTTP headers, the server component does not
|
17
16
|
have to be written in the same language as the clients.
|
18
17
|
|
19
|
-
How it works
|
20
|
-
------------
|
18
|
+
## How it works ##
|
21
19
|
|
22
|
-
1. A canonical string is first created using your HTTP headers containing the
|
23
|
-
content-type, content-MD5, request URI and the timestamp. If content-type or
|
24
|
-
content-MD5 are not present, then a blank string is used in their place. If the
|
25
|
-
timestamp isn't present, a valid HTTP date is automatically added to the
|
20
|
+
1. A canonical string is first created using your HTTP headers containing the
|
21
|
+
content-type, content-MD5, request URI and the timestamp. If content-type or
|
22
|
+
content-MD5 are not present, then a blank string is used in their place. If the
|
23
|
+
timestamp isn't present, a valid HTTP date is automatically added to the
|
26
24
|
request. The canonical string string is computed as follows:
|
27
25
|
|
28
26
|
canonical_string = 'content-type,content-MD5,request URI,timestamp'
|
29
27
|
|
30
|
-
2. This string is then used to create the signature which is a Base64 encoded
|
28
|
+
2. This string is then used to create the signature which is a Base64 encoded
|
31
29
|
SHA1 HMAC, using the client's private secret key.
|
32
30
|
|
33
31
|
3. This signature is then added as the `Authorization` HTTP header in the form:
|
34
32
|
|
35
33
|
Authorization = APIAuth 'client access id':'signature from step 2'
|
36
|
-
|
37
|
-
5. On the server side, the SHA1 HMAC is computed in the same way using the
|
38
|
-
request headers and the client's secret key, which is known to only
|
39
|
-
the client and the server but can be looked up on the server using the client's
|
40
|
-
access id that was attached in the header. The access id can be any integer or
|
34
|
+
|
35
|
+
5. On the server side, the SHA1 HMAC is computed in the same way using the
|
36
|
+
request headers and the client's secret key, which is known to only
|
37
|
+
the client and the server but can be looked up on the server using the client's
|
38
|
+
access id that was attached in the header. The access id can be any integer or
|
41
39
|
string that uniquely identifies the client.
|
42
40
|
|
43
41
|
|
44
|
-
References
|
45
|
-
----------
|
42
|
+
## References ##
|
46
43
|
|
47
44
|
* [Hash functions](http://en.wikipedia.org/wiki/Cryptographic_hash_function)
|
48
45
|
* [SHA-1 Hash function](http://en.wikipedia.org/wiki/SHA-1)
|
49
46
|
* [HMAC algorithm](http://en.wikipedia.org/wiki/HMAC)
|
50
47
|
* [RFC 2104 (HMAC)](http://tools.ietf.org/html/rfc2104)
|
51
48
|
|
52
|
-
Install
|
53
|
-
-------
|
49
|
+
## Install ##
|
54
50
|
|
55
|
-
The gem doesn't have any dependencies outside of having a working OpenSSL
|
51
|
+
The gem doesn't have any dependencies outside of having a working OpenSSL
|
56
52
|
configuration for your Ruby VM. To install:
|
57
53
|
|
58
|
-
[sudo] gem install
|
59
|
-
|
60
|
-
|
61
|
-
-------
|
54
|
+
[sudo] gem install api-auth
|
55
|
+
|
56
|
+
Please note the dash in the name versus the underscore.
|
62
57
|
|
63
|
-
|
58
|
+
## Clients ##
|
59
|
+
|
60
|
+
ApiAuth supports many popular HTTP clients. Support for other clients can be
|
64
61
|
added as a request driver.
|
65
62
|
|
66
63
|
Here is the current list of supported request objects:
|
@@ -73,73 +70,87 @@ Here is the current list of supported request objects:
|
|
73
70
|
### HTTP Client Objects ###
|
74
71
|
|
75
72
|
Here's a sample implementation of signing a request created with RestClient. For
|
76
|
-
more examples, please check out the ApiAuth Spec where every supported HTTP
|
73
|
+
more examples, please check out the ApiAuth Spec where every supported HTTP
|
77
74
|
client is tested.
|
78
75
|
|
79
76
|
Assuming you have a client access id and secret as follows:
|
80
77
|
|
78
|
+
``` ruby
|
81
79
|
@access_id = "1044"
|
82
80
|
@secret_key = ApiAuth.generate_secret_key
|
83
|
-
|
81
|
+
```
|
82
|
+
|
84
83
|
A typical RestClient PUT request may look like:
|
85
84
|
|
85
|
+
``` ruby
|
86
86
|
headers = { 'Content-MD5' => "e59ff97941044f85df5297e1c302d260",
|
87
87
|
'Content-Type' => "text/plain",
|
88
88
|
'Date' => "Mon, 23 Jan 1984 03:29:56 GMT" }
|
89
|
-
@request = RestClient::Request.new(:url => "/resource.xml?foo=bar&bar=foo",
|
89
|
+
@request = RestClient::Request.new(:url => "/resource.xml?foo=bar&bar=foo",
|
90
90
|
:headers => headers,
|
91
91
|
:method => :put)
|
92
|
-
|
92
|
+
```
|
93
|
+
|
93
94
|
To sign that request, simply call the `sign!` method as follows:
|
94
95
|
|
96
|
+
``` ruby
|
95
97
|
@signed_request = ApiAuth.sign!(@request, @access_id, @secret_key)
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
98
|
+
```
|
99
|
+
|
100
|
+
The proper `Authorization` request header has now been added to that request
|
101
|
+
object and it's ready to be transmitted. It's recommended that you sign the
|
102
|
+
request as one of the last steps in building the request to ensure the headers
|
103
|
+
don't change after the signing process which would cause the authentication
|
101
104
|
check to fail on the server side.
|
102
|
-
|
105
|
+
|
103
106
|
### ActiveResource Clients ###
|
104
107
|
|
105
|
-
ApiAuth can transparently protect your ActiveResource communications with a
|
108
|
+
ApiAuth can transparently protect your ActiveResource communications with a
|
106
109
|
single configuration line:
|
107
110
|
|
111
|
+
``` ruby
|
108
112
|
class MyResource < ActiveResource::Base
|
109
113
|
with_api_auth(access_id, secret_key)
|
110
114
|
end
|
111
|
-
|
115
|
+
```
|
116
|
+
|
112
117
|
This will automatically sign all outgoing ActiveResource requests from your app.
|
113
118
|
|
114
|
-
Server
|
115
|
-
------
|
119
|
+
## Server ##
|
116
120
|
|
117
|
-
ApiAuth provides some built in methods to help you generate API keys for your
|
121
|
+
ApiAuth provides some built in methods to help you generate API keys for your
|
118
122
|
clients as well as verifying incoming API requests.
|
119
123
|
|
120
124
|
To generate a Base64 encoded API key for a client:
|
121
125
|
|
126
|
+
``` ruby
|
122
127
|
ApiAuth.generate_secret_key
|
123
|
-
|
128
|
+
```
|
129
|
+
|
124
130
|
To validate whether or not a request is authentic:
|
125
|
-
|
131
|
+
|
132
|
+
``` ruby
|
126
133
|
ApiAuth.authentic?(signed_request, secret_key)
|
127
|
-
|
128
|
-
If your server is a Rails app, the signed request will be the `request` object.
|
134
|
+
```
|
129
135
|
|
130
|
-
|
136
|
+
If your server is a Rails app, the signed request will be the `request` object.
|
137
|
+
|
138
|
+
In order to obtain the secret key for the client, you first need to look up the
|
131
139
|
client's access_id. ApiAuth can pull that from the request headers for you:
|
132
140
|
|
141
|
+
``` ruby
|
133
142
|
ApiAuth.access_id(signed_request)
|
134
|
-
|
143
|
+
```
|
144
|
+
|
135
145
|
Once you've looked up the client's record via the access id, you can then verify
|
136
146
|
whether or not the request is authentic. Typically, the access id for the client
|
137
147
|
will be their record's primary key in the DB that stores the record or some other
|
138
148
|
public unique identifier for the client.
|
139
149
|
|
140
|
-
Here's a sample method that can be used in a `before_filter` if your server is a
|
150
|
+
Here's a sample method that can be used in a `before_filter` if your server is a
|
141
151
|
Rails app:
|
142
152
|
|
153
|
+
``` ruby
|
143
154
|
before_filter :api_authenticate
|
144
155
|
|
145
156
|
def api_authenticate
|
@@ -147,28 +158,26 @@ Rails app:
|
|
147
158
|
return ApiAuth.authentic?(request, @current_account.secret_key) unless @current_account.nil?
|
148
159
|
false
|
149
160
|
end
|
150
|
-
|
151
|
-
|
152
|
-
|
161
|
+
```
|
162
|
+
|
163
|
+
## Development ##
|
153
164
|
|
154
165
|
ApiAuth uses bundler for gem dependencies and RSpec for testing. Developing the
|
155
|
-
gem requires that you have all supported HTTP clients installed. Bundler will
|
166
|
+
gem requires that you have all supported HTTP clients installed. Bundler will
|
156
167
|
take care of all that for you.
|
157
168
|
|
158
169
|
To run the tests:
|
159
170
|
|
160
171
|
rake spec
|
161
|
-
|
172
|
+
|
162
173
|
If you'd like to add support for additional HTTP clients, check out the already
|
163
|
-
implemented drivers in `lib/api_auth/request_drivers` for reference. All of
|
174
|
+
implemented drivers in `lib/api_auth/request_drivers` for reference. All of
|
164
175
|
the public methods for each driver are required to be implemented by your driver.
|
165
|
-
|
166
|
-
Authors
|
167
|
-
-------
|
176
|
+
|
177
|
+
## Authors ##
|
168
178
|
|
169
179
|
* [Mauricio Gomes](http://github.com/mgomes)
|
170
180
|
|
171
|
-
Copyright
|
172
|
-
---------
|
181
|
+
## Copyright ##
|
173
182
|
|
174
|
-
Copyright (c)
|
183
|
+
Copyright (c) 2012 Gemini SBS LLC. See LICENSE.txt for further details.
|
data/Rakefile
CHANGED
@@ -1,37 +1,14 @@
|
|
1
|
-
require 'rubygems'
|
2
1
|
require 'bundler'
|
3
|
-
|
4
|
-
Bundler.setup(:default, :development)
|
5
|
-
rescue Bundler::BundlerError => e
|
6
|
-
$stderr.puts e.message
|
7
|
-
$stderr.puts "Run `bundle install` to install missing gems"
|
8
|
-
exit e.status_code
|
9
|
-
end
|
10
|
-
require 'rake'
|
11
|
-
|
12
|
-
require 'jeweler'
|
13
|
-
Jeweler::Tasks.new do |gem|
|
14
|
-
gem.name = "api-auth"
|
15
|
-
gem.homepage = "http://github.com/mgomes/api_auth"
|
16
|
-
gem.license = "MIT"
|
17
|
-
gem.summary = %Q{Simple HMAC authentication for your APIs}
|
18
|
-
gem.description = %Q{Full HMAC auth implementation for use in your gems and Rails apps.}
|
19
|
-
gem.email = "mgomes@geminisbs.com"
|
20
|
-
gem.authors = ["Mauricio Gomes"]
|
21
|
-
end
|
22
|
-
Jeweler::RubygemsDotOrgTasks.new
|
2
|
+
Bundler::GemHelper.install_tasks
|
23
3
|
|
4
|
+
require 'rake'
|
24
5
|
require 'rspec/core'
|
25
6
|
require 'rspec/core/rake_task'
|
7
|
+
|
26
8
|
RSpec::Core::RakeTask.new(:spec) do |spec|
|
27
9
|
spec.pattern = FileList['spec/**/*_spec.rb']
|
28
10
|
end
|
29
11
|
|
30
|
-
RSpec::Core::RakeTask.new(:rcov) do |spec|
|
31
|
-
spec.pattern = 'spec/**/*_spec.rb'
|
32
|
-
spec.rcov = true
|
33
|
-
end
|
34
|
-
|
35
12
|
task :default => :spec
|
36
13
|
|
37
14
|
require 'rake/rdoctask'
|
@@ -39,7 +16,7 @@ Rake::RDocTask.new do |rdoc|
|
|
39
16
|
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
40
17
|
|
41
18
|
rdoc.rdoc_dir = 'rdoc'
|
42
|
-
rdoc.title = "
|
19
|
+
rdoc.title = "test #{version}"
|
43
20
|
rdoc.rdoc_files.include('README*')
|
44
21
|
rdoc.rdoc_files.include('lib/**/*.rb')
|
45
22
|
end
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.9.
|
1
|
+
0.9.2
|
data/api_auth.gemspec
CHANGED
@@ -1,75 +1,25 @@
|
|
1
|
-
# Generated by jeweler
|
2
|
-
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
-
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
1
|
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
5
3
|
|
6
4
|
Gem::Specification.new do |s|
|
7
|
-
s.name = %q{
|
8
|
-
s.
|
9
|
-
|
10
|
-
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
-
s.authors = ["Mauricio Gomes"]
|
12
|
-
s.date = %q{2011-01-30}
|
5
|
+
s.name = %q{api-auth}
|
6
|
+
s.summary = %q{Simple HMAC authentication for your APIs}
|
13
7
|
s.description = %q{Full HMAC auth implementation for use in your gems and Rails apps.}
|
14
|
-
s.email = %q{mgomes@geminisbs.com}
|
15
|
-
s.extra_rdoc_files = [
|
16
|
-
"LICENSE.txt",
|
17
|
-
"README.md"
|
18
|
-
]
|
19
|
-
s.files = [
|
20
|
-
".document",
|
21
|
-
".rspec",
|
22
|
-
"Gemfile",
|
23
|
-
"LICENSE.txt",
|
24
|
-
"Rakefile",
|
25
|
-
"lib/api_auth.rb",
|
26
|
-
"spec/api_auth_spec.rb",
|
27
|
-
"spec/spec_helper.rb"
|
28
|
-
]
|
29
8
|
s.homepage = %q{http://github.com/geminisbs/api-auth}
|
30
|
-
s.
|
31
|
-
s.
|
32
|
-
s.
|
33
|
-
s.summary = %q{Simple HMAC authentication for your APIs}
|
34
|
-
s.test_files = [
|
35
|
-
"spec/api_auth_spec.rb",
|
36
|
-
"spec/headers_spec.rb",
|
37
|
-
"spec/helpers_spec.rb",
|
38
|
-
"spec/railtie_spec.rb",
|
39
|
-
"spec/spec_helper.rb"
|
40
|
-
]
|
9
|
+
s.version = File.read(File.join(File.dirname(__FILE__), 'VERSION'))
|
10
|
+
s.authors = ["Mauricio Gomes"]
|
11
|
+
s.email = "mauricio@edge14.com"
|
41
12
|
|
42
|
-
|
43
|
-
|
13
|
+
s.add_development_dependency "rspec", "~> 2.4.0"
|
14
|
+
s.add_development_dependency "amatch", "~> 0.2.10"
|
15
|
+
s.add_development_dependency "actionpack", "~> 2.3.2"
|
16
|
+
s.add_development_dependency "activesupport", "~> 2.3.2"
|
17
|
+
s.add_development_dependency "activeresource", "~> 2.3.2"
|
18
|
+
s.add_development_dependency "rest-client", "~> 1.6.0"
|
19
|
+
s.add_development_dependency "curb", "~> 0.7.7"
|
44
20
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
s.add_development_dependency(%q<amatch>, ["~> 0.2.5"])
|
50
|
-
s.add_development_dependency(%q<curb>, ["~> 0.7.7"])
|
51
|
-
s.add_development_dependency(%q<rest-client>, ["~> 1.6.0"])
|
52
|
-
s.add_development_dependency(%q<actionpack>, ["~> 2.3.2"])
|
53
|
-
s.add_development_dependency(%q<activeresource>, ["~> 2.3.2"])
|
54
|
-
else
|
55
|
-
s.add_dependency(%q<rspec>, ["~> 2.4.0"])
|
56
|
-
s.add_dependency(%q<bundler>, ["~> 1.0.0"])
|
57
|
-
s.add_dependency(%q<jeweler>, ["~> 1.5.2"])
|
58
|
-
s.add_dependency(%q<amatch>, ["~> 0.2.5"])
|
59
|
-
s.add_dependency(%q<curb>, ["~> 0.7.7"])
|
60
|
-
s.add_dependency(%q<rest-client>, ["~> 1.6.0"])
|
61
|
-
s.add_dependency(%q<actionpack>, ["~> 2.3.2"])
|
62
|
-
s.add_dependency(%q<activeresource>, ["~> 2.3.2"])
|
63
|
-
end
|
64
|
-
else
|
65
|
-
s.add_dependency(%q<rspec>, ["~> 2.4.0"])
|
66
|
-
s.add_dependency(%q<bundler>, ["~> 1.0.0"])
|
67
|
-
s.add_dependency(%q<jeweler>, ["~> 1.5.2"])
|
68
|
-
s.add_dependency(%q<amatch>, ["~> 0.2.5"])
|
69
|
-
s.add_dependency(%q<curb>, ["~> 0.7.7"])
|
70
|
-
s.add_dependency(%q<rest-client>, ["~> 1.6.0"])
|
71
|
-
s.add_dependency(%q<actionpack>, ["~> 2.3.2"])
|
72
|
-
s.add_dependency(%q<activeresource>, ["~> 2.3.2"])
|
73
|
-
end
|
21
|
+
s.files = `git ls-files`.split("\n")
|
22
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
23
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
24
|
+
s.require_paths = ["lib"]
|
74
25
|
end
|
75
|
-
|
data/lib/api_auth.rb
CHANGED
@@ -8,6 +8,7 @@ require 'api_auth/request_drivers/net_http'
|
|
8
8
|
require 'api_auth/request_drivers/curb'
|
9
9
|
require 'api_auth/request_drivers/rest_client'
|
10
10
|
require 'api_auth/request_drivers/action_controller'
|
11
|
+
require 'api_auth/request_drivers/action_dispatch'
|
11
12
|
|
12
13
|
require 'api_auth/headers'
|
13
14
|
require 'api_auth/base'
|
data/lib/api_auth/headers.rb
CHANGED
@@ -19,6 +19,8 @@ module ApiAuth
|
|
19
19
|
@request = ActionControllerRequest.new(request)
|
20
20
|
when /ActionController::TestRequest/
|
21
21
|
@request = ActionControllerRequest.new(request)
|
22
|
+
when /ActionDispatch::Request/
|
23
|
+
@request = ActionDispatchRequest.new(request)
|
22
24
|
else
|
23
25
|
raise UnknownHTTPRequest, "#{request.class.to_s} is not yet supported."
|
24
26
|
end
|
data/spec/api_auth_spec.rb
CHANGED
@@ -133,6 +133,41 @@ describe "ApiAuth" do
|
|
133
133
|
|
134
134
|
end
|
135
135
|
|
136
|
+
describe "with ActionController" do
|
137
|
+
|
138
|
+
before(:each) do
|
139
|
+
@request = ActionController::Request.new(
|
140
|
+
'PATH_INFO' => '/resource.xml',
|
141
|
+
'QUERY_STRING' => 'foo=bar&bar=foo',
|
142
|
+
'REQUEST_METHOD' => 'PUT',
|
143
|
+
'CONTENT_MD5' => 'e59ff97941044f85df5297e1c302d260',
|
144
|
+
'CONTENT_TYPE' => 'text/plain',
|
145
|
+
'HTTP_DATE' => 'Mon, 23 Jan 1984 03:29:56 GMT')
|
146
|
+
@signed_request = ApiAuth.sign!(@request, @access_id, @secret_key)
|
147
|
+
end
|
148
|
+
|
149
|
+
it "should return a ActionController::Request object after signing it" do
|
150
|
+
ApiAuth.sign!(@request, @access_id, @secret_key).class.to_s.should match("ActionController::Request")
|
151
|
+
end
|
152
|
+
|
153
|
+
it "should sign the request" do
|
154
|
+
@signed_request.env['Authorization'].should == "APIAuth 1044:#{hmac(@secret_key, @request)}"
|
155
|
+
end
|
156
|
+
|
157
|
+
it "should authenticate a valid request" do
|
158
|
+
ApiAuth.authentic?(@signed_request, @secret_key).should be_true
|
159
|
+
end
|
160
|
+
|
161
|
+
it "should NOT authenticate a non-valid request" do
|
162
|
+
ApiAuth.authentic?(@signed_request, @secret_key+'j').should be_false
|
163
|
+
end
|
164
|
+
|
165
|
+
it "should retrieve the access_id" do
|
166
|
+
ApiAuth.access_id(@signed_request).should == "1044"
|
167
|
+
end
|
168
|
+
|
169
|
+
end
|
170
|
+
|
136
171
|
end
|
137
172
|
|
138
173
|
end
|
data/spec/headers_spec.rb
CHANGED
@@ -99,4 +99,39 @@ describe "ApiAuth::Headers" do
|
|
99
99
|
|
100
100
|
end
|
101
101
|
|
102
|
+
describe "with ActionController" do
|
103
|
+
|
104
|
+
before(:each) do
|
105
|
+
@request = ActionController::Request.new(
|
106
|
+
'PATH_INFO' => '/resource.xml',
|
107
|
+
'QUERY_STRING' => 'foo=bar&bar=foo',
|
108
|
+
'REQUEST_METHOD' => 'PUT',
|
109
|
+
'CONTENT_MD5' => 'e59ff97941044f85df5297e1c302d260',
|
110
|
+
'CONTENT_TYPE' => 'text/plain',
|
111
|
+
'HTTP_DATE' => 'Mon, 23 Jan 1984 03:29:56 GMT')
|
112
|
+
@headers = ApiAuth::Headers.new(@request)
|
113
|
+
end
|
114
|
+
|
115
|
+
it "should generate the proper canonical string" do
|
116
|
+
@headers.canonical_string.should == CANONICAL_STRING
|
117
|
+
end
|
118
|
+
|
119
|
+
it "should set the authorization header" do
|
120
|
+
@headers.sign_header("alpha")
|
121
|
+
@headers.authorization_header.should == "alpha"
|
122
|
+
end
|
123
|
+
|
124
|
+
it "should set the DATE header if one is not already present" do
|
125
|
+
@request = ActionController::Request.new(
|
126
|
+
'PATH_INFO' => '/resource.xml',
|
127
|
+
'QUERY_STRING' => 'foo=bar&bar=foo',
|
128
|
+
'REQUEST_METHOD' => 'PUT',
|
129
|
+
'CONTENT_MD5' => 'e59ff97941044f85df5297e1c302d260',
|
130
|
+
'CONTENT_TYPE' => 'text/plain')
|
131
|
+
ApiAuth.sign!(@request, "some access id", "some secret key")
|
132
|
+
@request.headers['DATE'].should_not be_nil
|
133
|
+
end
|
134
|
+
|
135
|
+
end
|
136
|
+
|
102
137
|
end
|
data/spec/test_helper.rb
ADDED
metadata
CHANGED
@@ -1,117 +1,101 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: api-auth
|
3
|
-
version: !ruby/object:Gem::Version
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.9.2
|
4
5
|
prerelease:
|
5
|
-
version: 0.9.1
|
6
6
|
platform: ruby
|
7
|
-
authors:
|
7
|
+
authors:
|
8
8
|
- Mauricio Gomes
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
dependencies:
|
16
|
-
- !ruby/object:Gem::Dependency
|
12
|
+
date: 2012-03-08 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
17
15
|
name: rspec
|
18
|
-
requirement: &
|
16
|
+
requirement: &70291317916400 !ruby/object:Gem::Requirement
|
19
17
|
none: false
|
20
|
-
requirements:
|
18
|
+
requirements:
|
21
19
|
- - ~>
|
22
|
-
- !ruby/object:Gem::Version
|
20
|
+
- !ruby/object:Gem::Version
|
23
21
|
version: 2.4.0
|
24
22
|
type: :development
|
25
23
|
prerelease: false
|
26
|
-
version_requirements: *
|
27
|
-
- !ruby/object:Gem::Dependency
|
28
|
-
name:
|
29
|
-
requirement: &
|
24
|
+
version_requirements: *70291317916400
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: amatch
|
27
|
+
requirement: &70291317915760 !ruby/object:Gem::Requirement
|
30
28
|
none: false
|
31
|
-
requirements:
|
29
|
+
requirements:
|
32
30
|
- - ~>
|
33
|
-
- !ruby/object:Gem::Version
|
34
|
-
version:
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: 0.2.10
|
35
33
|
type: :development
|
36
34
|
prerelease: false
|
37
|
-
version_requirements: *
|
38
|
-
- !ruby/object:Gem::Dependency
|
39
|
-
name:
|
40
|
-
requirement: &
|
35
|
+
version_requirements: *70291317915760
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: actionpack
|
38
|
+
requirement: &70291317915220 !ruby/object:Gem::Requirement
|
41
39
|
none: false
|
42
|
-
requirements:
|
40
|
+
requirements:
|
43
41
|
- - ~>
|
44
|
-
- !ruby/object:Gem::Version
|
45
|
-
version:
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: 2.3.2
|
46
44
|
type: :development
|
47
45
|
prerelease: false
|
48
|
-
version_requirements: *
|
49
|
-
- !ruby/object:Gem::Dependency
|
50
|
-
name:
|
51
|
-
requirement: &
|
46
|
+
version_requirements: *70291317915220
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: activesupport
|
49
|
+
requirement: &70291317914540 !ruby/object:Gem::Requirement
|
52
50
|
none: false
|
53
|
-
requirements:
|
51
|
+
requirements:
|
54
52
|
- - ~>
|
55
|
-
- !ruby/object:Gem::Version
|
56
|
-
version:
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 2.3.2
|
57
55
|
type: :development
|
58
56
|
prerelease: false
|
59
|
-
version_requirements: *
|
60
|
-
- !ruby/object:Gem::Dependency
|
61
|
-
name:
|
62
|
-
requirement: &
|
57
|
+
version_requirements: *70291317914540
|
58
|
+
- !ruby/object:Gem::Dependency
|
59
|
+
name: activeresource
|
60
|
+
requirement: &70291317913500 !ruby/object:Gem::Requirement
|
63
61
|
none: false
|
64
|
-
requirements:
|
62
|
+
requirements:
|
65
63
|
- - ~>
|
66
|
-
- !ruby/object:Gem::Version
|
67
|
-
version:
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
version: 2.3.2
|
68
66
|
type: :development
|
69
67
|
prerelease: false
|
70
|
-
version_requirements: *
|
71
|
-
- !ruby/object:Gem::Dependency
|
68
|
+
version_requirements: *70291317913500
|
69
|
+
- !ruby/object:Gem::Dependency
|
72
70
|
name: rest-client
|
73
|
-
requirement: &
|
71
|
+
requirement: &70291317912540 !ruby/object:Gem::Requirement
|
74
72
|
none: false
|
75
|
-
requirements:
|
73
|
+
requirements:
|
76
74
|
- - ~>
|
77
|
-
- !ruby/object:Gem::Version
|
75
|
+
- !ruby/object:Gem::Version
|
78
76
|
version: 1.6.0
|
79
77
|
type: :development
|
80
78
|
prerelease: false
|
81
|
-
version_requirements: *
|
82
|
-
- !ruby/object:Gem::Dependency
|
83
|
-
name:
|
84
|
-
requirement: &
|
85
|
-
none: false
|
86
|
-
requirements:
|
87
|
-
- - ~>
|
88
|
-
- !ruby/object:Gem::Version
|
89
|
-
version: 2.3.2
|
90
|
-
type: :development
|
91
|
-
prerelease: false
|
92
|
-
version_requirements: *id007
|
93
|
-
- !ruby/object:Gem::Dependency
|
94
|
-
name: activeresource
|
95
|
-
requirement: &id008 !ruby/object:Gem::Requirement
|
79
|
+
version_requirements: *70291317912540
|
80
|
+
- !ruby/object:Gem::Dependency
|
81
|
+
name: curb
|
82
|
+
requirement: &70291317911220 !ruby/object:Gem::Requirement
|
96
83
|
none: false
|
97
|
-
requirements:
|
84
|
+
requirements:
|
98
85
|
- - ~>
|
99
|
-
- !ruby/object:Gem::Version
|
100
|
-
version:
|
86
|
+
- !ruby/object:Gem::Version
|
87
|
+
version: 0.7.7
|
101
88
|
type: :development
|
102
89
|
prerelease: false
|
103
|
-
version_requirements: *
|
90
|
+
version_requirements: *70291317911220
|
104
91
|
description: Full HMAC auth implementation for use in your gems and Rails apps.
|
105
|
-
email:
|
92
|
+
email: mauricio@edge14.com
|
106
93
|
executables: []
|
107
|
-
|
108
94
|
extensions: []
|
109
|
-
|
110
|
-
|
111
|
-
- LICENSE.txt
|
112
|
-
- README.md
|
113
|
-
files:
|
95
|
+
extra_rdoc_files: []
|
96
|
+
files:
|
114
97
|
- .document
|
98
|
+
- .gitignore
|
115
99
|
- .rspec
|
116
100
|
- Gemfile
|
117
101
|
- Gemfile.lock
|
@@ -128,48 +112,46 @@ files:
|
|
128
112
|
- lib/api_auth/helpers.rb
|
129
113
|
- lib/api_auth/railtie.rb
|
130
114
|
- lib/api_auth/request_drivers/action_controller.rb
|
115
|
+
- lib/api_auth/request_drivers/action_dispatch.rb
|
131
116
|
- lib/api_auth/request_drivers/curb.rb
|
132
117
|
- lib/api_auth/request_drivers/net_http.rb
|
133
118
|
- lib/api_auth/request_drivers/rest_client.rb
|
134
119
|
- spec/api_auth_spec.rb
|
120
|
+
- spec/application_helper.rb
|
135
121
|
- spec/headers_spec.rb
|
136
122
|
- spec/helpers_spec.rb
|
137
123
|
- spec/railtie_spec.rb
|
138
124
|
- spec/spec_helper.rb
|
139
|
-
|
140
|
-
homepage: http://github.com/
|
141
|
-
licenses:
|
142
|
-
- MIT
|
125
|
+
- spec/test_helper.rb
|
126
|
+
homepage: http://github.com/geminisbs/api-auth
|
127
|
+
licenses: []
|
143
128
|
post_install_message:
|
144
129
|
rdoc_options: []
|
145
|
-
|
146
|
-
require_paths:
|
130
|
+
require_paths:
|
147
131
|
- lib
|
148
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
132
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
149
133
|
none: false
|
150
|
-
requirements:
|
151
|
-
- -
|
152
|
-
- !ruby/object:Gem::Version
|
153
|
-
|
154
|
-
|
155
|
-
- 0
|
156
|
-
version: "0"
|
157
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
134
|
+
requirements:
|
135
|
+
- - ! '>='
|
136
|
+
- !ruby/object:Gem::Version
|
137
|
+
version: '0'
|
138
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
158
139
|
none: false
|
159
|
-
requirements:
|
160
|
-
- -
|
161
|
-
- !ruby/object:Gem::Version
|
162
|
-
version:
|
140
|
+
requirements:
|
141
|
+
- - ! '>='
|
142
|
+
- !ruby/object:Gem::Version
|
143
|
+
version: '0'
|
163
144
|
requirements: []
|
164
|
-
|
165
145
|
rubyforge_project:
|
166
|
-
rubygems_version: 1.
|
146
|
+
rubygems_version: 1.8.16
|
167
147
|
signing_key:
|
168
148
|
specification_version: 3
|
169
149
|
summary: Simple HMAC authentication for your APIs
|
170
|
-
test_files:
|
150
|
+
test_files:
|
171
151
|
- spec/api_auth_spec.rb
|
152
|
+
- spec/application_helper.rb
|
172
153
|
- spec/headers_spec.rb
|
173
154
|
- spec/helpers_spec.rb
|
174
155
|
- spec/railtie_spec.rb
|
175
156
|
- spec/spec_helper.rb
|
157
|
+
- spec/test_helper.rb
|