mirror of
https://github.com/inspec/inspec
synced 2024-11-27 07:00:39 +00:00
577688a3a0
Many of the resources are named as a top-level class with a fairly generic class name, such as "OS". This causes an issue specifically with kitchen-google which depends on a gem which depends on the "os" gem which itself defines an OS class with a different superclass. This prevents users from using TK, Google Compute, and Inspec without this fix. Some mocked commands had their digest changed as well due to the new indentation, specifically in the User and RegistryKey classes. I strongly recommend viewing this diff with `git diff --ignore-space-change` to see the *real* changes. :)
137 lines
3.5 KiB
Ruby
137 lines
3.5 KiB
Ruby
# encoding: utf-8
|
|
# author: Christoph Hartmann
|
|
# author: Dominik Richter
|
|
|
|
# Usage:
|
|
# describe group('root') do
|
|
# it { should exist }
|
|
# its('gid') { should eq 0 }
|
|
# end
|
|
#
|
|
# deprecated has matcher
|
|
# describe group('root') do
|
|
# it { should have_gid 0 }
|
|
# end
|
|
|
|
module Inspec::Resources
|
|
class Group < Inspec.resource(1)
|
|
name 'group'
|
|
desc 'Use the group InSpec audit resource to test groups on the system.'
|
|
example "
|
|
describe group('root') do
|
|
it { should exist }
|
|
its('gid') { should eq 0 }
|
|
end
|
|
"
|
|
|
|
def initialize(groupname, domain = nil)
|
|
@group = groupname.downcase
|
|
@domain = domain
|
|
@domain = @domain.downcase unless @domain.nil?
|
|
|
|
@cache = nil
|
|
|
|
# select group manager
|
|
@group_provider = nil
|
|
if inspec.os.unix?
|
|
@group_provider = UnixGroup.new(inspec)
|
|
elsif inspec.os.windows?
|
|
@group_provider = WindowsGroup.new(inspec)
|
|
else
|
|
return skip_resource 'The `group` resource is not supported on your OS yet.'
|
|
end
|
|
end
|
|
|
|
# verifies if a group exists
|
|
def exists?
|
|
# ensure that we found one group
|
|
!group_info.nil? && group_info.size > 0
|
|
end
|
|
|
|
def gid
|
|
return nil if group_info.nil? || group_info.size == 0
|
|
|
|
# the default case should be one group
|
|
return group_info[0][:gid] if group_info.size == 1
|
|
|
|
# return array if we got multiple gids
|
|
group_info.map { |grp| grp[:gid] }
|
|
end
|
|
|
|
# implements rspec has matcher, to be compatible with serverspec
|
|
def has_gid?(compare_gid)
|
|
gid == compare_gid
|
|
end
|
|
|
|
def local
|
|
return nil if group_info.nil? || group_info.size == 0
|
|
|
|
# the default case should be one group
|
|
return group_info[0][:local] if group_info.size == 1
|
|
|
|
# return array if we got multiple gids
|
|
group_info.map { |grp| grp[:local] }
|
|
end
|
|
|
|
def to_s
|
|
"Group #{@group}"
|
|
end
|
|
|
|
private
|
|
|
|
def group_info
|
|
return @cache if !@cache.nil?
|
|
@cache = @group_provider.group_info(@group, @domain) if !@group_provider.nil?
|
|
end
|
|
end
|
|
|
|
class GroupInfo
|
|
attr_reader :inspec
|
|
def initialize(inspec)
|
|
@inspec = inspec
|
|
end
|
|
end
|
|
|
|
# implements generic unix groups via /etc/group
|
|
class UnixGroup < GroupInfo
|
|
def group_info(group, _domain = nil)
|
|
inspec.etc_group.where(name: group).entries.map { |grp|
|
|
{
|
|
name: grp['name'],
|
|
gid: grp['gid'],
|
|
}
|
|
}
|
|
end
|
|
end
|
|
|
|
class WindowsGroup < GroupInfo
|
|
def group_info(compare_group, compare_domain = nil)
|
|
cmd = inspec.command('Get-WmiObject Win32_Group | Select-Object -Property Caption, Domain, Name, SID, LocalAccount | ConvertTo-Json')
|
|
|
|
# cannot rely on exit code for now, successful command returns exit code 1
|
|
# return nil if cmd.exit_status != 0, try to parse json
|
|
begin
|
|
groups = JSON.parse(cmd.stdout)
|
|
rescue JSON::ParserError => _e
|
|
return nil
|
|
end
|
|
|
|
# ensure we have an array of groups
|
|
groups = [groups] if !groups.is_a?(Array)
|
|
|
|
# reduce list
|
|
groups.each_with_object([]) do |grp, grp_collection|
|
|
# map object
|
|
grp_info = {
|
|
name: grp['Name'],
|
|
domain: grp['Domain'],
|
|
caption: grp['Caption'],
|
|
gid: nil,
|
|
sid: grp['SID'],
|
|
local: grp['LocalAccount'],
|
|
}
|
|
return grp_collection.push(grp_info) if grp_info[:name].casecmp(compare_group) == 0 && (compare_domain.nil? || grp_info[:domain].casecmp(compare_domain) == 0)
|
|
end
|
|
end
|
|
end
|
|
end
|