simple_oauth 0.3.0 → 0.3.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 +4 -4
- data/.rubocop.yml +3 -0
- data/Gemfile +1 -1
- data/lib/simple_oauth/header.rb +5 -1
- data/simple_oauth.gemspec +2 -2
- metadata +3 -7
- data/spec/helper.rb +0 -26
- data/spec/simple_oauth/header_spec.rb +0 -385
- data/spec/support/fixtures/rsa-private-key +0 -16
- data/spec/support/rsa.rb +0 -11
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e33b22e5f3c253796236a61dda5f130f2943c4e2
|
4
|
+
data.tar.gz: 070a415e6824f5e370668c3253c3431480a216b2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e861d3e040c487c501e1c422a9120be8fe51fefad5162956f686d4457fc602bf35f91ea7f2e5633cd18c94f0a039e10b3ffb578d253ff45d76f83d67bb02b85c
|
7
|
+
data.tar.gz: c4bd1d327734ab9b88d754ada4ce5b2f534a5db640c1f6126941910fe6877c90b39a52d218cd09fc1d77a94a2ddd47b16a60b49f744a537529ee430f72e4b764
|
data/.rubocop.yml
CHANGED
data/Gemfile
CHANGED
@@ -9,7 +9,7 @@ group :test do
|
|
9
9
|
gem 'mime-types', '~> 1.25', :platforms => [:jruby, :ruby_18]
|
10
10
|
gem 'rest-client', '~> 1.6.0', :platforms => [:jruby, :ruby_18]
|
11
11
|
gem 'rspec', '>= 2.14'
|
12
|
-
gem 'rubocop', '>= 0.
|
12
|
+
gem 'rubocop', '>= 0.28', :platforms => [:ruby_19, :ruby_20, :ruby_21]
|
13
13
|
gem 'simplecov', '>= 0.9'
|
14
14
|
gem 'yardstick'
|
15
15
|
end
|
data/lib/simple_oauth/header.rb
CHANGED
@@ -6,6 +6,9 @@ require 'cgi'
|
|
6
6
|
module SimpleOAuth
|
7
7
|
class Header
|
8
8
|
ATTRIBUTE_KEYS = [:callback, :consumer_key, :nonce, :signature_method, :timestamp, :token, :verifier, :version] unless defined? ::SimpleOAuth::Header::ATTRIBUTE_KEYS
|
9
|
+
|
10
|
+
IGNORED_KEYS = [:consumer_secret, :token_secret, :signature] unless defined? ::SimpleOAuth::Header::IGNORED_KEYS
|
11
|
+
|
9
12
|
attr_reader :method, :params, :options
|
10
13
|
|
11
14
|
class << self
|
@@ -82,8 +85,9 @@ module SimpleOAuth
|
|
82
85
|
|
83
86
|
def attributes
|
84
87
|
matching_keys, extra_keys = options.keys.partition { |key| ATTRIBUTE_KEYS.include?(key) }
|
88
|
+
extra_keys -= IGNORED_KEYS
|
85
89
|
if options[:ignore_extra_keys] || extra_keys.empty?
|
86
|
-
Hash[options.select { |key,
|
90
|
+
Hash[options.select { |key, _| matching_keys.include?(key) }.collect { |key, value| [:"oauth_#{key}", value] }]
|
87
91
|
else
|
88
92
|
fail "SimpleOAuth: Found extra option keys not matching ATTRIBUTE_KEYS:\n [#{extra_keys.collect(&:inspect).join(', ')}]"
|
89
93
|
end
|
data/simple_oauth.gemspec
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
Gem::Specification.new do |spec|
|
2
2
|
spec.add_development_dependency 'bundler', '~> 1.0'
|
3
3
|
spec.name = 'simple_oauth'
|
4
|
-
spec.version = '0.3.
|
4
|
+
spec.version = '0.3.1'
|
5
5
|
|
6
6
|
spec.authors = ['Steve Richert', 'Erik Michaels-Ober']
|
7
7
|
spec.email = %w(steve.richert@gmail.com sferik@gmail.com)
|
@@ -10,6 +10,6 @@ Gem::Specification.new do |spec|
|
|
10
10
|
spec.homepage = 'https://github.com/laserlemon/simple_oauth'
|
11
11
|
spec.licenses = %w(MIT)
|
12
12
|
|
13
|
-
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.start_with?('
|
13
|
+
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.start_with?('spec/') }
|
14
14
|
spec.require_paths = %w(lib)
|
15
15
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: simple_oauth
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Steve Richert
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2014-
|
12
|
+
date: 2014-12-28 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: bundler
|
@@ -46,10 +46,6 @@ files:
|
|
46
46
|
- lib/simple_oauth.rb
|
47
47
|
- lib/simple_oauth/header.rb
|
48
48
|
- simple_oauth.gemspec
|
49
|
-
- spec/helper.rb
|
50
|
-
- spec/simple_oauth/header_spec.rb
|
51
|
-
- spec/support/fixtures/rsa-private-key
|
52
|
-
- spec/support/rsa.rb
|
53
49
|
homepage: https://github.com/laserlemon/simple_oauth
|
54
50
|
licenses:
|
55
51
|
- MIT
|
@@ -70,7 +66,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
70
66
|
version: '0'
|
71
67
|
requirements: []
|
72
68
|
rubyforge_project:
|
73
|
-
rubygems_version: 2.4.
|
69
|
+
rubygems_version: 2.4.5
|
74
70
|
signing_key:
|
75
71
|
specification_version: 4
|
76
72
|
summary: Simply builds and verifies OAuth headers
|
data/spec/helper.rb
DELETED
@@ -1,26 +0,0 @@
|
|
1
|
-
if RUBY_VERSION >= '1.9'
|
2
|
-
require 'simplecov'
|
3
|
-
require 'coveralls'
|
4
|
-
|
5
|
-
SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[SimpleCov::Formatter::HTMLFormatter, Coveralls::SimpleCov::Formatter]
|
6
|
-
|
7
|
-
SimpleCov.start do
|
8
|
-
add_filter '/spec/'
|
9
|
-
minimum_coverage(100)
|
10
|
-
end
|
11
|
-
end
|
12
|
-
|
13
|
-
require 'simple_oauth'
|
14
|
-
require 'rspec'
|
15
|
-
|
16
|
-
def uri_parser
|
17
|
-
@uri_parser ||= URI.const_defined?(:Parser) ? URI::Parser.new : URI
|
18
|
-
end
|
19
|
-
|
20
|
-
RSpec.configure do |config|
|
21
|
-
config.expect_with :rspec do |c|
|
22
|
-
c.syntax = :expect
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
Dir[File.expand_path('../support/**/*.rb', __FILE__)].each { |f| require f }
|
@@ -1,385 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
require 'helper'
|
4
|
-
|
5
|
-
describe SimpleOAuth::Header do
|
6
|
-
describe '.default_options' do
|
7
|
-
let(:default_options) { SimpleOAuth::Header.default_options }
|
8
|
-
|
9
|
-
it 'is different every time' do
|
10
|
-
expect(SimpleOAuth::Header.default_options).not_to eq default_options
|
11
|
-
end
|
12
|
-
|
13
|
-
it 'is used for new headers' do
|
14
|
-
allow(SimpleOAuth::Header).to receive(:default_options).and_return(default_options)
|
15
|
-
header = SimpleOAuth::Header.new(:get, 'https://api.twitter.com/1/statuses/friendships.json', {})
|
16
|
-
expect(header.options).to eq default_options
|
17
|
-
end
|
18
|
-
|
19
|
-
it 'includes a signature method and an OAuth version' do
|
20
|
-
expect(default_options[:signature_method]).not_to be_nil
|
21
|
-
expect(default_options[:version]).not_to be_nil
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
|
-
describe '.escape' do
|
26
|
-
it 'escapes (most) non-word characters' do
|
27
|
-
[' ', '!', '@', '#', '$', '%', '^', '&'].each do |character|
|
28
|
-
escaped = SimpleOAuth::Header.escape(character)
|
29
|
-
expect(escaped).not_to eq character
|
30
|
-
expect(escaped).to eq uri_parser.escape(character, /.*/)
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
|
-
it 'does not escape - . or ~' do
|
35
|
-
['-', '.', '~'].each do |character|
|
36
|
-
escaped = SimpleOAuth::Header.escape(character)
|
37
|
-
expect(escaped).to eq character
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
def self.test_special_characters
|
42
|
-
it 'escapes non-ASCII characters' do
|
43
|
-
expect(SimpleOAuth::Header.escape('é')).to eq '%C3%A9'
|
44
|
-
end
|
45
|
-
|
46
|
-
it 'escapes multibyte characters' do
|
47
|
-
expect(SimpleOAuth::Header.escape('あ')).to eq '%E3%81%82'
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
|
-
if RUBY_VERSION >= '1.9'
|
52
|
-
test_special_characters
|
53
|
-
else
|
54
|
-
%w(n N e E s S u U).each do |kcode|
|
55
|
-
describe %(when $KCODE = "#{kcode}") do
|
56
|
-
original_kcode = $KCODE # rubocop:disable GlobalVars
|
57
|
-
begin
|
58
|
-
$KCODE = kcode # rubocop:disable GlobalVars
|
59
|
-
test_special_characters
|
60
|
-
ensure
|
61
|
-
$KCODE = original_kcode # rubocop:disable GlobalVars
|
62
|
-
end
|
63
|
-
end
|
64
|
-
end
|
65
|
-
end
|
66
|
-
end
|
67
|
-
|
68
|
-
describe '.unescape' do
|
69
|
-
pending
|
70
|
-
end
|
71
|
-
|
72
|
-
describe '.parse' do
|
73
|
-
let(:header) { SimpleOAuth::Header.new(:get, 'https://api.twitter.com/1/statuses/friends.json', {}) }
|
74
|
-
let(:parsed_options) { SimpleOAuth::Header.parse(header) }
|
75
|
-
|
76
|
-
it 'returns a hash' do
|
77
|
-
expect(parsed_options).to be_a(Hash)
|
78
|
-
end
|
79
|
-
|
80
|
-
it 'includes the options used to build the header' do
|
81
|
-
expect(parsed_options.reject { |k, _| k == :signature }).to eq header.options
|
82
|
-
end
|
83
|
-
|
84
|
-
it 'includes a signature' do
|
85
|
-
expect(header.options).not_to have_key(:signature)
|
86
|
-
expect(parsed_options).to have_key(:signature)
|
87
|
-
expect(parsed_options[:signature]).not_to be_nil
|
88
|
-
end
|
89
|
-
|
90
|
-
it "handles optional 'linear white space'" do
|
91
|
-
parsed_header_with_spaces = SimpleOAuth::Header.parse 'OAuth oauth_consumer_key="abcd", oauth_nonce="oLKtec51GQy", oauth_signature="efgh%26mnop", oauth_signature_method="PLAINTEXT", oauth_timestamp="1286977095", oauth_token="ijkl", oauth_version="1.0"'
|
92
|
-
expect(parsed_header_with_spaces).to be_a_kind_of(Hash)
|
93
|
-
expect(parsed_header_with_spaces.keys.size).to eq 7
|
94
|
-
|
95
|
-
parsed_header_with_tabs = SimpleOAuth::Header.parse 'OAuth oauth_consumer_key="abcd", oauth_nonce="oLKtec51GQy", oauth_signature="efgh%26mnop", oauth_signature_method="PLAINTEXT", oauth_timestamp="1286977095", oauth_token="ijkl", oauth_version="1.0"'
|
96
|
-
expect(parsed_header_with_tabs).to be_a_kind_of(Hash)
|
97
|
-
expect(parsed_header_with_tabs.keys.size).to eq 7
|
98
|
-
|
99
|
-
parsed_header_with_spaces_and_tabs = SimpleOAuth::Header.parse 'OAuth oauth_consumer_key="abcd", oauth_nonce="oLKtec51GQy", oauth_signature="efgh%26mnop", oauth_signature_method="PLAINTEXT", oauth_timestamp="1286977095", oauth_token="ijkl", oauth_version="1.0"'
|
100
|
-
expect(parsed_header_with_spaces_and_tabs).to be_a_kind_of(Hash)
|
101
|
-
expect(parsed_header_with_spaces_and_tabs.keys.size).to eq 7
|
102
|
-
|
103
|
-
parsed_header_without_spaces = SimpleOAuth::Header.parse 'OAuth oauth_consumer_key="abcd",oauth_nonce="oLKtec51GQy",oauth_signature="efgh%26mnop",oauth_signature_method="PLAINTEXT",oauth_timestamp="1286977095",oauth_token="ijkl",oauth_version="1.0"'
|
104
|
-
expect(parsed_header_without_spaces).to be_a_kind_of(Hash)
|
105
|
-
expect(parsed_header_without_spaces.keys.size).to eq 7
|
106
|
-
end
|
107
|
-
end
|
108
|
-
|
109
|
-
describe '#initialize' do
|
110
|
-
let(:header) { SimpleOAuth::Header.new(:get, 'HTTPS://api.TWITTER.com:443/1/statuses/friendships.json?foo=bar#anchor', {}) }
|
111
|
-
|
112
|
-
it 'stringifies and uppercases the request method' do
|
113
|
-
expect(header.method).to eq 'GET'
|
114
|
-
end
|
115
|
-
|
116
|
-
it 'downcases the scheme and authority' do
|
117
|
-
expect(header.url).to match %r{^https://api\.twitter\.com/}
|
118
|
-
end
|
119
|
-
|
120
|
-
it 'ignores the query and fragment' do
|
121
|
-
expect(header.url).to match %r{/1/statuses/friendships\.json$}
|
122
|
-
end
|
123
|
-
end
|
124
|
-
|
125
|
-
describe '#valid?' do
|
126
|
-
context 'using the HMAC-SHA1 signature method' do
|
127
|
-
it 'requires consumer and token secrets' do
|
128
|
-
secrets = {:consumer_secret => 'CONSUMER_SECRET', :token_secret => 'TOKEN_SECRET', :ignore_extra_keys => true}
|
129
|
-
header = SimpleOAuth::Header.new(:get, 'https://api.twitter.com/1/statuses/friends.json', {}, secrets)
|
130
|
-
parsed_header = SimpleOAuth::Header.new(:get, 'https://api.twitter.com/1/statuses/friends.json', {}, header)
|
131
|
-
parsed_header.options[:ignore_extra_keys] = true
|
132
|
-
expect(parsed_header).not_to be_valid
|
133
|
-
expect(parsed_header).to be_valid(secrets)
|
134
|
-
end
|
135
|
-
end
|
136
|
-
|
137
|
-
context 'using the RSA-SHA1 signature method' do
|
138
|
-
it 'requires an identical private key' do
|
139
|
-
secrets = {:consumer_secret => rsa_private_key, :ignore_extra_keys => true}
|
140
|
-
header = SimpleOAuth::Header.new(:get, 'https://api.twitter.com/1/statuses/friends.json', {}, secrets.merge(:signature_method => 'RSA-SHA1'))
|
141
|
-
parsed_header = SimpleOAuth::Header.new(:get, 'https://api.twitter.com/1/statuses/friends.json', {}, header)
|
142
|
-
expect { parsed_header.valid? }.to raise_error(TypeError)
|
143
|
-
expect(parsed_header).to be_valid(secrets)
|
144
|
-
end
|
145
|
-
end
|
146
|
-
|
147
|
-
context 'using the RSA-SHA1 signature method' do
|
148
|
-
it 'requires consumer and token secrets' do
|
149
|
-
secrets = {:consumer_secret => 'CONSUMER_SECRET', :token_secret => 'TOKEN_SECRET', :ignore_extra_keys => true}
|
150
|
-
header = SimpleOAuth::Header.new(:get, 'https://api.twitter.com/1/statuses/friends.json', {}, secrets.merge(:signature_method => 'PLAINTEXT'))
|
151
|
-
parsed_header = SimpleOAuth::Header.new(:get, 'https://api.twitter.com/1/statuses/friends.json', {}, header)
|
152
|
-
expect(parsed_header).not_to be_valid
|
153
|
-
expect(parsed_header).to be_valid(secrets)
|
154
|
-
end
|
155
|
-
end
|
156
|
-
end
|
157
|
-
|
158
|
-
describe '#normalized_attributes' do
|
159
|
-
let(:header) { SimpleOAuth::Header.new(:get, 'https://api.twitter.com/1/statuses/friends.json', {}) }
|
160
|
-
let(:normalized_attributes) { header.send(:normalized_attributes) }
|
161
|
-
|
162
|
-
it 'returns a sorted-key, quoted-value and comma-separated list' do
|
163
|
-
allow(header).to receive(:signed_attributes).and_return(:d => 1, :c => 2, :b => 3, :a => 4)
|
164
|
-
expect(normalized_attributes).to eq 'a="4", b="3", c="2", d="1"'
|
165
|
-
end
|
166
|
-
|
167
|
-
it 'URI encodes its values' do
|
168
|
-
allow(header).to receive(:signed_attributes).and_return(1 => '!', 2 => '@', 3 => '#', 4 => '$')
|
169
|
-
expect(normalized_attributes).to eq '1="%21", 2="%40", 3="%23", 4="%24"'
|
170
|
-
end
|
171
|
-
end
|
172
|
-
|
173
|
-
describe '#signed_attributes' do
|
174
|
-
it 'includes the OAuth signature' do
|
175
|
-
header = SimpleOAuth::Header.new(:get, 'https://api.twitter.com/1/statuses/friends.json', {})
|
176
|
-
expect(header.send(:signed_attributes)).to have_key(:oauth_signature)
|
177
|
-
end
|
178
|
-
end
|
179
|
-
|
180
|
-
describe '#attributes' do
|
181
|
-
let(:header) do
|
182
|
-
options = {}
|
183
|
-
SimpleOAuth::Header::ATTRIBUTE_KEYS.each { |k| options[k] = k.to_s.upcase }
|
184
|
-
options[:other] = 'OTHER'
|
185
|
-
SimpleOAuth::Header.new(:get, 'https://api.twitter.com/1/statuses/friendships.json', {}, options)
|
186
|
-
end
|
187
|
-
|
188
|
-
it "prepends keys with 'oauth_'" do
|
189
|
-
header.options[:ignore_extra_keys] = true
|
190
|
-
expect(header.send(:attributes).keys).to be_all { |k| k.to_s =~ /^oauth_/ }
|
191
|
-
end
|
192
|
-
|
193
|
-
it 'excludes keys not included in the list of valid attributes' do
|
194
|
-
header.options[:ignore_extra_keys] = true
|
195
|
-
expect(header.send(:attributes).keys).to be_all { |k| k.is_a?(Symbol) }
|
196
|
-
expect(header.send(:attributes)).not_to have_key(:oauth_other)
|
197
|
-
end
|
198
|
-
|
199
|
-
it 'preserves values for valid keys' do
|
200
|
-
header.options[:ignore_extra_keys] = true
|
201
|
-
expect(header.send(:attributes).size).to eq SimpleOAuth::Header::ATTRIBUTE_KEYS.size
|
202
|
-
expect(header.send(:attributes)).to be_all { |k, v| k.to_s == "oauth_#{v.downcase}" }
|
203
|
-
end
|
204
|
-
|
205
|
-
it 'raises exception for extra keys' do
|
206
|
-
expect { header.send(:attributes) }.to raise_error(RuntimeError, "SimpleOAuth: Found extra option keys not matching ATTRIBUTE_KEYS:\n [:other]")
|
207
|
-
end
|
208
|
-
end
|
209
|
-
|
210
|
-
describe '#signature' do
|
211
|
-
context 'calls the appropriate signature method' do
|
212
|
-
specify 'when using HMAC-SHA1' do
|
213
|
-
header = SimpleOAuth::Header.new(:get, 'https://api.twitter.com/1/statuses/friends.json', {}, :signature_method => 'HMAC-SHA1')
|
214
|
-
expect(header).to receive(:hmac_sha1_signature).once.and_return('HMAC_SHA1_SIGNATURE')
|
215
|
-
expect(header.send(:signature)).to eq 'HMAC_SHA1_SIGNATURE'
|
216
|
-
end
|
217
|
-
|
218
|
-
specify 'when using RSA-SHA1' do
|
219
|
-
header = SimpleOAuth::Header.new(:get, 'https://api.twitter.com/1/statuses/friends.json', {}, :signature_method => 'RSA-SHA1')
|
220
|
-
expect(header).to receive(:rsa_sha1_signature).once.and_return('RSA_SHA1_SIGNATURE')
|
221
|
-
expect(header.send(:signature)).to eq 'RSA_SHA1_SIGNATURE'
|
222
|
-
end
|
223
|
-
|
224
|
-
specify 'when using PLAINTEXT' do
|
225
|
-
header = SimpleOAuth::Header.new(:get, 'https://api.twitter.com/1/statuses/friends.json', {}, :signature_method => 'PLAINTEXT')
|
226
|
-
expect(header).to receive(:plaintext_signature).once.and_return('PLAINTEXT_SIGNATURE')
|
227
|
-
expect(header.send(:signature)).to eq 'PLAINTEXT_SIGNATURE'
|
228
|
-
end
|
229
|
-
end
|
230
|
-
end
|
231
|
-
|
232
|
-
describe '#hmac_sha1_signature' do
|
233
|
-
it 'reproduces a successful Twitter GET' do
|
234
|
-
options = {
|
235
|
-
:consumer_key => '8karQBlMg6gFOwcf8kcoYw',
|
236
|
-
:consumer_secret => '3d0vcHyUiiqADpWxolW8nlDIpSWMlyK7YNgc5Qna2M',
|
237
|
-
:nonce => '547fed103e122eecf84c080843eedfe6',
|
238
|
-
:signature_method => 'HMAC-SHA1',
|
239
|
-
:timestamp => '1286830180',
|
240
|
-
:token => '201425800-Sv4sTcgoffmHGkTCue0JnURT8vrm4DiFAkeFNDkh',
|
241
|
-
:token_secret => 'T5qa1tF57tfDzKmpM89DHsNuhgOY4NT6DlNLsTFcuQ',
|
242
|
-
:ignore_extra_keys => true,
|
243
|
-
}
|
244
|
-
header = SimpleOAuth::Header.new(:get, 'https://api.twitter.com/1/statuses/friends.json', {}, options)
|
245
|
-
expect(header.to_s).to eq 'OAuth oauth_consumer_key="8karQBlMg6gFOwcf8kcoYw", oauth_nonce="547fed103e122eecf84c080843eedfe6", oauth_signature="i9CT6ahDRAlfGX3hKYf78QzXsaw%3D", oauth_signature_method="HMAC-SHA1", oauth_timestamp="1286830180", oauth_token="201425800-Sv4sTcgoffmHGkTCue0JnURT8vrm4DiFAkeFNDkh", oauth_version="1.0"'
|
246
|
-
end
|
247
|
-
|
248
|
-
it 'reproduces a successful Twitter POST' do
|
249
|
-
options = {
|
250
|
-
:consumer_key => '8karQBlMg6gFOwcf8kcoYw',
|
251
|
-
:consumer_secret => '3d0vcHyUiiqADpWxolW8nlDIpSWMlyK7YNgc5Qna2M',
|
252
|
-
:nonce => 'b40a3e0f18590ecdcc0e273f7d7c82f8',
|
253
|
-
:signature_method => 'HMAC-SHA1',
|
254
|
-
:timestamp => '1286830181',
|
255
|
-
:token => '201425800-Sv4sTcgoffmHGkTCue0JnURT8vrm4DiFAkeFNDkh',
|
256
|
-
:token_secret => 'T5qa1tF57tfDzKmpM89DHsNuhgOY4NT6DlNLsTFcuQ',
|
257
|
-
:ignore_extra_keys => true,
|
258
|
-
}
|
259
|
-
header = SimpleOAuth::Header.new(:post, 'https://api.twitter.com/1/statuses/update.json', {:status => 'hi, again'}, options)
|
260
|
-
expect(header.to_s).to eq 'OAuth oauth_consumer_key="8karQBlMg6gFOwcf8kcoYw", oauth_nonce="b40a3e0f18590ecdcc0e273f7d7c82f8", oauth_signature="mPqSFKejrWWk3ZT9bTQjhO5b2xI%3D", oauth_signature_method="HMAC-SHA1", oauth_timestamp="1286830181", oauth_token="201425800-Sv4sTcgoffmHGkTCue0JnURT8vrm4DiFAkeFNDkh", oauth_version="1.0"'
|
261
|
-
end
|
262
|
-
end
|
263
|
-
|
264
|
-
describe '#secret' do
|
265
|
-
let(:header) { SimpleOAuth::Header.new(:get, 'https://api.twitter.com/1/statuses/friendships.json', {}) }
|
266
|
-
let(:secret) { header.send(:secret) }
|
267
|
-
|
268
|
-
it 'combines the consumer and token secrets with an ampersand' do
|
269
|
-
allow(header).to receive(:options).and_return(:consumer_secret => 'CONSUMER_SECRET', :token_secret => 'TOKEN_SECRET')
|
270
|
-
expect(secret).to eq 'CONSUMER_SECRET&TOKEN_SECRET'
|
271
|
-
end
|
272
|
-
|
273
|
-
it 'URI encodes each secret value before combination' do
|
274
|
-
allow(header).to receive(:options).and_return(:consumer_secret => 'CONSUM#R_SECRET', :token_secret => 'TOKEN_S#CRET')
|
275
|
-
expect(secret).to eq 'CONSUM%23R_SECRET&TOKEN_S%23CRET'
|
276
|
-
end
|
277
|
-
end
|
278
|
-
|
279
|
-
describe '#signature_base' do
|
280
|
-
let(:header) { SimpleOAuth::Header.new(:get, 'https://api.twitter.com/1/statuses/friendships.json', {}) }
|
281
|
-
let(:signature_base) { header.send(:signature_base) }
|
282
|
-
|
283
|
-
it 'combines the request method, URL and normalized parameters using ampersands' do
|
284
|
-
allow(header).to receive(:method).and_return('METHOD')
|
285
|
-
allow(header).to receive(:url).and_return('URL')
|
286
|
-
allow(header).to receive(:normalized_params).and_return('NORMALIZED_PARAMS')
|
287
|
-
expect(signature_base).to eq 'METHOD&URL&NORMALIZED_PARAMS'
|
288
|
-
end
|
289
|
-
|
290
|
-
it 'URI encodes each value before combination' do
|
291
|
-
allow(header).to receive(:method).and_return('ME#HOD')
|
292
|
-
allow(header).to receive(:url).and_return('U#L')
|
293
|
-
allow(header).to receive(:normalized_params).and_return('NORMAL#ZED_PARAMS')
|
294
|
-
expect(signature_base).to eq 'ME%23HOD&U%23L&NORMAL%23ZED_PARAMS'
|
295
|
-
end
|
296
|
-
end
|
297
|
-
|
298
|
-
describe '#normalized_params' do
|
299
|
-
let(:header) do
|
300
|
-
header = SimpleOAuth::Header.new(:get, 'https://api.twitter.com/1/statuses/friendships.json', {})
|
301
|
-
allow(header).to receive(:signature_params).and_return([%w(A 4), %w(B 3), %w(B 2), %w(C 1), ['D[]', '0 ']])
|
302
|
-
header
|
303
|
-
end
|
304
|
-
let(:signature_params) { header.send(:signature_params) }
|
305
|
-
let(:normalized_params) { header.send(:normalized_params) }
|
306
|
-
|
307
|
-
it 'joins key/value pairs with equal signs and ampersands' do
|
308
|
-
expect(normalized_params).to be_a(String)
|
309
|
-
parts = normalized_params.split('&')
|
310
|
-
expect(parts.size).to eq signature_params.size
|
311
|
-
pairs = parts.collect { |p| p.split('=') }
|
312
|
-
expect(pairs).to be_all { |p| p.size == 2 }
|
313
|
-
end
|
314
|
-
end
|
315
|
-
|
316
|
-
describe '#signature_params' do
|
317
|
-
let(:header) { SimpleOAuth::Header.new(:get, 'https://api.twitter.com/1/statuses/friendships.json', {}) }
|
318
|
-
let(:signature_params) { header.send(:signature_params) }
|
319
|
-
|
320
|
-
it 'combines OAuth header attributes, body parameters and URL parameters into an flattened array of key/value pairs' do
|
321
|
-
allow(header).to receive(:attributes).and_return(:attribute => 'ATTRIBUTE')
|
322
|
-
allow(header).to receive(:params).and_return('param' => 'PARAM')
|
323
|
-
allow(header).to receive(:url_params).and_return([%w(url_param 1), %w(url_param 2)])
|
324
|
-
expect(signature_params).to eq [
|
325
|
-
[:attribute, 'ATTRIBUTE'],
|
326
|
-
%w(param PARAM),
|
327
|
-
%w(url_param 1),
|
328
|
-
%w(url_param 2),
|
329
|
-
]
|
330
|
-
end
|
331
|
-
end
|
332
|
-
|
333
|
-
describe '#url_params' do
|
334
|
-
it 'returns an empty array when the URL has no query parameters' do
|
335
|
-
header = SimpleOAuth::Header.new(:get, 'https://api.twitter.com/1/statuses/friendships.json', {})
|
336
|
-
expect(header.send(:url_params)).to eq []
|
337
|
-
end
|
338
|
-
|
339
|
-
it 'returns an array of key/value pairs for each query parameter' do
|
340
|
-
header = SimpleOAuth::Header.new(:get, 'https://api.twitter.com/1/statuses/friendships.json?test=TEST', {})
|
341
|
-
expect(header.send(:url_params)).to eq [%w(test TEST)]
|
342
|
-
end
|
343
|
-
|
344
|
-
it 'sorts values for repeated keys' do
|
345
|
-
header = SimpleOAuth::Header.new(:get, 'https://api.twitter.com/1/statuses/friendships.json?test=3&test=1&test=2', {})
|
346
|
-
expect(header.send(:url_params)).to eq [%w(test 1), %w(test 2), %w(test 3)]
|
347
|
-
end
|
348
|
-
end
|
349
|
-
|
350
|
-
describe '#rsa_sha1_signature' do
|
351
|
-
it 'reproduces a successful OAuth example GET' do
|
352
|
-
options = {
|
353
|
-
:consumer_key => 'dpf43f3p2l4k3l03',
|
354
|
-
:consumer_secret => rsa_private_key,
|
355
|
-
:nonce => '13917289812797014437',
|
356
|
-
:signature_method => 'RSA-SHA1',
|
357
|
-
:timestamp => '1196666512',
|
358
|
-
:ignore_extra_keys => true,
|
359
|
-
}
|
360
|
-
header = SimpleOAuth::Header.new(:get, 'http://photos.example.net/photos', {:file => 'vacaction.jpg', :size => 'original'}, options)
|
361
|
-
expect(header.to_s).to eq 'OAuth oauth_consumer_key="dpf43f3p2l4k3l03", oauth_nonce="13917289812797014437", oauth_signature="jvTp%2FwX1TYtByB1m%2BPbyo0lnCOLIsyGCH7wke8AUs3BpnwZJtAuEJkvQL2%2F9n4s5wUmUl4aCI4BwpraNx4RtEXMe5qg5T1LVTGliMRpKasKsW%2F%2Fe%2BRinhejgCuzoH26dyF8iY2ZZ%2F5D1ilgeijhV%2FvBka5twt399mXwaYdCwFYE%3D", oauth_signature_method="RSA-SHA1", oauth_timestamp="1196666512", oauth_version="1.0"'
|
362
|
-
end
|
363
|
-
end
|
364
|
-
|
365
|
-
describe '#private_key' do
|
366
|
-
pending
|
367
|
-
end
|
368
|
-
|
369
|
-
describe '#plaintext_signature' do
|
370
|
-
it 'reproduces a successful OAuth example GET' do
|
371
|
-
options = {
|
372
|
-
:consumer_key => 'abcd',
|
373
|
-
:consumer_secret => 'efgh',
|
374
|
-
:nonce => 'oLKtec51GQy',
|
375
|
-
:signature_method => 'PLAINTEXT',
|
376
|
-
:timestamp => '1286977095',
|
377
|
-
:token => 'ijkl',
|
378
|
-
:token_secret => 'mnop',
|
379
|
-
:ignore_extra_keys => true,
|
380
|
-
}
|
381
|
-
header = SimpleOAuth::Header.new(:get, 'http://host.net/resource?name=value', {:name => 'value'}, options)
|
382
|
-
expect(header.to_s).to eq 'OAuth oauth_consumer_key="abcd", oauth_nonce="oLKtec51GQy", oauth_signature="efgh%26mnop", oauth_signature_method="PLAINTEXT", oauth_timestamp="1286977095", oauth_token="ijkl", oauth_version="1.0"'
|
383
|
-
end
|
384
|
-
end
|
385
|
-
end
|
@@ -1,16 +0,0 @@
|
|
1
|
-
-----BEGIN PRIVATE KEY-----
|
2
|
-
MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBALRiMLAh9iimur8V
|
3
|
-
A7qVvdqxevEuUkW4K+2KdMXmnQbG9Aa7k7eBjK1S+0LYmVjPKlJGNXHDGuy5Fw/d
|
4
|
-
7rjVJ0BLB+ubPK8iA/Tw3hLQgXMRRGRXXCn8ikfuQfjUS1uZSatdLB81mydBETlJ
|
5
|
-
hI6GH4twrbDJCR2Bwy/XWXgqgGRzAgMBAAECgYBYWVtleUzavkbrPjy0T5FMou8H
|
6
|
-
X9u2AC2ry8vD/l7cqedtwMPp9k7TubgNFo+NGvKsl2ynyprOZR1xjQ7WgrgVB+mm
|
7
|
-
uScOM/5HVceFuGRDhYTCObE+y1kxRloNYXnx3ei1zbeYLPCHdhxRYW7T0qcynNmw
|
8
|
-
rn05/KO2RLjgQNalsQJBANeA3Q4Nugqy4QBUCEC09SqylT2K9FrrItqL2QKc9v0Z
|
9
|
-
zO2uwllCbg0dwpVuYPYXYvikNHHg+aCWF+VXsb9rpPsCQQDWR9TT4ORdzoj+Nccn
|
10
|
-
qkMsDmzt0EfNaAOwHOmVJ2RVBspPcxt5iN4HI7HNeG6U5YsFBb+/GZbgfBT3kpNG
|
11
|
-
WPTpAkBI+gFhjfJvRw38n3g/+UeAkwMI2TJQS4n8+hid0uus3/zOjDySH3XHCUno
|
12
|
-
cn1xOJAyZODBo47E+67R4jV1/gzbAkEAklJaspRPXP877NssM5nAZMU0/O/NGCZ+
|
13
|
-
3jPgDUno6WbJn5cqm8MqWhW1xGkImgRk+fkDBquiq4gPiT898jusgQJAd5Zrr6Q8
|
14
|
-
AO/0isr/3aa6O6NLQxISLKcPDk2NOccAfS/xOtfOz4sJYM3+Bs4Io9+dZGSDCA54
|
15
|
-
Lw03eHTNQghS0A==
|
16
|
-
-----END PRIVATE KEY-----
|
data/spec/support/rsa.rb
DELETED