mixlib-authentication 1.4.1 → 1.4.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 9909dd06ad5a2444688f93330b5c9128238d14e0
4
- data.tar.gz: d9c72f4ae75782b00398ce12bc6823778e8aef45
3
+ metadata.gz: e493785efc5cf2caf7d1134378fd613f35712f1f
4
+ data.tar.gz: d855dabe2ebea778d9c37037e3f843c49acbecb9
5
5
  SHA512:
6
- metadata.gz: 606bfed6570c5fbc8c02bcf827985a07003cb191a60dada99496bf073427b91d7fb6e7db966a2c357d082f1d6306f9a8f67cb97708a119d05390db5a77fd3b2f
7
- data.tar.gz: 6305dcaae186d7a39054164a7061226b11713b9e35a5f5ca91d6f2025f42d838f174e9e699e616b2786fa776ef001929d33ff53858ed3a4e534193b206aed211
6
+ metadata.gz: '09e094e344bc46528877b69bb015c5d2386ab57da7f7f62edbbeda81dd338fae31194736f56e947d935b0a36306dac06d148b0dbddf5d11cd3249e3cfba65571'
7
+ data.tar.gz: 2f71c58ba5d85efbf1d00db61ca09abb57d0092d46e2f8d2fa578baf0c34d2e0ff86e36e1224b40e8d0e1ad8258ef717460dcb06385045d3c920f4cd5052a86b
data/Gemfile CHANGED
@@ -3,4 +3,5 @@ gemspec
3
3
 
4
4
  group(:development) do
5
5
  gem "pry"
6
+ gem "mixlib-log"
6
7
  end
data/Rakefile CHANGED
@@ -11,7 +11,7 @@ begin
11
11
  RuboCop::RakeTask.new(:style) do |task|
12
12
  task.options += ["--display-cop-names", "--no-color"]
13
13
  end
14
- rescue
14
+ rescue LoadError
15
15
  puts "chefstyle/rubocop is not available."
16
16
  end
17
17
 
@@ -16,12 +16,13 @@
16
16
  # limitations under the License.
17
17
  #
18
18
 
19
- require "mixlib/log"
20
-
21
19
  module Mixlib
22
20
  module Authentication
23
21
  DEFAULT_SERVER_API_VERSION = "0"
24
22
 
23
+ attr_accessor :logger
24
+ module_function :logger, :logger=
25
+
25
26
  class AuthenticationError < StandardError
26
27
  end
27
28
 
@@ -29,10 +30,17 @@ module Mixlib
29
30
  end
30
31
 
31
32
  class Log
32
- extend Mixlib::Log
33
33
  end
34
34
 
35
- Log.level = :error
35
+ begin
36
+ require "mixlib/log"
37
+ Mixlib::Authentication::Log.extend(Mixlib::Log)
38
+ rescue LoadError
39
+ require "mixlib/authentication/null_logger"
40
+ Mixlib::Authentication::Log.extend(Mixlib::Authentication::NullLogger)
41
+ end
36
42
 
43
+ Mixlib::Authentication.logger = Mixlib::Authentication::Log
44
+ Mixlib::Authentication.logger.level = :error
37
45
  end
38
46
  end
@@ -27,9 +27,7 @@ module Mixlib
27
27
  def hash_file(f, digest = OpenSSL::Digest::SHA1)
28
28
  digester = digest.new
29
29
  buf = ""
30
- while f.read(16384, buf)
31
- digester.update buf
32
- end
30
+ digester.update buf while f.read(16384, buf)
33
31
  ::Base64.encode64(digester.digest).chomp
34
32
  end
35
33
 
@@ -70,7 +70,8 @@ module Mixlib
70
70
 
71
71
  def request_signature
72
72
  unless @request_signature
73
- @request_signature = headers.find_all { |h| h[0].to_s =~ /^x_ops_authorization_/ }.sort { |x, y| x.to_s <=> y.to_s }.map { |i| i[1] }.join("\n")
73
+ @request_signature = headers.find_all { |h| h[0].to_s =~ /^x_ops_authorization_/ }
74
+ .sort { |x, y| x.to_s[/\d+/].to_i <=> y.to_s[/\d+/].to_i }.map { |i| i[1] }.join("\n")
74
75
  Mixlib::Authentication::Log.debug "Reconstituted (user-supplied) request signature: #{@request_signature}"
75
76
  end
76
77
  @request_signature
@@ -0,0 +1,24 @@
1
+ module Mixlib
2
+ module Authentication
3
+ module NullLogger
4
+
5
+ attr_accessor :level
6
+
7
+ %i{debug info warn error fatal}.each do |method_name|
8
+ class_eval(<<-METHOD_DEFN, __FILE__, __LINE__)
9
+ def #{method_name}(msg=nil, &block)
10
+ true
11
+ end
12
+ METHOD_DEFN
13
+ end
14
+
15
+ %i{debug? info? warn? error? fatal?}.each do |method_name|
16
+ class_eval(<<-METHOD_DEFN, __FILE__, __LINE__)
17
+ def #{method_name}
18
+ false
19
+ end
20
+ METHOD_DEFN
21
+ end
22
+ end
23
+ end
24
+ end
@@ -76,7 +76,7 @@ module Mixlib
76
76
  # X-Ops-Content-Hash:
77
77
  # X-Ops-Authorization-#{line_number}
78
78
  def authenticate_request(user_secret, time_skew = (15 * 60))
79
- Mixlib::Authentication::Log.debug "Initializing header auth : #{request.inspect}"
79
+ Mixlib::Authentication.logger.debug "Initializing header auth : #{request.inspect}"
80
80
 
81
81
  @user_secret = user_secret
82
82
  @allowed_time_skew = time_skew # in seconds
@@ -150,14 +150,14 @@ module Mixlib
150
150
  end
151
151
 
152
152
  # Keep the debug messages lined up so it's easy to scan them
153
- Mixlib::Authentication::Log.debug("Verifying request signature:")
154
- Mixlib::Authentication::Log.debug(" Expected Block is: '#{candidate_block}'")
155
- Mixlib::Authentication::Log.debug("Decrypted block is: '#{request_decrypted_block}'")
156
- Mixlib::Authentication::Log.debug("Signatures match? : '#{@valid_signature}'")
153
+ Mixlib::Authentication.logger.debug("Verifying request signature:")
154
+ Mixlib::Authentication.logger.debug(" Expected Block is: '#{candidate_block}'")
155
+ Mixlib::Authentication.logger.debug("Decrypted block is: '#{request_decrypted_block}'")
156
+ Mixlib::Authentication.logger.debug("Signatures match? : '#{@valid_signature}'")
157
157
 
158
158
  @valid_signature
159
159
  rescue => e
160
- Mixlib::Authentication::Log.debug("Failed to verify request signature: #{e.class.name}: #{e.message}")
160
+ Mixlib::Authentication.logger.debug("Failed to verify request signature: #{e.class.name}: #{e.message}")
161
161
  @valid_signature = false
162
162
  end
163
163
 
@@ -169,9 +169,9 @@ module Mixlib
169
169
  @valid_content_hash = (content_hash == hashed_body)
170
170
 
171
171
  # Keep the debug messages lined up so it's easy to scan them
172
- Mixlib::Authentication::Log.debug("Expected content hash is: '#{hashed_body}'")
173
- Mixlib::Authentication::Log.debug(" Request Content Hash is: '#{content_hash}'")
174
- Mixlib::Authentication::Log.debug(" Hashes match?: #{@valid_content_hash}")
172
+ Mixlib::Authentication.logger.debug("Expected content hash is: '#{hashed_body}'")
173
+ Mixlib::Authentication.logger.debug(" Request Content Hash is: '#{content_hash}'")
174
+ Mixlib::Authentication.logger.debug(" Hashes match?: #{@valid_content_hash}")
175
175
 
176
176
  @valid_content_hash
177
177
  end
@@ -211,11 +211,11 @@ module Mixlib
211
211
  # Any file that's included in the request is hashed if it's there. Otherwise,
212
212
  # we hash the body.
213
213
  if file_param
214
- Mixlib::Authentication::Log.debug "Digesting file_param: '#{file_param.inspect}'"
214
+ Mixlib::Authentication.logger.debug "Digesting file_param: '#{file_param.inspect}'"
215
215
  @hashed_body = digester.hash_file(file_param, digest)
216
216
  else
217
217
  body = request.raw_post
218
- Mixlib::Authentication::Log.debug "Digesting body: '#{body}'"
218
+ Mixlib::Authentication.logger.debug "Digesting body: '#{body}'"
219
219
  @hashed_body = digester.hash_string(body, digest)
220
220
  end
221
221
  end
@@ -232,7 +232,7 @@ module Mixlib
232
232
  def timestamp_within_bounds?(time1, time2)
233
233
  time_diff = (time2 - time1).abs
234
234
  is_allowed = (time_diff < @allowed_time_skew)
235
- Mixlib::Authentication::Log.debug "Request time difference: #{time_diff}, within #{@allowed_time_skew} seconds? : #{!!is_allowed}"
235
+ Mixlib::Authentication.logger.debug "Request time difference: #{time_diff}, within #{@allowed_time_skew} seconds? : #{!!is_allowed}"
236
236
  is_allowed
237
237
  end
238
238
  end
@@ -115,7 +115,7 @@ module Mixlib
115
115
  header_hash[key] = signature_lines[idx]
116
116
  end
117
117
 
118
- Mixlib::Authentication::Log.debug "Header hash: #{header_hash.inspect}"
118
+ Mixlib::Authentication.logger.debug "Header hash: #{header_hash.inspect}"
119
119
 
120
120
  header_hash
121
121
  end
@@ -166,7 +166,8 @@ module Mixlib
166
166
  # Hence, we're going to assume the one that is passed to sign is
167
167
  # the correct one and needs to passed through all the functions
168
168
  # that do any sort of digest.
169
- if @hashed_body_digest != nil && @hashed_body_digest != digest
169
+ @hashed_body_digest = nil unless defined?(@hashed_body_digest)
170
+ if !@hashed_body_digest.nil? && @hashed_body_digest != digest
170
171
  raise "hashed_body must always be called with the same digest"
171
172
  else
172
173
  @hashed_body_digest = digest
@@ -176,10 +177,10 @@ module Mixlib
176
177
  # TODO: tim 2009-12-28: It'd be nice to just remove this special case,
177
178
  # always sign the entire request body, using the expanded multipart
178
179
  # body in the case of a file being include.
179
- @hashed_body ||= if self.file && self.file.respond_to?(:read)
180
- digester.hash_file(self.file, digest)
180
+ @hashed_body ||= if file && file.respond_to?(:read)
181
+ digester.hash_file(file, digest)
181
182
  else
182
- digester.hash_string(self.body, digest)
183
+ digester.hash_string(body, digest)
183
184
  end
184
185
  end
185
186
 
@@ -235,7 +236,7 @@ module Mixlib
235
236
  memo[field_name.to_sym] = field_value.strip
236
237
  memo
237
238
  end
238
- Mixlib::Authentication::Log.debug "Parsed signing description: #{parts.inspect}"
239
+ Mixlib::Authentication.logger.debug "Parsed signing description: #{parts.inspect}"
239
240
  parts
240
241
  end
241
242
 
@@ -246,7 +247,7 @@ module Mixlib
246
247
  # private
247
248
  def do_sign(private_key, digest, sign_algorithm, sign_version)
248
249
  string_to_sign = canonicalize_request(sign_algorithm, sign_version)
249
- Mixlib::Authentication::Log.debug "String to sign: '#{string_to_sign}'"
250
+ Mixlib::Authentication.logger.debug "String to sign: '#{string_to_sign}'"
250
251
  case sign_version
251
252
  when "1.3"
252
253
  private_key.sign(digest.new, string_to_sign)
@@ -263,18 +264,19 @@ module Mixlib
263
264
  # A Struct-based value object that contains the necessary information to
264
265
  # generate a request signature. `SignedHeaderAuth.signing_object()`
265
266
  # provides a more convenient interface to the constructor.
266
- class SigningObject < Struct.new(:http_method, :path, :body, :host,
267
+ SigningObject = Struct.new(:http_method, :path, :body, :host,
267
268
  :timestamp, :user_id, :file, :proto_version,
268
- :headers)
269
+ :headers) do
270
+
269
271
  include SignedHeaderAuth
270
272
 
271
273
  def proto_version
272
- (self[:proto_version] || DEFAULT_PROTO_VERSION).to_s
274
+ (self[:proto_version] || SignedHeaderAuth::DEFAULT_PROTO_VERSION).to_s
273
275
  end
274
276
 
275
277
  def server_api_version
276
278
  key = (self[:headers] || {}).keys.select do |k|
277
- k.downcase == "x-ops-server-api-version"
279
+ k.casecmp("x-ops-server-api-version") == 0
278
280
  end.first
279
281
  if key
280
282
  self[:headers][key]
@@ -15,6 +15,6 @@
15
15
 
16
16
  module Mixlib
17
17
  module Authentication
18
- VERSION = "1.4.1"
18
+ VERSION = "1.4.2"
19
19
  end
20
20
  end
@@ -12,14 +12,11 @@ Gem::Specification.new do |s|
12
12
  s.email = "info@chef.io"
13
13
  s.homepage = "https://www.chef.io"
14
14
 
15
- # Uncomment this to add a dependency
16
- s.add_dependency "mixlib-log"
17
-
18
15
  s.require_path = "lib"
19
16
  s.files = %w{LICENSE README.md Gemfile Rakefile NOTICE} + Dir.glob("*.gemspec") +
20
17
  Dir.glob("{lib,spec}/**/*", File::FNM_DOTMATCH).reject { |f| File.directory?(f) }
21
18
 
22
19
  %w{rspec-core rspec-expectations rspec-mocks}.each { |gem| s.add_development_dependency gem, "~> 3.2" }
23
20
  s.add_development_dependency "chefstyle"
24
- s.add_development_dependency "rake", "~> 10.4"
21
+ s.add_development_dependency "rake", "~> 11"
25
22
  end
@@ -7,14 +7,14 @@ describe Mixlib::Authentication::Digester do
7
7
  let(:test_string) { "hello" }
8
8
  let(:test_string_checksum) { "qvTGHdzF6KLavt4PO0gs2a6pQ00=" }
9
9
 
10
- describe '#hash_file' do
10
+ describe "#hash_file" do
11
11
  it "should default to use SHA1" do
12
12
  expect(described_class.hash_file(StringIO.new(test_string))).to(
13
13
  eq(test_string_checksum))
14
14
  end
15
15
  end
16
16
 
17
- describe '#hash_string' do
17
+ describe "#hash_string" do
18
18
  it "should default to use SHA1" do
19
19
  expect(described_class.hash_string(test_string)).to(
20
20
  eq(test_string_checksum))
@@ -63,8 +63,7 @@ class MockFile
63
63
  end
64
64
 
65
65
  # Uncomment this to get some more info from the methods we're testing.
66
- #Mixlib::Authentication::Log.logger = Logger.new(STDERR)
67
- #Mixlib::Authentication::Log.level :debug
66
+ #Mixlib::Authentication.logger.level = :debug
68
67
 
69
68
  describe "Mixlib::Authentication::SignedHeaderAuth" do
70
69
 
@@ -0,0 +1,55 @@
1
+ describe "Mixlib::Authentication::Log" do
2
+ before do
3
+ Mixlib::Authentication.send(:remove_const, "DEFAULT_SERVER_API_VERSION")
4
+ Mixlib::Authentication.send(:remove_const, "Log")
5
+ end
6
+
7
+ context "without mixlib-log" do
8
+ before do
9
+ @mixlib_path = $LOAD_PATH.find { |p| p.match("mixlib-log") }
10
+ $LOAD_PATH.reject! { |p| p.match("mixlib-log") }
11
+
12
+ load "mixlib/authentication.rb"
13
+ end
14
+
15
+ after do
16
+ $LOAD_PATH.unshift(@mixlib_path)
17
+ end
18
+
19
+ it "uses MixlibLogMissing" do
20
+ expect(Mixlib::Authentication::Log.singleton_class.included_modules)
21
+ .to include(Mixlib::Authentication::NullLogger)
22
+ end
23
+
24
+ it "default log level is :error" do
25
+ expect(Mixlib::Authentication::Log.level).to eq(:error)
26
+ end
27
+
28
+ %w{debug info warn error fatal}.each do |level|
29
+ it "logs at level #{level}" do
30
+ expect(Mixlib::Authentication::Log).to receive(level).with("foo")
31
+
32
+ Mixlib::Authentication.logger.send(level, "foo")
33
+ end
34
+ end
35
+ end
36
+
37
+ context "with mixlib-log" do
38
+ before do
39
+ load "mixlib/authentication.rb"
40
+ end
41
+
42
+ it "uses Mixlib::Log" do
43
+ expect(Mixlib::Authentication::Log.singleton_class.included_modules)
44
+ .to include(Mixlib::Log)
45
+ end
46
+
47
+ %w{debug info warn error fatal}.each do |level|
48
+ it "forward #{level} to mixlib-log" do
49
+ expect(Mixlib::Authentication::Log.logger).to receive(level).with("foo")
50
+
51
+ Mixlib::Authentication.logger.send(level, "foo")
52
+ end
53
+ end
54
+ end
55
+ end
@@ -18,6 +18,5 @@
18
18
  #
19
19
 
20
20
  $:.unshift File.expand_path(File.join(File.dirname(__FILE__), "..", "lib")) # lib in mixlib-authentication
21
- $:.unshift File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "mixlib-log", "lib")) # mixlib-log/log
22
21
 
23
22
  require "rubygems"
metadata CHANGED
@@ -1,29 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mixlib-authentication
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.4.1
4
+ version: 1.4.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Chef Software, Inc.
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-06-08 00:00:00.000000000 Z
11
+ date: 2017-08-17 00:00:00.000000000 Z
12
12
  dependencies:
13
- - !ruby/object:Gem::Dependency
14
- name: mixlib-log
15
- requirement: !ruby/object:Gem::Requirement
16
- requirements:
17
- - - ">="
18
- - !ruby/object:Gem::Version
19
- version: '0'
20
- type: :runtime
21
- prerelease: false
22
- version_requirements: !ruby/object:Gem::Requirement
23
- requirements:
24
- - - ">="
25
- - !ruby/object:Gem::Version
26
- version: '0'
27
13
  - !ruby/object:Gem::Dependency
28
14
  name: rspec-core
29
15
  requirement: !ruby/object:Gem::Requirement
@@ -86,14 +72,14 @@ dependencies:
86
72
  requirements:
87
73
  - - "~>"
88
74
  - !ruby/object:Gem::Version
89
- version: '10.4'
75
+ version: '11'
90
76
  type: :development
91
77
  prerelease: false
92
78
  version_requirements: !ruby/object:Gem::Requirement
93
79
  requirements:
94
80
  - - "~>"
95
81
  - !ruby/object:Gem::Version
96
- version: '10.4'
82
+ version: '11'
97
83
  description: Mixes in simple per-request authentication
98
84
  email: info@chef.io
99
85
  executables: []
@@ -108,6 +94,7 @@ files:
108
94
  - lib/mixlib/authentication.rb
109
95
  - lib/mixlib/authentication/digester.rb
110
96
  - lib/mixlib/authentication/http_authentication_request.rb
97
+ - lib/mixlib/authentication/null_logger.rb
111
98
  - lib/mixlib/authentication/signatureverification.rb
112
99
  - lib/mixlib/authentication/signedheaderauth.rb
113
100
  - lib/mixlib/authentication/version.rb
@@ -115,6 +102,7 @@ files:
115
102
  - spec/mixlib/authentication/digester_spec.rb
116
103
  - spec/mixlib/authentication/http_authentication_request_spec.rb
117
104
  - spec/mixlib/authentication/mixlib_authentication_spec.rb
105
+ - spec/mixlib/authentication/mixlib_log_missing_spec.rb
118
106
  - spec/spec_helper.rb
119
107
  homepage: https://www.chef.io
120
108
  licenses:
@@ -136,7 +124,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
136
124
  version: '0'
137
125
  requirements: []
138
126
  rubyforge_project:
139
- rubygems_version: 2.4.5.1
127
+ rubygems_version: 2.6.11
140
128
  signing_key:
141
129
  specification_version: 4
142
130
  summary: Mixes in simple per-request authentication