simple_oauth 0.2.0 → 0.3.0

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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 3094ba98c7ac1b573727f0c7e1e420d6a2f4d8fc
4
+ data.tar.gz: 8653e61a74dd4ae0622100fa275627ac3f40c4ca
5
+ SHA512:
6
+ metadata.gz: 761b9e2cba618d77b811dcf1441e357cf7e0dac191ba138f2ecfd2949373ec4772f99aeb3eb8d087810bb21b8f29562b4fbc6c814bad3068632cd35b2671efd4
7
+ data.tar.gz: 112cb20fc8bf10a1fcec15fd3a40e248c05c897d21668ba31a87b4deac57c682b93ef37c253d43208e02da031c8c858b4d01d7105b6b42c5750274768fe4de5e
data/.gitignore CHANGED
@@ -1,9 +1,10 @@
1
1
  *.rbc
2
- .bundle
3
2
  .DS_Store
3
+ .bundle
4
4
  .yardoc
5
+ Gemfile.lock
5
6
  coverage
6
7
  doc
7
- Gemfile.lock
8
+ measurement
8
9
  pkg
9
10
  rdoc
data/.rspec CHANGED
@@ -1,3 +1,2 @@
1
1
  --color
2
- --fail-fast
3
2
  --order random
@@ -0,0 +1,54 @@
1
+ Metrics/BlockNesting:
2
+ Max: 1
3
+
4
+ Metrics/LineLength:
5
+ AllowURI: true
6
+ Enabled: false
7
+
8
+ Metrics/MethodLength:
9
+ CountComments: false
10
+ Max: 7
11
+
12
+ Metrics/ParameterLists:
13
+ Max: 4
14
+ CountKeywordArgs: true
15
+
16
+ Style/AccessModifierIndentation:
17
+ EnforcedStyle: outdent
18
+
19
+ Style/CollectionMethods:
20
+ PreferredMethods:
21
+ map: 'collect'
22
+ reduce: 'inject'
23
+ find: 'detect'
24
+ find_all: 'select'
25
+
26
+ Style/Documentation:
27
+ Enabled: false
28
+
29
+ Style/DotPosition:
30
+ EnforcedStyle: trailing
31
+
32
+ Style/DoubleNegation:
33
+ Enabled: false
34
+
35
+ Style/EachWithObject:
36
+ Enabled: false
37
+
38
+ Style/Encoding:
39
+ Enabled: false
40
+
41
+ Style/HashSyntax:
42
+ EnforcedStyle: hash_rockets
43
+
44
+ Style/Lambda:
45
+ Enabled: false
46
+
47
+ Style/RaiseArgs:
48
+ EnforcedStyle: compact
49
+
50
+ Style/SpaceInsideHashLiteralBraces:
51
+ EnforcedStyle: no_space
52
+
53
+ Style/TrailingComma:
54
+ EnforcedStyleForMultiline: 'comma'
@@ -1,10 +1,21 @@
1
1
  language: ruby
2
+ env:
3
+ global:
4
+ - JRUBY_OPTS="$JRUBY_OPTS --debug"
2
5
  rvm:
3
- - rbx-18mode
4
- - rbx-19mode
5
- - jruby-18mode
6
- - jruby-19mode
7
6
  - 1.8.7
8
- - 1.9.2
9
7
  - 1.9.3
8
+ - 2.0.0
9
+ - 2.1
10
+ - jruby-18mode
11
+ - jruby-19mode
12
+ - jruby-head
13
+ - rbx-2
10
14
  - ruby-head
15
+ matrix:
16
+ allow_failures:
17
+ - rvm: jruby-head
18
+ - rvm: rbx-2
19
+ - rvm: ruby-head
20
+ fast_finish: true
21
+ sudo: false
data/.yardopts CHANGED
@@ -1,4 +1,5 @@
1
1
  --markup markdown
2
2
  -
3
- HISTORY.md
3
+ CONTRIBUTING.md
4
4
  LICENSE.md
5
+ README.md
data/Gemfile CHANGED
@@ -1,7 +1,17 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
- platforms :jruby do
4
- gem 'jruby-openssl', '~> 0.7'
3
+ gem 'jruby-openssl', :platforms => :jruby
4
+ gem 'rake'
5
+
6
+ group :test do
7
+ gem 'backports'
8
+ gem 'coveralls'
9
+ gem 'mime-types', '~> 1.25', :platforms => [:jruby, :ruby_18]
10
+ gem 'rest-client', '~> 1.6.0', :platforms => [:jruby, :ruby_18]
11
+ gem 'rspec', '>= 2.14'
12
+ gem 'rubocop', '>= 0.25', :platforms => [:ruby_19, :ruby_20, :ruby_21]
13
+ gem 'simplecov', '>= 0.9'
14
+ gem 'yardstick'
5
15
  end
6
16
 
7
17
  gemspec
@@ -1,6 +1,4 @@
1
- Copyright (c) 2010 Steve Richert, Erik Michaels-Ober
2
-
3
- MIT License
1
+ Copyright (c) 2010-2013 Steve Richert, Erik Michaels-Ober
4
2
 
5
3
  Permission is hereby granted, free of charge, to any person obtaining
6
4
  a copy of this software and associated documentation files (the
data/README.md CHANGED
@@ -1,4 +1,16 @@
1
- # simple_oauth [![Build Status](https://secure.travis-ci.org/laserlemon/simple_oauth.png)](http://travis-ci.org/laserlemon/simple_oauth) [![Dependency Status](https://gemnasium.com/laserlemon/simple_oauth.png)](https://gemnasium.com/laserlemon/simple_oauth)
1
+ # simple_oauth
2
+
3
+ [![Gem Version](http://img.shields.io/gem/v/simple_oauth.svg)][gem]
4
+ [![Build Status](http://img.shields.io/travis/laserlemon/simple_oauth.svg)][travis]
5
+ [![Dependency Status](http://img.shields.io/gemnasium/laserlemon/simple_oauth.svg)][gemnasium]
6
+ [![Code Climate](http://img.shields.io/codeclimate/github/laserlemon/simple_oauth.svg)][codeclimate]
7
+ [![Coverage Status](http://img.shields.io/coveralls/laserlemon/simple_oauth.svg)][coveralls]
8
+
9
+ [gem]: https://rubygems.org/gems/simple_oauth
10
+ [travis]: http://travis-ci.org/laserlemon/simple_oauth
11
+ [gemnasium]: https://gemnasium.com/laserlemon/simple_oauth
12
+ [codeclimate]: https://codeclimate.com/github/laserlemon/simple_oauth
13
+ [coveralls]: https://coveralls.io/r/laserlemon/simple_oauth
2
14
 
3
15
  Simply builds and verifies OAuth headers
4
16
 
@@ -8,14 +20,13 @@ against](http://travis-ci.org/laserlemon/simple_oauth) the following Ruby
8
20
  implementations:
9
21
 
10
22
  * Ruby 1.8.7
11
- * Ruby 1.9.2
12
23
  * Ruby 1.9.3
13
- * Ruby head
14
- * [JRuby](http://www.jruby.org/)
24
+ * Ruby 2.0.0
25
+ * Ruby 2.1
26
+ * [JRuby](http://jruby.org/)
15
27
  * [Rubinius](http://rubini.us/)
16
28
 
17
- If something doesn't work on one of these interpreters, it should be considered
18
- a bug.
29
+ If something doesn't work on one of these interpreters, it's a bug.
19
30
 
20
31
  This library may inadvertently work (or seem to work) on other Ruby
21
32
  implementations, however support will only be provided for the versions listed
@@ -24,10 +35,10 @@ above.
24
35
  If you would like this library to support another Ruby version, you may
25
36
  volunteer to be a maintainer. Being a maintainer entails making sure all tests
26
37
  run and pass on that implementation. When something breaks on your
27
- implementation, you will be personally responsible for providing patches in a
28
- timely fashion. If critical issues for a particular implementation exist at the
29
- time of a major release, support for that Ruby version may be dropped.
38
+ implementation, you will be responsible for providing patches in a timely
39
+ fashion. If critical issues for a particular implementation exist at the time
40
+ of a major release, support for that Ruby version may be dropped.
30
41
 
31
42
  ## Copyright
32
- Copyright (c) 2010 Steve Richert, Erik Michaels-Ober.
33
- See [LICENSE](https://github.com/laserlemon/simple_oauth/blob/master/LICENSE) for details.
43
+ Copyright (c) 2010-2013 Steve Richert, Erik Michaels-Ober. See
44
+ [LICENSE](LICENSE.md) for details.
data/Rakefile CHANGED
@@ -3,4 +3,25 @@ require 'rspec/core/rake_task'
3
3
 
4
4
  RSpec::Core::RakeTask.new(:spec)
5
5
 
6
- task :default => :spec
6
+ task :test => :spec
7
+
8
+ begin
9
+ require 'rubocop/rake_task'
10
+ RuboCop::RakeTask.new
11
+ rescue LoadError
12
+ task :rubocop do
13
+ $stderr.puts 'RuboCop is disabled'
14
+ end
15
+ end
16
+
17
+ require 'yardstick/rake/measurement'
18
+ Yardstick::Rake::Measurement.new do |measurement|
19
+ measurement.output = 'measurement/report.txt'
20
+ end
21
+
22
+ require 'yardstick/rake/verify'
23
+ Yardstick::Rake::Verify.new do |verify|
24
+ verify.threshold = 47
25
+ end
26
+
27
+ task :default => [:spec, :rubocop, :verify_measurements]
@@ -14,33 +14,32 @@ module SimpleOAuth
14
14
  :nonce => OpenSSL::Random.random_bytes(16).unpack('H*')[0],
15
15
  :signature_method => 'HMAC-SHA1',
16
16
  :timestamp => Time.now.to_i.to_s,
17
- :version => '1.0'
17
+ :version => '1.0',
18
18
  }
19
19
  end
20
20
 
21
21
  def parse(header)
22
22
  header.to_s.sub(/^OAuth\s/, '').split(/,\s*/).inject({}) do |attributes, pair|
23
23
  match = pair.match(/^(\w+)\=\"([^\"]*)\"$/)
24
- attributes.merge(match[1].sub(/^oauth_/, '').to_sym => decode(match[2]))
24
+ attributes.merge(match[1].sub(/^oauth_/, '').to_sym => unescape(match[2]))
25
25
  end
26
26
  end
27
27
 
28
28
  def escape(value)
29
29
  uri_parser.escape(value.to_s, /[^a-z0-9\-\.\_\~]/i)
30
30
  end
31
- alias encode escape
31
+ alias_method :encode, :escape
32
32
 
33
33
  def unescape(value)
34
34
  uri_parser.unescape(value.to_s)
35
35
  end
36
- alias decode unescape
36
+ alias_method :decode, :unescape
37
37
 
38
38
  private
39
39
 
40
40
  def uri_parser
41
41
  @uri_parser ||= URI.const_defined?(:Parser) ? URI::Parser.new : URI
42
42
  end
43
-
44
43
  end
45
44
 
46
45
  def initialize(method, url, params, oauth = {})
@@ -78,11 +77,16 @@ module SimpleOAuth
78
77
  private
79
78
 
80
79
  def normalized_attributes
81
- signed_attributes.sort_by{|k,v| k.to_s }.map{|k,v| %(#{k}="#{self.class.encode(v)}") }.join(', ')
80
+ signed_attributes.sort_by { |k, _| k.to_s }.collect { |k, v| %(#{k}="#{self.class.escape(v)}") }.join(', ')
82
81
  end
83
82
 
84
83
  def attributes
85
- ATTRIBUTE_KEYS.inject({}){|a,k| options[k] ? a.merge(:"oauth_#{k}" => options[k]) : a }
84
+ matching_keys, extra_keys = options.keys.partition { |key| ATTRIBUTE_KEYS.include?(key) }
85
+ if options[:ignore_extra_keys] || extra_keys.empty?
86
+ Hash[options.select { |key, _value| matching_keys.include?(key) }.collect { |key, value| [:"oauth_#{key}", value] }]
87
+ else
88
+ fail "SimpleOAuth: Found extra option keys not matching ATTRIBUTE_KEYS:\n [#{extra_keys.collect(&:inspect).join(', ')}]"
89
+ end
86
90
  end
87
91
 
88
92
  def signature
@@ -94,16 +98,16 @@ module SimpleOAuth
94
98
  end
95
99
 
96
100
  def secret
97
- options.values_at(:consumer_secret, :token_secret).map{|v| self.class.encode(v) }.join('&')
101
+ options.values_at(:consumer_secret, :token_secret).collect { |v| self.class.escape(v) }.join('&')
98
102
  end
99
103
  alias_method :plaintext_signature, :secret
100
104
 
101
105
  def signature_base
102
- [method, url, normalized_params].map{|v| self.class.encode(v) }.join('&')
106
+ [method, url, normalized_params].collect { |v| self.class.escape(v) }.join('&')
103
107
  end
104
108
 
105
109
  def normalized_params
106
- signature_params.map{|p| p.map{|v| self.class.encode(v) } }.sort.map{|p| p.join('=') }.join('&')
110
+ signature_params.collect { |p| p.collect { |v| self.class.escape(v) } }.sort.collect { |p| p.join('=') }.join('&')
107
111
  end
108
112
 
109
113
  def signature_params
@@ -111,7 +115,7 @@ module SimpleOAuth
111
115
  end
112
116
 
113
117
  def url_params
114
- CGI.parse(@uri.query || '').inject([]){|p,(k,vs)| p + vs.sort.map{|v| [k, v] } }
118
+ CGI.parse(@uri.query || '').inject([]) { |p, (k, vs)| p + vs.sort.collect { |v| [k, v] } }
115
119
  end
116
120
 
117
121
  def rsa_sha1_signature
@@ -121,6 +125,5 @@ module SimpleOAuth
121
125
  def private_key
122
126
  OpenSSL::PKey::RSA.new(options[:consumer_secret])
123
127
  end
124
-
125
128
  end
126
129
  end
@@ -1,21 +1,15 @@
1
- # encoding: utf-8
2
-
3
1
  Gem::Specification.new do |spec|
2
+ spec.add_development_dependency 'bundler', '~> 1.0'
4
3
  spec.name = 'simple_oauth'
5
- spec.version = '0.2.0'
4
+ spec.version = '0.3.0'
6
5
 
7
- spec.authors = ["Steve Richert", "Erik Michaels-Ober"]
8
- spec.email = ['steve.richert@gmail.com', 'sferik@gmail.com']
6
+ spec.authors = ['Steve Richert', 'Erik Michaels-Ober']
7
+ spec.email = %w(steve.richert@gmail.com sferik@gmail.com)
9
8
  spec.description = 'Simply builds and verifies OAuth headers'
10
9
  spec.summary = spec.description
11
10
  spec.homepage = 'https://github.com/laserlemon/simple_oauth'
12
- spec.licenses = ['MIT']
13
-
14
- spec.add_development_dependency 'rake'
15
- spec.add_development_dependency 'rspec', '>= 2'
16
- spec.add_development_dependency 'simplecov'
11
+ spec.licenses = %w(MIT)
17
12
 
18
- spec.files = `git ls-files`.split($\)
19
- spec.test_files = spec.files.grep(/^test\//)
20
- spec.require_paths = ["lib"]
13
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.start_with?('test/') }
14
+ spec.require_paths = %w(lib)
21
15
  end
@@ -1,7 +1,12 @@
1
- unless ENV['CI']
1
+ if RUBY_VERSION >= '1.9'
2
2
  require 'simplecov'
3
+ require 'coveralls'
4
+
5
+ SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[SimpleCov::Formatter::HTMLFormatter, Coveralls::SimpleCov::Formatter]
6
+
3
7
  SimpleCov.start do
4
- add_filter 'spec'
8
+ add_filter '/spec/'
9
+ minimum_coverage(100)
5
10
  end
6
11
  end
7
12
 
@@ -18,4 +23,4 @@ RSpec.configure do |config|
18
23
  end
19
24
  end
20
25
 
21
- Dir[File.expand_path('../support/**/*.rb', __FILE__)].each{|f| require f }
26
+ Dir[File.expand_path('../support/**/*.rb', __FILE__)].each { |f| require f }
@@ -3,27 +3,27 @@
3
3
  require 'helper'
4
4
 
5
5
  describe SimpleOAuth::Header do
6
- describe ".default_options" do
7
- let(:default_options){ SimpleOAuth::Header.default_options }
6
+ describe '.default_options' do
7
+ let(:default_options) { SimpleOAuth::Header.default_options }
8
8
 
9
- it "is different every time" do
9
+ it 'is different every time' do
10
10
  expect(SimpleOAuth::Header.default_options).not_to eq default_options
11
11
  end
12
12
 
13
- it "is used for new headers" do
14
- SimpleOAuth::Header.stub(:default_options => default_options)
13
+ it 'is used for new headers' do
14
+ allow(SimpleOAuth::Header).to receive(:default_options).and_return(default_options)
15
15
  header = SimpleOAuth::Header.new(:get, 'https://api.twitter.com/1/statuses/friendships.json', {})
16
16
  expect(header.options).to eq default_options
17
17
  end
18
18
 
19
- it "includes a signature method and an OAuth version" do
19
+ it 'includes a signature method and an OAuth version' do
20
20
  expect(default_options[:signature_method]).not_to be_nil
21
21
  expect(default_options[:version]).not_to be_nil
22
22
  end
23
23
  end
24
24
 
25
- describe ".escape" do
26
- it "escapes (most) non-word characters" do
25
+ describe '.escape' do
26
+ it 'escapes (most) non-word characters' do
27
27
  [' ', '!', '@', '#', '$', '%', '^', '&'].each do |character|
28
28
  escaped = SimpleOAuth::Header.escape(character)
29
29
  expect(escaped).not_to eq character
@@ -31,7 +31,7 @@ describe SimpleOAuth::Header do
31
31
  end
32
32
  end
33
33
 
34
- it "does not escape - . or ~" do
34
+ it 'does not escape - . or ~' do
35
35
  ['-', '.', '~'].each do |character|
36
36
  escaped = SimpleOAuth::Header.escape(character)
37
37
  expect(escaped).to eq character
@@ -39,11 +39,11 @@ describe SimpleOAuth::Header do
39
39
  end
40
40
 
41
41
  def self.test_special_characters
42
- it "escapes non-ASCII characters" do
42
+ it 'escapes non-ASCII characters' do
43
43
  expect(SimpleOAuth::Header.escape('é')).to eq '%C3%A9'
44
44
  end
45
45
 
46
- it "escapes multibyte characters" do
46
+ it 'escapes multibyte characters' do
47
47
  expect(SimpleOAuth::Header.escape('あ')).to eq '%E3%81%82'
48
48
  end
49
49
  end
@@ -53,35 +53,35 @@ describe SimpleOAuth::Header do
53
53
  else
54
54
  %w(n N e E s S u U).each do |kcode|
55
55
  describe %(when $KCODE = "#{kcode}") do
56
- original_kcode = $KCODE
56
+ original_kcode = $KCODE # rubocop:disable GlobalVars
57
57
  begin
58
- $KCODE = kcode
58
+ $KCODE = kcode # rubocop:disable GlobalVars
59
59
  test_special_characters
60
60
  ensure
61
- $KCODE = original_kcode
61
+ $KCODE = original_kcode # rubocop:disable GlobalVars
62
62
  end
63
63
  end
64
64
  end
65
65
  end
66
66
  end
67
67
 
68
- describe ".unescape" do
68
+ describe '.unescape' do
69
69
  pending
70
70
  end
71
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) }
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
75
 
76
- it "returns a hash" do
76
+ it 'returns a hash' do
77
77
  expect(parsed_options).to be_a(Hash)
78
78
  end
79
79
 
80
- it "includes the options used to build the header" do
81
- expect(parsed_options.reject{|k,_| k == :signature }).to eq header.options
80
+ it 'includes the options used to build the header' do
81
+ expect(parsed_options.reject { |k, _| k == :signature }).to eq header.options
82
82
  end
83
83
 
84
- it "includes a signature" do
84
+ it 'includes a signature' do
85
85
  expect(header.options).not_to have_key(:signature)
86
86
  expect(parsed_options).to have_key(:signature)
87
87
  expect(parsed_options[:signature]).not_to be_nil
@@ -106,46 +106,47 @@ describe SimpleOAuth::Header do
106
106
  end
107
107
  end
108
108
 
109
- describe "#initialize" do
110
- let(:header){ SimpleOAuth::Header.new(:get, 'HTTPS://api.TWITTER.com:443/1/statuses/friendships.json?foo=bar#anchor', {}) }
109
+ describe '#initialize' do
110
+ let(:header) { SimpleOAuth::Header.new(:get, 'HTTPS://api.TWITTER.com:443/1/statuses/friendships.json?foo=bar#anchor', {}) }
111
111
 
112
- it "stringifies and uppercases the request method" do
112
+ it 'stringifies and uppercases the request method' do
113
113
  expect(header.method).to eq 'GET'
114
114
  end
115
115
 
116
- it "downcases the scheme and authority" do
117
- expect(header.url).to match %r(^https://api\.twitter\.com/)
116
+ it 'downcases the scheme and authority' do
117
+ expect(header.url).to match %r{^https://api\.twitter\.com/}
118
118
  end
119
119
 
120
- it "ignores the query and fragment" do
121
- expect(header.url).to match %r(/1/statuses/friendships\.json$)
120
+ it 'ignores the query and fragment' do
121
+ expect(header.url).to match %r{/1/statuses/friendships\.json$}
122
122
  end
123
123
  end
124
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'}
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
129
  header = SimpleOAuth::Header.new(:get, 'https://api.twitter.com/1/statuses/friends.json', {}, secrets)
130
130
  parsed_header = SimpleOAuth::Header.new(:get, 'https://api.twitter.com/1/statuses/friends.json', {}, header)
131
+ parsed_header.options[:ignore_extra_keys] = true
131
132
  expect(parsed_header).not_to be_valid
132
133
  expect(parsed_header).to be_valid(secrets)
133
134
  end
134
135
  end
135
136
 
136
- context "using the RSA-SHA1 signature method" do
137
- it "requires an identical private key" do
138
- secrets = {:consumer_secret => rsa_private_key}
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}
139
140
  header = SimpleOAuth::Header.new(:get, 'https://api.twitter.com/1/statuses/friends.json', {}, secrets.merge(:signature_method => 'RSA-SHA1'))
140
141
  parsed_header = SimpleOAuth::Header.new(:get, 'https://api.twitter.com/1/statuses/friends.json', {}, header)
141
- expect{ parsed_header.valid? }.to raise_error(TypeError)
142
+ expect { parsed_header.valid? }.to raise_error(TypeError)
142
143
  expect(parsed_header).to be_valid(secrets)
143
144
  end
144
145
  end
145
146
 
146
- context "using the RSA-SHA1 signature method" do
147
- it "requires consumer and token secrets" do
148
- secrets = {:consumer_secret => 'CONSUMER_SECRET', :token_secret => 'TOKEN_SECRET'}
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}
149
150
  header = SimpleOAuth::Header.new(:get, 'https://api.twitter.com/1/statuses/friends.json', {}, secrets.merge(:signature_method => 'PLAINTEXT'))
150
151
  parsed_header = SimpleOAuth::Header.new(:get, 'https://api.twitter.com/1/statuses/friends.json', {}, header)
151
152
  expect(parsed_header).not_to be_valid
@@ -154,76 +155,82 @@ describe SimpleOAuth::Header do
154
155
  end
155
156
  end
156
157
 
157
- describe "#normalized_attributes" do
158
- let(:header){ SimpleOAuth::Header.new(:get, 'https://api.twitter.com/1/statuses/friends.json', {}) }
159
- let(:normalized_attributes){ header.send(:normalized_attributes) }
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) }
160
161
 
161
- it "returns a sorted-key, quoted-value and comma-separated list" do
162
- header.stub(:signed_attributes => {:d => 1, :c => 2, :b => 3, :a => 4})
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)
163
164
  expect(normalized_attributes).to eq 'a="4", b="3", c="2", d="1"'
164
165
  end
165
166
 
166
- it "URI encodes its values" do
167
- header.stub(:signed_attributes => {1 => '!', 2 => '@', 3 => '#', 4 => '$'})
167
+ it 'URI encodes its values' do
168
+ allow(header).to receive(:signed_attributes).and_return(1 => '!', 2 => '@', 3 => '#', 4 => '$')
168
169
  expect(normalized_attributes).to eq '1="%21", 2="%40", 3="%23", 4="%24"'
169
170
  end
170
171
  end
171
172
 
172
- describe "#signed_attributes" do
173
- it "includes the OAuth signature" do
173
+ describe '#signed_attributes' do
174
+ it 'includes the OAuth signature' do
174
175
  header = SimpleOAuth::Header.new(:get, 'https://api.twitter.com/1/statuses/friends.json', {})
175
176
  expect(header.send(:signed_attributes)).to have_key(:oauth_signature)
176
177
  end
177
178
  end
178
179
 
179
- describe "#attributes" do
180
+ describe '#attributes' do
180
181
  let(:header) do
181
182
  options = {}
182
- SimpleOAuth::Header::ATTRIBUTE_KEYS.each{|k| options[k] = k.to_s.upcase }
183
+ SimpleOAuth::Header::ATTRIBUTE_KEYS.each { |k| options[k] = k.to_s.upcase }
183
184
  options[:other] = 'OTHER'
184
185
  SimpleOAuth::Header.new(:get, 'https://api.twitter.com/1/statuses/friendships.json', {}, options)
185
186
  end
186
- let(:attributes){ header.send(:attributes) }
187
187
 
188
188
  it "prepends keys with 'oauth_'" do
189
- expect(attributes.keys).to be_all{|k| k.to_s =~ /^oauth_/ }
189
+ header.options[:ignore_extra_keys] = true
190
+ expect(header.send(:attributes).keys).to be_all { |k| k.to_s =~ /^oauth_/ }
190
191
  end
191
192
 
192
- it "excludes keys not included in the list of valid attributes" do
193
- expect(attributes.keys).to be_all{|k| k.is_a?(Symbol) }
194
- expect(attributes).not_to have_key(:oauth_other)
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)
195
197
  end
196
198
 
197
- it "preserves values for valid keys" do
198
- expect(attributes.size).to eq SimpleOAuth::Header::ATTRIBUTE_KEYS.size
199
- expect(attributes).to be_all{|k,v| k.to_s == "oauth_#{v.downcase}" }
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]")
200
207
  end
201
208
  end
202
209
 
203
- describe "#signature" do
204
- context "calls the appropriate signature method" do
205
- specify "when using HMAC-SHA1" do
210
+ describe '#signature' do
211
+ context 'calls the appropriate signature method' do
212
+ specify 'when using HMAC-SHA1' do
206
213
  header = SimpleOAuth::Header.new(:get, 'https://api.twitter.com/1/statuses/friends.json', {}, :signature_method => 'HMAC-SHA1')
207
- header.should_receive(:hmac_sha1_signature).once.and_return('HMAC_SHA1_SIGNATURE')
214
+ expect(header).to receive(:hmac_sha1_signature).once.and_return('HMAC_SHA1_SIGNATURE')
208
215
  expect(header.send(:signature)).to eq 'HMAC_SHA1_SIGNATURE'
209
216
  end
210
217
 
211
- specify "when using RSA-SHA1" do
218
+ specify 'when using RSA-SHA1' do
212
219
  header = SimpleOAuth::Header.new(:get, 'https://api.twitter.com/1/statuses/friends.json', {}, :signature_method => 'RSA-SHA1')
213
- header.should_receive(:rsa_sha1_signature).once.and_return('RSA_SHA1_SIGNATURE')
220
+ expect(header).to receive(:rsa_sha1_signature).once.and_return('RSA_SHA1_SIGNATURE')
214
221
  expect(header.send(:signature)).to eq 'RSA_SHA1_SIGNATURE'
215
222
  end
216
223
 
217
- specify "when using PLAINTEXT" do
224
+ specify 'when using PLAINTEXT' do
218
225
  header = SimpleOAuth::Header.new(:get, 'https://api.twitter.com/1/statuses/friends.json', {}, :signature_method => 'PLAINTEXT')
219
- header.should_receive(:plaintext_signature).once.and_return('PLAINTEXT_SIGNATURE')
226
+ expect(header).to receive(:plaintext_signature).once.and_return('PLAINTEXT_SIGNATURE')
220
227
  expect(header.send(:signature)).to eq 'PLAINTEXT_SIGNATURE'
221
228
  end
222
229
  end
223
230
  end
224
231
 
225
- describe "#hmac_sha1_signature" do
226
- it "reproduces a successful Twitter GET" do
232
+ describe '#hmac_sha1_signature' do
233
+ it 'reproduces a successful Twitter GET' do
227
234
  options = {
228
235
  :consumer_key => '8karQBlMg6gFOwcf8kcoYw',
229
236
  :consumer_secret => '3d0vcHyUiiqADpWxolW8nlDIpSWMlyK7YNgc5Qna2M',
@@ -231,13 +238,14 @@ describe SimpleOAuth::Header do
231
238
  :signature_method => 'HMAC-SHA1',
232
239
  :timestamp => '1286830180',
233
240
  :token => '201425800-Sv4sTcgoffmHGkTCue0JnURT8vrm4DiFAkeFNDkh',
234
- :token_secret => 'T5qa1tF57tfDzKmpM89DHsNuhgOY4NT6DlNLsTFcuQ'
241
+ :token_secret => 'T5qa1tF57tfDzKmpM89DHsNuhgOY4NT6DlNLsTFcuQ',
242
+ :ignore_extra_keys => true,
235
243
  }
236
244
  header = SimpleOAuth::Header.new(:get, 'https://api.twitter.com/1/statuses/friends.json', {}, options)
237
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"'
238
246
  end
239
247
 
240
- it "reproduces a successful Twitter POST" do
248
+ it 'reproduces a successful Twitter POST' do
241
249
  options = {
242
250
  :consumer_key => '8karQBlMg6gFOwcf8kcoYw',
243
251
  :consumer_secret => '3d0vcHyUiiqADpWxolW8nlDIpSWMlyK7YNgc5Qna2M',
@@ -245,117 +253,121 @@ describe SimpleOAuth::Header do
245
253
  :signature_method => 'HMAC-SHA1',
246
254
  :timestamp => '1286830181',
247
255
  :token => '201425800-Sv4sTcgoffmHGkTCue0JnURT8vrm4DiFAkeFNDkh',
248
- :token_secret => 'T5qa1tF57tfDzKmpM89DHsNuhgOY4NT6DlNLsTFcuQ'
256
+ :token_secret => 'T5qa1tF57tfDzKmpM89DHsNuhgOY4NT6DlNLsTFcuQ',
257
+ :ignore_extra_keys => true,
249
258
  }
250
259
  header = SimpleOAuth::Header.new(:post, 'https://api.twitter.com/1/statuses/update.json', {:status => 'hi, again'}, options)
251
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"'
252
261
  end
253
262
  end
254
263
 
255
- describe "#secret" do
256
- let(:header){ SimpleOAuth::Header.new(:get, 'https://api.twitter.com/1/statuses/friendships.json', {}) }
257
- let(:secret){ header.send(:secret) }
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) }
258
267
 
259
- it "combines the consumer and token secrets with an ampersand" do
260
- header.stub(:options => {:consumer_secret => 'CONSUMER_SECRET', :token_secret => 'TOKEN_SECRET'})
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')
261
270
  expect(secret).to eq 'CONSUMER_SECRET&TOKEN_SECRET'
262
271
  end
263
272
 
264
- it "URI encodes each secret value before combination" do
265
- header.stub(:options => {:consumer_secret => 'CONSUM#R_SECRET', :token_secret => 'TOKEN_S#CRET'})
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')
266
275
  expect(secret).to eq 'CONSUM%23R_SECRET&TOKEN_S%23CRET'
267
276
  end
268
277
  end
269
278
 
270
- describe "#signature_base" do
271
- let(:header){ SimpleOAuth::Header.new(:get, 'https://api.twitter.com/1/statuses/friendships.json', {}) }
272
- let(:signature_base){ header.send(:signature_base) }
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) }
273
282
 
274
- it "combines the request method, URL and normalized parameters using ampersands" do
275
- header.stub(:method => 'METHOD', :url => 'URL', :normalized_params => 'NORMALIZED_PARAMS')
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')
276
287
  expect(signature_base).to eq 'METHOD&URL&NORMALIZED_PARAMS'
277
288
  end
278
289
 
279
- it "URI encodes each value before combination" do
280
- header.stub(:method => 'ME#HOD', :url => 'U#L', :normalized_params => 'NORMAL#ZED_PARAMS')
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')
281
294
  expect(signature_base).to eq 'ME%23HOD&U%23L&NORMAL%23ZED_PARAMS'
282
295
  end
283
296
  end
284
297
 
285
- describe "#normalized_params" do
298
+ describe '#normalized_params' do
286
299
  let(:header) do
287
300
  header = SimpleOAuth::Header.new(:get, 'https://api.twitter.com/1/statuses/friendships.json', {})
288
- header.stub(:signature_params => [['A', '4'], ['B', '3'], ['B', '2'], ['C', '1'], ['D[]', '0 ']])
301
+ allow(header).to receive(:signature_params).and_return([%w(A 4), %w(B 3), %w(B 2), %w(C 1), ['D[]', '0 ']])
289
302
  header
290
303
  end
291
- let(:signature_params){ header.send(:signature_params) }
292
- let(:normalized_params){ header.send(:normalized_params) }
304
+ let(:signature_params) { header.send(:signature_params) }
305
+ let(:normalized_params) { header.send(:normalized_params) }
293
306
 
294
- it "joins key/value pairs with equal signs and ampersands" do
307
+ it 'joins key/value pairs with equal signs and ampersands' do
295
308
  expect(normalized_params).to be_a(String)
296
309
  parts = normalized_params.split('&')
297
310
  expect(parts.size).to eq signature_params.size
298
- pairs = parts.map{|p| p.split('=') }
299
- expect(pairs).to be_all{|p| p.size == 2 }
311
+ pairs = parts.collect { |p| p.split('=') }
312
+ expect(pairs).to be_all { |p| p.size == 2 }
300
313
  end
301
314
  end
302
315
 
303
- describe "#signature_params" do
304
- let(:header){ SimpleOAuth::Header.new(:get, 'https://api.twitter.com/1/statuses/friendships.json', {}) }
305
- let(:signature_params){ header.send(:signature_params) }
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) }
306
319
 
307
- it "combines OAuth header attributes, body parameters and URL parameters into an flattened array of key/value pairs" do
308
- header.stub(
309
- :attributes => {:attribute => 'ATTRIBUTE'},
310
- :params => {'param' => 'PARAM'},
311
- :url_params => [['url_param', '1'], ['url_param', '2']]
312
- )
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)])
313
324
  expect(signature_params).to eq [
314
325
  [:attribute, 'ATTRIBUTE'],
315
- ['param', 'PARAM'],
316
- ['url_param', '1'],
317
- ['url_param', '2']
326
+ %w(param PARAM),
327
+ %w(url_param 1),
328
+ %w(url_param 2),
318
329
  ]
319
330
  end
320
331
  end
321
332
 
322
- describe "#url_params" do
323
- it "returns an empty array when the URL has no query parameters" do
333
+ describe '#url_params' do
334
+ it 'returns an empty array when the URL has no query parameters' do
324
335
  header = SimpleOAuth::Header.new(:get, 'https://api.twitter.com/1/statuses/friendships.json', {})
325
336
  expect(header.send(:url_params)).to eq []
326
337
  end
327
338
 
328
- it "returns an array of key/value pairs for each query parameter" do
339
+ it 'returns an array of key/value pairs for each query parameter' do
329
340
  header = SimpleOAuth::Header.new(:get, 'https://api.twitter.com/1/statuses/friendships.json?test=TEST', {})
330
- expect(header.send(:url_params)).to eq [['test', 'TEST']]
341
+ expect(header.send(:url_params)).to eq [%w(test TEST)]
331
342
  end
332
343
 
333
- it "sorts values for repeated keys" do
344
+ it 'sorts values for repeated keys' do
334
345
  header = SimpleOAuth::Header.new(:get, 'https://api.twitter.com/1/statuses/friendships.json?test=3&test=1&test=2', {})
335
- expect(header.send(:url_params)).to eq [['test', '1'], ['test', '2'], ['test', '3']]
346
+ expect(header.send(:url_params)).to eq [%w(test 1), %w(test 2), %w(test 3)]
336
347
  end
337
348
  end
338
349
 
339
- describe "#rsa_sha1_signature" do
340
- it "reproduces a successful OAuth example GET" do
350
+ describe '#rsa_sha1_signature' do
351
+ it 'reproduces a successful OAuth example GET' do
341
352
  options = {
342
353
  :consumer_key => 'dpf43f3p2l4k3l03',
343
354
  :consumer_secret => rsa_private_key,
344
355
  :nonce => '13917289812797014437',
345
356
  :signature_method => 'RSA-SHA1',
346
- :timestamp => '1196666512'
357
+ :timestamp => '1196666512',
358
+ :ignore_extra_keys => true,
347
359
  }
348
360
  header = SimpleOAuth::Header.new(:get, 'http://photos.example.net/photos', {:file => 'vacaction.jpg', :size => 'original'}, options)
349
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"'
350
362
  end
351
363
  end
352
364
 
353
- describe "#private_key" do
365
+ describe '#private_key' do
354
366
  pending
355
367
  end
356
368
 
357
- describe "#plaintext_signature" do
358
- it "reproduces a successful OAuth example GET" do
369
+ describe '#plaintext_signature' do
370
+ it 'reproduces a successful OAuth example GET' do
359
371
  options = {
360
372
  :consumer_key => 'abcd',
361
373
  :consumer_secret => 'efgh',
@@ -363,7 +375,8 @@ describe SimpleOAuth::Header do
363
375
  :signature_method => 'PLAINTEXT',
364
376
  :timestamp => '1286977095',
365
377
  :token => 'ijkl',
366
- :token_secret => 'mnop'
378
+ :token_secret => 'mnop',
379
+ :ignore_extra_keys => true,
367
380
  }
368
381
  header = SimpleOAuth::Header.new(:get, 'http://host.net/resource?name=value', {:name => 'value'}, options)
369
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"'
metadata CHANGED
@@ -1,8 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: simple_oauth
3
3
  version: !ruby/object:Gem::Version
4
- prerelease:
5
- version: 0.2.0
4
+ version: 0.3.0
6
5
  platform: ruby
7
6
  authors:
8
7
  - Steve Richert
@@ -10,56 +9,22 @@ authors:
10
9
  autorequire:
11
10
  bindir: bin
12
11
  cert_chain: []
13
- date: 2012-12-02 00:00:00.000000000 Z
12
+ date: 2014-10-09 00:00:00.000000000 Z
14
13
  dependencies:
15
14
  - !ruby/object:Gem::Dependency
16
- version_requirements: !ruby/object:Gem::Requirement
17
- requirements:
18
- - - ! '>='
19
- - !ruby/object:Gem::Version
20
- version: '0'
21
- none: false
22
- name: rake
23
- type: :development
24
- prerelease: false
15
+ name: bundler
25
16
  requirement: !ruby/object:Gem::Requirement
26
17
  requirements:
27
- - - ! '>='
28
- - !ruby/object:Gem::Version
29
- version: '0'
30
- none: false
31
- - !ruby/object:Gem::Dependency
32
- version_requirements: !ruby/object:Gem::Requirement
33
- requirements:
34
- - - ! '>='
18
+ - - "~>"
35
19
  - !ruby/object:Gem::Version
36
- version: '2'
37
- none: false
38
- name: rspec
20
+ version: '1.0'
39
21
  type: :development
40
22
  prerelease: false
41
- requirement: !ruby/object:Gem::Requirement
42
- requirements:
43
- - - ! '>='
44
- - !ruby/object:Gem::Version
45
- version: '2'
46
- none: false
47
- - !ruby/object:Gem::Dependency
48
23
  version_requirements: !ruby/object:Gem::Requirement
49
24
  requirements:
50
- - - ! '>='
51
- - !ruby/object:Gem::Version
52
- version: '0'
53
- none: false
54
- name: simplecov
55
- type: :development
56
- prerelease: false
57
- requirement: !ruby/object:Gem::Requirement
58
- requirements:
59
- - - ! '>='
25
+ - - "~>"
60
26
  - !ruby/object:Gem::Version
61
- version: '0'
62
- none: false
27
+ version: '1.0'
63
28
  description: Simply builds and verifies OAuth headers
64
29
  email:
65
30
  - steve.richert@gmail.com
@@ -68,14 +33,14 @@ executables: []
68
33
  extensions: []
69
34
  extra_rdoc_files: []
70
35
  files:
71
- - .gemtest
72
- - .gitignore
73
- - .rspec
74
- - .travis.yml
75
- - .yardopts
36
+ - ".gitignore"
37
+ - ".rspec"
38
+ - ".rubocop.yml"
39
+ - ".travis.yml"
40
+ - ".yardopts"
76
41
  - CONTRIBUTING.md
77
42
  - Gemfile
78
- - LICENSE
43
+ - LICENSE.md
79
44
  - README.md
80
45
  - Rakefile
81
46
  - lib/simple_oauth.rb
@@ -88,27 +53,26 @@ files:
88
53
  homepage: https://github.com/laserlemon/simple_oauth
89
54
  licenses:
90
55
  - MIT
56
+ metadata: {}
91
57
  post_install_message:
92
58
  rdoc_options: []
93
59
  require_paths:
94
60
  - lib
95
61
  required_ruby_version: !ruby/object:Gem::Requirement
96
62
  requirements:
97
- - - ! '>='
63
+ - - ">="
98
64
  - !ruby/object:Gem::Version
99
65
  version: '0'
100
- none: false
101
66
  required_rubygems_version: !ruby/object:Gem::Requirement
102
67
  requirements:
103
- - - ! '>='
68
+ - - ">="
104
69
  - !ruby/object:Gem::Version
105
70
  version: '0'
106
- none: false
107
71
  requirements: []
108
72
  rubyforge_project:
109
- rubygems_version: 1.8.23
73
+ rubygems_version: 2.4.1
110
74
  signing_key:
111
- specification_version: 3
75
+ specification_version: 4
112
76
  summary: Simply builds and verifies OAuth headers
113
77
  test_files: []
114
78
  has_rdoc:
data/.gemtest DELETED
File without changes