rack-url_auth 0.0.0 → 0.2.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +2 -0
- data/Gemfile.lock +25 -11
- data/README.md +77 -2
- data/lib/rack/url_auth/proxy.rb +10 -5
- data/lib/rack/url_auth/signer.rb +23 -19
- data/lib/rack/url_auth/version.rb +1 -1
- data/lib/rack/url_auth.rb +14 -5
- data/rack-signed_urls.gemspec +3 -0
- data/spec/middleware_spec.rb +69 -29
- data/spec/signer_spec.rb +35 -19
- metadata +39 -14
- data/spec/proxy_spec.rb +0 -40
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a72ca23ae12a4e7216c70321800a4381a265f92e
|
4
|
+
data.tar.gz: ff999de6188aeb84d739e7763402de8ce7984022
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 20b8935975cd8a6970b457be30728e909c9a7b25c9c56dc7daee0b9799530a37ed821833da72ec64be833b058380416a2ded57d95c01d5fcb45194201583e7b4
|
7
|
+
data.tar.gz: 5d06158fc1c9f29f45eef0efceb4a2f22bea0982885bb5f4b25a10ab20ea270576439e03ee561c0fde68af76abf60776bf3aadb2a683d9e88093de0e59cfcd2e
|
data/.gitignore
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,24 +1,35 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
rack-url_auth (0.
|
4
|
+
rack-url_auth (0.2.0)
|
5
|
+
addressable
|
6
|
+
ruby-hmac
|
5
7
|
|
6
8
|
GEM
|
7
9
|
remote: https://rubygems.org/
|
8
10
|
specs:
|
9
|
-
|
11
|
+
addressable (2.5.1)
|
12
|
+
public_suffix (~> 2.0, >= 2.0.2)
|
13
|
+
diff-lcs (1.3)
|
14
|
+
public_suffix (2.0.5)
|
10
15
|
rack (1.5.2)
|
11
16
|
rack-test (0.6.2)
|
12
17
|
rack (>= 1.0)
|
13
|
-
rake (
|
14
|
-
rspec (
|
15
|
-
rspec-core (~>
|
16
|
-
rspec-expectations (~>
|
17
|
-
rspec-mocks (~>
|
18
|
-
rspec-core (
|
19
|
-
|
20
|
-
|
21
|
-
|
18
|
+
rake (12.0.0)
|
19
|
+
rspec (3.6.0)
|
20
|
+
rspec-core (~> 3.6.0)
|
21
|
+
rspec-expectations (~> 3.6.0)
|
22
|
+
rspec-mocks (~> 3.6.0)
|
23
|
+
rspec-core (3.6.0)
|
24
|
+
rspec-support (~> 3.6.0)
|
25
|
+
rspec-expectations (3.6.0)
|
26
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
27
|
+
rspec-support (~> 3.6.0)
|
28
|
+
rspec-mocks (3.6.0)
|
29
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
30
|
+
rspec-support (~> 3.6.0)
|
31
|
+
rspec-support (3.6.0)
|
32
|
+
ruby-hmac (0.4.0)
|
22
33
|
|
23
34
|
PLATFORMS
|
24
35
|
ruby
|
@@ -30,3 +41,6 @@ DEPENDENCIES
|
|
30
41
|
rack-url_auth!
|
31
42
|
rake
|
32
43
|
rspec
|
44
|
+
|
45
|
+
BUNDLED WITH
|
46
|
+
1.14.6
|
data/README.md
CHANGED
@@ -1,6 +1,24 @@
|
|
1
1
|
# Rack::UrlAuth
|
2
2
|
|
3
|
-
|
3
|
+
Rack::UrlAuth is a Rack middleware for HMAC URL authentication.
|
4
|
+
|
5
|
+
The most obvious use case would be a service that allows its users to perform
|
6
|
+
an action by clicking on an email sent to them, such as activating an
|
7
|
+
account, claiming a discount coupon or reseting a password.
|
8
|
+
|
9
|
+
The user would receive an email with a link to an url such as:
|
10
|
+
`http://example.org/accounts/1/activate?expires=2013-12-12&signature=bf3a53...`
|
11
|
+
|
12
|
+
Because any tampering with the query string or any other url component
|
13
|
+
can be detected, the service can tell if the person is authorized to
|
14
|
+
perform that action.
|
15
|
+
|
16
|
+
Keep in mind that **all GET actions should be idempotent**, meaning that
|
17
|
+
accessing them every time yields the same result.
|
18
|
+
|
19
|
+
Amazon S3, Braintree and may other services use this same principle to
|
20
|
+
authenticate requests by either signing the request body or the url.
|
21
|
+
|
4
22
|
|
5
23
|
## Installation
|
6
24
|
|
@@ -16,9 +34,66 @@ Or install it yourself as:
|
|
16
34
|
|
17
35
|
$ gem install rack-url_auth
|
18
36
|
|
37
|
+
|
19
38
|
## Usage
|
20
39
|
|
21
|
-
|
40
|
+
### Rails example
|
41
|
+
|
42
|
+
|
43
|
+
```ruby
|
44
|
+
# config/application.rb
|
45
|
+
...
|
46
|
+
|
47
|
+
module MyApp
|
48
|
+
class Application < Rails::Application
|
49
|
+
config.middleware.use 'Rack::UrlAuth', secret: 'very-long-and-arbitrary-string'
|
50
|
+
...
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
# controllers/application_controller.rb
|
55
|
+
class ApplicationController < ActionController::Base
|
56
|
+
...
|
57
|
+
protected
|
58
|
+
def authenticate_url!
|
59
|
+
unless env['rack.url_auth'].url_authorized?
|
60
|
+
render file: 'public/401', status: 401
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def sign_url(url)
|
65
|
+
env['rack.url_auth'].sign_url url
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
# controllers/private_stuff_controller.rb
|
70
|
+
class PrivateThingsController < ApplicationController
|
71
|
+
before_filter :authenticate_url!, only: :view_private_thing
|
72
|
+
|
73
|
+
def send_authorization
|
74
|
+
signed_url = sign_url(view_private_thing_url(id: params[:id]))
|
75
|
+
ApplicationMailer.
|
76
|
+
private_thing_view_authorization(params[:email], signed_url).
|
77
|
+
deliver
|
78
|
+
...
|
79
|
+
end
|
80
|
+
|
81
|
+
def view_private_thing
|
82
|
+
# Not for you unless you are authorized ;)
|
83
|
+
@thing = PrivateThing.find(params[:id])
|
84
|
+
...
|
85
|
+
end
|
86
|
+
end
|
87
|
+
```
|
88
|
+
|
89
|
+
|
90
|
+
## Resources
|
91
|
+
|
92
|
+
|
93
|
+
* [Using HMAC to authenticate Web service requests](http://rc3.org/2011/12/02/using-hmac-to-authenticate-web-service-requests/)
|
94
|
+
* [Signed Idempotent Action Links](http://www.intridea.com/blog/2012/6/7/signed-idempotent-action-links)
|
95
|
+
* [Why you should never use hash functions for message authentication](http://blog.jcoglan.com/2012/06/09/why-you-should-never-use-hash-functions-for-message-authentication/)
|
96
|
+
|
22
97
|
|
23
98
|
## Contributing
|
24
99
|
|
data/lib/rack/url_auth/proxy.rb
CHANGED
@@ -8,13 +8,18 @@ module Rack
|
|
8
8
|
@signer = signer
|
9
9
|
end
|
10
10
|
|
11
|
-
def
|
12
|
-
|
13
|
-
|
11
|
+
def authorized?
|
12
|
+
method = request.request_method.downcase
|
13
|
+
signature_header = request.env["HTTP_X_SIGNATURE"]
|
14
14
|
|
15
|
-
|
16
|
-
|
15
|
+
if !signature_header && request.get? || request.head?
|
16
|
+
signer.verify_url(request.url, method)
|
17
|
+
else
|
18
|
+
body = request.body.read; request.body.rewind
|
19
|
+
signer.verify(method + request.url + body, signature_header)
|
20
|
+
end
|
17
21
|
end
|
18
22
|
end
|
23
|
+
|
19
24
|
end
|
20
25
|
end
|
data/lib/rack/url_auth/signer.rb
CHANGED
@@ -1,3 +1,6 @@
|
|
1
|
+
require 'hmac-sha2'
|
2
|
+
require 'addressable'
|
3
|
+
|
1
4
|
module Rack
|
2
5
|
class UrlAuth
|
3
6
|
class Signer
|
@@ -8,41 +11,42 @@ module Rack
|
|
8
11
|
end
|
9
12
|
|
10
13
|
def sign(message)
|
11
|
-
|
12
|
-
OpenSSL::HMAC.hexdigest sha1, secret, message
|
14
|
+
HMAC::SHA256.hexdigest(secret, message)
|
13
15
|
end
|
14
16
|
|
15
17
|
def verify(message, signature)
|
16
|
-
actual
|
18
|
+
actual = Digest::SHA1.hexdigest sign(message)
|
17
19
|
expected = Digest::SHA1.hexdigest signature
|
18
20
|
actual == expected
|
19
21
|
end
|
20
22
|
|
21
|
-
def sign_url(url)
|
22
|
-
purl
|
23
|
-
|
24
|
-
query
|
23
|
+
def sign_url(url, method)
|
24
|
+
purl, query = parse_and_extract_query(url)
|
25
|
+
normalized = purl.normalize.to_s
|
26
|
+
query['signature'] = sign(method.to_s.downcase + normalized)
|
25
27
|
|
26
|
-
build_url
|
28
|
+
build_url(purl, query)
|
27
29
|
end
|
28
30
|
|
29
|
-
def verify_url(url)
|
30
|
-
purl
|
31
|
-
|
32
|
-
|
31
|
+
def verify_url(url, method)
|
32
|
+
purl, query = parse_and_extract_query(url)
|
33
|
+
signature = query.delete('signature').to_s
|
34
|
+
message = method.to_s.downcase + build_url(purl, query)
|
33
35
|
|
34
|
-
verify
|
36
|
+
verify(message, signature)
|
35
37
|
end
|
36
38
|
|
37
39
|
private
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
40
|
+
|
41
|
+
def parse_and_extract_query(url)
|
42
|
+
purl = Addressable::URI.parse(url)
|
43
|
+
query = purl.query_values || {}
|
44
|
+
[purl, query]
|
43
45
|
end
|
44
46
|
|
45
|
-
|
47
|
+
def build_url(purl, query)
|
48
|
+
purl.query = Rack::Utils.build_query(query)
|
49
|
+
purl.normalize.to_s
|
46
50
|
end
|
47
51
|
end
|
48
52
|
end
|
data/lib/rack/url_auth.rb
CHANGED
@@ -4,16 +4,25 @@ require "rack/url_auth/proxy"
|
|
4
4
|
|
5
5
|
module Rack
|
6
6
|
class UrlAuth
|
7
|
-
attr_reader :app, :signer
|
7
|
+
attr_reader :app, :signer, :forward_auth
|
8
8
|
|
9
9
|
def initialize(app, opts = {})
|
10
|
-
secret = opts[:secret] or
|
11
|
-
|
10
|
+
secret = opts[:secret] or
|
11
|
+
raise(ArgumentError, 'Please provide `secret`')
|
12
|
+
|
13
|
+
@app = app
|
14
|
+
@signer = Signer.new(secret)
|
15
|
+
@forward_auth = !!opts[:forward_auth]
|
12
16
|
end
|
13
17
|
|
14
18
|
def call(env)
|
15
|
-
env['rack.
|
16
|
-
|
19
|
+
proxy = env['rack.signature_auth'] = Proxy.new(env, signer)
|
20
|
+
|
21
|
+
if !@forward_auth && !proxy.authorized?
|
22
|
+
[403, {}, ['Forbidden']]
|
23
|
+
else
|
24
|
+
@app.call(env)
|
25
|
+
end
|
17
26
|
end
|
18
27
|
end
|
19
28
|
end
|
data/rack-signed_urls.gemspec
CHANGED
@@ -18,6 +18,9 @@ Gem::Specification.new do |spec|
|
|
18
18
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
19
|
spec.require_paths = ["lib"]
|
20
20
|
|
21
|
+
spec.add_dependency "ruby-hmac"
|
22
|
+
spec.add_dependency "addressable"
|
23
|
+
|
21
24
|
spec.add_development_dependency "bundler", "~> 1.3"
|
22
25
|
spec.add_development_dependency "rake"
|
23
26
|
end
|
data/spec/middleware_spec.rb
CHANGED
@@ -1,48 +1,88 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
|
3
|
+
describe Rack::UrlAuth do
|
4
|
+
include Rack::Test::Methods
|
4
5
|
|
5
|
-
|
6
|
-
let(:
|
7
|
-
let(:
|
6
|
+
let(:secret) { 'secretive-secret' }
|
7
|
+
let(:inner_app) { ->(env){ [200,{},['Hello, world.']] } }
|
8
|
+
let(:app) { Rack::UrlAuth.new(inner_app, secret: secret) }
|
8
9
|
|
9
|
-
|
10
|
+
describe 'instantiation' do
|
11
|
+
it 'requires a secret' do
|
12
|
+
expect { Rack::UrlAuth.new(app) }.to raise_error ArgumentError
|
13
|
+
end
|
14
|
+
end
|
10
15
|
|
11
|
-
describe '
|
12
|
-
let(:
|
16
|
+
describe 'request without body' do
|
17
|
+
let(:signature) {
|
18
|
+
'b645417491551a215286db40cd3fbdd97c7e2f146b2feb0ae5f32f03537ed343'
|
19
|
+
}
|
13
20
|
|
14
|
-
it '
|
15
|
-
|
16
|
-
|
21
|
+
it 'authorizes request' do
|
22
|
+
get "/index?signature=#{signature}"
|
23
|
+
expect( last_request.env['rack.signature_auth'] ).to be_authorized
|
17
24
|
end
|
18
25
|
|
19
|
-
it '
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
and_return(signer)
|
26
|
+
it 'forbids request if url is tampered' do
|
27
|
+
get "/forbid?signature=#{signature}"
|
28
|
+
expect( last_request.env['rack.signature_auth'] ).not_to be_authorized
|
29
|
+
end
|
24
30
|
|
25
|
-
|
26
|
-
|
31
|
+
it 'forbids request if method is incorrect' do
|
32
|
+
head "/index?signature=#{signature}"
|
33
|
+
expect( last_request.env['rack.signature_auth'] ).not_to be_authorized
|
27
34
|
end
|
28
35
|
end
|
29
36
|
|
30
|
-
describe 'calling' do
|
31
|
-
let(:app) { UrlAuth.new(inner_app, secret: secret) }
|
32
|
-
let(:env) { { path: '/'} }
|
33
|
-
let(:proxy) { mock('Proxy') }
|
34
37
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
+
describe 'request with body' do
|
39
|
+
let(:signature) {
|
40
|
+
'bab5dd78fce9f4fd85c5037466c5a5e22cf67ba14f25005f499ddc7820710475'
|
41
|
+
}
|
42
|
+
|
43
|
+
it 'autorizes request' do
|
44
|
+
header 'X-Signature', signature
|
45
|
+
post '/index', name: 'Macario'
|
46
|
+
expect( last_request.env['rack.signature_auth'] ).to be_authorized
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'forbids request if url is tampered' do
|
50
|
+
header 'X-Signature', signature
|
51
|
+
post '/forbid', name: 'Macario'
|
52
|
+
expect( last_request.env['rack.signature_auth'] ).not_to be_authorized
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'forbids request if body is tampered' do
|
56
|
+
header 'X-Signature', signature
|
57
|
+
post '/index', name: 'Juan'
|
58
|
+
expect( last_request.env['rack.signature_auth'] ).not_to be_authorized
|
59
|
+
end
|
60
|
+
|
61
|
+
it 'forbids request if method is incorrect' do
|
62
|
+
header 'X-Signature', signature
|
63
|
+
put '/index', name: 'Macario'
|
64
|
+
expect( last_request.env['rack.signature_auth'] ).not_to be_authorized
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
describe 'handling authentication' do
|
69
|
+
context 'not forwarding auth to app' do
|
70
|
+
let(:app) { Rack::UrlAuth.new(inner_app, secret: secret) }
|
38
71
|
|
39
|
-
|
40
|
-
|
72
|
+
it 'returns forbidden status code' do
|
73
|
+
get "/forbid"
|
74
|
+
expect( last_response.status ).to eq 403
|
75
|
+
end
|
41
76
|
end
|
42
77
|
|
43
|
-
|
44
|
-
|
45
|
-
|
78
|
+
context 'forwarding auth to app' do
|
79
|
+
let(:app) { Rack::UrlAuth.new(inner_app,
|
80
|
+
forward_auth: true, secret: secret) }
|
81
|
+
|
82
|
+
it 'returns forbidden status code' do
|
83
|
+
get "/forbid"
|
84
|
+
expect( last_response.status ).to eq 200
|
85
|
+
end
|
46
86
|
end
|
47
87
|
end
|
48
88
|
end
|
data/spec/signer_spec.rb
CHANGED
@@ -6,48 +6,64 @@ describe UrlAuth::Signer do
|
|
6
6
|
let(:signer) { UrlAuth::Signer.new('my-secretive-secret') }
|
7
7
|
|
8
8
|
describe 'signing and validating messages' do
|
9
|
-
let(:message)
|
9
|
+
let(:message) { 'HMAC is fun!!' }
|
10
10
|
let(:tampered_message) { 'HMAC is fun!!!' }
|
11
|
+
let(:signature) { signer.sign message }
|
11
12
|
|
12
13
|
it 'signs a messages' do
|
13
|
-
signature
|
14
|
-
|
15
|
-
|
16
|
-
signer.verify(message, signature).should be true
|
17
|
-
signer.verify(tampered_message, signature).should be false
|
14
|
+
expect(signature.size).to eq(64)
|
15
|
+
expect(signer.verify(message, signature)).to be true
|
16
|
+
expect(signer.verify(tampered_message, signature)).to be false
|
18
17
|
end
|
19
18
|
end
|
20
19
|
|
21
20
|
describe 'signed urls' do
|
22
|
-
let(:url)
|
23
|
-
let(:signed_url) { signer.sign_url url }
|
21
|
+
let(:url) { 'http://example.com/path?token=1&query=sumething' }
|
22
|
+
let(:signed_url) { signer.sign_url url, 'get' }
|
24
23
|
|
25
24
|
it 'appends signature' do
|
26
|
-
signed_url.
|
25
|
+
expect(signed_url).to match %r{&signature=\w{64}}
|
27
26
|
end
|
28
27
|
|
29
28
|
it 'keeps params' do
|
30
|
-
signed_url.
|
29
|
+
expect(signed_url).to include '?token=1&query=sumething'
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'keeps host and path' do
|
33
|
+
expect(signed_url).to match %r{http://example\.com/path}
|
31
34
|
end
|
32
35
|
|
33
|
-
it 'keeps port' do
|
34
|
-
signed_url
|
36
|
+
it 'keeps port if different than 80' do
|
37
|
+
signed_url = signer.
|
38
|
+
sign_url 'http://example.com:3000/path?token=1&query=sumething', 'get'
|
39
|
+
expect(signed_url).to match %{^http://example.com:3000}
|
35
40
|
end
|
36
41
|
|
37
42
|
it 'verifies untampered url' do
|
38
|
-
signer.verify_url(signed_url).
|
43
|
+
expect( signer.verify_url(signed_url, 'get') ).to be true
|
39
44
|
end
|
40
45
|
|
41
46
|
it 'verifies false if url is tampered' do
|
42
|
-
signer.verify_url(signed_url.sub(/\.com/, '.me')).
|
43
|
-
|
44
|
-
signer.verify_url(signed_url.sub('
|
47
|
+
expect( signer.verify_url(signed_url.sub(/\.com/, '.me'), 'get') ).
|
48
|
+
to be false
|
49
|
+
expect( signer.verify_url(signed_url.sub('path', 'other-path'), 'get') ).
|
50
|
+
to be false
|
51
|
+
expect( signer.verify_url(signed_url.sub('1', '2'), 'get') ).
|
52
|
+
to be false
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'verifies that the method is correct' do
|
56
|
+
expect( signer.verify_url(signed_url, 'delete') ).to be false
|
45
57
|
end
|
46
58
|
|
47
59
|
it 'raises error when url is unsigned while verifying url' do
|
48
|
-
|
49
|
-
|
50
|
-
|
60
|
+
expect(signer.verify_url 'http://example.com', 'get').to be false
|
61
|
+
end
|
62
|
+
|
63
|
+
it 'normalizes url' do
|
64
|
+
signed_url = signer.
|
65
|
+
sign_url 'http://example.com/path?token=點看&query=sumething:else', 'get'
|
66
|
+
expect( signer.verify_url(signed_url, 'get') ).to be true
|
51
67
|
end
|
52
68
|
end
|
53
69
|
end
|
metadata
CHANGED
@@ -1,41 +1,69 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rack-url_auth
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- macario
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2017-09-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: ruby-hmac
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: addressable
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
13
41
|
- !ruby/object:Gem::Dependency
|
14
42
|
name: bundler
|
15
43
|
requirement: !ruby/object:Gem::Requirement
|
16
44
|
requirements:
|
17
|
-
- - ~>
|
45
|
+
- - "~>"
|
18
46
|
- !ruby/object:Gem::Version
|
19
47
|
version: '1.3'
|
20
48
|
type: :development
|
21
49
|
prerelease: false
|
22
50
|
version_requirements: !ruby/object:Gem::Requirement
|
23
51
|
requirements:
|
24
|
-
- - ~>
|
52
|
+
- - "~>"
|
25
53
|
- !ruby/object:Gem::Version
|
26
54
|
version: '1.3'
|
27
55
|
- !ruby/object:Gem::Dependency
|
28
56
|
name: rake
|
29
57
|
requirement: !ruby/object:Gem::Requirement
|
30
58
|
requirements:
|
31
|
-
- -
|
59
|
+
- - ">="
|
32
60
|
- !ruby/object:Gem::Version
|
33
61
|
version: '0'
|
34
62
|
type: :development
|
35
63
|
prerelease: false
|
36
64
|
version_requirements: !ruby/object:Gem::Requirement
|
37
65
|
requirements:
|
38
|
-
- -
|
66
|
+
- - ">="
|
39
67
|
- !ruby/object:Gem::Version
|
40
68
|
version: '0'
|
41
69
|
description: Middleware for signing urls
|
@@ -45,8 +73,8 @@ executables: []
|
|
45
73
|
extensions: []
|
46
74
|
extra_rdoc_files: []
|
47
75
|
files:
|
48
|
-
- .gitignore
|
49
|
-
- .rspec
|
76
|
+
- ".gitignore"
|
77
|
+
- ".rspec"
|
50
78
|
- Gemfile
|
51
79
|
- Gemfile.lock
|
52
80
|
- LICENSE.txt
|
@@ -58,7 +86,6 @@ files:
|
|
58
86
|
- lib/rack/url_auth/version.rb
|
59
87
|
- rack-signed_urls.gemspec
|
60
88
|
- spec/middleware_spec.rb
|
61
|
-
- spec/proxy_spec.rb
|
62
89
|
- spec/signer_spec.rb
|
63
90
|
- spec/spec_helper.rb
|
64
91
|
homepage: http://github.com/maca/rack-url_auth
|
@@ -71,23 +98,21 @@ require_paths:
|
|
71
98
|
- lib
|
72
99
|
required_ruby_version: !ruby/object:Gem::Requirement
|
73
100
|
requirements:
|
74
|
-
- -
|
101
|
+
- - ">="
|
75
102
|
- !ruby/object:Gem::Version
|
76
103
|
version: '0'
|
77
104
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
78
105
|
requirements:
|
79
|
-
- -
|
106
|
+
- - ">="
|
80
107
|
- !ruby/object:Gem::Version
|
81
108
|
version: '0'
|
82
109
|
requirements: []
|
83
110
|
rubyforge_project:
|
84
|
-
rubygems_version: 2.
|
111
|
+
rubygems_version: 2.6.11
|
85
112
|
signing_key:
|
86
113
|
specification_version: 4
|
87
114
|
summary: Middleware authorizing signed urls, so they can't be tampered
|
88
115
|
test_files:
|
89
116
|
- spec/middleware_spec.rb
|
90
|
-
- spec/proxy_spec.rb
|
91
117
|
- spec/signer_spec.rb
|
92
118
|
- spec/spec_helper.rb
|
93
|
-
has_rdoc:
|
data/spec/proxy_spec.rb
DELETED
@@ -1,40 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
include Rack
|
4
|
-
|
5
|
-
describe UrlAuth::Proxy do
|
6
|
-
let(:env) { Rack::MockRequest.env_for('/home?signature=mock') }
|
7
|
-
let(:signer) { mock('Signer') }
|
8
|
-
let(:proxy) { UrlAuth::Proxy.new(env, signer) }
|
9
|
-
|
10
|
-
describe 'signing urls' do
|
11
|
-
it 'signs a url' do
|
12
|
-
signer.
|
13
|
-
should_receive(:sign_url).
|
14
|
-
and_return('/home?signature=mock')
|
15
|
-
|
16
|
-
proxy.sign_url('/home').
|
17
|
-
should eq '/home?signature=mock'
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
describe 'signer' do
|
22
|
-
it 'authorizes url' do
|
23
|
-
signer.
|
24
|
-
should_receive(:verify_url).
|
25
|
-
with('http://example.org/home?signature=mock').
|
26
|
-
and_return(true)
|
27
|
-
|
28
|
-
proxy.url_authorized?.should be true
|
29
|
-
end
|
30
|
-
|
31
|
-
it 'returns false for tampered url' do
|
32
|
-
signer.
|
33
|
-
should_receive(:verify_url).
|
34
|
-
with('http://example.org/home?signature=mock').
|
35
|
-
and_return(false)
|
36
|
-
|
37
|
-
proxy.url_authorized?.should be false
|
38
|
-
end
|
39
|
-
end
|
40
|
-
end
|