url_signer 0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +14 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +48 -0
- data/Rakefile +2 -0
- data/lib/url_signer/base.rb +55 -0
- data/lib/url_signer/signer.rb +23 -0
- data/lib/url_signer/verifier.rb +26 -0
- data/lib/url_signer/version.rb +3 -0
- data/lib/url_signer.rb +44 -0
- data/spec/base_spec.rb +67 -0
- data/spec/signer_spec.rb +41 -0
- data/spec/spec_helper.rb +6 -0
- data/spec/url_signer_spec.rb +32 -0
- data/spec/verifier_spec.rb +48 -0
- data/url_signer.gemspec +24 -0
- metadata +109 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 49fa2bf8648727c23d178c1e56fe48292ad9072f
|
4
|
+
data.tar.gz: 838502de43dea1e2811b34d84c5f45c3855980d7
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: af6a065fff64fcc206865a2efd0811dbd7e70ccb559ba2ac59afc6fbf8c9311c32fbb9e9135b3e7b911edba5b20c29a77c54fea1828255e4fb0ce2779299eaa4
|
7
|
+
data.tar.gz: 8b12be5dafbde8ae03e3ec96c515a543b807b0283d551335502724168427b21fe38cb744d462b5225c4273032fa7484f4b68cb1c6d2b0460c92a60e58fc8c1d9
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2014 Aurélien Noce
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
# UrlSign
|
2
|
+
|
3
|
+
Quickly generate and verify signed urls.
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
```ruby
|
10
|
+
gem 'url_signer'
|
11
|
+
```
|
12
|
+
|
13
|
+
And then execute:
|
14
|
+
|
15
|
+
$ bundle
|
16
|
+
|
17
|
+
Or install it yourself as:
|
18
|
+
|
19
|
+
$ gem install url_signer
|
20
|
+
|
21
|
+
## Usage
|
22
|
+
|
23
|
+
### URL signing
|
24
|
+
|
25
|
+
To convert a URL into a signed url, pass it to `UrlSigner.sign`, passing it either a string of an instance of `URI`.
|
26
|
+
|
27
|
+
```ruby
|
28
|
+
>>> signed_url = UrlSigner.sign('http://google.fr?q=test', key='mykey')
|
29
|
+
```
|
30
|
+
|
31
|
+
the returned value `signed_url` is an instance of `URI`.
|
32
|
+
|
33
|
+
### URL verification
|
34
|
+
|
35
|
+
Given a signed URL, you can check its authenticity by calling `UrlSigner.valid?` on it:
|
36
|
+
|
37
|
+
```ruby
|
38
|
+
>>> UrlSigner.valid?(signed_url)
|
39
|
+
true
|
40
|
+
```
|
41
|
+
|
42
|
+
## Contributing
|
43
|
+
|
44
|
+
1. Fork it ( https://github.com/[my-github-username]/url_sign/fork )
|
45
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
46
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
47
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
48
|
+
5. Create a new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1,55 @@
|
|
1
|
+
require 'uri'
|
2
|
+
require 'cgi'
|
3
|
+
require 'digest/hmac'
|
4
|
+
require 'digest/sha1'
|
5
|
+
|
6
|
+
module UrlSigner
|
7
|
+
class Base < Struct.new(:url, :key, :hash_method)
|
8
|
+
|
9
|
+
def initialize(url, key: nil, hash_method: nil)
|
10
|
+
# load and check url
|
11
|
+
url = URI.parse(url) if url.kind_of?(String)
|
12
|
+
raise "expecting a String or URI instance" unless url.kind_of?(URI)
|
13
|
+
|
14
|
+
# load and check signing key
|
15
|
+
key ||= ENV['URL_SIGNING_KEY']
|
16
|
+
raise "You need to provided a signing key to your UrlSigner instance" unless key
|
17
|
+
|
18
|
+
# load the hash method
|
19
|
+
hash_method ||= Digest::SHA1
|
20
|
+
|
21
|
+
super(url, key, hash_method)
|
22
|
+
end
|
23
|
+
|
24
|
+
def signature
|
25
|
+
compute_signature(url.host, url.path, params)
|
26
|
+
end
|
27
|
+
|
28
|
+
protected
|
29
|
+
|
30
|
+
def params
|
31
|
+
@params ||= begin
|
32
|
+
raw_params = CGI.parse(query || '')
|
33
|
+
Hash[raw_params.map { |k,v| v.size == 1 ? [k, v[0]] : [k, v] }]
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def query
|
38
|
+
url.query
|
39
|
+
end
|
40
|
+
|
41
|
+
def compute_signature(host, path, params)
|
42
|
+
keys = params.keys.sort
|
43
|
+
query_string = keys.map { |k| "#{CGI.escape(k)}=#{CGI.escape(params[k])}" }.join
|
44
|
+
base_string = "#{CGI.escape(host)}&#{CGI.escape(path)}&#{CGI.escape(query_string)}"
|
45
|
+
|
46
|
+
return Digest::HMAC.hexdigest(base_string, key, hash_method)
|
47
|
+
end
|
48
|
+
|
49
|
+
def signed?
|
50
|
+
params.has_key?('signature')
|
51
|
+
end
|
52
|
+
|
53
|
+
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'url_signer/base'
|
2
|
+
|
3
|
+
module UrlSigner
|
4
|
+
class Signer < Base
|
5
|
+
|
6
|
+
def sign
|
7
|
+
raise "this URL is already signed !" if signed?
|
8
|
+
|
9
|
+
# build new url
|
10
|
+
signed_url = url.dup
|
11
|
+
signed_url.query = extended_query
|
12
|
+
signed_url
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
def extended_query
|
18
|
+
base_query = query ? query + '&' : ''
|
19
|
+
base_query + "signature=#{signature}"
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'url_signer/base'
|
2
|
+
|
3
|
+
module UrlSigner
|
4
|
+
class Verifier < Base
|
5
|
+
|
6
|
+
def valid?
|
7
|
+
return false unless signed?
|
8
|
+
|
9
|
+
# extract signature from params
|
10
|
+
remaining_params = params.dup
|
11
|
+
provided_signature = remaining_params.delete('signature')
|
12
|
+
|
13
|
+
# recompute the signature using the secret key
|
14
|
+
recomputed_signature = compute_signature(url.host, url.path, remaining_params)
|
15
|
+
|
16
|
+
safe_compare(provided_signature, recomputed_signature)
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def safe_compare(signature, other_signature)
|
22
|
+
hash_method.digest(signature) == hash_method.digest(other_signature)
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
end
|
data/lib/url_signer.rb
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
module UrlSigner
|
2
|
+
autoload :Base, 'url_signer/base'
|
3
|
+
autoload :Signer, 'url_signer/signer'
|
4
|
+
autoload :Verifier, 'url_signer/verifier'
|
5
|
+
|
6
|
+
module_function
|
7
|
+
|
8
|
+
# Returns a new <tt>URI</tt> instance by appending a <tt>signature</tt> parameter to the query of +url+.
|
9
|
+
# The method accepts that +url+ can be either a <tt>String</tt> or a <tt>URI</tt> instance.
|
10
|
+
#
|
11
|
+
# signed_url = UrlSigner.sign('http://google.fr&q=test') # => <URI::HTTP...>
|
12
|
+
#
|
13
|
+
# The following key/value parameters can be given to +options+:
|
14
|
+
# * <tt>:key</tt> - the secret key used for encryption
|
15
|
+
# * <tt>:hash_method</tt> - the hash function to pass to <tt>Digest::HMAC</tt>. Defaults to <tt>Digest::SHA1</tt>.
|
16
|
+
#
|
17
|
+
# Note that if a +URL_SIGNING_KEY+ environment variable is defined, it will be used as a default value for the +:key+ option.
|
18
|
+
def sign(url, *options)
|
19
|
+
temp_signer = UrlSigner::Signer.new(url, *options)
|
20
|
+
temp_signer.sign
|
21
|
+
end
|
22
|
+
|
23
|
+
# Verify the authenticity of the +url+ by checking the value of the <tt>signature</tt> query parameter (if present).
|
24
|
+
# The method accepts that +url+ can be either a <tt>String</tt> or a <tt>URI</tt> instance.
|
25
|
+
#
|
26
|
+
# The following key/value parameters can be given to +options+:
|
27
|
+
# * <tt>:key</tt> - the secret key used for encryption
|
28
|
+
# * <tt>:hash_method</tt> - the hash function to pass to <tt>Digest::HMAC</tt>. Defaults to <tt>Digest::SHA1</tt>.
|
29
|
+
#
|
30
|
+
# Note that if a +URL_SIGNING_KEY+ environment variable is defined, it will be used as a default value for the +:key+ option.
|
31
|
+
#
|
32
|
+
# ==== Examples
|
33
|
+
#
|
34
|
+
# dummy_url = 'http://google.fr?q=test
|
35
|
+
# UrlSigner.valid?(dummy_url) # => false
|
36
|
+
#
|
37
|
+
# signed_url = UrlSigner.sign('http://google.fr&q=test')
|
38
|
+
# UrlSigner.valid?(signed_url) # => true
|
39
|
+
def valid?(url, *options)
|
40
|
+
temp_verifier = UrlSigner::Verifier.new(url, *options)
|
41
|
+
temp_verifier.valid?
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
data/spec/base_spec.rb
ADDED
@@ -0,0 +1,67 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module UrlSigner
|
4
|
+
describe Base do
|
5
|
+
let(:url_string) { 'http://mysite.com/my/path?test=1&retest=2' }
|
6
|
+
let(:url) { URI.parse(url_string) }
|
7
|
+
let(:params) { CGI.parse(url.query) }
|
8
|
+
|
9
|
+
let(:base) { Base.new(url, key: 'testkey') }
|
10
|
+
|
11
|
+
describe "#signature:" do
|
12
|
+
let(:url_with_other_params) { URI.parse('http://mysite.com/my/path?test=2&retest=2') }
|
13
|
+
let(:url_with_other_domain) { URI.parse('http://myothersite.com/my/path?test=1&retest=2') }
|
14
|
+
let(:url_with_other_path) { URI.parse('http://mysite.com/my/other/path?test=1&retest=2') }
|
15
|
+
|
16
|
+
it "depends on the signing key" do
|
17
|
+
other = Base.new(url, key: 'othertestkey')
|
18
|
+
expect(other.signature).not_to eq(base.signature)
|
19
|
+
end
|
20
|
+
|
21
|
+
it "depends on the parameters" do
|
22
|
+
other = Base.new(url_with_other_params, key: 'testkey')
|
23
|
+
expect(other.signature).not_to eq(base.signature)
|
24
|
+
end
|
25
|
+
|
26
|
+
it "depends on the domain" do
|
27
|
+
other = Base.new(url_with_other_domain, key: 'testkey')
|
28
|
+
expect(other.signature).not_to eq(base.signature)
|
29
|
+
end
|
30
|
+
|
31
|
+
it "depends on the path" do
|
32
|
+
other = Base.new(url_with_other_path, key: 'testkey')
|
33
|
+
expect(other.signature).not_to eq(base.signature)
|
34
|
+
end
|
35
|
+
end # #signature
|
36
|
+
|
37
|
+
describe "url parameter:" do
|
38
|
+
|
39
|
+
context "when the url is given as a string," do
|
40
|
+
let(:base_from_string) { Base.new(url_string, key: 'testkey') }
|
41
|
+
|
42
|
+
it "builds a new signer" do
|
43
|
+
expect { Base.new(url_string, key: 'testkey') }.not_to raise_error
|
44
|
+
end
|
45
|
+
|
46
|
+
it "works as usual" do
|
47
|
+
expect{ base_from_string.signature }.not_to raise_error
|
48
|
+
end
|
49
|
+
|
50
|
+
it "is equivalent to the save Signer built from a URI instance" do
|
51
|
+
expect(base_from_string.signature).to eq(base.signature)
|
52
|
+
end
|
53
|
+
|
54
|
+
it "raise if the URL can not be parsed" do
|
55
|
+
expect{ Base.new('not a good idea') }.to raise_error
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
59
|
+
|
60
|
+
it "raise a descriptive message if an invalid type is passed" do
|
61
|
+
expect{ Signer.new([ 'not a good idea' ]) }.to raise_error
|
62
|
+
end
|
63
|
+
|
64
|
+
end # url parameter:
|
65
|
+
|
66
|
+
end
|
67
|
+
end
|
data/spec/signer_spec.rb
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module UrlSigner
|
4
|
+
describe Signer do
|
5
|
+
let(:url_string) { 'http://mysite.com/my/path?test=1&retest=2' }
|
6
|
+
let(:url) { URI.parse(url_string) }
|
7
|
+
let(:params) { CGI.parse(url.query) }
|
8
|
+
|
9
|
+
let(:signer) { Signer.new(url, key: 'testkey') }
|
10
|
+
|
11
|
+
describe "#sign:" do
|
12
|
+
let(:signed_url) { signer.sign }
|
13
|
+
let(:signed_params) { CGI.parse(signed_url.query) }
|
14
|
+
|
15
|
+
it "returns a new url" do
|
16
|
+
expect(signed_url).to be_a(URI)
|
17
|
+
expect(signed_url).not_to be(url)
|
18
|
+
end
|
19
|
+
|
20
|
+
it "keeps all the incoming parameters" do
|
21
|
+
signed_params.delete('signature')
|
22
|
+
expect(signed_params).to eq(params)
|
23
|
+
end
|
24
|
+
|
25
|
+
it "adds a signature parameter" do
|
26
|
+
expect(signed_params).to have_key('signature')
|
27
|
+
end
|
28
|
+
|
29
|
+
describe "signature param" do
|
30
|
+
let(:signature_param) { signed_params['signature'][0] }
|
31
|
+
|
32
|
+
it "contains the computed signature" do
|
33
|
+
expect(signature_param).to eq(signer.signature)
|
34
|
+
end
|
35
|
+
|
36
|
+
end # signature param
|
37
|
+
|
38
|
+
end # #sign
|
39
|
+
|
40
|
+
end
|
41
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe UrlSigner do
|
4
|
+
let(:url) { 'http://google.fr' }
|
5
|
+
let(:fake_signer) { double(sign: true, valid?: true) }
|
6
|
+
|
7
|
+
FORWARDED_METHOD = {
|
8
|
+
sign: ::UrlSigner::Signer,
|
9
|
+
valid?: ::UrlSigner::Verifier
|
10
|
+
}
|
11
|
+
FORWARDED_METHOD.each do |method, klass|
|
12
|
+
describe ".#{method}:" do
|
13
|
+
|
14
|
+
it "builds a new #{klass} instance" do
|
15
|
+
expect(klass).to receive(:new).with(url, key: 'toto').and_return(fake_signer)
|
16
|
+
|
17
|
+
# call method by name dynamically
|
18
|
+
UrlSigner.send(method, url, key: 'toto')
|
19
|
+
end
|
20
|
+
|
21
|
+
it "calls ##{method} on the new #{klass} instance" do
|
22
|
+
allow(klass).to receive(:new).and_return(fake_signer)
|
23
|
+
expect(fake_signer).to receive(method)
|
24
|
+
|
25
|
+
# call method by name dynamically
|
26
|
+
UrlSigner.send(method, url, key: 'toto')
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module UrlSigner
|
4
|
+
describe Verifier do
|
5
|
+
let(:url_string) { 'http://mysite.com/my/path?test=1&retest=2' }
|
6
|
+
let(:url) { URI.parse(url_string) }
|
7
|
+
let(:params) { CGI.parse(url.query) }
|
8
|
+
|
9
|
+
let(:signer) { Signer.new(url, key: 'testkey') }
|
10
|
+
|
11
|
+
describe "#valid?:" do
|
12
|
+
let(:signed_url) { signer.sign }
|
13
|
+
|
14
|
+
context "when an url has been signed," do
|
15
|
+
let(:verifier) { Verifier.new(signed_url, key: 'testkey') }
|
16
|
+
|
17
|
+
it "can verify the url" do
|
18
|
+
expect(verifier.valid?).to be(true)
|
19
|
+
end
|
20
|
+
|
21
|
+
context "when the signed url has been modified," do
|
22
|
+
# will overload signed_url in this context
|
23
|
+
let(:signed_url) {
|
24
|
+
vanilla_url = signer.sign
|
25
|
+
vanilla_url.query += '&toto=titi'
|
26
|
+
vanilla_url
|
27
|
+
}
|
28
|
+
|
29
|
+
it "does not verify the url" do
|
30
|
+
expect(verifier.valid?).to be(false)
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
context "when an url has not been signed," do
|
37
|
+
let(:verifier) { Verifier.new(url, key: 'testkey') }
|
38
|
+
|
39
|
+
it "does not verify the url" do
|
40
|
+
expect(verifier.valid?).to be(false)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
end # #valid?
|
45
|
+
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
data/url_signer.gemspec
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'url_signer/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "url_signer"
|
8
|
+
spec.version = UrlSigner::VERSION
|
9
|
+
spec.authors = ["Aurélien Noce"]
|
10
|
+
spec.email = ["aurnoce@gmail.com"]
|
11
|
+
spec.summary = %q{Sign and verify URLs}
|
12
|
+
spec.description = %q{Simple solution (2 methods) to sign URLs and verify the generated URLs. Use HAMC/SHA1 for signing by default but can be configured.}
|
13
|
+
spec.homepage = "https://github.com/ushu/url_signer"
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0")
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_development_dependency "bundler", "~> 1.6"
|
22
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
23
|
+
spec.add_development_dependency "rspec", "~> 3.1"
|
24
|
+
end
|
metadata
ADDED
@@ -0,0 +1,109 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: url_signer
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: '0.1'
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Aurélien Noce
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-12-30 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ~>
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.6'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ~>
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.6'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ~>
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '10.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ~>
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '10.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rspec
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ~>
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '3.1'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ~>
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '3.1'
|
55
|
+
description: Simple solution (2 methods) to sign URLs and verify the generated URLs.
|
56
|
+
Use HAMC/SHA1 for signing by default but can be configured.
|
57
|
+
email:
|
58
|
+
- aurnoce@gmail.com
|
59
|
+
executables: []
|
60
|
+
extensions: []
|
61
|
+
extra_rdoc_files: []
|
62
|
+
files:
|
63
|
+
- .gitignore
|
64
|
+
- Gemfile
|
65
|
+
- LICENSE.txt
|
66
|
+
- README.md
|
67
|
+
- Rakefile
|
68
|
+
- lib/url_signer.rb
|
69
|
+
- lib/url_signer/base.rb
|
70
|
+
- lib/url_signer/signer.rb
|
71
|
+
- lib/url_signer/verifier.rb
|
72
|
+
- lib/url_signer/version.rb
|
73
|
+
- spec/base_spec.rb
|
74
|
+
- spec/signer_spec.rb
|
75
|
+
- spec/spec_helper.rb
|
76
|
+
- spec/url_signer_spec.rb
|
77
|
+
- spec/verifier_spec.rb
|
78
|
+
- url_signer.gemspec
|
79
|
+
homepage: https://github.com/ushu/url_signer
|
80
|
+
licenses:
|
81
|
+
- MIT
|
82
|
+
metadata: {}
|
83
|
+
post_install_message:
|
84
|
+
rdoc_options: []
|
85
|
+
require_paths:
|
86
|
+
- lib
|
87
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
88
|
+
requirements:
|
89
|
+
- - '>='
|
90
|
+
- !ruby/object:Gem::Version
|
91
|
+
version: '0'
|
92
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - '>='
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
requirements: []
|
98
|
+
rubyforge_project:
|
99
|
+
rubygems_version: 2.0.14
|
100
|
+
signing_key:
|
101
|
+
specification_version: 4
|
102
|
+
summary: Sign and verify URLs
|
103
|
+
test_files:
|
104
|
+
- spec/base_spec.rb
|
105
|
+
- spec/signer_spec.rb
|
106
|
+
- spec/spec_helper.rb
|
107
|
+
- spec/url_signer_spec.rb
|
108
|
+
- spec/verifier_spec.rb
|
109
|
+
has_rdoc:
|