url_signer 0.1
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.
- 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:
|