diff options
-rw-r--r-- | .travis.yml | 5 | ||||
-rw-r--r-- | Gemfile | 2 | ||||
-rw-r--r-- | Rakefile | 50 | ||||
-rw-r--r-- | lib/mixlib/authentication.rb | 16 | ||||
-rw-r--r-- | lib/mixlib/authentication/digester.rb | 12 | ||||
-rw-r--r-- | lib/mixlib/authentication/http_authentication_request.rb | 11 | ||||
-rw-r--r-- | lib/mixlib/authentication/signatureverification.rb | 65 | ||||
-rw-r--r-- | lib/mixlib/authentication/signedheaderauth.rb | 52 | ||||
-rw-r--r-- | lib/mixlib/authentication/version.rb | 3 | ||||
-rw-r--r-- | mixlib-authentication.gemspec | 13 | ||||
-rw-r--r-- | spec/mixlib/authentication/digester_spec.rb | 12 | ||||
-rw-r--r-- | spec/mixlib/authentication/http_authentication_request_spec.rb | 88 | ||||
-rw-r--r-- | spec/mixlib/authentication/mixlib_authentication_spec.rb | 256 | ||||
-rw-r--r-- | spec/spec_helper.rb | 6 |
14 files changed, 278 insertions, 313 deletions
diff --git a/.travis.yml b/.travis.yml index eff00c2..62b3473 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,10 +1,13 @@ sudo: false language: ruby rvm: - - 2.0 - 2.1 - 2.2 + - 2.3.1 branches: only: - master + +before_install: gem install bundler -v 1.11.2 +script: bundle exec rake ci @@ -2,5 +2,5 @@ source "https://rubygems.org" gemspec group(:development) do - gem 'pry' + gem "pry" end @@ -1,46 +1,18 @@ -require 'rubygems' -require 'rubygems/package_task' -require 'rubygems/specification' -require 'date' -require 'rspec/core/rake_task' +require "bundler/gem_tasks" +require "rspec/core/rake_task" -GEM = "mixlib-authentication" -GEM_VERSION = "1.2.1" -AUTHOR = "Opscode, Inc." -EMAIL = "info@opscode.com" -HOMEPAGE = "http://www.opscode.com" -SUMMARY = "Mixes in simple per-request authentication" +RSpec::Core::RakeTask.new(:spec) task :default => :spec -desc "Run specs" -RSpec::Core::RakeTask.new do |t| - t.pattern = 'spec/**/*_spec.rb' - t.rspec_opts = %w(--format documentation --color) -end - -gem_spec = eval(File.read("mixlib-authentication.gemspec")) - -Gem::PackageTask.new(gem_spec) do |pkg| - pkg.gem_spec = gem_spec -end - -desc "install the gem locally" -task :install => [:package] do - sh %{gem install pkg/#{GEM}-#{GEM_VERSION}} -end - -desc "create a gemspec file" -task :make_spec do - File.open("#{GEM}.gemspec", "w") do |file| - file.puts spec.to_ruby +begin + require "chefstyle" + require "rubocop/rake_task" + RuboCop::RakeTask.new(:style) do |task| + task.options += ["--display-cop-names", "--no-color"] end +rescue + puts "chefstyle/rubocop is not available." end -desc "remove build files" -task :clean do - sh %Q{ rm -f pkg/*.gem } -end - -desc "Run the spec and features" -task :test => [ :features, :spec ] +task :ci => [:style, :spec] diff --git a/lib/mixlib/authentication.rb b/lib/mixlib/authentication.rb index 245aa24..443512e 100644 --- a/lib/mixlib/authentication.rb +++ b/lib/mixlib/authentication.rb @@ -6,9 +6,9 @@ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at -# +# # http://www.apache.org/licenses/LICENSE-2.0 -# +# # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -16,11 +16,11 @@ # limitations under the License. # -require 'mixlib/log' +require "mixlib/log" module Mixlib module Authentication - DEFAULT_SERVER_API_VERSION = '0' + DEFAULT_SERVER_API_VERSION = "0" class AuthenticationError < StandardError end @@ -29,12 +29,10 @@ module Mixlib end class Log - extend Mixlib::Log + extend Mixlib::Log end - + Log.level = :error - + end end - - diff --git a/lib/mixlib/authentication/digester.rb b/lib/mixlib/authentication/digester.rb index c456824..8628d53 100644 --- a/lib/mixlib/authentication/digester.rb +++ b/lib/mixlib/authentication/digester.rb @@ -6,9 +6,9 @@ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at -# +# # http://www.apache.org/licenses/LICENSE-2.0 -# +# # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -16,15 +16,15 @@ # limitations under the License. # -require 'mixlib/authentication' -require 'openssl' +require "mixlib/authentication" +require "openssl" module Mixlib module Authentication class Digester class << self - def hash_file(f, digest=OpenSSL::Digest::SHA1) + def hash_file(f, digest = OpenSSL::Digest::SHA1) digester = digest.new buf = "" while f.read(16384, buf) @@ -37,7 +37,7 @@ module Mixlib # # ====Parameters # - def hash_string(str, digest=OpenSSL::Digest::SHA1) + def hash_string(str, digest = OpenSSL::Digest::SHA1) ::Base64.encode64(digest.digest(str)).chomp end diff --git a/lib/mixlib/authentication/http_authentication_request.rb b/lib/mixlib/authentication/http_authentication_request.rb index ad8354f..819f8f5 100644 --- a/lib/mixlib/authentication/http_authentication_request.rb +++ b/lib/mixlib/authentication/http_authentication_request.rb @@ -6,9 +6,9 @@ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at -# +# # http://www.apache.org/licenses/LICENSE-2.0 -# +# # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -16,7 +16,7 @@ # limitations under the License. # -require 'mixlib/authentication' +require "mixlib/authentication" module Mixlib module Authentication @@ -33,7 +33,7 @@ module Mixlib end def headers - @headers ||= @request.env.inject({ }) { |memo, kv| memo[$2.gsub(/\-/,"_").downcase.to_sym] = kv[1] if kv[0] =~ /^(HTTP_)(.*)/; memo } + @headers ||= @request.env.inject({}) { |memo, kv| memo[$2.tr("-", "_").downcase.to_sym] = kv[1] if kv[0] =~ /^(HTTP_)(.*)/; memo } end def http_method @@ -70,13 +70,12 @@ module Mixlib def request_signature unless @request_signature - @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") + @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") Mixlib::Authentication::Log.debug "Reconstituted (user-supplied) request signature: #{@request_signature}" end @request_signature end - def validate_headers! missing_headers = MANDATORY_HEADERS - headers.keys unless missing_headers.empty? diff --git a/lib/mixlib/authentication/signatureverification.rb b/lib/mixlib/authentication/signatureverification.rb index 20b18a5..842fc1f 100644 --- a/lib/mixlib/authentication/signatureverification.rb +++ b/lib/mixlib/authentication/signatureverification.rb @@ -7,9 +7,9 @@ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at -# +# # http://www.apache.org/licenses/LICENSE-2.0 -# +# # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -17,11 +17,11 @@ # limitations under the License. # -require 'net/http' -require 'forwardable' -require 'mixlib/authentication' -require 'mixlib/authentication/http_authentication_request' -require 'mixlib/authentication/signedheaderauth' +require "net/http" +require "forwardable" +require "mixlib/authentication" +require "mixlib/authentication/http_authentication_request" +require "mixlib/authentication/signedheaderauth" module Mixlib module Authentication @@ -52,7 +52,7 @@ module Mixlib include Mixlib::Authentication::SignedHeaderAuth - def initialize(request=nil) + def initialize(request = nil) @auth_request = HTTPAuthenticationRequest.new(request) if request @valid_signature, @valid_timestamp, @valid_content_hash = false, false, false @@ -60,8 +60,7 @@ module Mixlib @hashed_body = nil end - - def authenticate_user_request(request, user_lookup, time_skew=(15*60)) + def authenticate_user_request(request, user_lookup, time_skew = (15 * 60)) @auth_request = HTTPAuthenticationRequest.new(request) authenticate_request(user_lookup, time_skew) end @@ -74,9 +73,9 @@ module Mixlib # X-Ops-Sign: algorithm=sha1;version=1.0; # X-Ops-UserId: <user_id> # X-Ops-Timestamp: - # X-Ops-Content-Hash: + # X-Ops-Content-Hash: # X-Ops-Authorization-#{line_number} - def authenticate_request(user_secret, time_skew=(15*60)) + def authenticate_request(user_secret, time_skew = (15 * 60)) Mixlib::Authentication::Log.debug "Initializing header auth : #{request.inspect}" @user_secret = user_secret @@ -87,14 +86,14 @@ module Mixlib # version 1.0 clients don't include their algorithm in the # signing description, so default to sha1 - parts[:algorithm] ||= 'sha1' + parts[:algorithm] ||= "sha1" verify_signature(parts[:algorithm], parts[:version]) verify_timestamp verify_content_hash - rescue StandardError=>se - raise AuthenticationError,"Failed to authenticate user request. Check your client key and clock: #{se.message}", se.backtrace + rescue StandardError => se + raise AuthenticationError, "Failed to authenticate user request. Check your client key and clock: #{se.message}", se.backtrace end if valid_request? @@ -121,11 +120,11 @@ module Mixlib end # The authorization header is a Base64-encoded version of an RSA signature. - # The client sent it on multiple header lines, starting at index 1 - + # The client sent it on multiple header lines, starting at index 1 - # X-Ops-Authorization-1, X-Ops-Authorization-2, etc. Pull them out and # concatenate. def headers - @headers ||= request.env.inject({ }) { |memo, kv| memo[$2.gsub(/\-/,"_").downcase.to_sym] = kv[1] if kv[0] =~ /^(HTTP_)(.*)/; memo } + @headers ||= request.env.inject({}) { |memo, kv| memo[$2.tr("-", "_").downcase.to_sym] = kv[1] if kv[0] =~ /^(HTTP_)(.*)/; memo } end private @@ -142,7 +141,7 @@ module Mixlib candidate_block = canonicalize_request(algorithm, version) signature = Base64.decode64(request_signature) @valid_signature = case version - when '1.3' + when "1.3" digest = validate_sign_version_digest!(algorithm, version) @user_secret.verify(digest.new, signature, candidate_block) else @@ -177,10 +176,9 @@ module Mixlib @valid_content_hash end - # The request signature is based on any file attached, if any. Otherwise # it's based on the body of the request. - def hashed_body(digest=Digest::SHA1) + def hashed_body(digest = Digest::SHA1) unless @hashed_body # TODO: tim: 2009-112-28: It'd be nice to remove this special case, and # always hash the entire request body. In the file case it would just be @@ -189,22 +187,22 @@ module Mixlib # Pull out any file that was attached to this request, using multipart # form uploads. # Depending on the server we're running in, multipart form uploads are - # handed to us differently. - # - In Passenger (Cookbooks Community Site), the File is handed to us - # directly in the params hash. The name is whatever the client used, - # its value is therefore a File or Tempfile. + # handed to us differently. + # - In Passenger (Cookbooks Community Site), the File is handed to us + # directly in the params hash. The name is whatever the client used, + # its value is therefore a File or Tempfile. # e.g. request['file_param'] = File - # - # - In Merb (Chef server), the File is wrapped. The original parameter + # + # - In Merb (Chef server), the File is wrapped. The original parameter # name used for the file is used, but its value is a Hash. Within - # the hash is a name/value pair named 'file' which actually + # the hash is a name/value pair named 'file' which actually # contains the Tempfile instance. # e.g. request['file_param'] = { :file => Tempfile } file_param = request.params.values.find { |value| value.respond_to?(:read) } # No file_param; we're running in Merb, or it's just not there.. if file_param.nil? - hash_param = request.params.values.find { |value| value.respond_to?(:has_key?) } # Hash responds to :has_key? . + hash_param = request.params.values.find { |value| value.respond_to?(:has_key?) } # Hash responds to :has_key? . if !hash_param.nil? file_param = hash_param.values.find { |value| value.respond_to?(:read) } # File/Tempfile responds to :read. end @@ -225,22 +223,19 @@ module Mixlib end # Compare the request timestamp with boundary time - # - # + # + # # ====Parameters # time1<Time>:: minuend # time2<Time>:: subtrahend # def timestamp_within_bounds?(time1, time2) - time_diff = (time2-time1).abs + time_diff = (time2 - time1).abs is_allowed = (time_diff < @allowed_time_skew) Mixlib::Authentication::Log.debug "Request time difference: #{time_diff}, within #{@allowed_time_skew} seconds? : #{!!is_allowed}" - is_allowed + is_allowed end end - end end - - diff --git a/lib/mixlib/authentication/signedheaderauth.rb b/lib/mixlib/authentication/signedheaderauth.rb index 09a22ee..ab8d989 100644 --- a/lib/mixlib/authentication/signedheaderauth.rb +++ b/lib/mixlib/authentication/signedheaderauth.rb @@ -17,11 +17,11 @@ # limitations under the License. # -require 'time' -require 'base64' -require 'openssl/digest' -require 'mixlib/authentication' -require 'mixlib/authentication/digester' +require "time" +require "base64" +require "openssl/digest" +require "mixlib/authentication" +require "mixlib/authentication/digester" module Mixlib module Authentication @@ -31,18 +31,18 @@ module Mixlib NULL_ARG = Object.new ALGORITHM_FOR_VERSION = { - '1.0' => 'sha1', - '1.1' => 'sha1', - '1.3' => 'sha256', + "1.0" => "sha1", + "1.1" => "sha1", + "1.3" => "sha256", }.freeze() # Use of SUPPORTED_ALGORITHMS and SUPPORTED_VERSIONS is deprecated. Use # ALGORITHM_FOR_VERSION instead - SUPPORTED_ALGORITHMS = ['sha1'].freeze - SUPPORTED_VERSIONS = ['1.0', '1.1'].freeze + SUPPORTED_ALGORITHMS = ["sha1"].freeze + SUPPORTED_VERSIONS = ["1.0", "1.1"].freeze - DEFAULT_SIGN_ALGORITHM = 'sha1'.freeze - DEFAULT_PROTO_VERSION = '1.0'.freeze + DEFAULT_SIGN_ALGORITHM = "sha1".freeze + DEFAULT_PROTO_VERSION = "1.0".freeze # === signing_object # This is the intended interface for signing requests with the @@ -72,7 +72,7 @@ module Mixlib # ==== Other Parameters: # These parameters are accepted but not used in the computation of the signature. # * `:host`: The host part of the URI - def self.signing_object(args={ }) + def self.signing_object(args = {}) SigningObject.new(args[:http_method], args[:path], args[:body], @@ -97,7 +97,7 @@ module Mixlib # compute the signature from the request, using the looked-up user secret # ====Parameters # private_key<OpenSSL::PKey::RSA>:: user's RSA private key. - def sign(private_key, sign_algorithm=algorithm, sign_version=proto_version) + def sign(private_key, sign_algorithm = algorithm, sign_version = proto_version) digest = validate_sign_version_digest!(sign_algorithm, sign_version) # Our multiline hash for authorization will be encoded in multiple header # lines - X-Ops-Authorization-1, ... (starts at 1, not 0!) @@ -132,9 +132,9 @@ module Mixlib end case sign_algorithm - when 'sha1' + when "sha1" OpenSSL::Digest::SHA1 - when 'sha256' + when "sha256" OpenSSL::Digest::SHA256 else # This case should never happen @@ -156,11 +156,11 @@ module Mixlib # ====Parameters # def canonical_path - p = path.gsub(/\/+/,'/') - p.length > 1 ? p.chomp('/') : p + p = path.gsub(/\/+/, "/") + p.length > 1 ? p.chomp("/") : p end - def hashed_body(digest=OpenSSL::Digest::SHA1) + def hashed_body(digest = OpenSSL::Digest::SHA1) # This is weird. sign() is called with the digest type and signing # version. These are also expected to be properties of the object. # Hence, we're going to assume the one that is passed to sign is @@ -189,7 +189,7 @@ module Mixlib # ====Parameters # # - def canonicalize_request(sign_algorithm=algorithm, sign_version=proto_version) + def canonicalize_request(sign_algorithm = algorithm, sign_version = proto_version) digest = validate_sign_version_digest!(sign_algorithm, sign_version) canonical_x_ops_user_id = canonicalize_user_id(user_id, sign_version, digest) case sign_version @@ -209,12 +209,12 @@ module Mixlib "Hashed Path:#{digester.hash_string(canonical_path, digest)}", "X-Ops-Content-Hash:#{hashed_body(digest)}", "X-Ops-Timestamp:#{canonical_time}", - "X-Ops-UserId:#{canonical_x_ops_user_id}" + "X-Ops-UserId:#{canonical_x_ops_user_id}", ].join("\n") end end - def canonicalize_user_id(user_id, proto_version, digest=OpenSSL::Digest::SHA1) + def canonicalize_user_id(user_id, proto_version, digest = OpenSSL::Digest::SHA1) case proto_version when "1.1" # and 1.2 if that ever gets implemented @@ -230,7 +230,7 @@ module Mixlib # ====Parameters # def parse_signing_description - parts = signing_description.strip.split(";").inject({ }) do |memo, part| + parts = signing_description.strip.split(";").inject({}) do |memo, part| field_name, field_value = part.split("=") memo[field_name.to_sym] = field_value.strip memo @@ -248,7 +248,7 @@ module Mixlib string_to_sign = canonicalize_request(sign_algorithm, sign_version) Mixlib::Authentication::Log.debug "String to sign: '#{string_to_sign}'" case sign_version - when '1.3' + when "1.3" private_key.sign(digest.new, string_to_sign) else private_key.private_encrypt(string_to_sign) @@ -269,12 +269,12 @@ module Mixlib include SignedHeaderAuth def proto_version - (self[:proto_version] or DEFAULT_PROTO_VERSION).to_s + (self[:proto_version] || DEFAULT_PROTO_VERSION).to_s end def server_api_version key = (self[:headers] || {}).keys.select do |k| - k.downcase == 'x-ops-server-api-version' + k.downcase == "x-ops-server-api-version" end.first if key self[:headers][key] diff --git a/lib/mixlib/authentication/version.rb b/lib/mixlib/authentication/version.rb index 3af3f48..8a832fd 100644 --- a/lib/mixlib/authentication/version.rb +++ b/lib/mixlib/authentication/version.rb @@ -13,9 +13,8 @@ # See the License for the specific language governing permissions and # limitations under the License. - module Mixlib module Authentication - VERSION = '1.4.1' + VERSION = "1.4.1" end end diff --git a/mixlib-authentication.gemspec b/mixlib-authentication.gemspec index d39b286..d48dbeb 100644 --- a/mixlib-authentication.gemspec +++ b/mixlib-authentication.gemspec @@ -1,5 +1,5 @@ -$:.unshift(File.dirname(__FILE__) + '/lib') -require 'mixlib/authentication/version' +$:.unshift(File.dirname(__FILE__) + "/lib") +require "mixlib/authentication/version" Gem::Specification.new do |s| s.name = "mixlib-authentication" @@ -15,10 +15,11 @@ Gem::Specification.new do |s| # Uncomment this to add a dependency s.add_dependency "mixlib-log" - s.require_path = 'lib' - s.files = %w(LICENSE README.md Gemfile Rakefile NOTICE) + Dir.glob("*.gemspec") + - Dir.glob("{lib,spec}/**/*", File::FNM_DOTMATCH).reject {|f| File.directory?(f) } + s.require_path = "lib" + s.files = %w{LICENSE README.md Gemfile Rakefile NOTICE} + Dir.glob("*.gemspec") + + Dir.glob("{lib,spec}/**/*", File::FNM_DOTMATCH).reject { |f| File.directory?(f) } - %w(rspec-core rspec-expectations rspec-mocks).each { |gem| s.add_development_dependency gem, "~> 3.2" } + %w{rspec-core rspec-expectations rspec-mocks}.each { |gem| s.add_development_dependency gem, "~> 3.2" } + s.add_development_dependency "chefstyle" s.add_development_dependency "rake", "~> 10.4" end diff --git a/spec/mixlib/authentication/digester_spec.rb b/spec/mixlib/authentication/digester_spec.rb index 747227d..fd3eb41 100644 --- a/spec/mixlib/authentication/digester_spec.rb +++ b/spec/mixlib/authentication/digester_spec.rb @@ -1,21 +1,21 @@ -require 'mixlib/authentication/digester' +require "mixlib/authentication/digester" describe Mixlib::Authentication::Digester do - context 'backcompat' do + context "backcompat" do # The digester API should really have been private, # however oc-chef-pedant uses it. - let(:test_string) { 'hello' } - let(:test_string_checksum) { 'qvTGHdzF6KLavt4PO0gs2a6pQ00=' } + let(:test_string) { "hello" } + let(:test_string_checksum) { "qvTGHdzF6KLavt4PO0gs2a6pQ00=" } describe '#hash_file' do - it 'should default to use SHA1' do + it "should default to use SHA1" do expect(described_class.hash_file(StringIO.new(test_string))).to( eq(test_string_checksum)) end end describe '#hash_string' do - it 'should default to use SHA1' do + it "should default to use SHA1" do expect(described_class.hash_string(test_string)).to( eq(test_string_checksum)) end diff --git a/spec/mixlib/authentication/http_authentication_request_spec.rb b/spec/mixlib/authentication/http_authentication_request_spec.rb index 1c6c814..0025cf4 100644 --- a/spec/mixlib/authentication/http_authentication_request_spec.rb +++ b/spec/mixlib/authentication/http_authentication_request_spec.rb @@ -5,9 +5,9 @@ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at -# +# # http://www.apache.org/licenses/LICENSE-2.0 -# +# # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -15,12 +15,12 @@ # limitations under the License. # -require File.expand_path(File.join(File.dirname(__FILE__), '..','..','spec_helper')) +require File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "spec_helper")) -require 'mixlib/authentication' -require 'mixlib/authentication/http_authentication_request' -require 'ostruct' -require 'pp' +require "mixlib/authentication" +require "mixlib/authentication/http_authentication_request" +require "ostruct" +require "pp" describe Mixlib::Authentication::HTTPAuthenticationRequest do before do @@ -39,66 +39,66 @@ describe Mixlib::Authentication::HTTPAuthenticationRequest do @merb_headers = { # These are used by signatureverification. An arbitrary sampling of non-HTTP_* # headers are in here to exercise that code path. - "HTTP_HOST"=>"127.0.0.1", - "HTTP_X_OPS_SIGN"=>"version=1.0", - "HTTP_X_OPS_REQUESTID"=>"127.0.0.1 1258566194.85386", - "HTTP_X_OPS_TIMESTAMP"=>@timestamp_iso8601, - "HTTP_X_OPS_CONTENT_HASH"=>@x_ops_content_hash, - "HTTP_X_OPS_USERID"=>@user_id, - "HTTP_X_OPS_AUTHORIZATION_1"=>@http_x_ops_lines[0], - "HTTP_X_OPS_AUTHORIZATION_2"=>@http_x_ops_lines[1], - "HTTP_X_OPS_AUTHORIZATION_3"=>@http_x_ops_lines[2], - "HTTP_X_OPS_AUTHORIZATION_4"=>@http_x_ops_lines[3], - "HTTP_X_OPS_AUTHORIZATION_5"=>@http_x_ops_lines[4], - "HTTP_X_OPS_AUTHORIZATION_6"=>@http_x_ops_lines[5], + "HTTP_HOST" => "127.0.0.1", + "HTTP_X_OPS_SIGN" => "version=1.0", + "HTTP_X_OPS_REQUESTID" => "127.0.0.1 1258566194.85386", + "HTTP_X_OPS_TIMESTAMP" => @timestamp_iso8601, + "HTTP_X_OPS_CONTENT_HASH" => @x_ops_content_hash, + "HTTP_X_OPS_USERID" => @user_id, + "HTTP_X_OPS_AUTHORIZATION_1" => @http_x_ops_lines[0], + "HTTP_X_OPS_AUTHORIZATION_2" => @http_x_ops_lines[1], + "HTTP_X_OPS_AUTHORIZATION_3" => @http_x_ops_lines[2], + "HTTP_X_OPS_AUTHORIZATION_4" => @http_x_ops_lines[3], + "HTTP_X_OPS_AUTHORIZATION_5" => @http_x_ops_lines[4], + "HTTP_X_OPS_AUTHORIZATION_6" => @http_x_ops_lines[5], # Random sampling - "REMOTE_ADDR"=>"127.0.0.1", - "PATH_INFO"=>"/organizations/local-test-org/cookbooks", - "REQUEST_PATH"=>"/organizations/local-test-org/cookbooks", - "CONTENT_TYPE"=>"multipart/form-data; boundary=----RubyMultipartClient6792ZZZZZ", - "CONTENT_LENGTH"=>"394", + "REMOTE_ADDR" => "127.0.0.1", + "PATH_INFO" => "/organizations/local-test-org/cookbooks", + "REQUEST_PATH" => "/organizations/local-test-org/cookbooks", + "CONTENT_TYPE" => "multipart/form-data; boundary=----RubyMultipartClient6792ZZZZZ", + "CONTENT_LENGTH" => "394", } - @request = request.new(@merb_headers, "POST", '/nodes') + @request = request.new(@merb_headers, "POST", "/nodes") @http_authentication_request = Mixlib::Authentication::HTTPAuthenticationRequest.new(@request) end it "normalizes the headers to lowercase symbols" do - expected = {:host=>"127.0.0.1", - :x_ops_sign=>"version=1.0", - :x_ops_requestid=>"127.0.0.1 1258566194.85386", - :x_ops_timestamp=>"2009-01-01T12:00:00Z", - :x_ops_content_hash=>"DFteJZPVv6WKdQmMqZUQUumUyRs=", - :x_ops_userid=>"spec-user", - :x_ops_authorization_1=>"jVHrNniWzpbez/eGWjFnO6lINRIuKOg40ZTIQudcFe47Z9e/HvrszfVXlKG4", - :x_ops_authorization_2=>"NMzYZgyooSvU85qkIUmKuCqgG2AIlvYa2Q/2ctrMhoaHhLOCWWoqYNMaEqPc", - :x_ops_authorization_3=>"3tKHE+CfvP+WuPdWk4jv4wpIkAz6ZLxToxcGhXmZbXpk56YTmqgBW2cbbw4O", - :x_ops_authorization_4=>"IWPZDHSiPcw//AYNgW1CCDptt+UFuaFYbtqZegcBd2n/jzcWODA7zL4KWEUy", - :x_ops_authorization_5=>"9q4rlh/+1tBReg60QdsmDRsw/cdO1GZrKtuCwbuD4+nbRdVBKv72rqHX9cu0", - :x_ops_authorization_6=>"utju9jzczCyB+sSAQWrxSsXB/b8vV2qs0l4VD2ML+w=="} + expected = { :host => "127.0.0.1", + :x_ops_sign => "version=1.0", + :x_ops_requestid => "127.0.0.1 1258566194.85386", + :x_ops_timestamp => "2009-01-01T12:00:00Z", + :x_ops_content_hash => "DFteJZPVv6WKdQmMqZUQUumUyRs=", + :x_ops_userid => "spec-user", + :x_ops_authorization_1 => "jVHrNniWzpbez/eGWjFnO6lINRIuKOg40ZTIQudcFe47Z9e/HvrszfVXlKG4", + :x_ops_authorization_2 => "NMzYZgyooSvU85qkIUmKuCqgG2AIlvYa2Q/2ctrMhoaHhLOCWWoqYNMaEqPc", + :x_ops_authorization_3 => "3tKHE+CfvP+WuPdWk4jv4wpIkAz6ZLxToxcGhXmZbXpk56YTmqgBW2cbbw4O", + :x_ops_authorization_4 => "IWPZDHSiPcw//AYNgW1CCDptt+UFuaFYbtqZegcBd2n/jzcWODA7zL4KWEUy", + :x_ops_authorization_5 => "9q4rlh/+1tBReg60QdsmDRsw/cdO1GZrKtuCwbuD4+nbRdVBKv72rqHX9cu0", + :x_ops_authorization_6 => "utju9jzczCyB+sSAQWrxSsXB/b8vV2qs0l4VD2ML+w==" } expect(@http_authentication_request.headers).to eq(expected) end it "raises an error when not all required headers are given" do @merb_headers.delete("HTTP_X_OPS_SIGN") exception = Mixlib::Authentication::MissingAuthenticationHeader - expect{ Mixlib::Authentication::HTTPAuthenticationRequest.new(@request) }.to raise_error(exception) + expect { Mixlib::Authentication::HTTPAuthenticationRequest.new(@request) }.to raise_error(exception) end it "extracts the path from the request" do - expect(@http_authentication_request.path).to eq('/nodes') + expect(@http_authentication_request.path).to eq("/nodes") end it "extracts the request method from the request" do - expect(@http_authentication_request.http_method).to eq('POST') + expect(@http_authentication_request.http_method).to eq("POST") end it "extracts the signing description from the request headers" do - expect(@http_authentication_request.signing_description).to eq('version=1.0') + expect(@http_authentication_request.signing_description).to eq("version=1.0") end it "extracts the user_id from the request headers" do - expect(@http_authentication_request.user_id).to eq('spec-user') + expect(@http_authentication_request.user_id).to eq("spec-user") end it "extracts the timestamp from the request headers" do @@ -114,7 +114,7 @@ describe Mixlib::Authentication::HTTPAuthenticationRequest do end it "rebuilds the request signature from the headers" do - expected=<<-SIG + expected = <<-SIG jVHrNniWzpbez/eGWjFnO6lINRIuKOg40ZTIQudcFe47Z9e/HvrszfVXlKG4 NMzYZgyooSvU85qkIUmKuCqgG2AIlvYa2Q/2ctrMhoaHhLOCWWoqYNMaEqPc 3tKHE+CfvP+WuPdWk4jv4wpIkAz6ZLxToxcGhXmZbXpk56YTmqgBW2cbbw4O @@ -126,7 +126,7 @@ SIG end it "defaults to server api version 0" do - expect(@http_authentication_request.server_api_version).to eq('0') + expect(@http_authentication_request.server_api_version).to eq("0") end end diff --git a/spec/mixlib/authentication/mixlib_authentication_spec.rb b/spec/mixlib/authentication/mixlib_authentication_spec.rb index 69500a4..d0e8071 100644 --- a/spec/mixlib/authentication/mixlib_authentication_spec.rb +++ b/spec/mixlib/authentication/mixlib_authentication_spec.rb @@ -18,13 +18,13 @@ # limitations under the License. # -require File.expand_path(File.join(File.dirname(__FILE__), '..','..','spec_helper')) -require 'rubygems' +require File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "spec_helper")) +require "rubygems" -require 'ostruct' -require 'openssl' -require 'mixlib/authentication/signatureverification' -require 'time' +require "ostruct" +require "openssl" +require "mixlib/authentication/signatureverification" +require "time" # TODO: should make these regular spec-based mock objects. class MockRequest @@ -102,10 +102,9 @@ describe "Mixlib::Authentication::SignedHeaderAuth" do expect(V1_3_SHA256_SIGNING_OBJECT.sign(PRIVATE_KEY)).to eq(EXPECTED_SIGN_RESULT_V1_3_SHA256) end - it "should generate the correct string to sign and signature for non-default proto version when used as a mixin" do - algorithm = 'sha1' - version = '1.1' + algorithm = "sha1" + version = "1.1" V1_1_SIGNING_OBJECT.proto_version = "1.0" expect(V1_1_SIGNING_OBJECT.proto_version).to eq("1.0") @@ -118,19 +117,19 @@ describe "Mixlib::Authentication::SignedHeaderAuth" do end it "should not choke when signing a request for a long user id with version 1.1" do - expect { LONG_SIGNING_OBJECT.sign(PRIVATE_KEY, 'sha1', '1.1') }.not_to raise_error + expect { LONG_SIGNING_OBJECT.sign(PRIVATE_KEY, "sha1", "1.1") }.not_to raise_error end it "should choke when signing a request for a long user id with version 1.0" do - expect { LONG_SIGNING_OBJECT.sign(PRIVATE_KEY, 'sha1', '1.0') }.to raise_error(OpenSSL::PKey::RSAError) + expect { LONG_SIGNING_OBJECT.sign(PRIVATE_KEY, "sha1", "1.0") }.to raise_error(OpenSSL::PKey::RSAError) end it "should choke when signing a request with a bad version" do - expect { V1_1_SIGNING_OBJECT.sign(PRIVATE_KEY, 'sha1', 'poo') }.to raise_error(Mixlib::Authentication::AuthenticationError) + expect { V1_1_SIGNING_OBJECT.sign(PRIVATE_KEY, "sha1", "poo") }.to raise_error(Mixlib::Authentication::AuthenticationError) end it "should choke when signing a request with a bad algorithm" do - expect { V1_1_SIGNING_OBJECT.sign(PRIVATE_KEY, 'sha_poo', '1.1') }.to raise_error(Mixlib::Authentication::AuthenticationError) + expect { V1_1_SIGNING_OBJECT.sign(PRIVATE_KEY, "sha_poo", "1.1") }.to raise_error(Mixlib::Authentication::AuthenticationError) end end @@ -144,7 +143,7 @@ describe "Mixlib::Authentication::SignatureVerification" do it "should authenticate a File-containing request V1.1 - Merb" do request_params = MERB_REQUEST_PARAMS.clone request_params["file"] = - { "size"=>MockFile.length, "content_type"=>"application/octet-stream", "filename"=>"zsh.tar.gz", "tempfile"=>MockFile.new } + { "size" => MockFile.length, "content_type" => "application/octet-stream", "filename" => "zsh.tar.gz", "tempfile" => MockFile.new } mock_request = MockRequest.new(PATH, request_params, MERB_HEADERS_V1_1, "") expect(Time).to receive(:now).at_least(:once).and_return(TIMESTAMP_OBJ) @@ -157,7 +156,7 @@ describe "Mixlib::Authentication::SignatureVerification" do it "should authenticate a File-containing request V1.3 SHA256 - Merb" do request_params = MERB_REQUEST_PARAMS.clone request_params["file"] = - { "size"=>MockFile.length, "content_type"=>"application/octet-stream", "filename"=>"zsh.tar.gz", "tempfile"=>MockFile.new } + { "size" => MockFile.length, "content_type" => "application/octet-stream", "filename" => "zsh.tar.gz", "tempfile" => MockFile.new } mock_request = MockRequest.new(PATH, request_params, MERB_HEADERS_V1_3_SHA256, "") expect(Time).to receive(:now).at_least(:once).and_return(TIMESTAMP_OBJ) @@ -215,7 +214,7 @@ describe "Mixlib::Authentication::SignatureVerification" do #Time.stub!(:now).and_return(TIMESTAMP_OBJ) auth_req = Mixlib::Authentication::SignatureVerification.new - expect {auth_req.authenticate_user_request(mock_request, @user_private_key)}.to raise_error(Mixlib::Authentication::AuthenticationError) + expect { auth_req.authenticate_user_request(mock_request, @user_private_key) }.to raise_error(Mixlib::Authentication::AuthenticationError) expect(auth_req).not_to be_a_valid_request expect(auth_req).not_to be_a_valid_timestamp @@ -223,7 +222,6 @@ describe "Mixlib::Authentication::SignatureVerification" do expect(auth_req).not_to be_a_valid_content_hash end - it "shouldn't authenticate if Authorization header is wrong" do headers = MERB_HEADERS_V1_1.clone headers["HTTP_X_OPS_CONTENT_HASH"] += "_" @@ -255,7 +253,7 @@ describe "Mixlib::Authentication::SignatureVerification" do end it "shouldn't authenticate if the signature is wrong" do - headers = MERB_HEADERS_V1_1.dup + headers = MERB_HEADERS_V1_1.dup headers["HTTP_X_OPS_AUTHORIZATION_1"] = "epicfail" mock_request = MockRequest.new(PATH, MERB_REQUEST_PARAMS, headers, BODY) expect(Time).to receive(:now).at_least(:once).and_return(TIMESTAMP_OBJ) @@ -270,7 +268,7 @@ describe "Mixlib::Authentication::SignatureVerification" do end it "shouldn't authenticate if the signature is wrong for v1.3 SHA256" do - headers = MERB_HEADERS_V1_3_SHA256.dup + headers = MERB_HEADERS_V1_3_SHA256.dup headers["HTTP_X_OPS_AUTHORIZATION_1"] = "epicfail" mock_request = MockRequest.new(PATH, MERB_REQUEST_PARAMS, headers, BODY) expect(Time).to receive(:now).at_least(:once).and_return(TIMESTAMP_OBJ) @@ -301,7 +299,7 @@ V1_0_ARGS = { :http_method => :post, :timestamp => TIMESTAMP_ISO8601, # fixed timestamp so we get back the same answer each time. :file => MockFile.new, - :path => PATH + :path => PATH, } V1_1_ARGS = { @@ -311,7 +309,7 @@ V1_1_ARGS = { :timestamp => TIMESTAMP_ISO8601, # fixed timestamp so we get back the same answer each time. :file => MockFile.new, :path => PATH, - :proto_version => 1.1 + :proto_version => 1.1, } V1_3_ARGS_SHA256 = { @@ -321,9 +319,9 @@ V1_3_ARGS_SHA256 = { :timestamp => TIMESTAMP_ISO8601, # fixed timestamp so we get back the same answer each time. :file => MockFile.new, :path => PATH, - :proto_version => '1.3', + :proto_version => "1.3", :headers => { - 'X-OpS-SeRvEr-ApI-VerSiOn' => '1' + "X-OpS-SeRvEr-ApI-VerSiOn" => "1", } # This defaults to sha256 } @@ -332,9 +330,9 @@ LONG_PATH_LONG_USER_ARGS = { :body => BODY, :user_id => "A" * 200, :http_method => :put, - :timestamp => TIMESTAMP_ISO8601, # fixed timestamp so we get back the same answer each time. + :timestamp => TIMESTAMP_ISO8601, # fixed timestamp so we get back the same answer each time. :file => MockFile.new, - :path => PATH + "/nodes/#{"A" * 250}" + :path => PATH + "/nodes/#{"A" * 250}", } REQUESTING_ACTOR_ID = "c0f8a68c52bffa1020222a56b23cccfa" @@ -349,7 +347,7 @@ X_OPS_AUTHORIZATION_LINES_V1_0 = [ "3tKHE+CfvP+WuPdWk4jv4wpIkAz6ZLxToxcGhXmZbXpk56YTmqgBW2cbbw4O", "IWPZDHSiPcw//AYNgW1CCDptt+UFuaFYbtqZegcBd2n/jzcWODA7zL4KWEUy", "9q4rlh/+1tBReg60QdsmDRsw/cdO1GZrKtuCwbuD4+nbRdVBKv72rqHX9cu0", -"utju9jzczCyB+sSAQWrxSsXB/b8vV2qs0l4VD2ML+w==" +"utju9jzczCyB+sSAQWrxSsXB/b8vV2qs0l4VD2ML+w==", ] X_OPS_AUTHORIZATION_LINES = [ @@ -358,7 +356,7 @@ X_OPS_AUTHORIZATION_LINES = [ "c2R9bx/43IWA/r8w8Q6decuu0f6ZlNheJeJhaYPI8piX/aH+uHBH8zTACZu8", "vMnl5MF3/OIlsZc8cemq6eKYstp8a8KYq9OmkB5IXIX6qVMJHA6fRvQEB/7j", "281Q7oI/O+lE8AmVyBbwruPb7Mp6s4839eYiOdjbDwFjYtbS3XgAjrHlaD7W", -"FDlbAG7H8Dmvo+wBxmtNkszhzbBnEYtuwQqT8nM/8A==" +"FDlbAG7H8Dmvo+wBxmtNkszhzbBnEYtuwQqT8nM/8A==", ] X_OPS_AUTHORIZATION_LINES_V1_3_SHA256 = [ @@ -367,154 +365,154 @@ X_OPS_AUTHORIZATION_LINES_V1_3_SHA256 = [ "42dZ9N+V9I5SVfcL/lWrrlpdybfceJC5jOcP5tzfJXWUITwb6Z3Erg3DU3Uh", "H9h9E0qWlYGqmiNCVrBnpe6Si1gU/Jl+rXlRSNbLJ4GlArAPuL976iTYJTzE", "MmbLUIm3JRYi00Yb01IUCCKdI90vUq1HHNtlTEu93YZfQaJwRxXlGkCNwIJe", - "fy49QzaCIEu1XiOx5Jn+4GmkrZch/RrK9VzQWXgs+w==" + "fy49QzaCIEu1XiOx5Jn+4GmkrZch/RrK9VzQWXgs+w==", ] # We expect Mixlib::Authentication::SignedHeaderAuth#sign to return this # if passed the BODY above, based on version EXPECTED_SIGN_RESULT_V1_0 = { - "X-Ops-Content-Hash"=>X_OPS_CONTENT_HASH, - "X-Ops-Userid"=>USER_ID, - "X-Ops-Sign"=>"algorithm=sha1;version=1.0;", - "X-Ops-Authorization-1"=>X_OPS_AUTHORIZATION_LINES_V1_0[0], - "X-Ops-Authorization-2"=>X_OPS_AUTHORIZATION_LINES_V1_0[1], - "X-Ops-Authorization-3"=>X_OPS_AUTHORIZATION_LINES_V1_0[2], - "X-Ops-Authorization-4"=>X_OPS_AUTHORIZATION_LINES_V1_0[3], - "X-Ops-Authorization-5"=>X_OPS_AUTHORIZATION_LINES_V1_0[4], - "X-Ops-Authorization-6"=>X_OPS_AUTHORIZATION_LINES_V1_0[5], - "X-Ops-Timestamp"=>TIMESTAMP_ISO8601 + "X-Ops-Content-Hash" => X_OPS_CONTENT_HASH, + "X-Ops-Userid" => USER_ID, + "X-Ops-Sign" => "algorithm=sha1;version=1.0;", + "X-Ops-Authorization-1" => X_OPS_AUTHORIZATION_LINES_V1_0[0], + "X-Ops-Authorization-2" => X_OPS_AUTHORIZATION_LINES_V1_0[1], + "X-Ops-Authorization-3" => X_OPS_AUTHORIZATION_LINES_V1_0[2], + "X-Ops-Authorization-4" => X_OPS_AUTHORIZATION_LINES_V1_0[3], + "X-Ops-Authorization-5" => X_OPS_AUTHORIZATION_LINES_V1_0[4], + "X-Ops-Authorization-6" => X_OPS_AUTHORIZATION_LINES_V1_0[5], + "X-Ops-Timestamp" => TIMESTAMP_ISO8601, } EXPECTED_SIGN_RESULT_V1_1 = { - "X-Ops-Content-Hash"=>X_OPS_CONTENT_HASH, - "X-Ops-Userid"=>USER_ID, - "X-Ops-Sign"=>"algorithm=sha1;version=1.1;", - "X-Ops-Authorization-1"=>X_OPS_AUTHORIZATION_LINES[0], - "X-Ops-Authorization-2"=>X_OPS_AUTHORIZATION_LINES[1], - "X-Ops-Authorization-3"=>X_OPS_AUTHORIZATION_LINES[2], - "X-Ops-Authorization-4"=>X_OPS_AUTHORIZATION_LINES[3], - "X-Ops-Authorization-5"=>X_OPS_AUTHORIZATION_LINES[4], - "X-Ops-Authorization-6"=>X_OPS_AUTHORIZATION_LINES[5], - "X-Ops-Timestamp"=>TIMESTAMP_ISO8601 + "X-Ops-Content-Hash" => X_OPS_CONTENT_HASH, + "X-Ops-Userid" => USER_ID, + "X-Ops-Sign" => "algorithm=sha1;version=1.1;", + "X-Ops-Authorization-1" => X_OPS_AUTHORIZATION_LINES[0], + "X-Ops-Authorization-2" => X_OPS_AUTHORIZATION_LINES[1], + "X-Ops-Authorization-3" => X_OPS_AUTHORIZATION_LINES[2], + "X-Ops-Authorization-4" => X_OPS_AUTHORIZATION_LINES[3], + "X-Ops-Authorization-5" => X_OPS_AUTHORIZATION_LINES[4], + "X-Ops-Authorization-6" => X_OPS_AUTHORIZATION_LINES[5], + "X-Ops-Timestamp" => TIMESTAMP_ISO8601, } EXPECTED_SIGN_RESULT_V1_3_SHA256 = { - "X-Ops-Content-Hash"=>X_OPS_CONTENT_HASH_SHA256, - "X-Ops-Userid"=>USER_ID, - "X-Ops-Sign"=>"algorithm=sha256;version=1.3;", - "X-Ops-Authorization-1"=>X_OPS_AUTHORIZATION_LINES_V1_3_SHA256[0], - "X-Ops-Authorization-2"=>X_OPS_AUTHORIZATION_LINES_V1_3_SHA256[1], - "X-Ops-Authorization-3"=>X_OPS_AUTHORIZATION_LINES_V1_3_SHA256[2], - "X-Ops-Authorization-4"=>X_OPS_AUTHORIZATION_LINES_V1_3_SHA256[3], - "X-Ops-Authorization-5"=>X_OPS_AUTHORIZATION_LINES_V1_3_SHA256[4], - "X-Ops-Authorization-6"=>X_OPS_AUTHORIZATION_LINES_V1_3_SHA256[5], - "X-Ops-Timestamp"=>TIMESTAMP_ISO8601 + "X-Ops-Content-Hash" => X_OPS_CONTENT_HASH_SHA256, + "X-Ops-Userid" => USER_ID, + "X-Ops-Sign" => "algorithm=sha256;version=1.3;", + "X-Ops-Authorization-1" => X_OPS_AUTHORIZATION_LINES_V1_3_SHA256[0], + "X-Ops-Authorization-2" => X_OPS_AUTHORIZATION_LINES_V1_3_SHA256[1], + "X-Ops-Authorization-3" => X_OPS_AUTHORIZATION_LINES_V1_3_SHA256[2], + "X-Ops-Authorization-4" => X_OPS_AUTHORIZATION_LINES_V1_3_SHA256[3], + "X-Ops-Authorization-5" => X_OPS_AUTHORIZATION_LINES_V1_3_SHA256[4], + "X-Ops-Authorization-6" => X_OPS_AUTHORIZATION_LINES_V1_3_SHA256[5], + "X-Ops-Timestamp" => TIMESTAMP_ISO8601, } OTHER_HEADERS = { # An arbitrary sampling of non-HTTP_* headers are in here to # exercise that code path. - "REMOTE_ADDR"=>"127.0.0.1", - "PATH_INFO"=>"/organizations/local-test-org/cookbooks", - "REQUEST_PATH"=>"/organizations/local-test-org/cookbooks", - "CONTENT_TYPE"=>"multipart/form-data; boundary=----RubyMultipartClient6792ZZZZZ", - "CONTENT_LENGTH"=>"394", + "REMOTE_ADDR" => "127.0.0.1", + "PATH_INFO" => "/organizations/local-test-org/cookbooks", + "REQUEST_PATH" => "/organizations/local-test-org/cookbooks", + "CONTENT_TYPE" => "multipart/form-data; boundary=----RubyMultipartClient6792ZZZZZ", + "CONTENT_LENGTH" => "394", } # This is what will be in request.params for the Merb case. MERB_REQUEST_PARAMS = { - "name"=>"zsh", "action"=>"create", "controller"=>"chef_server_api/cookbooks", - "organization_id"=>"local-test-org", "requesting_actor_id"=>REQUESTING_ACTOR_ID, + "name" => "zsh", "action" => "create", "controller" => "chef_server_api/cookbooks", + "organization_id" => "local-test-org", "requesting_actor_id" => REQUESTING_ACTOR_ID } MERB_HEADERS_V1_3_SHA256 = { # These are used by signatureverification. - "HTTP_HOST"=>"127.0.0.1", - "HTTP_X_OPS_SIGN"=>"algorithm=sha256;version=1.3;", - "HTTP_X_OPS_REQUESTID"=>"127.0.0.1 1258566194.85386", - "HTTP_X_OPS_TIMESTAMP"=>TIMESTAMP_ISO8601, - "HTTP_X_OPS_CONTENT_HASH"=>X_OPS_CONTENT_HASH_SHA256, - "HTTP_X_OPS_USERID"=>USER_ID, - "HTTP_X_OPS_SERVER_API_VERSION"=>"1", - "HTTP_X_OPS_AUTHORIZATION_1"=>X_OPS_AUTHORIZATION_LINES_V1_3_SHA256[0], - "HTTP_X_OPS_AUTHORIZATION_2"=>X_OPS_AUTHORIZATION_LINES_V1_3_SHA256[1], - "HTTP_X_OPS_AUTHORIZATION_3"=>X_OPS_AUTHORIZATION_LINES_V1_3_SHA256[2], - "HTTP_X_OPS_AUTHORIZATION_4"=>X_OPS_AUTHORIZATION_LINES_V1_3_SHA256[3], - "HTTP_X_OPS_AUTHORIZATION_5"=>X_OPS_AUTHORIZATION_LINES_V1_3_SHA256[4], - "HTTP_X_OPS_AUTHORIZATION_6"=>X_OPS_AUTHORIZATION_LINES_V1_3_SHA256[5], + "HTTP_HOST" => "127.0.0.1", + "HTTP_X_OPS_SIGN" => "algorithm=sha256;version=1.3;", + "HTTP_X_OPS_REQUESTID" => "127.0.0.1 1258566194.85386", + "HTTP_X_OPS_TIMESTAMP" => TIMESTAMP_ISO8601, + "HTTP_X_OPS_CONTENT_HASH" => X_OPS_CONTENT_HASH_SHA256, + "HTTP_X_OPS_USERID" => USER_ID, + "HTTP_X_OPS_SERVER_API_VERSION" => "1", + "HTTP_X_OPS_AUTHORIZATION_1" => X_OPS_AUTHORIZATION_LINES_V1_3_SHA256[0], + "HTTP_X_OPS_AUTHORIZATION_2" => X_OPS_AUTHORIZATION_LINES_V1_3_SHA256[1], + "HTTP_X_OPS_AUTHORIZATION_3" => X_OPS_AUTHORIZATION_LINES_V1_3_SHA256[2], + "HTTP_X_OPS_AUTHORIZATION_4" => X_OPS_AUTHORIZATION_LINES_V1_3_SHA256[3], + "HTTP_X_OPS_AUTHORIZATION_5" => X_OPS_AUTHORIZATION_LINES_V1_3_SHA256[4], + "HTTP_X_OPS_AUTHORIZATION_6" => X_OPS_AUTHORIZATION_LINES_V1_3_SHA256[5], }.merge(OTHER_HEADERS) # Tis is what will be in request.env for the Merb case. MERB_HEADERS_V1_1 = { # These are used by signatureverification. - "HTTP_HOST"=>"127.0.0.1", - "HTTP_X_OPS_SIGN"=>"algorithm=sha1;version=1.1;", - "HTTP_X_OPS_REQUESTID"=>"127.0.0.1 1258566194.85386", - "HTTP_X_OPS_TIMESTAMP"=>TIMESTAMP_ISO8601, - "HTTP_X_OPS_CONTENT_HASH"=>X_OPS_CONTENT_HASH, - "HTTP_X_OPS_USERID"=>USER_ID, - "HTTP_X_OPS_AUTHORIZATION_1"=>X_OPS_AUTHORIZATION_LINES[0], - "HTTP_X_OPS_AUTHORIZATION_2"=>X_OPS_AUTHORIZATION_LINES[1], - "HTTP_X_OPS_AUTHORIZATION_3"=>X_OPS_AUTHORIZATION_LINES[2], - "HTTP_X_OPS_AUTHORIZATION_4"=>X_OPS_AUTHORIZATION_LINES[3], - "HTTP_X_OPS_AUTHORIZATION_5"=>X_OPS_AUTHORIZATION_LINES[4], - "HTTP_X_OPS_AUTHORIZATION_6"=>X_OPS_AUTHORIZATION_LINES[5], + "HTTP_HOST" => "127.0.0.1", + "HTTP_X_OPS_SIGN" => "algorithm=sha1;version=1.1;", + "HTTP_X_OPS_REQUESTID" => "127.0.0.1 1258566194.85386", + "HTTP_X_OPS_TIMESTAMP" => TIMESTAMP_ISO8601, + "HTTP_X_OPS_CONTENT_HASH" => X_OPS_CONTENT_HASH, + "HTTP_X_OPS_USERID" => USER_ID, + "HTTP_X_OPS_AUTHORIZATION_1" => X_OPS_AUTHORIZATION_LINES[0], + "HTTP_X_OPS_AUTHORIZATION_2" => X_OPS_AUTHORIZATION_LINES[1], + "HTTP_X_OPS_AUTHORIZATION_3" => X_OPS_AUTHORIZATION_LINES[2], + "HTTP_X_OPS_AUTHORIZATION_4" => X_OPS_AUTHORIZATION_LINES[3], + "HTTP_X_OPS_AUTHORIZATION_5" => X_OPS_AUTHORIZATION_LINES[4], + "HTTP_X_OPS_AUTHORIZATION_6" => X_OPS_AUTHORIZATION_LINES[5], }.merge(OTHER_HEADERS) # Tis is what will be in request.env for the Merb case. MERB_HEADERS_V1_0 = { # These are used by signatureverification. - "HTTP_HOST"=>"127.0.0.1", - "HTTP_X_OPS_SIGN"=>"version=1.0", - "HTTP_X_OPS_REQUESTID"=>"127.0.0.1 1258566194.85386", - "HTTP_X_OPS_TIMESTAMP"=>TIMESTAMP_ISO8601, - "HTTP_X_OPS_CONTENT_HASH"=>X_OPS_CONTENT_HASH, - "HTTP_X_OPS_USERID"=>USER_ID, - "HTTP_X_OPS_AUTHORIZATION_1"=>X_OPS_AUTHORIZATION_LINES_V1_0[0], - "HTTP_X_OPS_AUTHORIZATION_2"=>X_OPS_AUTHORIZATION_LINES_V1_0[1], - "HTTP_X_OPS_AUTHORIZATION_3"=>X_OPS_AUTHORIZATION_LINES_V1_0[2], - "HTTP_X_OPS_AUTHORIZATION_4"=>X_OPS_AUTHORIZATION_LINES_V1_0[3], - "HTTP_X_OPS_AUTHORIZATION_5"=>X_OPS_AUTHORIZATION_LINES_V1_0[4], - "HTTP_X_OPS_AUTHORIZATION_6"=>X_OPS_AUTHORIZATION_LINES_V1_0[5], + "HTTP_HOST" => "127.0.0.1", + "HTTP_X_OPS_SIGN" => "version=1.0", + "HTTP_X_OPS_REQUESTID" => "127.0.0.1 1258566194.85386", + "HTTP_X_OPS_TIMESTAMP" => TIMESTAMP_ISO8601, + "HTTP_X_OPS_CONTENT_HASH" => X_OPS_CONTENT_HASH, + "HTTP_X_OPS_USERID" => USER_ID, + "HTTP_X_OPS_AUTHORIZATION_1" => X_OPS_AUTHORIZATION_LINES_V1_0[0], + "HTTP_X_OPS_AUTHORIZATION_2" => X_OPS_AUTHORIZATION_LINES_V1_0[1], + "HTTP_X_OPS_AUTHORIZATION_3" => X_OPS_AUTHORIZATION_LINES_V1_0[2], + "HTTP_X_OPS_AUTHORIZATION_4" => X_OPS_AUTHORIZATION_LINES_V1_0[3], + "HTTP_X_OPS_AUTHORIZATION_5" => X_OPS_AUTHORIZATION_LINES_V1_0[4], + "HTTP_X_OPS_AUTHORIZATION_6" => X_OPS_AUTHORIZATION_LINES_V1_0[5], }.merge(OTHER_HEADERS) PASSENGER_REQUEST_PARAMS = { - "action"=>"create", + "action" => "create", #"tarball"=>#<File:/tmp/RackMultipart20091120-25570-mgq2sa-0>, - "controller"=>"api/v1/cookbooks", - "cookbook"=>"{\"category\":\"databases\"}", + "controller" => "api/v1/cookbooks", + "cookbook" => "{\"category\":\"databases\"}", } PASSENGER_HEADERS_V1_1 = { # These are used by signatureverification. - "HTTP_HOST"=>"127.0.0.1", - "HTTP_X_OPS_SIGN"=>"algorithm=sha1;version=1.1;", - "HTTP_X_OPS_REQUESTID"=>"127.0.0.1 1258566194.85386", - "HTTP_X_OPS_TIMESTAMP"=>TIMESTAMP_ISO8601, - "HTTP_X_OPS_CONTENT_HASH"=>X_OPS_CONTENT_HASH, - "HTTP_X_OPS_USERID"=>USER_ID, - "HTTP_X_OPS_AUTHORIZATION_1"=>X_OPS_AUTHORIZATION_LINES[0], - "HTTP_X_OPS_AUTHORIZATION_2"=>X_OPS_AUTHORIZATION_LINES[1], - "HTTP_X_OPS_AUTHORIZATION_3"=>X_OPS_AUTHORIZATION_LINES[2], - "HTTP_X_OPS_AUTHORIZATION_4"=>X_OPS_AUTHORIZATION_LINES[3], - "HTTP_X_OPS_AUTHORIZATION_5"=>X_OPS_AUTHORIZATION_LINES[4], - "HTTP_X_OPS_AUTHORIZATION_6"=>X_OPS_AUTHORIZATION_LINES[5], + "HTTP_HOST" => "127.0.0.1", + "HTTP_X_OPS_SIGN" => "algorithm=sha1;version=1.1;", + "HTTP_X_OPS_REQUESTID" => "127.0.0.1 1258566194.85386", + "HTTP_X_OPS_TIMESTAMP" => TIMESTAMP_ISO8601, + "HTTP_X_OPS_CONTENT_HASH" => X_OPS_CONTENT_HASH, + "HTTP_X_OPS_USERID" => USER_ID, + "HTTP_X_OPS_AUTHORIZATION_1" => X_OPS_AUTHORIZATION_LINES[0], + "HTTP_X_OPS_AUTHORIZATION_2" => X_OPS_AUTHORIZATION_LINES[1], + "HTTP_X_OPS_AUTHORIZATION_3" => X_OPS_AUTHORIZATION_LINES[2], + "HTTP_X_OPS_AUTHORIZATION_4" => X_OPS_AUTHORIZATION_LINES[3], + "HTTP_X_OPS_AUTHORIZATION_5" => X_OPS_AUTHORIZATION_LINES[4], + "HTTP_X_OPS_AUTHORIZATION_6" => X_OPS_AUTHORIZATION_LINES[5], }.merge(OTHER_HEADERS) PASSENGER_HEADERS_V1_0 = { # These are used by signatureverification. - "HTTP_HOST"=>"127.0.0.1", - "HTTP_X_OPS_SIGN"=>"version=1.0", - "HTTP_X_OPS_REQUESTID"=>"127.0.0.1 1258566194.85386", - "HTTP_X_OPS_TIMESTAMP"=>TIMESTAMP_ISO8601, - "HTTP_X_OPS_CONTENT_HASH"=>X_OPS_CONTENT_HASH, - "HTTP_X_OPS_USERID"=>USER_ID, - "HTTP_X_OPS_AUTHORIZATION_1"=>X_OPS_AUTHORIZATION_LINES_V1_0[0], - "HTTP_X_OPS_AUTHORIZATION_2"=>X_OPS_AUTHORIZATION_LINES_V1_0[1], - "HTTP_X_OPS_AUTHORIZATION_3"=>X_OPS_AUTHORIZATION_LINES_V1_0[2], - "HTTP_X_OPS_AUTHORIZATION_4"=>X_OPS_AUTHORIZATION_LINES_V1_0[3], - "HTTP_X_OPS_AUTHORIZATION_5"=>X_OPS_AUTHORIZATION_LINES_V1_0[4], - "HTTP_X_OPS_AUTHORIZATION_6"=>X_OPS_AUTHORIZATION_LINES_V1_0[5], + "HTTP_HOST" => "127.0.0.1", + "HTTP_X_OPS_SIGN" => "version=1.0", + "HTTP_X_OPS_REQUESTID" => "127.0.0.1 1258566194.85386", + "HTTP_X_OPS_TIMESTAMP" => TIMESTAMP_ISO8601, + "HTTP_X_OPS_CONTENT_HASH" => X_OPS_CONTENT_HASH, + "HTTP_X_OPS_USERID" => USER_ID, + "HTTP_X_OPS_AUTHORIZATION_1" => X_OPS_AUTHORIZATION_LINES_V1_0[0], + "HTTP_X_OPS_AUTHORIZATION_2" => X_OPS_AUTHORIZATION_LINES_V1_0[1], + "HTTP_X_OPS_AUTHORIZATION_3" => X_OPS_AUTHORIZATION_LINES_V1_0[2], + "HTTP_X_OPS_AUTHORIZATION_4" => X_OPS_AUTHORIZATION_LINES_V1_0[3], + "HTTP_X_OPS_AUTHORIZATION_5" => X_OPS_AUTHORIZATION_LINES_V1_0[4], + "HTTP_X_OPS_AUTHORIZATION_6" => X_OPS_AUTHORIZATION_LINES_V1_0[5], }.merge(OTHER_HEADERS) # generated with diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 3185a12..fe03c12 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -7,9 +7,9 @@ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at -# +# # http://www.apache.org/licenses/LICENSE-2.0 -# +# # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -20,4 +20,4 @@ $:.unshift File.expand_path(File.join(File.dirname(__FILE__), "..", "lib")) # lib in mixlib-authentication $:.unshift File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "mixlib-log", "lib")) # mixlib-log/log -require 'rubygems' +require "rubygems" |