inspec/lib/plugins/inspec-compliance/test/unit/api_test.rb
Ryan Davis 22a3ee5855 Fixed missing requires.
Telemetry tests were hitting inspec/config via a different route and
inspec/config uses forwardable w/o requiring.

lib/plugins/inspec-compliance/test/unit/api_test.rb had a test that
had never run before and required webmock.

Signed-off-by: Ryan Davis <zenspider@chef.io>
2019-05-18 21:02:13 -07:00

386 lines
17 KiB
Ruby

require 'minitest/autorun'
require 'webmock/minitest'
require 'mocha/setup'
require_relative '../../lib/inspec-compliance/api.rb'
describe InspecPlugins::Compliance::API do
let(:profiles_response) do
[{ 'name'=>'apache-baseline',
'title'=>'DevSec Apache Baseline',
'maintainer'=>'DevSec Hardening Framework Team',
'copyright'=>'DevSec Hardening Framework Team',
'copyright_email'=>'hello@dev-sec.io',
'license'=>'Apache 2 license',
'summary'=>'Test-suite for best-practice apache hardening',
'version'=>'2.0.2',
'supports'=>[{ 'os-family'=>'unix' }],
'depends'=>nil,
'owner_id'=>'admin' },
{ 'name'=>'apache-baseline',
'title'=>'DevSec Apache Baseline',
'maintainer'=>'Hardening Framework Team',
'copyright'=>'Hardening Framework Team',
'copyright_email'=>'hello@dev-sec.io',
'license'=>'Apache 2 license',
'summary'=>'Test-suite for best-practice apache hardening',
'version'=>'2.0.1',
'supports'=>[{ 'os-family'=>'unix' }],
'depends'=>nil,
'latest_version'=>'2.0.2',
'owner_id'=>'admin' },
{ 'name'=>'cis-aix-5.3-6.1-level1',
'title'=>'CIS AIX 5.3 and AIX 6.1 Benchmark Level 1',
'maintainer'=>'Chef Software, Inc.',
'copyright'=>'Chef Software, Inc.',
'copyright_email'=>'support@chef.io',
'license'=>'Proprietary, All rights reserved',
'summary'=>'CIS AIX 5.3 and AIX 6.1 Benchmark Level 1 translated from SCAP',
'version'=>'1.1.0',
'supports'=>nil,
'depends'=>nil,
'latest_version'=>'1.1.0-3',
'owner_id'=>'admin' }]
end
describe '.version' do
let(:headers) { 'test-headers' }
let(:config) do
{
'server' => 'myserver',
'insecure' => true,
}
end
before do
InspecPlugins::Compliance::API.expects(:get_headers).returns(headers)
end
describe 'when a 404 is received' do
it 'should return an empty hash' do
response = mock
response.stubs(:code).returns('404')
InspecPlugins::Compliance::HTTP.expects(:get).with('myserver/version', 'test-headers', true).returns(response)
InspecPlugins::Compliance::API.version(config).must_equal({})
end
end
describe 'when the returned body is nil' do
it 'should return an empty hash' do
response = mock
response.stubs(:code).returns('200')
response.stubs(:body).returns(nil)
InspecPlugins::Compliance::HTTP.expects(:get).with('myserver/version', 'test-headers', true).returns(response)
InspecPlugins::Compliance::API.version(config).must_equal({})
end
end
describe 'when the returned body is an empty string' do
it 'should return an empty hash' do
response = mock
response.stubs(:code).returns('200')
response.stubs(:body).returns('')
InspecPlugins::Compliance::HTTP.expects(:get).with('myserver/version', 'test-headers', true).returns(response)
InspecPlugins::Compliance::API.version(config).must_equal({})
end
end
describe 'when the returned body has no version key' do
it 'should return an empty hash' do
response = mock
response.stubs(:code).returns('200')
response.stubs(:body).returns('{"api":"compliance"}')
InspecPlugins::Compliance::HTTP.expects(:get).with('myserver/version', 'test-headers', true).returns(response)
InspecPlugins::Compliance::API.version(config).must_equal({})
end
end
describe 'when the returned body has an empty version key' do
it 'should return an empty hash' do
response = mock
response.stubs(:code).returns('200')
response.stubs(:body).returns('{"api":"compliance","version":""}')
InspecPlugins::Compliance::HTTP.expects(:get).with('myserver/version', 'test-headers', true).returns(response)
InspecPlugins::Compliance::API.version(config).must_equal({})
end
end
describe 'when the returned body has a proper version' do
it 'should return an empty hash' do
response = mock
response.stubs(:code).returns('200')
response.stubs(:body).returns('{"api":"compliance","version":"1.2.3"}')
InspecPlugins::Compliance::HTTP.expects(:get).with('myserver/version', 'test-headers', true).returns(response)
InspecPlugins::Compliance::API.version(config).must_equal({ 'version' => '1.2.3', 'api' => 'compliance' })
end
end
end
describe 'automate/compliance is? checks' do
describe 'when the config has a compliance server_type' do
it 'automate/compliance server is? methods return correctly' do
config = InspecPlugins::Compliance::Configuration.new
config.clean
config['server_type'] = 'compliance'
InspecPlugins::Compliance::API.is_compliance_server?(config).must_equal true
InspecPlugins::Compliance::API.is_automate_server?(config).must_equal false
InspecPlugins::Compliance::API.is_automate_server_pre_080?(config).must_equal false
InspecPlugins::Compliance::API.is_automate_server_080_and_later?(config).must_equal false
InspecPlugins::Compliance::API.is_automate2_server?(config).must_equal false
end
end
describe 'when the config has a automate2 server_type' do
it 'automate/compliance server is? methods return correctly' do
config = InspecPlugins::Compliance::Configuration.new
config.clean
config['server_type'] = 'automate2'
InspecPlugins::Compliance::API.is_compliance_server?(config).must_equal false
InspecPlugins::Compliance::API.is_automate_server?(config).must_equal false
InspecPlugins::Compliance::API.is_automate_server_pre_080?(config).must_equal false
InspecPlugins::Compliance::API.is_automate_server_080_and_later?(config).must_equal false
InspecPlugins::Compliance::API.is_automate2_server?(config).must_equal true
end
end
describe 'when the config has an automate server_type and no version key' do
it 'automate/compliance server is? methods return correctly' do
config = InspecPlugins::Compliance::Configuration.new
config.clean
config['server_type'] = 'automate'
InspecPlugins::Compliance::API.is_compliance_server?(config).must_equal false
InspecPlugins::Compliance::API.is_automate_server?(config).must_equal true
InspecPlugins::Compliance::API.is_automate_server_pre_080?(config).must_equal true
InspecPlugins::Compliance::API.is_automate_server_080_and_later?(config).must_equal false
InspecPlugins::Compliance::API.is_automate2_server?(config).must_equal false
end
end
describe 'when the config has an automate server_type and a version key that is not a hash' do
it 'automate/compliance server is? methods return correctly' do
config = InspecPlugins::Compliance::Configuration.new
config.clean
config['server_type'] = 'automate'
config['version'] = '1.2.3'
InspecPlugins::Compliance::API.is_compliance_server?(config).must_equal false
InspecPlugins::Compliance::API.is_automate_server?(config).must_equal true
InspecPlugins::Compliance::API.is_automate_server_pre_080?(config).must_equal true
InspecPlugins::Compliance::API.is_automate_server_080_and_later?(config).must_equal false
InspecPlugins::Compliance::API.is_automate2_server?(config).must_equal false
end
end
describe 'when the config has an automate server_type and a version hash with no version' do
it 'automate/compliance server is? methods return correctly' do
config = InspecPlugins::Compliance::Configuration.new
config.clean
config['server_type'] = 'automate'
config['version'] = {}
InspecPlugins::Compliance::API.is_compliance_server?(config).must_equal false
InspecPlugins::Compliance::API.is_automate_server?(config).must_equal true
InspecPlugins::Compliance::API.is_automate_server_pre_080?(config).must_equal true
InspecPlugins::Compliance::API.is_automate_server_080_and_later?(config).must_equal false
end
end
describe 'when the config has an automate server_type and a version hash with a version' do
it 'automate/compliance server is? methods return correctly' do
config = InspecPlugins::Compliance::Configuration.new
config.clean
config['server_type'] = 'automate'
config['version'] = { 'version' => '0.8.1' }
InspecPlugins::Compliance::API.is_compliance_server?(config).must_equal false
InspecPlugins::Compliance::API.is_automate_server?(config).must_equal true
InspecPlugins::Compliance::API.is_automate_server_pre_080?(config).must_equal false
InspecPlugins::Compliance::API.is_automate_server_080_and_later?(config).must_equal true
end
end
end
describe '.server_version_from_config' do
it 'returns nil when the config has no version key' do
config = {}
InspecPlugins::Compliance::API.server_version_from_config(config).must_be_nil
end
it 'returns nil when the version value is not a hash' do
config = { 'version' => '123' }
InspecPlugins::Compliance::API.server_version_from_config(config).must_be_nil
end
it 'returns nil when the version value is a hash but has no version key inside' do
config = { 'version' => {} }
InspecPlugins::Compliance::API.server_version_from_config(config).must_be_nil
end
it 'returns the version if the version value is a hash containing a version' do
config = { 'version' => { 'version' => '1.2.3' } }
InspecPlugins::Compliance::API.server_version_from_config(config).must_equal '1.2.3'
end
end
describe 'profile_split' do
it 'handles a profile without version' do
InspecPlugins::Compliance::API.profile_split('admin/apache-baseline').must_equal ['admin', 'apache-baseline', nil]
end
it 'handles a profile with a version' do
InspecPlugins::Compliance::API.profile_split('admin/apache-baseline#2.0.1').must_equal ['admin', 'apache-baseline', '2.0.1']
end
end
describe 'target_url' do
it 'handles a automate profile with and without version' do
config = InspecPlugins::Compliance::Configuration.new
config.clean
config['server_type'] = 'automate'
config['server'] = 'https://myautomate'
config['version'] = '1.6.99'
InspecPlugins::Compliance::API.target_url(config, 'admin/apache-baseline').must_equal 'https://myautomate/profiles/admin/apache-baseline/tar'
InspecPlugins::Compliance::API.target_url(config, 'admin/apache-baseline#2.0.2').must_equal 'https://myautomate/profiles/admin/apache-baseline/version/2.0.2/tar'
end
it 'handles a chef-compliance profile with and without version' do
config = InspecPlugins::Compliance::Configuration.new
config.clean
config['server_type'] = 'compliance'
config['server'] = 'https://mychefcompliance'
config['version'] = '1.1.2'
InspecPlugins::Compliance::API.target_url(config, 'admin/apache-baseline').must_equal 'https://mychefcompliance/owners/admin/compliance/apache-baseline/tar'
InspecPlugins::Compliance::API.target_url(config, 'admin/apache-baseline#2.0.2').must_equal 'https://mychefcompliance/owners/admin/compliance/apache-baseline/tar'
end
end
describe 'exist?' do
it 'works with profiles returned by Automate' do
# ruby 2.3.3 has issues running stub_requests properly
# skipping for that specific version
return if RUBY_VERSION == '2.3.3'
config = InspecPlugins::Compliance::Configuration.new
config.clean
config['owner'] = 'admin'
config['server_type'] = 'automate'
config['server'] = 'https://myautomate'
config['version'] = '1.6.99'
config['automate'] = { 'ent'=>'automate', 'token_type'=>'dctoken' }
config['version'] = { 'api'=> 'compliance', 'version'=>'0.8.24' }
stub_request(:get, 'https://myautomate/profiles/admin')
.with(headers: { 'Accept'=>'*/*', 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Chef-Delivery-Enterprise'=>'automate', 'User-Agent'=>'Ruby', 'X-Data-Collector-Token'=>'' })
.to_return(status: 200, body: profiles_response.to_json, headers: {})
InspecPlugins::Compliance::API.exist?(config, 'admin/apache-baseline').must_equal true
InspecPlugins::Compliance::API.exist?(config, 'admin/apache-baseline#2.0.1').must_equal true
InspecPlugins::Compliance::API.exist?(config, 'admin/apache-baseline#2.0.999').must_equal false
InspecPlugins::Compliance::API.exist?(config, 'admin/missing-in-action').must_equal false
end
end
describe '.determine_server_type' do
let(:url) { 'https://someserver.onthe.net/' }
let(:compliance_endpoint) { '/api/version' }
let(:automate_endpoint) { '/compliance/version' }
let(:automate2_endpoint) { '/dex/auth' }
let(:headers) { nil }
let(:insecure) { true }
let(:good_response) { mock }
let(:bad_response) { mock }
it 'returns `:automate2` when a 400 is received from `https://URL/dex/auth`' do
good_response.stubs(:code).returns('400')
InspecPlugins::Compliance::HTTP.expects(:get)
.with(url + automate2_endpoint, headers, insecure)
.returns(good_response)
InspecPlugins::Compliance::API.determine_server_type(url, insecure).must_equal(:automate2)
end
it 'returns `:automate` when a 401 is received from `https://URL/compliance/version`' do
good_response.stubs(:code).returns('401')
bad_response.stubs(:code).returns('404')
InspecPlugins::Compliance::HTTP.expects(:get)
.with(url + automate2_endpoint, headers, insecure)
.returns(bad_response)
InspecPlugins::Compliance::HTTP.expects(:get)
.with(url + automate_endpoint, headers, insecure)
.returns(good_response)
InspecPlugins::Compliance::API.determine_server_type(url, insecure).must_equal(:automate)
end
# Chef Automate currently returns 401 for `/compliance/version` but some
# versions of OpsWorks Chef Automate return 200 and a Chef Manage page when
# unauthenticated requests are received.
it 'returns `:automate` when a 200 is received from `https://URL/compliance/version`' do
bad_response.stubs(:code).returns('404')
good_response.stubs(:code).returns('200')
good_response.stubs(:body).returns('Are You Looking For the Chef Server?')
InspecPlugins::Compliance::HTTP.expects(:get)
.with(url + automate2_endpoint, headers, insecure)
.returns(bad_response)
InspecPlugins::Compliance::HTTP.expects(:get)
.with(url + automate_endpoint, headers, insecure)
.returns(good_response)
InspecPlugins::Compliance::API.determine_server_type(url, insecure).must_equal(:automate)
end
it 'returns `nil` if a 200 is received from `https://URL/compliance/version` but not redirected to Chef Manage' do
bad_response.stubs(:code).returns('200')
bad_response.stubs(:body).returns('No Chef Manage here')
InspecPlugins::Compliance::HTTP.expects(:get)
.with(url + automate_endpoint, headers, insecure)
.returns(bad_response)
InspecPlugins::Compliance::HTTP.expects(:get)
.with(url + automate2_endpoint, headers, insecure)
.returns(bad_response)
mock_compliance_response = mock
mock_compliance_response.stubs(:code).returns('404')
InspecPlugins::Compliance::HTTP.expects(:get)
.with(url + compliance_endpoint, headers, insecure)
.returns(mock_compliance_response)
InspecPlugins::Compliance::API.determine_server_type(url, insecure).must_be_nil
end
it 'returns `:compliance` when a 200 is received from `https://URL/api/version`' do
good_response.stubs(:code).returns('200')
bad_response.stubs(:code).returns('404')
InspecPlugins::Compliance::HTTP.expects(:get)
.with(url + automate_endpoint, headers, insecure)
.returns(bad_response)
InspecPlugins::Compliance::HTTP.expects(:get)
.with(url + automate2_endpoint, headers, insecure)
.returns(bad_response)
InspecPlugins::Compliance::HTTP.expects(:get)
.with(url + compliance_endpoint, headers, insecure)
.returns(good_response)
InspecPlugins::Compliance::API.determine_server_type(url, insecure).must_equal(:compliance)
end
it 'returns `nil` if it cannot determine the server type' do
bad_response.stubs(:code).returns('404')
InspecPlugins::Compliance::HTTP.expects(:get)
.with(url + automate2_endpoint, headers, insecure)
.returns(bad_response)
InspecPlugins::Compliance::HTTP.expects(:get)
.with(url + automate_endpoint, headers, insecure)
.returns(bad_response)
InspecPlugins::Compliance::HTTP.expects(:get)
.with(url + compliance_endpoint, headers, insecure)
.returns(bad_response)
InspecPlugins::Compliance::API.determine_server_type(url, insecure).must_be_nil
end
end
end