mixlib-authentication 2.1.1 → 3.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  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"