mixlib-authentication 1.4.1 → 1.4.2

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 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