mixlib-authentication 2.1.1 → 3.0.1

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
  SHA256:
3
- metadata.gz: 2b6507935567e05c617f3c9080ddc8156540ec8fb1049c5feff4b2126a044fff
4
- data.tar.gz: 9c76665ef8e8f6ed8a625771d308ccade14df6fbf088085a9cf3752f22e2c0f3
3
+ metadata.gz: 88d9bf450271dbf1b6884eeb815e840f0fb6a7aa00bb72f535d2a9a5f35bc095
4
+ data.tar.gz: 72b4cc1872d3460f81db893acff7d3745e9616f0621fe2d91a15496384fb6c83
5
5
  SHA512:
6
- metadata.gz: 22528baf13168f7feabfe06c4643817c6f54d7f99722d7bfe889588fe1c45bcbf830e1340cd05d01dc11966addadd2de713e929474d8a0135de6b0efa1405f57
7
- data.tar.gz: 3ee4f86660dfeafd506f2e59e05b2d9d569efc11b9a652814d5f07eb706b89f20247949cddd99c65a18f7d7a5a07828f313dcccf87fa3b2efc0079409c45df6c
6
+ metadata.gz: 7895adb5f1673569a491f49be00ea06a4ab28ecebc69366c3d8903c3434af47729ab962f4a386c7a5713cfba354de7437025715b2a05380e6feae1a22a3b42ef
7
+ data.tar.gz: b6194627f7cefb22a92688d06761391fd2bbdcd2432e2438e13ca19daa7f2e634348d00545be71c1ee0add8befaf081f7f1bd4222923fae0f147b8bf28cb1a39
@@ -1,6 +1,6 @@
1
1
  #
2
- # Author:: Christopher Brown (<cb@opscode.com>)
3
- # Copyright:: Copyright (c) 2009 Opscode, Inc.
2
+ # Author:: Christopher Brown (<cb@chef.io>)
3
+ # Copyright:: Copyright (c) 2009-2018 Chef Software, Inc.
4
4
  # License:: Apache License, Version 2.0
5
5
  #
6
6
  # Licensed under the Apache License, Version 2.0 (the "License");
@@ -1,6 +1,6 @@
1
1
  #
2
- # Author:: Christopher Brown (<cb@opscode.com>)
3
- # Copyright:: Copyright (c) 2009 Opscode, Inc.
2
+ # Author:: Christopher Brown (<cb@chef.io>)
3
+ # Copyright:: Copyright (c) 2009-2018 Chef Software, Inc.
4
4
  # License:: Apache License, Version 2.0
5
5
  #
6
6
  # Licensed under the Apache License, Version 2.0 (the "License");
@@ -1,6 +1,6 @@
1
1
  #
2
- # Author:: Daniel DeLeo (<dan@opscode.com>)
3
- # Copyright:: Copyright (c) 2010 Opscode, Inc.
2
+ # Author:: Daniel DeLeo (<dan@chef.io>)
3
+ # Copyright:: Copyright (c) 2010-2018 Chef Software, Inc.
4
4
  # License:: Apache License, Version 2.0
5
5
  #
6
6
  # Licensed under the Apache License, Version 2.0 (the "License");
@@ -1,7 +1,7 @@
1
1
  #
2
- # Author:: Christopher Brown (<cb@opscode.com>)
3
- # Author:: Christopher Walters (<cw@opscode.com>)
4
- # Copyright:: Copyright (c) 2009, 2010 Opscode, Inc.
2
+ # Author:: Christopher Brown (<cb@chef.io>)
3
+ # Author:: Christopher Walters (<cw@chef.io>)
4
+ # Copyright:: Copyright (c) 2009-2018 Chef Software, Inc.
5
5
  # License:: Apache License, Version 2.0
6
6
  #
7
7
  # Licensed under the Apache License, Version 2.0 (the "License");
@@ -1,7 +1,7 @@
1
1
  #
2
- # Author:: Christopher Brown (<cb@opscode.com>)
3
- # Author:: Christopher Walters (<cw@opscode.com>)
4
- # Copyright:: Copyright (c) 2009, 2010 Opscode, Inc.
2
+ # Author:: Christopher Brown (<cb@chef.io>)
3
+ # Author:: Christopher Walters (<cw@chef.io>)
4
+ # Copyright:: Copyright (c) 2009-2018 Chef Software, Inc.
5
5
  # License:: Apache License, Version 2.0
6
6
  #
7
7
  # Licensed under the Apache License, Version 2.0 (the "License");
@@ -1,4 +1,5 @@
1
- # Copyright:: Copyright (c) 2010-2015 Chef Software, Inc.
1
+ #
2
+ # Copyright:: Copyright (c) 2010-2019, Chef Software Inc.
2
3
  # License:: Apache License, Version 2.0
3
4
  #
4
5
  # Licensed under the Apache License, Version 2.0 (the "License");
@@ -15,6 +16,6 @@
15
16
 
16
17
  module Mixlib
17
18
  module Authentication
18
- VERSION = "2.1.1"
19
+ VERSION = "3.0.1"
19
20
  end
20
21
  end
metadata CHANGED
@@ -1,96 +1,22 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mixlib-authentication
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.1.1
4
+ version: 3.0.1
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: 2018-06-01 00:00:00.000000000 Z
12
- dependencies:
13
- - !ruby/object:Gem::Dependency
14
- name: rspec-core
15
- requirement: !ruby/object:Gem::Requirement
16
- requirements:
17
- - - "~>"
18
- - !ruby/object:Gem::Version
19
- version: '3.2'
20
- type: :development
21
- prerelease: false
22
- version_requirements: !ruby/object:Gem::Requirement
23
- requirements:
24
- - - "~>"
25
- - !ruby/object:Gem::Version
26
- version: '3.2'
27
- - !ruby/object:Gem::Dependency
28
- name: rspec-expectations
29
- requirement: !ruby/object:Gem::Requirement
30
- requirements:
31
- - - "~>"
32
- - !ruby/object:Gem::Version
33
- version: '3.2'
34
- type: :development
35
- prerelease: false
36
- version_requirements: !ruby/object:Gem::Requirement
37
- requirements:
38
- - - "~>"
39
- - !ruby/object:Gem::Version
40
- version: '3.2'
41
- - !ruby/object:Gem::Dependency
42
- name: rspec-mocks
43
- requirement: !ruby/object:Gem::Requirement
44
- requirements:
45
- - - "~>"
46
- - !ruby/object:Gem::Version
47
- version: '3.2'
48
- type: :development
49
- prerelease: false
50
- version_requirements: !ruby/object:Gem::Requirement
51
- requirements:
52
- - - "~>"
53
- - !ruby/object:Gem::Version
54
- version: '3.2'
55
- - !ruby/object:Gem::Dependency
56
- name: chefstyle
57
- requirement: !ruby/object:Gem::Requirement
58
- requirements:
59
- - - ">="
60
- - !ruby/object:Gem::Version
61
- version: '0'
62
- type: :development
63
- prerelease: false
64
- version_requirements: !ruby/object:Gem::Requirement
65
- requirements:
66
- - - ">="
67
- - !ruby/object:Gem::Version
68
- version: '0'
69
- - !ruby/object:Gem::Dependency
70
- name: rake
71
- requirement: !ruby/object:Gem::Requirement
72
- requirements:
73
- - - "~>"
74
- - !ruby/object:Gem::Version
75
- version: '11'
76
- type: :development
77
- prerelease: false
78
- version_requirements: !ruby/object:Gem::Requirement
79
- requirements:
80
- - - "~>"
81
- - !ruby/object:Gem::Version
82
- version: '11'
11
+ date: 2019-04-23 00:00:00.000000000 Z
12
+ dependencies: []
83
13
  description: Mixes in simple per-request authentication
84
14
  email: info@chef.io
85
15
  executables: []
86
16
  extensions: []
87
17
  extra_rdoc_files: []
88
18
  files:
89
- - Gemfile
90
19
  - LICENSE
91
- - NOTICE
92
- - README.md
93
- - Rakefile
94
20
  - lib/mixlib/authentication.rb
95
21
  - lib/mixlib/authentication/digester.rb
96
22
  - lib/mixlib/authentication/http_authentication_request.rb
@@ -98,13 +24,7 @@ files:
98
24
  - lib/mixlib/authentication/signatureverification.rb
99
25
  - lib/mixlib/authentication/signedheaderauth.rb
100
26
  - lib/mixlib/authentication/version.rb
101
- - mixlib-authentication.gemspec
102
- - spec/mixlib/authentication/digester_spec.rb
103
- - spec/mixlib/authentication/http_authentication_request_spec.rb
104
- - spec/mixlib/authentication/mixlib_authentication_spec.rb
105
- - spec/mixlib/authentication/mixlib_log_missing_spec.rb
106
- - spec/spec_helper.rb
107
- homepage: https://www.chef.io
27
+ homepage: https://github.com/chef/mixlib-authentication
108
28
  licenses:
109
29
  - Apache-2.0
110
30
  metadata: {}
@@ -116,15 +36,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
116
36
  requirements:
117
37
  - - ">="
118
38
  - !ruby/object:Gem::Version
119
- version: '0'
39
+ version: '2.4'
120
40
  required_rubygems_version: !ruby/object:Gem::Requirement
121
41
  requirements:
122
42
  - - ">="
123
43
  - !ruby/object:Gem::Version
124
44
  version: '0'
125
45
  requirements: []
126
- rubyforge_project:
127
- rubygems_version: 2.7.6
46
+ rubygems_version: 3.0.3
128
47
  signing_key:
129
48
  specification_version: 4
130
49
  summary: Mixes in simple per-request authentication
data/Gemfile DELETED
@@ -1,8 +0,0 @@
1
- source "https://rubygems.org"
2
- gemspec
3
-
4
- group(:development) do
5
- gem "pry"
6
- gem "mixlib-log", "~> 2"
7
- gem "net-ssh"
8
- end
data/NOTICE DELETED
@@ -1,7 +0,0 @@
1
- Mixlib::Authentication NOTICE
2
- =================
3
-
4
- Developed at Chef (https://www.chef.io/).
5
-
6
- * Copyright 2009-2016, Chef Software, Inc. <legal@chef.io>
7
-
data/README.md DELETED
@@ -1,23 +0,0 @@
1
- # Mixlib::Authentication
2
- [![Build Status Master](https://travis-ci.org/chef/mixlib-authentication.svg?branch=master)](https://travis-ci.org/chef/mixlib-authentication) [![Gem Version](https://badge.fury.io/rb/mixlib-authentication.svg)](https://badge.fury.io/rb/mixlib-authentication)
3
-
4
- Mixlib::Authentication provides a class-based header signing authentication object, like the one used in Chef.
5
-
6
- ## License
7
- - Author:: Christopher Brown ([cb@chef.io](mailto:cb@chef.io))
8
- - Copyright:: Copyright (c) 2009-2016 Chef Software, Inc.
9
- - License:: Apache License, Version 2.0
10
-
11
- ```text
12
- Licensed under the Apache License, Version 2.0 (the "License");
13
- you may not use this file except in compliance with the License.
14
- You may obtain a copy of the License at
15
-
16
- http://www.apache.org/licenses/LICENSE-2.0
17
-
18
- Unless required by applicable law or agreed to in writing, software
19
- distributed under the License is distributed on an "AS IS" BASIS,
20
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
21
- See the License for the specific language governing permissions and
22
- limitations under the License.
23
- ```
data/Rakefile DELETED
@@ -1,18 +0,0 @@
1
- require "bundler/gem_tasks"
2
- require "rspec/core/rake_task"
3
-
4
- RSpec::Core::RakeTask.new(:spec)
5
-
6
- task :default => :spec
7
-
8
- begin
9
- require "chefstyle"
10
- require "rubocop/rake_task"
11
- RuboCop::RakeTask.new(:style) do |task|
12
- task.options += ["--display-cop-names", "--no-color"]
13
- end
14
- rescue LoadError
15
- puts "chefstyle/rubocop is not available."
16
- end
17
-
18
- task :ci => [:style, :spec]
@@ -1,22 +0,0 @@
1
- $:.unshift(File.dirname(__FILE__) + "/lib")
2
- require "mixlib/authentication/version"
3
-
4
- Gem::Specification.new do |s|
5
- s.name = "mixlib-authentication"
6
- s.version = Mixlib::Authentication::VERSION
7
- s.platform = Gem::Platform::RUBY
8
- s.summary = "Mixes in simple per-request authentication"
9
- s.description = s.summary
10
- s.license = "Apache-2.0"
11
- s.author = "Chef Software, Inc."
12
- s.email = "info@chef.io"
13
- s.homepage = "https://www.chef.io"
14
-
15
- s.require_path = "lib"
16
- s.files = %w{LICENSE README.md Gemfile Rakefile NOTICE} + Dir.glob("*.gemspec") +
17
- Dir.glob("{lib,spec}/**/*", File::FNM_DOTMATCH).reject { |f| File.directory?(f) }
18
-
19
- %w{rspec-core rspec-expectations rspec-mocks}.each { |gem| s.add_development_dependency gem, "~> 3.2" }
20
- s.add_development_dependency "chefstyle"
21
- s.add_development_dependency "rake", "~> 11"
22
- end
@@ -1,24 +0,0 @@
1
- require "mixlib/authentication/digester"
2
-
3
- describe Mixlib::Authentication::Digester do
4
- context "backcompat" do
5
- # The digester API should really have been private,
6
- # however oc-chef-pedant uses it.
7
- let(:test_string) { "hello" }
8
- let(:test_string_checksum) { "qvTGHdzF6KLavt4PO0gs2a6pQ00=" }
9
-
10
- describe "#hash_file" do
11
- it "should default to use SHA1" do
12
- expect(described_class.hash_file(StringIO.new(test_string))).to(
13
- eq(test_string_checksum))
14
- end
15
- end
16
-
17
- describe "#hash_string" do
18
- it "should default to use SHA1" do
19
- expect(described_class.hash_string(test_string)).to(
20
- eq(test_string_checksum))
21
- end
22
- end
23
- end
24
- end
@@ -1,132 +0,0 @@
1
- # Author:: Daniel DeLeo (<dan@opscode.com>)
2
- # Copyright:: Copyright (c) 2010 Opscode, Inc.
3
- # License:: Apache License, Version 2.0
4
- #
5
- # Licensed under the Apache License, Version 2.0 (the "License");
6
- # you may not use this file except in compliance with the License.
7
- # You may obtain a copy of the License at
8
- #
9
- # http://www.apache.org/licenses/LICENSE-2.0
10
- #
11
- # Unless required by applicable law or agreed to in writing, software
12
- # distributed under the License is distributed on an "AS IS" BASIS,
13
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
- # See the License for the specific language governing permissions and
15
- # limitations under the License.
16
- #
17
-
18
- require File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "spec_helper"))
19
-
20
- require "mixlib/authentication"
21
- require "mixlib/authentication/http_authentication_request"
22
- require "ostruct"
23
- require "pp"
24
-
25
- describe Mixlib::Authentication::HTTPAuthenticationRequest do
26
- before do
27
- request = Struct.new(:env, :method, :path)
28
-
29
- @timestamp_iso8601 = "2009-01-01T12:00:00Z"
30
- @x_ops_content_hash = "DFteJZPVv6WKdQmMqZUQUumUyRs="
31
- @user_id = "spec-user"
32
- @http_x_ops_lines = [
33
- "jVHrNniWzpbez/eGWjFnO6lINRIuKOg40ZTIQudcFe47Z9e/HvrszfVXlKG4",
34
- "NMzYZgyooSvU85qkIUmKuCqgG2AIlvYa2Q/2ctrMhoaHhLOCWWoqYNMaEqPc",
35
- "3tKHE+CfvP+WuPdWk4jv4wpIkAz6ZLxToxcGhXmZbXpk56YTmqgBW2cbbw4O",
36
- "IWPZDHSiPcw//AYNgW1CCDptt+UFuaFYbtqZegcBd2n/jzcWODA7zL4KWEUy",
37
- "9q4rlh/+1tBReg60QdsmDRsw/cdO1GZrKtuCwbuD4+nbRdVBKv72rqHX9cu0",
38
- "utju9jzczCyB+sSAQWrxSsXB/b8vV2qs0l4VD2ML+w=="]
39
- @merb_headers = {
40
- # These are used by signatureverification. An arbitrary sampling of non-HTTP_*
41
- # headers are in here to exercise that code path.
42
- "HTTP_HOST" => "127.0.0.1",
43
- "HTTP_X_OPS_SIGN" => "version=1.0",
44
- "HTTP_X_OPS_REQUESTID" => "127.0.0.1 1258566194.85386",
45
- "HTTP_X_OPS_TIMESTAMP" => @timestamp_iso8601,
46
- "HTTP_X_OPS_CONTENT_HASH" => @x_ops_content_hash,
47
- "HTTP_X_OPS_USERID" => @user_id,
48
- "HTTP_X_OPS_AUTHORIZATION_1" => @http_x_ops_lines[0],
49
- "HTTP_X_OPS_AUTHORIZATION_2" => @http_x_ops_lines[1],
50
- "HTTP_X_OPS_AUTHORIZATION_3" => @http_x_ops_lines[2],
51
- "HTTP_X_OPS_AUTHORIZATION_4" => @http_x_ops_lines[3],
52
- "HTTP_X_OPS_AUTHORIZATION_5" => @http_x_ops_lines[4],
53
- "HTTP_X_OPS_AUTHORIZATION_6" => @http_x_ops_lines[5],
54
-
55
- # Random sampling
56
- "REMOTE_ADDR" => "127.0.0.1",
57
- "PATH_INFO" => "/organizations/local-test-org/cookbooks",
58
- "REQUEST_PATH" => "/organizations/local-test-org/cookbooks",
59
- "CONTENT_TYPE" => "multipart/form-data; boundary=----RubyMultipartClient6792ZZZZZ",
60
- "CONTENT_LENGTH" => "394",
61
- }
62
- @request = request.new(@merb_headers, "POST", "/nodes")
63
- @http_authentication_request = Mixlib::Authentication::HTTPAuthenticationRequest.new(@request)
64
- end
65
-
66
- it "normalizes the headers to lowercase symbols" do
67
- expected = { :host => "127.0.0.1",
68
- :x_ops_sign => "version=1.0",
69
- :x_ops_requestid => "127.0.0.1 1258566194.85386",
70
- :x_ops_timestamp => "2009-01-01T12:00:00Z",
71
- :x_ops_content_hash => "DFteJZPVv6WKdQmMqZUQUumUyRs=",
72
- :x_ops_userid => "spec-user",
73
- :x_ops_authorization_1 => "jVHrNniWzpbez/eGWjFnO6lINRIuKOg40ZTIQudcFe47Z9e/HvrszfVXlKG4",
74
- :x_ops_authorization_2 => "NMzYZgyooSvU85qkIUmKuCqgG2AIlvYa2Q/2ctrMhoaHhLOCWWoqYNMaEqPc",
75
- :x_ops_authorization_3 => "3tKHE+CfvP+WuPdWk4jv4wpIkAz6ZLxToxcGhXmZbXpk56YTmqgBW2cbbw4O",
76
- :x_ops_authorization_4 => "IWPZDHSiPcw//AYNgW1CCDptt+UFuaFYbtqZegcBd2n/jzcWODA7zL4KWEUy",
77
- :x_ops_authorization_5 => "9q4rlh/+1tBReg60QdsmDRsw/cdO1GZrKtuCwbuD4+nbRdVBKv72rqHX9cu0",
78
- :x_ops_authorization_6 => "utju9jzczCyB+sSAQWrxSsXB/b8vV2qs0l4VD2ML+w==" }
79
- expect(@http_authentication_request.headers).to eq(expected)
80
- end
81
-
82
- it "raises an error when not all required headers are given" do
83
- @merb_headers.delete("HTTP_X_OPS_SIGN")
84
- exception = Mixlib::Authentication::MissingAuthenticationHeader
85
- expect { Mixlib::Authentication::HTTPAuthenticationRequest.new(@request) }.to raise_error(exception)
86
- end
87
-
88
- it "extracts the path from the request" do
89
- expect(@http_authentication_request.path).to eq("/nodes")
90
- end
91
-
92
- it "extracts the request method from the request" do
93
- expect(@http_authentication_request.http_method).to eq("POST")
94
- end
95
-
96
- it "extracts the signing description from the request headers" do
97
- expect(@http_authentication_request.signing_description).to eq("version=1.0")
98
- end
99
-
100
- it "extracts the user_id from the request headers" do
101
- expect(@http_authentication_request.user_id).to eq("spec-user")
102
- end
103
-
104
- it "extracts the timestamp from the request headers" do
105
- expect(@http_authentication_request.timestamp).to eq("2009-01-01T12:00:00Z")
106
- end
107
-
108
- it "extracts the host from the request headers" do
109
- expect(@http_authentication_request.host).to eq("127.0.0.1")
110
- end
111
-
112
- it "extracts the content hash from the request headers" do
113
- expect(@http_authentication_request.content_hash).to eq("DFteJZPVv6WKdQmMqZUQUumUyRs=")
114
- end
115
-
116
- it "rebuilds the request signature from the headers" do
117
- expected = <<-SIG
118
- jVHrNniWzpbez/eGWjFnO6lINRIuKOg40ZTIQudcFe47Z9e/HvrszfVXlKG4
119
- NMzYZgyooSvU85qkIUmKuCqgG2AIlvYa2Q/2ctrMhoaHhLOCWWoqYNMaEqPc
120
- 3tKHE+CfvP+WuPdWk4jv4wpIkAz6ZLxToxcGhXmZbXpk56YTmqgBW2cbbw4O
121
- IWPZDHSiPcw//AYNgW1CCDptt+UFuaFYbtqZegcBd2n/jzcWODA7zL4KWEUy
122
- 9q4rlh/+1tBReg60QdsmDRsw/cdO1GZrKtuCwbuD4+nbRdVBKv72rqHX9cu0
123
- utju9jzczCyB+sSAQWrxSsXB/b8vV2qs0l4VD2ML+w==
124
- SIG
125
- expect(@http_authentication_request.request_signature).to eq(expected.chomp)
126
- end
127
-
128
- it "defaults to server api version 0" do
129
- expect(@http_authentication_request.server_api_version).to eq("0")
130
- end
131
-
132
- end
@@ -1,623 +0,0 @@
1
- #
2
- # Author:: Tim Hinderliter (<tim@opscode.com>)
3
- # Author:: Christopher Walters (<cw@opscode.com>)
4
- # Author:: Christopher Brown (<cb@opscode.com>)
5
- # Copyright:: Copyright (c) 2009, 2010 Opscode, Inc.
6
- # License:: Apache License, Version 2.0
7
- #
8
- # Licensed under the Apache License, Version 2.0 (the "License");
9
- # you may not use this file except in compliance with the License.
10
- # You may obtain a copy of the License at
11
- #
12
- # http://www.apache.org/licenses/LICENSE-2.0
13
- #
14
- # Unless required by applicable law or agreed to in writing, software
15
- # distributed under the License is distributed on an "AS IS" BASIS,
16
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17
- # See the License for the specific language governing permissions and
18
- # limitations under the License.
19
- #
20
-
21
- require File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "spec_helper"))
22
- require "rubygems"
23
-
24
- require "ostruct"
25
- require "openssl"
26
- require "mixlib/authentication/signatureverification"
27
- require "time"
28
- require "net/ssh"
29
-
30
- # TODO: should make these regular spec-based mock objects.
31
- class MockRequest
32
- attr_accessor :env, :params, :path, :raw_post
33
-
34
- def initialize(path, params, headers, raw_post)
35
- @path = path
36
- @params = params
37
- @env = headers
38
- @raw_post = raw_post
39
- end
40
-
41
- def method
42
- "POST"
43
- end
44
- end
45
-
46
- class MockFile
47
- def initialize
48
- @have_read = nil
49
- end
50
-
51
- def self.length
52
- BODY.length
53
- end
54
-
55
- def read(len, out_str)
56
- if @have_read.nil?
57
- @have_read = 1
58
- out_str[0..-1] = BODY
59
- BODY
60
- else
61
- nil
62
- end
63
- end
64
- end
65
-
66
- # Uncomment this to get some more info from the methods we're testing.
67
- #Mixlib::Authentication.logger.level = :trace
68
-
69
- describe "Mixlib::Authentication::SignedHeaderAuth" do
70
-
71
- # NOTE: Version 1.0 will be the default until Chef 11 is released.
72
-
73
- it "should generate the correct string to sign and signature, version 1.0 (default)" do
74
-
75
- expect(V1_0_SIGNING_OBJECT.canonicalize_request).to eq(V1_0_CANONICAL_REQUEST)
76
-
77
- # If you need to regenerate the constants in this test spec, print out
78
- # the results of res.inspect and copy them as appropriate into the
79
- # the constants in this file.
80
- expect(V1_0_SIGNING_OBJECT.sign(PRIVATE_KEY)).to eq(EXPECTED_SIGN_RESULT_V1_0)
81
- end
82
-
83
- it "should generate the correct string to sign and signature, version 1.1" do
84
- expect(V1_1_SIGNING_OBJECT.proto_version).to eq("1.1")
85
- expect(V1_1_SIGNING_OBJECT.canonicalize_request).to eq(V1_1_CANONICAL_REQUEST)
86
-
87
- # If you need to regenerate the constants in this test spec, print out
88
- # the results of res.inspect and copy them as appropriate into the
89
- # the constants in this file.
90
- expect(V1_1_SIGNING_OBJECT.sign(PRIVATE_KEY)).to eq(EXPECTED_SIGN_RESULT_V1_1)
91
- end
92
-
93
- it "should generate the correct string to sign and signature for version 1.3 with SHA256" do
94
- expect(V1_3_SHA256_SIGNING_OBJECT.proto_version).to eq("1.3")
95
- expect(V1_3_SHA256_SIGNING_OBJECT.algorithm).to eq("sha256")
96
- expect(V1_3_SHA256_SIGNING_OBJECT.server_api_version).to eq("1")
97
- expect(V1_3_SHA256_SIGNING_OBJECT.canonicalize_request).to eq(V1_3_SHA256_CANONICAL_REQUEST)
98
-
99
- # If you need to regenerate the constants in this test spec, print out
100
- # the results of res.inspect and copy them as appropriate into the
101
- # the constants in this file.
102
- expect(V1_3_SHA256_SIGNING_OBJECT.sign(PRIVATE_KEY)).to eq(EXPECTED_SIGN_RESULT_V1_3_SHA256)
103
- end
104
-
105
- it "should generate the correct string to sign and signature for version 1.3 with SHA256 via ssh-agent" do
106
- agent = double("ssh-agent")
107
- expect(Net::SSH::Authentication::Agent).to receive(:connect).and_return(agent)
108
- expect(agent).to receive(:sign).and_return(SSH_AGENT_RESPONSE)
109
- expect(V1_3_SHA256_SIGNING_OBJECT.sign(PUBLIC_KEY, use_ssh_agent: true)).to eq(EXPECTED_SIGN_RESULT_V1_3_SHA256)
110
- end
111
-
112
- it "should generate the correct string to sign and signature for non-default proto version when used as a mixin" do
113
- algorithm = "sha1"
114
- version = "1.1"
115
-
116
- V1_1_SIGNING_OBJECT.proto_version = "1.0"
117
- expect(V1_1_SIGNING_OBJECT.proto_version).to eq("1.0")
118
- expect(V1_1_SIGNING_OBJECT.canonicalize_request(algorithm, version)).to eq(V1_1_CANONICAL_REQUEST)
119
-
120
- # If you need to regenerate the constants in this test spec, print out
121
- # the results of res.inspect and copy them as appropriate into the
122
- # the constants in this file.
123
- expect(V1_1_SIGNING_OBJECT.sign(PRIVATE_KEY, algorithm, version)).to eq(EXPECTED_SIGN_RESULT_V1_1)
124
- expect(V1_1_SIGNING_OBJECT.sign(PRIVATE_KEY, sign_algorithm: algorithm, sign_version: version)).to eq(EXPECTED_SIGN_RESULT_V1_1)
125
- end
126
-
127
- it "should not choke when signing a request for a long user id with version 1.1" do
128
- expect { LONG_SIGNING_OBJECT.sign(PRIVATE_KEY, "sha1", "1.1") }.not_to raise_error
129
- expect { LONG_SIGNING_OBJECT.sign(PRIVATE_KEY, sign_algorithm: "sha1", sign_version: "1.1") }.not_to raise_error
130
- end
131
-
132
- it "should choke when signing a request for a long user id with version 1.0" do
133
- expect { LONG_SIGNING_OBJECT.sign(PRIVATE_KEY, "sha1", "1.0") }.to raise_error(OpenSSL::PKey::RSAError)
134
- expect { LONG_SIGNING_OBJECT.sign(PRIVATE_KEY, sign_algorithm: "sha1", sign_version: "1.0") }.to raise_error(OpenSSL::PKey::RSAError)
135
- end
136
-
137
- it "should choke when signing a request with a bad version" do
138
- expect { V1_1_SIGNING_OBJECT.sign(PRIVATE_KEY, "sha1", "poo") }.to raise_error(Mixlib::Authentication::AuthenticationError)
139
- end
140
-
141
- it "should choke when signing a request with a bad algorithm" do
142
- expect { V1_1_SIGNING_OBJECT.sign(PRIVATE_KEY, "sha_poo", "1.1") }.to raise_error(Mixlib::Authentication::AuthenticationError)
143
- end
144
-
145
- it "should choke when signing a request via ssh-agent and ssh-agent is not reachable with version 1.3" do
146
- expect(Net::SSH::Authentication::Agent).to receive(:connect).and_raise(Net::SSH::Authentication::AgentNotAvailable)
147
- expect { V1_3_SHA256_SIGNING_OBJECT.sign(PUBLIC_KEY, use_ssh_agent: true) }.to raise_error(Mixlib::Authentication::AuthenticationError)
148
- end
149
-
150
- it "should choke when signing a request via ssh-agent and the key is not loaded with version 1.3" do
151
- agent = double("ssh-agent")
152
- expect(Net::SSH::Authentication::Agent).to receive(:connect).and_return(agent)
153
- expect(agent).to receive(:sign).and_raise(Net::SSH::Authentication::AgentError)
154
- expect { V1_3_SHA256_SIGNING_OBJECT.sign(PUBLIC_KEY, use_ssh_agent: true) }.to raise_error(Mixlib::Authentication::AuthenticationError)
155
- end
156
-
157
- end
158
-
159
- describe "Mixlib::Authentication::SignatureVerification" do
160
-
161
- before(:each) do
162
- @user_private_key = PRIVATE_KEY
163
- end
164
-
165
- it "should authenticate a File-containing request V1.1 - Merb" do
166
- request_params = MERB_REQUEST_PARAMS.clone
167
- request_params["file"] =
168
- { "size" => MockFile.length, "content_type" => "application/octet-stream", "filename" => "zsh.tar.gz", "tempfile" => MockFile.new }
169
-
170
- mock_request = MockRequest.new(PATH, request_params, MERB_HEADERS_V1_1, "")
171
- expect(Time).to receive(:now).at_least(:once).and_return(TIMESTAMP_OBJ)
172
-
173
- service = Mixlib::Authentication::SignatureVerification.new
174
- res = service.authenticate_user_request(mock_request, @user_private_key)
175
- expect(res).not_to be_nil
176
- end
177
-
178
- it "should authenticate a File-containing request V1.3 SHA256 - Merb" do
179
- request_params = MERB_REQUEST_PARAMS.clone
180
- request_params["file"] =
181
- { "size" => MockFile.length, "content_type" => "application/octet-stream", "filename" => "zsh.tar.gz", "tempfile" => MockFile.new }
182
-
183
- mock_request = MockRequest.new(PATH, request_params, MERB_HEADERS_V1_3_SHA256, "")
184
- expect(Time).to receive(:now).at_least(:once).and_return(TIMESTAMP_OBJ)
185
-
186
- service = Mixlib::Authentication::SignatureVerification.new
187
- res = service.authenticate_user_request(mock_request, @user_private_key)
188
- expect(res).not_to be_nil
189
- end
190
-
191
- it "should authenticate a File-containing request from a v1.0 client - Passenger" do
192
- request_params = PASSENGER_REQUEST_PARAMS.clone
193
- request_params["tarball"] = MockFile.new
194
-
195
- mock_request = MockRequest.new(PATH, request_params, PASSENGER_HEADERS_V1_0, "")
196
- expect(Time).to receive(:now).at_least(:once).and_return(TIMESTAMP_OBJ)
197
-
198
- auth_req = Mixlib::Authentication::SignatureVerification.new
199
- res = auth_req.authenticate_user_request(mock_request, @user_private_key)
200
- expect(res).not_to be_nil
201
- end
202
-
203
- it "should authenticate a normal (post body) request v1.3 SHA256 - Merb" do
204
- mock_request = MockRequest.new(PATH, MERB_REQUEST_PARAMS, MERB_HEADERS_V1_3_SHA256, BODY)
205
- expect(Time).to receive(:now).at_least(:once).and_return(TIMESTAMP_OBJ)
206
-
207
- service = Mixlib::Authentication::SignatureVerification.new
208
- res = service.authenticate_user_request(mock_request, @user_private_key)
209
- expect(res).not_to be_nil
210
- end
211
-
212
- it "should authenticate a normal (post body) request v1.1 - Merb" do
213
- mock_request = MockRequest.new(PATH, MERB_REQUEST_PARAMS, MERB_HEADERS_V1_1, BODY)
214
- expect(Time).to receive(:now).at_least(:once).and_return(TIMESTAMP_OBJ)
215
-
216
- service = Mixlib::Authentication::SignatureVerification.new
217
- res = service.authenticate_user_request(mock_request, @user_private_key)
218
- expect(res).not_to be_nil
219
- end
220
-
221
- it "should authenticate a normal (post body) request from a v1.0 client - Merb" do
222
- mock_request = MockRequest.new(PATH, MERB_REQUEST_PARAMS, MERB_HEADERS_V1_0, BODY)
223
- expect(Time).to receive(:now).at_least(:once).and_return(TIMESTAMP_OBJ)
224
-
225
- service = Mixlib::Authentication::SignatureVerification.new
226
- res = service.authenticate_user_request(mock_request, @user_private_key)
227
- expect(res).not_to be_nil
228
- end
229
-
230
- it "shouldn't authenticate if an Authorization header is missing" do
231
- headers = MERB_HEADERS_V1_1.clone
232
- headers.delete("HTTP_X_OPS_SIGN")
233
-
234
- mock_request = MockRequest.new(PATH, MERB_REQUEST_PARAMS, headers, BODY)
235
- allow(Time).to receive(:now).and_return(TIMESTAMP_OBJ)
236
- #Time.stub!(:now).and_return(TIMESTAMP_OBJ)
237
-
238
- auth_req = Mixlib::Authentication::SignatureVerification.new
239
- expect { auth_req.authenticate_user_request(mock_request, @user_private_key) }.to raise_error(Mixlib::Authentication::AuthenticationError)
240
-
241
- expect(auth_req).not_to be_a_valid_request
242
- expect(auth_req).not_to be_a_valid_timestamp
243
- expect(auth_req).not_to be_a_valid_signature
244
- expect(auth_req).not_to be_a_valid_content_hash
245
- end
246
-
247
- it "shouldn't authenticate if Authorization header is wrong" do
248
- headers = MERB_HEADERS_V1_1.clone
249
- headers["HTTP_X_OPS_CONTENT_HASH"] += "_"
250
-
251
- mock_request = MockRequest.new(PATH, MERB_REQUEST_PARAMS, headers, BODY)
252
- expect(Time).to receive(:now).at_least(:once).and_return(TIMESTAMP_OBJ)
253
-
254
- auth_req = Mixlib::Authentication::SignatureVerification.new
255
- res = auth_req.authenticate_user_request(mock_request, @user_private_key)
256
- expect(res).to be_nil
257
-
258
- expect(auth_req).not_to be_a_valid_request
259
- expect(auth_req).to be_a_valid_timestamp
260
- expect(auth_req).to be_a_valid_signature
261
- expect(auth_req).not_to be_a_valid_content_hash
262
- end
263
-
264
- it "shouldn't authenticate if the timestamp is not within bounds" do
265
- mock_request = MockRequest.new(PATH, MERB_REQUEST_PARAMS, MERB_HEADERS_V1_1, BODY)
266
- expect(Time).to receive(:now).at_least(:once).and_return(TIMESTAMP_OBJ - 1000)
267
-
268
- auth_req = Mixlib::Authentication::SignatureVerification.new
269
- res = auth_req.authenticate_user_request(mock_request, @user_private_key)
270
- expect(res).to be_nil
271
- expect(auth_req).not_to be_a_valid_request
272
- expect(auth_req).not_to be_a_valid_timestamp
273
- expect(auth_req).to be_a_valid_signature
274
- expect(auth_req).to be_a_valid_content_hash
275
- end
276
-
277
- it "shouldn't authenticate if the signature is wrong" do
278
- headers = MERB_HEADERS_V1_1.dup
279
- headers["HTTP_X_OPS_AUTHORIZATION_1"] = "epicfail"
280
- mock_request = MockRequest.new(PATH, MERB_REQUEST_PARAMS, headers, BODY)
281
- expect(Time).to receive(:now).at_least(:once).and_return(TIMESTAMP_OBJ)
282
-
283
- auth_req = Mixlib::Authentication::SignatureVerification.new
284
- res = auth_req.authenticate_user_request(mock_request, @user_private_key)
285
- expect(res).to be_nil
286
- expect(auth_req).not_to be_a_valid_request
287
- expect(auth_req).not_to be_a_valid_signature
288
- expect(auth_req).to be_a_valid_timestamp
289
- expect(auth_req).to be_a_valid_content_hash
290
- end
291
-
292
- it "shouldn't authenticate if the signature is wrong for v1.3 SHA256" do
293
- headers = MERB_HEADERS_V1_3_SHA256.dup
294
- headers["HTTP_X_OPS_AUTHORIZATION_1"] = "epicfail"
295
- mock_request = MockRequest.new(PATH, MERB_REQUEST_PARAMS, headers, BODY)
296
- expect(Time).to receive(:now).at_least(:once).and_return(TIMESTAMP_OBJ)
297
-
298
- auth_req = Mixlib::Authentication::SignatureVerification.new
299
- res = auth_req.authenticate_user_request(mock_request, @user_private_key)
300
- expect(res).to be_nil
301
- expect(auth_req).not_to be_a_valid_request
302
- expect(auth_req).not_to be_a_valid_signature
303
- expect(auth_req).to be_a_valid_timestamp
304
- expect(auth_req).to be_a_valid_content_hash
305
- end
306
- end
307
-
308
- USER_ID = "spec-user"
309
- DIGESTED_USER_ID = Base64.encode64(Digest::SHA1.new.digest(USER_ID)).chomp
310
- BODY = "Spec Body"
311
- HASHED_BODY = "DFteJZPVv6WKdQmMqZUQUumUyRs=" # Base64.encode64(Digest::SHA1.digest("Spec Body")).chomp
312
- HASHED_BODY_SHA256 = "hDlKNZhIhgso3Fs0S0pZwJ0xyBWtR1RBaeHs1DrzOho="
313
- TIMESTAMP_ISO8601 = "2009-01-01T12:00:00Z"
314
- TIMESTAMP_OBJ = Time.parse("Thu Jan 01 12:00:00 -0000 2009")
315
- PATH = "/organizations/clownco"
316
- HASHED_CANONICAL_PATH = "YtBWDn1blGGuFIuKksdwXzHU9oE=" # Base64.encode64(Digest::SHA1.digest("/organizations/clownco")).chomp
317
-
318
- V1_0_ARGS = {
319
- :body => BODY,
320
- :user_id => USER_ID,
321
- :http_method => :post,
322
- :timestamp => TIMESTAMP_ISO8601, # fixed timestamp so we get back the same answer each time.
323
- :file => MockFile.new,
324
- :path => PATH,
325
- }
326
-
327
- V1_1_ARGS = {
328
- :body => BODY,
329
- :user_id => USER_ID,
330
- :http_method => :post,
331
- :timestamp => TIMESTAMP_ISO8601, # fixed timestamp so we get back the same answer each time.
332
- :file => MockFile.new,
333
- :path => PATH,
334
- :proto_version => 1.1,
335
- }
336
-
337
- V1_3_ARGS_SHA256 = {
338
- :body => BODY,
339
- :user_id => USER_ID,
340
- :http_method => :post,
341
- :timestamp => TIMESTAMP_ISO8601, # fixed timestamp so we get back the same answer each time.
342
- :file => MockFile.new,
343
- :path => PATH,
344
- :proto_version => "1.3",
345
- :headers => {
346
- "X-OpS-SeRvEr-ApI-VerSiOn" => "1",
347
- }
348
- # This defaults to sha256
349
- }
350
-
351
- LONG_PATH_LONG_USER_ARGS = {
352
- :body => BODY,
353
- :user_id => "A" * 200,
354
- :http_method => :put,
355
- :timestamp => TIMESTAMP_ISO8601, # fixed timestamp so we get back the same answer each time.
356
- :file => MockFile.new,
357
- :path => PATH + "/nodes/#{"A" * 250}",
358
- }
359
-
360
- REQUESTING_ACTOR_ID = "c0f8a68c52bffa1020222a56b23cccfa"
361
-
362
- # Content hash is ???TODO
363
- X_OPS_CONTENT_HASH = "DFteJZPVv6WKdQmMqZUQUumUyRs="
364
- X_OPS_CONTENT_HASH_SHA256 = "hDlKNZhIhgso3Fs0S0pZwJ0xyBWtR1RBaeHs1DrzOho="
365
-
366
- X_OPS_AUTHORIZATION_LINES_V1_0 = [
367
- "jVHrNniWzpbez/eGWjFnO6lINRIuKOg40ZTIQudcFe47Z9e/HvrszfVXlKG4",
368
- "NMzYZgyooSvU85qkIUmKuCqgG2AIlvYa2Q/2ctrMhoaHhLOCWWoqYNMaEqPc",
369
- "3tKHE+CfvP+WuPdWk4jv4wpIkAz6ZLxToxcGhXmZbXpk56YTmqgBW2cbbw4O",
370
- "IWPZDHSiPcw//AYNgW1CCDptt+UFuaFYbtqZegcBd2n/jzcWODA7zL4KWEUy",
371
- "9q4rlh/+1tBReg60QdsmDRsw/cdO1GZrKtuCwbuD4+nbRdVBKv72rqHX9cu0",
372
- "utju9jzczCyB+sSAQWrxSsXB/b8vV2qs0l4VD2ML+w==",
373
- ]
374
-
375
- X_OPS_AUTHORIZATION_LINES = [
376
- "UfZD9dRz6rFu6LbP5Mo1oNHcWYxpNIcUfFCffJS1FQa0GtfU/vkt3/O5HuCM",
377
- "1wIFl/U0f5faH9EWpXWY5NwKR031Myxcabw4t4ZLO69CIh/3qx1XnjcZvt2w",
378
- "c2R9bx/43IWA/r8w8Q6decuu0f6ZlNheJeJhaYPI8piX/aH+uHBH8zTACZu8",
379
- "vMnl5MF3/OIlsZc8cemq6eKYstp8a8KYq9OmkB5IXIX6qVMJHA6fRvQEB/7j",
380
- "281Q7oI/O+lE8AmVyBbwruPb7Mp6s4839eYiOdjbDwFjYtbS3XgAjrHlaD7W",
381
- "FDlbAG7H8Dmvo+wBxmtNkszhzbBnEYtuwQqT8nM/8A==",
382
- ]
383
-
384
- X_OPS_AUTHORIZATION_LINES_V1_3_SHA256 = [
385
- "FZOmXAyOBAZQV/uw188iBljBJXOm+m8xQ/8KTGLkgGwZNcRFxk1m953XjE3W",
386
- "VGy1dFT76KeaNWmPCNtDmprfH2na5UZFtfLIKrPv7xm80V+lzEzTd9WBwsfP",
387
- "42dZ9N+V9I5SVfcL/lWrrlpdybfceJC5jOcP5tzfJXWUITwb6Z3Erg3DU3Uh",
388
- "H9h9E0qWlYGqmiNCVrBnpe6Si1gU/Jl+rXlRSNbLJ4GlArAPuL976iTYJTzE",
389
- "MmbLUIm3JRYi00Yb01IUCCKdI90vUq1HHNtlTEu93YZfQaJwRxXlGkCNwIJe",
390
- "fy49QzaCIEu1XiOx5Jn+4GmkrZch/RrK9VzQWXgs+w==",
391
- ]
392
-
393
- SSH_AGENT_RESPONSE = "\x00\x00\x00\frsa-sha2-256\x00\x00\x01\x00\x15\x93\xA6\\\f\x8E\x04\x06PW\xFB\xB0\xD7\xCF\"\x06X\xC1%s\xA6\xFAo1C\xFF\nLb\xE4\x80l\x195\xC4E\xC6Mf\xF7\x9D\xD7\x8CM\xD6Tl\xB5tT\xFB\xE8\xA7\x9A5i\x8F\b\xDBC\x9A\x9A\xDF\x1Fi\xDA\xE5FE\xB5\xF2\xC8*\xB3\xEF\xEF\x19\xBC\xD1_\xA5\xCCL\xD3w\xD5\x81\xC2\xC7\xCF\xE3gY\xF4\xDF\x95\xF4\x8ERU\xF7\v\xFEU\xAB\xAEZ]\xC9\xB7\xDCx\x90\xB9\x8C\xE7\x0F\xE6\xDC\xDF%u\x94!<\e\xE9\x9D\xC4\xAE\r\xC3Su!\x1F\xD8}\x13J\x96\x95\x81\xAA\x9A#BV\xB0g\xA5\xEE\x92\x8BX\x14\xFC\x99~\xADyQH\xD6\xCB'\x81\xA5\x02\xB0\x0F\xB8\xBF{\xEA$\xD8%<\xC42f\xCBP\x89\xB7%\x16\"\xD3F\e\xD3R\x14\b\"\x9D#\xDD/R\xADG\x1C\xDBeLK\xBD\xDD\x86_A\xA2pG\x15\xE5\x1A@\x8D\xC0\x82^\x7F.=C6\x82 K\xB5^#\xB1\xE4\x99\xFE\xE0i\xA4\xAD\x97!\xFD\x1A\xCA\xF5\\\xD0Yx,\xFB"
394
- # We expect Mixlib::Authentication::SignedHeaderAuth#sign to return this
395
- # if passed the BODY above, based on version
396
-
397
- EXPECTED_SIGN_RESULT_V1_0 = {
398
- "X-Ops-Content-Hash" => X_OPS_CONTENT_HASH,
399
- "X-Ops-Userid" => USER_ID,
400
- "X-Ops-Sign" => "algorithm=sha1;version=1.0;",
401
- "X-Ops-Authorization-1" => X_OPS_AUTHORIZATION_LINES_V1_0[0],
402
- "X-Ops-Authorization-2" => X_OPS_AUTHORIZATION_LINES_V1_0[1],
403
- "X-Ops-Authorization-3" => X_OPS_AUTHORIZATION_LINES_V1_0[2],
404
- "X-Ops-Authorization-4" => X_OPS_AUTHORIZATION_LINES_V1_0[3],
405
- "X-Ops-Authorization-5" => X_OPS_AUTHORIZATION_LINES_V1_0[4],
406
- "X-Ops-Authorization-6" => X_OPS_AUTHORIZATION_LINES_V1_0[5],
407
- "X-Ops-Timestamp" => TIMESTAMP_ISO8601,
408
- }
409
-
410
- EXPECTED_SIGN_RESULT_V1_1 = {
411
- "X-Ops-Content-Hash" => X_OPS_CONTENT_HASH,
412
- "X-Ops-Userid" => USER_ID,
413
- "X-Ops-Sign" => "algorithm=sha1;version=1.1;",
414
- "X-Ops-Authorization-1" => X_OPS_AUTHORIZATION_LINES[0],
415
- "X-Ops-Authorization-2" => X_OPS_AUTHORIZATION_LINES[1],
416
- "X-Ops-Authorization-3" => X_OPS_AUTHORIZATION_LINES[2],
417
- "X-Ops-Authorization-4" => X_OPS_AUTHORIZATION_LINES[3],
418
- "X-Ops-Authorization-5" => X_OPS_AUTHORIZATION_LINES[4],
419
- "X-Ops-Authorization-6" => X_OPS_AUTHORIZATION_LINES[5],
420
- "X-Ops-Timestamp" => TIMESTAMP_ISO8601,
421
- }
422
-
423
- EXPECTED_SIGN_RESULT_V1_3_SHA256 = {
424
- "X-Ops-Content-Hash" => X_OPS_CONTENT_HASH_SHA256,
425
- "X-Ops-Userid" => USER_ID,
426
- "X-Ops-Sign" => "algorithm=sha256;version=1.3;",
427
- "X-Ops-Authorization-1" => X_OPS_AUTHORIZATION_LINES_V1_3_SHA256[0],
428
- "X-Ops-Authorization-2" => X_OPS_AUTHORIZATION_LINES_V1_3_SHA256[1],
429
- "X-Ops-Authorization-3" => X_OPS_AUTHORIZATION_LINES_V1_3_SHA256[2],
430
- "X-Ops-Authorization-4" => X_OPS_AUTHORIZATION_LINES_V1_3_SHA256[3],
431
- "X-Ops-Authorization-5" => X_OPS_AUTHORIZATION_LINES_V1_3_SHA256[4],
432
- "X-Ops-Authorization-6" => X_OPS_AUTHORIZATION_LINES_V1_3_SHA256[5],
433
- "X-Ops-Timestamp" => TIMESTAMP_ISO8601,
434
- }
435
-
436
- OTHER_HEADERS = {
437
- # An arbitrary sampling of non-HTTP_* headers are in here to
438
- # exercise that code path.
439
- "REMOTE_ADDR" => "127.0.0.1",
440
- "PATH_INFO" => "/organizations/local-test-org/cookbooks",
441
- "REQUEST_PATH" => "/organizations/local-test-org/cookbooks",
442
- "CONTENT_TYPE" => "multipart/form-data; boundary=----RubyMultipartClient6792ZZZZZ",
443
- "CONTENT_LENGTH" => "394",
444
- }
445
-
446
- # This is what will be in request.params for the Merb case.
447
- MERB_REQUEST_PARAMS = {
448
- "name" => "zsh", "action" => "create", "controller" => "chef_server_api/cookbooks",
449
- "organization_id" => "local-test-org", "requesting_actor_id" => REQUESTING_ACTOR_ID
450
- }
451
-
452
- MERB_HEADERS_V1_3_SHA256 = {
453
- # These are used by signatureverification.
454
- "HTTP_HOST" => "127.0.0.1",
455
- "HTTP_X_OPS_SIGN" => "algorithm=sha256;version=1.3;",
456
- "HTTP_X_OPS_REQUESTID" => "127.0.0.1 1258566194.85386",
457
- "HTTP_X_OPS_TIMESTAMP" => TIMESTAMP_ISO8601,
458
- "HTTP_X_OPS_CONTENT_HASH" => X_OPS_CONTENT_HASH_SHA256,
459
- "HTTP_X_OPS_USERID" => USER_ID,
460
- "HTTP_X_OPS_SERVER_API_VERSION" => "1",
461
- "HTTP_X_OPS_AUTHORIZATION_1" => X_OPS_AUTHORIZATION_LINES_V1_3_SHA256[0],
462
- "HTTP_X_OPS_AUTHORIZATION_2" => X_OPS_AUTHORIZATION_LINES_V1_3_SHA256[1],
463
- "HTTP_X_OPS_AUTHORIZATION_3" => X_OPS_AUTHORIZATION_LINES_V1_3_SHA256[2],
464
- "HTTP_X_OPS_AUTHORIZATION_4" => X_OPS_AUTHORIZATION_LINES_V1_3_SHA256[3],
465
- "HTTP_X_OPS_AUTHORIZATION_5" => X_OPS_AUTHORIZATION_LINES_V1_3_SHA256[4],
466
- "HTTP_X_OPS_AUTHORIZATION_6" => X_OPS_AUTHORIZATION_LINES_V1_3_SHA256[5],
467
- }.merge(OTHER_HEADERS)
468
-
469
- # Tis is what will be in request.env for the Merb case.
470
- MERB_HEADERS_V1_1 = {
471
- # These are used by signatureverification.
472
- "HTTP_HOST" => "127.0.0.1",
473
- "HTTP_X_OPS_SIGN" => "algorithm=sha1;version=1.1;",
474
- "HTTP_X_OPS_REQUESTID" => "127.0.0.1 1258566194.85386",
475
- "HTTP_X_OPS_TIMESTAMP" => TIMESTAMP_ISO8601,
476
- "HTTP_X_OPS_CONTENT_HASH" => X_OPS_CONTENT_HASH,
477
- "HTTP_X_OPS_USERID" => USER_ID,
478
- "HTTP_X_OPS_AUTHORIZATION_1" => X_OPS_AUTHORIZATION_LINES[0],
479
- "HTTP_X_OPS_AUTHORIZATION_2" => X_OPS_AUTHORIZATION_LINES[1],
480
- "HTTP_X_OPS_AUTHORIZATION_3" => X_OPS_AUTHORIZATION_LINES[2],
481
- "HTTP_X_OPS_AUTHORIZATION_4" => X_OPS_AUTHORIZATION_LINES[3],
482
- "HTTP_X_OPS_AUTHORIZATION_5" => X_OPS_AUTHORIZATION_LINES[4],
483
- "HTTP_X_OPS_AUTHORIZATION_6" => X_OPS_AUTHORIZATION_LINES[5],
484
- }.merge(OTHER_HEADERS)
485
-
486
- # Tis is what will be in request.env for the Merb case.
487
- MERB_HEADERS_V1_0 = {
488
- # These are used by signatureverification.
489
- "HTTP_HOST" => "127.0.0.1",
490
- "HTTP_X_OPS_SIGN" => "version=1.0",
491
- "HTTP_X_OPS_REQUESTID" => "127.0.0.1 1258566194.85386",
492
- "HTTP_X_OPS_TIMESTAMP" => TIMESTAMP_ISO8601,
493
- "HTTP_X_OPS_CONTENT_HASH" => X_OPS_CONTENT_HASH,
494
- "HTTP_X_OPS_USERID" => USER_ID,
495
- "HTTP_X_OPS_AUTHORIZATION_1" => X_OPS_AUTHORIZATION_LINES_V1_0[0],
496
- "HTTP_X_OPS_AUTHORIZATION_2" => X_OPS_AUTHORIZATION_LINES_V1_0[1],
497
- "HTTP_X_OPS_AUTHORIZATION_3" => X_OPS_AUTHORIZATION_LINES_V1_0[2],
498
- "HTTP_X_OPS_AUTHORIZATION_4" => X_OPS_AUTHORIZATION_LINES_V1_0[3],
499
- "HTTP_X_OPS_AUTHORIZATION_5" => X_OPS_AUTHORIZATION_LINES_V1_0[4],
500
- "HTTP_X_OPS_AUTHORIZATION_6" => X_OPS_AUTHORIZATION_LINES_V1_0[5],
501
- }.merge(OTHER_HEADERS)
502
-
503
- PASSENGER_REQUEST_PARAMS = {
504
- "action" => "create",
505
- #"tarball"=>#<File:/tmp/RackMultipart20091120-25570-mgq2sa-0>,
506
- "controller" => "api/v1/cookbooks",
507
- "cookbook" => "{\"category\":\"databases\"}",
508
- }
509
-
510
- PASSENGER_HEADERS_V1_1 = {
511
- # These are used by signatureverification.
512
- "HTTP_HOST" => "127.0.0.1",
513
- "HTTP_X_OPS_SIGN" => "algorithm=sha1;version=1.1;",
514
- "HTTP_X_OPS_REQUESTID" => "127.0.0.1 1258566194.85386",
515
- "HTTP_X_OPS_TIMESTAMP" => TIMESTAMP_ISO8601,
516
- "HTTP_X_OPS_CONTENT_HASH" => X_OPS_CONTENT_HASH,
517
- "HTTP_X_OPS_USERID" => USER_ID,
518
- "HTTP_X_OPS_AUTHORIZATION_1" => X_OPS_AUTHORIZATION_LINES[0],
519
- "HTTP_X_OPS_AUTHORIZATION_2" => X_OPS_AUTHORIZATION_LINES[1],
520
- "HTTP_X_OPS_AUTHORIZATION_3" => X_OPS_AUTHORIZATION_LINES[2],
521
- "HTTP_X_OPS_AUTHORIZATION_4" => X_OPS_AUTHORIZATION_LINES[3],
522
- "HTTP_X_OPS_AUTHORIZATION_5" => X_OPS_AUTHORIZATION_LINES[4],
523
- "HTTP_X_OPS_AUTHORIZATION_6" => X_OPS_AUTHORIZATION_LINES[5],
524
- }.merge(OTHER_HEADERS)
525
-
526
- PASSENGER_HEADERS_V1_0 = {
527
- # These are used by signatureverification.
528
- "HTTP_HOST" => "127.0.0.1",
529
- "HTTP_X_OPS_SIGN" => "version=1.0",
530
- "HTTP_X_OPS_REQUESTID" => "127.0.0.1 1258566194.85386",
531
- "HTTP_X_OPS_TIMESTAMP" => TIMESTAMP_ISO8601,
532
- "HTTP_X_OPS_CONTENT_HASH" => X_OPS_CONTENT_HASH,
533
- "HTTP_X_OPS_USERID" => USER_ID,
534
- "HTTP_X_OPS_AUTHORIZATION_1" => X_OPS_AUTHORIZATION_LINES_V1_0[0],
535
- "HTTP_X_OPS_AUTHORIZATION_2" => X_OPS_AUTHORIZATION_LINES_V1_0[1],
536
- "HTTP_X_OPS_AUTHORIZATION_3" => X_OPS_AUTHORIZATION_LINES_V1_0[2],
537
- "HTTP_X_OPS_AUTHORIZATION_4" => X_OPS_AUTHORIZATION_LINES_V1_0[3],
538
- "HTTP_X_OPS_AUTHORIZATION_5" => X_OPS_AUTHORIZATION_LINES_V1_0[4],
539
- "HTTP_X_OPS_AUTHORIZATION_6" => X_OPS_AUTHORIZATION_LINES_V1_0[5],
540
- }.merge(OTHER_HEADERS)
541
-
542
- # generated with
543
- # openssl genrsa -out private.pem 2048
544
- # openssl rsa -in private.pem -out public.pem -pubout
545
- PUBLIC_KEY_DATA = <<EOS
546
- -----BEGIN PUBLIC KEY-----
547
- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0ueqo76MXuP6XqZBILFz
548
- iH/9AI7C6PaN5W0dSvkr9yInyGHSz/IR1+4tqvP2qlfKVKI4CP6BFH251Ft9qMUB
549
- uAsnlAVQ1z0exDtIFFOyQCdR7iXmjBIWMSS4buBwRQXwDK7id1OxtU23qVJv+xwE
550
- V0IzaaSJmaGLIbvRBD+qatfUuQJBMU/04DdJIwvLtZBYdC2219m5dUBQaa4bimL+
551
- YN9EcsDzD9h9UxQo5ReK7b3cNMzJBKJWLzFBcJuePMzAnLFktr/RufX4wpXe6XJx
552
- oVPaHo72GorLkwnQ0HYMTY8rehT4mDi1FI969LHCFFaFHSAaRnwdXaQkJmSfcxzC
553
- YQIDAQAB
554
- -----END PUBLIC KEY-----
555
- EOS
556
-
557
- PUBLIC_KEY = OpenSSL::PKey::RSA.new(PUBLIC_KEY_DATA)
558
-
559
- PRIVATE_KEY_DATA = <<EOS
560
- -----BEGIN RSA PRIVATE KEY-----
561
- MIIEpAIBAAKCAQEA0ueqo76MXuP6XqZBILFziH/9AI7C6PaN5W0dSvkr9yInyGHS
562
- z/IR1+4tqvP2qlfKVKI4CP6BFH251Ft9qMUBuAsnlAVQ1z0exDtIFFOyQCdR7iXm
563
- jBIWMSS4buBwRQXwDK7id1OxtU23qVJv+xwEV0IzaaSJmaGLIbvRBD+qatfUuQJB
564
- MU/04DdJIwvLtZBYdC2219m5dUBQaa4bimL+YN9EcsDzD9h9UxQo5ReK7b3cNMzJ
565
- BKJWLzFBcJuePMzAnLFktr/RufX4wpXe6XJxoVPaHo72GorLkwnQ0HYMTY8rehT4
566
- mDi1FI969LHCFFaFHSAaRnwdXaQkJmSfcxzCYQIDAQABAoIBAQCW3I4sKN5B9jOe
567
- xq/pkeWBq4OvhW8Ys1yW0zFT8t6nHbB1XrwscQygd8gE9BPqj3e0iIEqtdphbPmj
568
- VHqTYbC0FI6QDClifV7noTwTBjeIOlgZ0NSUN0/WgVzIOxUz2mZ2vBZUovKILPqG
569
- TOi7J7RXMoySMdcXpP1f+PgvYNcnKsT72UcWaSXEV8/zo+Zm/qdGPVWwJonri5Mp
570
- DVm5EQSENBiRyt028rU6ElXORNmoQpVjDVqZ1gipzXkifdjGyENw2rt4V/iKYD7V
571
- 5iqXOsvP6Cemf4gbrjunAgDG08S00kiUgvVWcdXW+dlsR2nCvH4DOEe3AYYh/aH8
572
- DxEE7FbtAoGBAPcNO8fJ56mNw0ow4Qg38C+Zss/afhBOCfX4O/SZKv/roRn5+gRM
573
- KRJYSVXNnsjPI1plzqR4OCyOrjAhtuvL4a0DinDzf1+fiztyNohwYsW1vYmqn3ti
574
- EN0GhSgE7ppZjqvLQ3f3LUTxynhA0U+k9wflb4irIlViTUlCsOPkrNJDAoGBANqL
575
- Q+vvuGSsmRLU/Cenjy+Mjj6+QENg51dz34o8JKuVKIPKU8pNnyeLa5fat0qD2MHm
576
- OB9opeQOcw0dStodxr6DB3wi83bpjeU6BWUGITNiWEaZEBrQ0aiqNJJKrrHm8fAZ
577
- 9o4l4oHc4hI0kYVYYDuxtKuVJrzZiEapTwoOcYiLAoGBAI/EWbeIHZIj9zOjgjEA
578
- LHvm25HtulLOtyk2jd1njQhlHNk7CW2azIPqcLLH99EwCYi/miNH+pijZ2aHGCXb
579
- /bZrSxM0ADmrZKDxdB6uGCyp+GS2sBxjEyEsfCyvwhJ8b3Q100tqwiNO+d5FCglp
580
- HICx2dgUjuRVUliBwOK93nx1AoGAUI8RhIEjOYkeDAESyhNMBr0LGjnLOosX+/as
581
- qiotYkpjWuFULbibOFp+WMW41vDvD9qrSXir3fstkeIAW5KqVkO6mJnRoT3Knnra
582
- zjiKOITCAZQeiaP8BO5o3pxE9TMqb9VCO3ffnPstIoTaN4syPg7tiGo8k1SklVeH
583
- 2S8lzq0CgYAKG2fljIYWQvGH628rp4ZcXS4hWmYohOxsnl1YrszbJ+hzR+IQOhGl
584
- YlkUQYXhy9JixmUUKtH+NXkKX7Lyc8XYw5ETr7JBT3ifs+G7HruDjVG78EJVojbd
585
- 8uLA+DdQm5mg4vd1GTiSK65q/3EeoBlUaVor3HhLFki+i9qpT8CBsg==
586
- -----END RSA PRIVATE KEY-----
587
- EOS
588
-
589
- PRIVATE_KEY = OpenSSL::PKey::RSA.new(PRIVATE_KEY_DATA)
590
-
591
- V1_0_CANONICAL_REQUEST_DATA = <<EOS
592
- Method:POST
593
- Hashed Path:#{HASHED_CANONICAL_PATH}
594
- X-Ops-Content-Hash:#{HASHED_BODY}
595
- X-Ops-Timestamp:#{TIMESTAMP_ISO8601}
596
- X-Ops-UserId:#{USER_ID}
597
- EOS
598
- V1_0_CANONICAL_REQUEST = V1_0_CANONICAL_REQUEST_DATA.chomp
599
-
600
- V1_1_CANONICAL_REQUEST_DATA = <<EOS
601
- Method:POST
602
- Hashed Path:#{HASHED_CANONICAL_PATH}
603
- X-Ops-Content-Hash:#{HASHED_BODY}
604
- X-Ops-Timestamp:#{TIMESTAMP_ISO8601}
605
- X-Ops-UserId:#{DIGESTED_USER_ID}
606
- EOS
607
- V1_1_CANONICAL_REQUEST = V1_1_CANONICAL_REQUEST_DATA.chomp
608
-
609
- V1_3_SHA256_CANONICAL_REQUEST_DATA = <<EOS
610
- Method:POST
611
- Path:#{PATH}
612
- X-Ops-Content-Hash:#{HASHED_BODY_SHA256}
613
- X-Ops-Sign:version=1.3
614
- X-Ops-Timestamp:#{TIMESTAMP_ISO8601}
615
- X-Ops-UserId:#{USER_ID}
616
- X-Ops-Server-API-Version:1
617
- EOS
618
- V1_3_SHA256_CANONICAL_REQUEST = V1_3_SHA256_CANONICAL_REQUEST_DATA.chomp
619
-
620
- V1_3_SHA256_SIGNING_OBJECT = Mixlib::Authentication::SignedHeaderAuth.signing_object(V1_3_ARGS_SHA256)
621
- V1_1_SIGNING_OBJECT = Mixlib::Authentication::SignedHeaderAuth.signing_object(V1_1_ARGS)
622
- V1_0_SIGNING_OBJECT = Mixlib::Authentication::SignedHeaderAuth.signing_object(V1_0_ARGS)
623
- LONG_SIGNING_OBJECT = Mixlib::Authentication::SignedHeaderAuth.signing_object(LONG_PATH_LONG_USER_ARGS)
@@ -1,55 +0,0 @@
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{trace 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{trace debug info warn error fatal}.each do |level|
48
- it "forward #{level} to mixlib-log" do
49
- expect_any_instance_of(Mixlib::Log).to receive(level).with("foo")
50
-
51
- Mixlib::Authentication.logger.send(level, "foo")
52
- end
53
- end
54
- end
55
- end
@@ -1,22 +0,0 @@
1
- #
2
- # Author:: Tim Hinderliter (<tim@opscode.com>)
3
- # Author:: Christopher Walters (<cw@opscode.com>)
4
- # Copyright:: Copyright (c) 2009, 2010 Opscode, Inc.
5
- # License:: Apache License, Version 2.0
6
- #
7
- # Licensed under the Apache License, Version 2.0 (the "License");
8
- # you may not use this file except in compliance with the License.
9
- # You may obtain a copy of the License at
10
- #
11
- # http://www.apache.org/licenses/LICENSE-2.0
12
- #
13
- # Unless required by applicable law or agreed to in writing, software
14
- # distributed under the License is distributed on an "AS IS" BASIS,
15
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
- # See the License for the specific language governing permissions and
17
- # limitations under the License.
18
- #
19
-
20
- $:.unshift File.expand_path(File.join(File.dirname(__FILE__), "..", "lib")) # lib in mixlib-authentication
21
-
22
- require "rubygems"