uri_signer 0.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.
- data/.gitignore +18 -0
- data/.rvmrc.sample +1 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +65 -0
- data/Rakefile +1 -0
- data/lib/uri_signer.rb +26 -0
- data/lib/uri_signer/errors.rb +10 -0
- data/lib/uri_signer/errors/missing_base_uri_error.rb +6 -0
- data/lib/uri_signer/errors/missing_http_method_error.rb +6 -0
- data/lib/uri_signer/errors/missing_query_hash_error.rb +7 -0
- data/lib/uri_signer/errors/missing_secret_error.rb +6 -0
- data/lib/uri_signer/errors/missing_signature_string_error.rb +6 -0
- data/lib/uri_signer/errors/missing_uri_error.rb +6 -0
- data/lib/uri_signer/helpers.rb +4 -0
- data/lib/uri_signer/helpers/hash.rb +12 -0
- data/lib/uri_signer/helpers/string.rb +59 -0
- data/lib/uri_signer/query_hash_parser.rb +47 -0
- data/lib/uri_signer/request_parser.rb +143 -0
- data/lib/uri_signer/request_signature.rb +123 -0
- data/lib/uri_signer/signer.rb +108 -0
- data/lib/uri_signer/uri_signature.rb +79 -0
- data/lib/uri_signer/version.rb +3 -0
- data/reload_yard +3 -0
- data/spec/query_hash_parser_spec.rb +79 -0
- data/spec/request_parser_spec.rb +250 -0
- data/spec/request_signature_spec.rb +146 -0
- data/spec/signer_spec.rb +91 -0
- data/spec/unit/helpers/hash_spec.rb +12 -0
- data/spec/unit/helpers/string_spec.rb +41 -0
- data/spec/uri_signature_spec.rb +41 -0
- data/uri_signer.gemspec +31 -0
- metadata +237 -0
@@ -0,0 +1,146 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '../lib/uri_signer'))
|
2
|
+
|
3
|
+
describe UriSigner::RequestSignature do
|
4
|
+
before do
|
5
|
+
@method = "GET"
|
6
|
+
@base_uri = 'https://example.com/members.json'
|
7
|
+
@query_params = { "page" => 5, "per_page" => 15 }
|
8
|
+
end
|
9
|
+
|
10
|
+
subject { described_class.new(@method, @base_uri, @query_params) }
|
11
|
+
|
12
|
+
it "responds to #http_method" do
|
13
|
+
subject.should respond_to(:http_method)
|
14
|
+
end
|
15
|
+
|
16
|
+
it "responds to #base_uri" do
|
17
|
+
subject.should respond_to(:base_uri)
|
18
|
+
end
|
19
|
+
|
20
|
+
it "responds to #encoded_base_uri" do
|
21
|
+
subject.should respond_to(:encoded_base_uri)
|
22
|
+
end
|
23
|
+
|
24
|
+
it "responds to #query_params" do
|
25
|
+
subject.should respond_to(:query_params)
|
26
|
+
end
|
27
|
+
|
28
|
+
it "responds to #query_params?" do
|
29
|
+
subject.should respond_to(:query_params?)
|
30
|
+
end
|
31
|
+
|
32
|
+
it "responds to #encoded_query_params" do
|
33
|
+
subject.should respond_to(:encoded_query_params)
|
34
|
+
end
|
35
|
+
|
36
|
+
it "responds to #signature" do
|
37
|
+
subject.should respond_to(:signature)
|
38
|
+
end
|
39
|
+
|
40
|
+
context "with duplicate values for a query string param" do
|
41
|
+
before do
|
42
|
+
@query_params = { "format" => ['json', 'json'], 'where' => ["name:nate", "name:nate"] }
|
43
|
+
end
|
44
|
+
|
45
|
+
subject { described_class.new(@method, @base_uri, @query_params) }
|
46
|
+
|
47
|
+
it "returns the encoded query params" do
|
48
|
+
subject.encoded_query_params.should == "format%3Djson%26format%3Djson%26where%3Dname%3Anate%26where%3Dname%3Anate"
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
context "with multiple keys in the query string" do
|
53
|
+
before do
|
54
|
+
@query_params = {"order"=>["name:desc", "id:desc"], "where"=>["name:nate", "id:123"]}
|
55
|
+
end
|
56
|
+
|
57
|
+
subject { described_class.new(@method, @base_uri, @query_params) }
|
58
|
+
|
59
|
+
it "returns the #signature string" do
|
60
|
+
subject.signature.should == "GET&https%3A%2F%2Fexample.com%2Fmembers.json&order%3Dname%3Adesc%26order%3Did%3Adesc%26where%3Dname%3Anate%26where%3Did%3A123"
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
context "Handling the signature" do
|
65
|
+
it "returns the #signature string" do
|
66
|
+
subject.signature.should == "GET&https%3A%2F%2Fexample.com%2Fmembers.json&page%3D5%26per_page%3D15"
|
67
|
+
end
|
68
|
+
|
69
|
+
it "removes the trailing ampersand if not query params are provided" do
|
70
|
+
sig = described_class.new(@method, @base_uri, {})
|
71
|
+
sig.signature.should == "GET&https%3A%2F%2Fexample.com%2Fmembers.json"
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
context "Handling the HTTP Method" do
|
76
|
+
it "returns 'GET' for the #http_method" do
|
77
|
+
subject.http_method.should == "GET"
|
78
|
+
end
|
79
|
+
|
80
|
+
it "allows you to specify the HTTP method in lowercase" do
|
81
|
+
sig = described_class.new('get', @base_uri, @query_params)
|
82
|
+
sig.http_method.should == "GET"
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
context "Handling the base_uri" do
|
87
|
+
it "returns 'https://example.com/members.json' for the #base_uri" do
|
88
|
+
subject.base_uri.should == "https://example.com/members.json"
|
89
|
+
end
|
90
|
+
|
91
|
+
it "returns the #encoded_base_uri" do
|
92
|
+
subject.encoded_base_uri.should == "https%3A%2F%2Fexample.com%2Fmembers.json"
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
context "Handling the Query Params" do
|
97
|
+
it "returns the page and per_page query params" do
|
98
|
+
subject.query_params.keys.should include('page', 'per_page')
|
99
|
+
end
|
100
|
+
|
101
|
+
it "converts the keys to strings" do
|
102
|
+
sig = described_class.new(@method, @base_uri, { :page => 4, :per_page => 35 })
|
103
|
+
sig.query_params.keys.should include('page', 'per_page')
|
104
|
+
end
|
105
|
+
|
106
|
+
it "returns true for #query_params?" do
|
107
|
+
subject.query_params?.should be_true
|
108
|
+
end
|
109
|
+
|
110
|
+
it "returns the sorted and #encoded_query_params" do
|
111
|
+
subject.encoded_query_params.should == "page%3D5%26per_page%3D15"
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
context "Handling when no Query Params are provided" do
|
116
|
+
subject { described_class.new(@method, @base_uri, {}) }
|
117
|
+
|
118
|
+
it "returns an empty hash for query_params" do
|
119
|
+
subject.query_params.should == {}
|
120
|
+
end
|
121
|
+
|
122
|
+
it "returns false for #query_params?" do
|
123
|
+
subject.query_params?.should be_false
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
context "Validating the HTTP Method" do
|
128
|
+
it "raises a UriSigner::MissingHttpMethodError when empty string is provided" do
|
129
|
+
lambda { described_class.new('', @base_uri, @query_params) }.should raise_error(UriSigner::Errors::MissingHttpMethodError)
|
130
|
+
end
|
131
|
+
|
132
|
+
it "raises a UriSigner::MissingHttpMethodError when nil is provided" do
|
133
|
+
lambda { described_class.new(nil, @base_uri, @query_params) }.should raise_error(UriSigner::Errors::MissingHttpMethodError)
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
context "Validating the Base URI" do
|
138
|
+
it "raises a UriSigner::MissingBaseUriError when empty string is provided" do
|
139
|
+
lambda { described_class.new(@method, '', @query_params) }.should raise_error(UriSigner::Errors::MissingBaseUriError)
|
140
|
+
end
|
141
|
+
|
142
|
+
it "raises a UriSigner::MissingBaseUriError when nil is provided" do
|
143
|
+
lambda { described_class.new(@method, nil, @query_params) }.should raise_error(UriSigner::Errors::MissingBaseUriError)
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
data/spec/signer_spec.rb
ADDED
@@ -0,0 +1,91 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '../lib/uri_signer'))
|
2
|
+
|
3
|
+
describe UriSigner::Signer do
|
4
|
+
before do
|
5
|
+
@http_method = :get
|
6
|
+
@uri = "https://api.example.com/core/people.json?page=5&per_page=25&order=name:desc&select=id,name"
|
7
|
+
@secret = "my_secret"
|
8
|
+
end
|
9
|
+
|
10
|
+
subject { described_class.new(@http_method, @uri, @secret) }
|
11
|
+
|
12
|
+
it "responds to #uri" do
|
13
|
+
subject.should respond_to(:uri)
|
14
|
+
end
|
15
|
+
|
16
|
+
it "responds to #http_method" do
|
17
|
+
subject.should respond_to(:http_method)
|
18
|
+
end
|
19
|
+
|
20
|
+
it "responds to #signature" do
|
21
|
+
subject.should respond_to(:signature)
|
22
|
+
end
|
23
|
+
|
24
|
+
it "responds to #uri_with_signature" do
|
25
|
+
subject.should respond_to(:uri_with_signature)
|
26
|
+
end
|
27
|
+
|
28
|
+
it "responds to #valid?" do
|
29
|
+
subject.should respond_to(:valid?)
|
30
|
+
end
|
31
|
+
|
32
|
+
it "returns the #uri" do
|
33
|
+
subject.uri.should == "https://api.example.com/core/people.json?page=5&per_page=25&order=name:desc&select=id,name"
|
34
|
+
end
|
35
|
+
|
36
|
+
it "returns the upcased #http_method" do
|
37
|
+
subject.http_method.should == "GET"
|
38
|
+
end
|
39
|
+
|
40
|
+
it "returns the signed URI with the secret" do
|
41
|
+
subject.signature.should == "1AaJvChjz%2BZYJKxWsUQWNK1a%2BeGjpCs6uwQKwPw1%2FV8%3D"
|
42
|
+
end
|
43
|
+
|
44
|
+
context "appending the signature" do
|
45
|
+
it "appends the _signature on to the URI" do
|
46
|
+
subject.uri_with_signature.should == "https://api.example.com/core/people.json?page=5&per_page=25&order=name:desc&select=id,name&_signature=1AaJvChjz%2BZYJKxWsUQWNK1a%2BeGjpCs6uwQKwPw1%2FV8%3D"
|
47
|
+
end
|
48
|
+
|
49
|
+
it "appends the _signature when there are no query string params" do
|
50
|
+
uri = "https://api.example.com/core/people.json"
|
51
|
+
signer = described_class.new(@http_method, uri, @secret)
|
52
|
+
signer.uri_with_signature.should == "https://api.example.com/core/people.json?_signature=6G4xiABih7FGvjwB1JsYXoeETtBCOdshIu93X1hltzk%3D"
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
context "Validating the signature" do
|
57
|
+
it "returns true for #valid?" do
|
58
|
+
subject.valid?('1AaJvChjz%2BZYJKxWsUQWNK1a%2BeGjpCs6uwQKwPw1%2FV8%3D').should be_true
|
59
|
+
end
|
60
|
+
|
61
|
+
it "returns false for #valid?" do
|
62
|
+
subject.valid?('invalid').should be_false
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
context "Exception handling" do
|
67
|
+
it "raises a UriSigner::MissingHttpMethodError if an empty string is provided" do
|
68
|
+
lambda { described_class.new('', @uri, @secret) }.should raise_error(UriSigner::Errors::MissingHttpMethodError)
|
69
|
+
end
|
70
|
+
|
71
|
+
it "raises a UriSigner::MissingHttpMethodError if nil is provided" do
|
72
|
+
lambda { described_class.new(nil, @uri, @secret) }.should raise_error(UriSigner::Errors::MissingHttpMethodError)
|
73
|
+
end
|
74
|
+
|
75
|
+
it "raises a UriSigner::MissingUriError if an empty string is provided" do
|
76
|
+
lambda { described_class.new(@http_method, '', @secret) }.should raise_error(UriSigner::Errors::MissingUriError)
|
77
|
+
end
|
78
|
+
|
79
|
+
it "raises a UriSigner::MissingUriError if nil is provided" do
|
80
|
+
lambda { described_class.new(@http_method, nil, @secret) }.should raise_error(UriSigner::Errors::MissingUriError)
|
81
|
+
end
|
82
|
+
|
83
|
+
it "raises a UriSigner::MissingSecretError if an empty string is provided" do
|
84
|
+
lambda { described_class.new(@http_method, @uri, '') }.should raise_error(UriSigner::Errors::MissingSecretError)
|
85
|
+
end
|
86
|
+
|
87
|
+
it "raises a UriSigner::MissingSecretError if nil is provided" do
|
88
|
+
lambda { described_class.new(@http_method, @uri, nil) }.should raise_error(UriSigner::Errors::MissingSecretError)
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '../../../lib/uri_signer'))
|
2
|
+
|
3
|
+
describe UriSigner::Helpers::Hash do
|
4
|
+
before(:each) do
|
5
|
+
@hash = { :first => 'element', 'string' => 'element' }
|
6
|
+
@hash.extend(UriSigner::Helpers::Hash)
|
7
|
+
end
|
8
|
+
|
9
|
+
it "converts all keys to strings" do
|
10
|
+
@hash.stringify_keys.keys.should == ["first", "string"]
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '../../../lib/uri_signer'))
|
2
|
+
|
3
|
+
describe UriSigner::Helpers::String do
|
4
|
+
before(:each) do
|
5
|
+
@string = "this is the string"
|
6
|
+
@string.extend(UriSigner::Helpers::String)
|
7
|
+
end
|
8
|
+
|
9
|
+
context "Escaping with Rack::Utils" do
|
10
|
+
subject { "This & That = Your's + Mine"}
|
11
|
+
|
12
|
+
it "escapes the string properly" do
|
13
|
+
subject.extend(UriSigner::Helpers::String).escaped.should == "This+%26+That+%3D+Your%27s+%2B+Mine"
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
context "Unescaping with Rack::Utils" do
|
18
|
+
subject { "This+%26+That+%3D+Your%27s+%2B+Mine" }
|
19
|
+
|
20
|
+
it "unescapes the string properly" do
|
21
|
+
subject.extend(UriSigner::Helpers::String).unescaped.should == "This & That = Your's + Mine"
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
context "Base64 encoding" do
|
26
|
+
subject { "abcd\n" }
|
27
|
+
|
28
|
+
it "base64 encodes the string and removes the newline character at the end" do
|
29
|
+
Base64.stub!(:encode64).and_return("bcdf\n")
|
30
|
+
subject.extend(UriSigner::Helpers::String).base64_encoded.should == "bcdf"
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
context "URI Parsed string" do
|
35
|
+
subject { "https://example.com/core/person.json" }
|
36
|
+
|
37
|
+
it "returns an Addressable parsed URI" do
|
38
|
+
subject.extend(UriSigner::Helpers::String).to_parsed_uri.should be_a_kind_of(Addressable::URI)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '../lib/uri_signer'))
|
2
|
+
|
3
|
+
describe UriSigner::UriSignature do
|
4
|
+
before do
|
5
|
+
@signature_string = "GET&https://test.example.com"
|
6
|
+
@secret = "abcd1234"
|
7
|
+
end
|
8
|
+
|
9
|
+
subject { described_class.new(@signature_string, @secret) }
|
10
|
+
|
11
|
+
it "responds to #signature_string" do
|
12
|
+
subject.should respond_to(:signature_string)
|
13
|
+
end
|
14
|
+
|
15
|
+
it "responds to #signature" do
|
16
|
+
subject.should respond_to(:signature)
|
17
|
+
end
|
18
|
+
|
19
|
+
it "signs the request" do
|
20
|
+
# NOTE: Want to somehow refactor this when looking into the players of signing (String Helpers)
|
21
|
+
subject.signature.should == "KwLgbFRjaoQ8IBQs3xje6uhgyoT6gQR04YQs36lAXmk%3D"
|
22
|
+
end
|
23
|
+
|
24
|
+
context "Validations" do
|
25
|
+
it "raises UriSigner::MissingSignatureStringError when empty string is provided" do
|
26
|
+
lambda { described_class.new('', @secret) }.should raise_error(UriSigner::Errors::MissingSignatureStringError)
|
27
|
+
end
|
28
|
+
|
29
|
+
it "raises UriSigner::MissingSignatureStringError when nil is provided" do
|
30
|
+
lambda { described_class.new(nil, @secret) }.should raise_error(UriSigner::Errors::MissingSignatureStringError)
|
31
|
+
end
|
32
|
+
|
33
|
+
it "raises UriSigner::MissingSecretError when empty string is provided" do
|
34
|
+
lambda { described_class.new(@signature_string, '') }.should raise_error(UriSigner::Errors::MissingSecretError)
|
35
|
+
end
|
36
|
+
|
37
|
+
it "raises UriSigner::MissingSecretError when nil is provided" do
|
38
|
+
lambda { described_class.new(@signature_string, nil) }.should raise_error(UriSigner::Errors::MissingSecretError)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
data/uri_signer.gemspec
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'uri_signer/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "uri_signer"
|
8
|
+
spec.version = UriSigner::VERSION
|
9
|
+
spec.authors = ["Nate Klaiber"]
|
10
|
+
spec.email = ["nklaiber@kissmetrics.com"]
|
11
|
+
spec.description = %q{ Handle the generation of a URI signature for API }
|
12
|
+
spec.summary = %q{ Given a client secret, we can digitally sign the URL and make requests to the API. }
|
13
|
+
spec.homepage = "https://github.com/kissmetrics/uri_signer"
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files`.split($/)
|
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_dependency 'activesupport', ">=3.0.0"
|
22
|
+
spec.add_dependency 'rack'
|
23
|
+
spec.add_dependency 'addressable'
|
24
|
+
spec.add_dependency 'ruby-hmac'
|
25
|
+
|
26
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
27
|
+
spec.add_development_dependency "rake"
|
28
|
+
spec.add_development_dependency 'rspec'
|
29
|
+
spec.add_development_dependency 'yard'
|
30
|
+
spec.add_development_dependency 'redcarpet'
|
31
|
+
end
|
metadata
ADDED
@@ -0,0 +1,237 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: uri_signer
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Nate Klaiber
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-04-12 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: activesupport
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: 3.0.0
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: 3.0.0
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: rack
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
38
|
+
type: :runtime
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: addressable
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ! '>='
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
54
|
+
type: :runtime
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: ruby-hmac
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ! '>='
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0'
|
70
|
+
type: :runtime
|
71
|
+
prerelease: false
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ! '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
78
|
+
- !ruby/object:Gem::Dependency
|
79
|
+
name: bundler
|
80
|
+
requirement: !ruby/object:Gem::Requirement
|
81
|
+
none: false
|
82
|
+
requirements:
|
83
|
+
- - ~>
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: '1.3'
|
86
|
+
type: :development
|
87
|
+
prerelease: false
|
88
|
+
version_requirements: !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
90
|
+
requirements:
|
91
|
+
- - ~>
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '1.3'
|
94
|
+
- !ruby/object:Gem::Dependency
|
95
|
+
name: rake
|
96
|
+
requirement: !ruby/object:Gem::Requirement
|
97
|
+
none: false
|
98
|
+
requirements:
|
99
|
+
- - ! '>='
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
version: '0'
|
102
|
+
type: :development
|
103
|
+
prerelease: false
|
104
|
+
version_requirements: !ruby/object:Gem::Requirement
|
105
|
+
none: false
|
106
|
+
requirements:
|
107
|
+
- - ! '>='
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: '0'
|
110
|
+
- !ruby/object:Gem::Dependency
|
111
|
+
name: rspec
|
112
|
+
requirement: !ruby/object:Gem::Requirement
|
113
|
+
none: false
|
114
|
+
requirements:
|
115
|
+
- - ! '>='
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
none: false
|
122
|
+
requirements:
|
123
|
+
- - ! '>='
|
124
|
+
- !ruby/object:Gem::Version
|
125
|
+
version: '0'
|
126
|
+
- !ruby/object:Gem::Dependency
|
127
|
+
name: yard
|
128
|
+
requirement: !ruby/object:Gem::Requirement
|
129
|
+
none: false
|
130
|
+
requirements:
|
131
|
+
- - ! '>='
|
132
|
+
- !ruby/object:Gem::Version
|
133
|
+
version: '0'
|
134
|
+
type: :development
|
135
|
+
prerelease: false
|
136
|
+
version_requirements: !ruby/object:Gem::Requirement
|
137
|
+
none: false
|
138
|
+
requirements:
|
139
|
+
- - ! '>='
|
140
|
+
- !ruby/object:Gem::Version
|
141
|
+
version: '0'
|
142
|
+
- !ruby/object:Gem::Dependency
|
143
|
+
name: redcarpet
|
144
|
+
requirement: !ruby/object:Gem::Requirement
|
145
|
+
none: false
|
146
|
+
requirements:
|
147
|
+
- - ! '>='
|
148
|
+
- !ruby/object:Gem::Version
|
149
|
+
version: '0'
|
150
|
+
type: :development
|
151
|
+
prerelease: false
|
152
|
+
version_requirements: !ruby/object:Gem::Requirement
|
153
|
+
none: false
|
154
|
+
requirements:
|
155
|
+
- - ! '>='
|
156
|
+
- !ruby/object:Gem::Version
|
157
|
+
version: '0'
|
158
|
+
description: ! ' Handle the generation of a URI signature for API '
|
159
|
+
email:
|
160
|
+
- nklaiber@kissmetrics.com
|
161
|
+
executables: []
|
162
|
+
extensions: []
|
163
|
+
extra_rdoc_files: []
|
164
|
+
files:
|
165
|
+
- .gitignore
|
166
|
+
- .rvmrc.sample
|
167
|
+
- Gemfile
|
168
|
+
- LICENSE.txt
|
169
|
+
- README.md
|
170
|
+
- Rakefile
|
171
|
+
- lib/uri_signer.rb
|
172
|
+
- lib/uri_signer/errors.rb
|
173
|
+
- lib/uri_signer/errors/missing_base_uri_error.rb
|
174
|
+
- lib/uri_signer/errors/missing_http_method_error.rb
|
175
|
+
- lib/uri_signer/errors/missing_query_hash_error.rb
|
176
|
+
- lib/uri_signer/errors/missing_secret_error.rb
|
177
|
+
- lib/uri_signer/errors/missing_signature_string_error.rb
|
178
|
+
- lib/uri_signer/errors/missing_uri_error.rb
|
179
|
+
- lib/uri_signer/helpers.rb
|
180
|
+
- lib/uri_signer/helpers/hash.rb
|
181
|
+
- lib/uri_signer/helpers/string.rb
|
182
|
+
- lib/uri_signer/query_hash_parser.rb
|
183
|
+
- lib/uri_signer/request_parser.rb
|
184
|
+
- lib/uri_signer/request_signature.rb
|
185
|
+
- lib/uri_signer/signer.rb
|
186
|
+
- lib/uri_signer/uri_signature.rb
|
187
|
+
- lib/uri_signer/version.rb
|
188
|
+
- reload_yard
|
189
|
+
- spec/query_hash_parser_spec.rb
|
190
|
+
- spec/request_parser_spec.rb
|
191
|
+
- spec/request_signature_spec.rb
|
192
|
+
- spec/signer_spec.rb
|
193
|
+
- spec/unit/helpers/hash_spec.rb
|
194
|
+
- spec/unit/helpers/string_spec.rb
|
195
|
+
- spec/uri_signature_spec.rb
|
196
|
+
- uri_signer.gemspec
|
197
|
+
homepage: https://github.com/kissmetrics/uri_signer
|
198
|
+
licenses:
|
199
|
+
- MIT
|
200
|
+
post_install_message:
|
201
|
+
rdoc_options: []
|
202
|
+
require_paths:
|
203
|
+
- lib
|
204
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
205
|
+
none: false
|
206
|
+
requirements:
|
207
|
+
- - ! '>='
|
208
|
+
- !ruby/object:Gem::Version
|
209
|
+
version: '0'
|
210
|
+
segments:
|
211
|
+
- 0
|
212
|
+
hash: 538882935789920834
|
213
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
214
|
+
none: false
|
215
|
+
requirements:
|
216
|
+
- - ! '>='
|
217
|
+
- !ruby/object:Gem::Version
|
218
|
+
version: '0'
|
219
|
+
segments:
|
220
|
+
- 0
|
221
|
+
hash: 538882935789920834
|
222
|
+
requirements: []
|
223
|
+
rubyforge_project:
|
224
|
+
rubygems_version: 1.8.25
|
225
|
+
signing_key:
|
226
|
+
specification_version: 3
|
227
|
+
summary: Given a client secret, we can digitally sign the URL and make requests to
|
228
|
+
the API.
|
229
|
+
test_files:
|
230
|
+
- spec/query_hash_parser_spec.rb
|
231
|
+
- spec/request_parser_spec.rb
|
232
|
+
- spec/request_signature_spec.rb
|
233
|
+
- spec/signer_spec.rb
|
234
|
+
- spec/unit/helpers/hash_spec.rb
|
235
|
+
- spec/unit/helpers/string_spec.rb
|
236
|
+
- spec/uri_signature_spec.rb
|
237
|
+
has_rdoc:
|