diff --git a/lib/openscap_parser/profile.rb b/lib/openscap_parser/profile.rb
index a448096..4e87f8f 100644
--- a/lib/openscap_parser/profile.rb
+++ b/lib/openscap_parser/profile.rb
@@ -1,3 +1,5 @@
+require 'openscap_parser/regex_handler'
+
module OpenscapParser
class Profile < XmlNode
def id
@@ -20,7 +22,27 @@ def description
end
def selected_rule_ids
- @selected_rule_ids ||= @parsed_xml.xpath("select[@selected='true']/@idref") &&
+ # Look for selected rule ids where the idref contains '_rule_' that is not preceded by 'group'
+ @selected_rule_ids ||= @parsed_xml.xpath("select[@selected='true']
+ [regex(@idref, '^((?!_group_).)*?(_rule_).*$')]
+ /@idref", RegexHandler) &&
+ @parsed_xml.xpath("select[@selected='true']
+ [regex(@idref, '^((?!_group_).)*?(_rule_).*$')]
+ /@idref", RegexHandler).map(&:text)
+ end
+
+ def selected_group_ids
+ # Look for selected group ids where the idref contains '_group_' that is not preceded by 'rule'
+ @selected_group_ids ||= @parsed_xml.xpath("select[@selected='true']
+ [regex(@idref, '^((?!_rule_).)*?(_group_).*$')]
+ /@idref", RegexHandler) &&
+ @parsed_xml.xpath("select[@selected='true']
+ [regex(@idref, '^((?!_rule_).)*?(_group_).*$')]
+ /@idref", RegexHandler).map(&:text)
+ end
+
+ def selected_entity_ids
+ @selected_entity_ids ||= @parsed_xml.xpath("select[@selected='true']/@idref") &&
@parsed_xml.xpath("select[@selected='true']/@idref").map(&:text)
end
diff --git a/lib/openscap_parser/regex_handler.rb b/lib/openscap_parser/regex_handler.rb
new file mode 100644
index 0000000..d694ada
--- /dev/null
+++ b/lib/openscap_parser/regex_handler.rb
@@ -0,0 +1,9 @@
+# frozen_string_literal: true
+
+module OpenscapParser
+ class RegexHandler < XmlNode
+ def self.regex node_set, regex
+ node_set.find_all { |node| node.to_s =~ /#{regex}/ }
+ end
+ end
+end
diff --git a/test/fixtures/files/xccdf_report_with_conflicts_and_requires.xml b/test/fixtures/files/xccdf_report_with_conflicts_and_requires.xml
index b44af0f..a6fed81 100644
--- a/test/fixtures/files/xccdf_report_with_conflicts_and_requires.xml
+++ b/test/fixtures/files/xccdf_report_with_conflicts_and_requires.xml
@@ -298,9 +298,13 @@ CIS' terms and conditions, specifically Restrictions(8), note
there is no representation or claim that the C2S profile will
ensure a system is in compliance or consistency with the CIS
baseline.
+
+
+
+
@@ -528,15 +532,20 @@ baseline.
-
+
-
+
+
+
+
+
+
-
+
@@ -643,10 +652,10 @@ baseline.
-
-
-
-
+
+
+
+
diff --git a/test/openscap_parser/test_result_file_test.rb b/test/openscap_parser/test_result_file_test.rb
index 8c86374..2d37e3c 100644
--- a/test/openscap_parser/test_result_file_test.rb
+++ b/test/openscap_parser/test_result_file_test.rb
@@ -29,6 +29,39 @@ def setup
end
context 'profiles' do
+ test 'profile_id' do
+ assert_match(/^xccdf_org.ssgproject.content_profile_C2S/,
+ @test_result_file2.benchmark.profiles.first.id)
+ end
+
+ test 'profile_selected_rule_ids' do
+ assert_equal(238, @test_result_file2.benchmark.profiles.first.selected_rule_ids.length)
+ refute_includes(@test_result_file2.benchmark.profiles.first.selected_rule_ids, "xccdf_org.ssgproject.rules_group_crypto")
+ refute_includes(@test_result_file2.benchmark.profiles.first.selected_rule_ids, "xccdf_org.ssgproject.content_group_rule_crypto")
+ refute_includes(@test_result_file2.benchmark.profiles.first.selected_rule_ids, "xccdf_org.ssgproject.contentrule_group_crypto")
+ refute_includes(@test_result_file2.benchmark.profiles.first.selected_rule_ids, "xccdf_org.ssgproject.content_group_rule_group_crypto")
+ end
+
+ test 'profile_selected_group_ids' do
+ assert_equal(["xccdf_org.ssgproject.rules_group_crypto",
+ "xccdf_org.ssgproject_rules.content_group_crypto",
+ "xccdf_org.ssgproject.contentrule_group_crypto",
+ "xccdf_org.ssgproject.content_group_rule_crypto",
+ "xccdf_org.ssgproject.content_group_rule_group_crypto",
+ "xccdf_org.ssgproject.content_group_endpoint_rule_security_software",
+ "xccdf_org.ssgproject.content_group_nfs_configuring_all_machines",
+ "xccdf_org.ssgproject.content_group_nfs_client_or_server_not_both",
+ "xccdf_org.ssgproject.content_group_nfs_configure_fixed_ports",
+ "xccdf_org.ssgproject.content_group_mounting_remote_filesystems"],
+ @test_result_file2.benchmark.profiles.first.selected_group_ids)
+ end
+
+ test 'profile_selected_entity_ids' do
+ all_selected_ids = @test_result_file2.benchmark.profiles.first.selected_rule_ids +
+ @test_result_file2.benchmark.profiles.first.selected_group_ids
+ assert_equal(248, @test_result_file2.benchmark.profiles.first.selected_entity_ids.length)
+ assert_equal(all_selected_ids.sort, @test_result_file2.benchmark.profiles.first.selected_entity_ids.sort)
+ end
end
context 'groups' do
@@ -36,36 +69,45 @@ def setup
assert_match(/^xccdf_org.ssgproject.content_group_system/,
@test_result_file2.benchmark.groups.first.id)
end
+
test 'group_no_conflicts' do
assert_equal([], @test_result_file2.benchmark.groups.first.conflicts)
end
+
test 'group_with_conflicts' do
assert_equal(["xccdf_org.ssgproject.content_rule_selinux_state",
"xccdf_org.ssgproject.content_group_mcafee_security_software"],
@test_result_file2.benchmark.groups[1].conflicts)
end
+
test 'group_no_requires' do
assert_equal([], @test_result_file2.benchmark.groups[1].requires)
end
+
test 'group_with_requires' do
assert_equal(['A', 'B', 'C'], @test_result_file2.benchmark.groups.first.requires)
end
+
test 'group_description' do
assert_match(/^Contains rules that check correct system settings./,
@test_result_file2.benchmark.groups.first.description)
end
+
test 'group_parent_id_benchmark' do
assert_match(/^xccdf_org.ssgproject.content_benchmark_RHEL-7/,
@test_result_file2.benchmark.groups.first.parent_id)
end
+
test 'group_parent_id_group' do
assert_match(/^xccdf_org.ssgproject.content_group_system/,
@test_result_file2.benchmark.groups[1].parent_id)
end
+
test 'group_parent_type_with_benchmark_parent' do
assert_match(/^Benchmark/,
@test_result_file2.benchmark.groups.first.parent_type)
end
+
test 'group_parent_type_with_group_parent' do
assert_match(/^Group/,
@test_result_file2.benchmark.groups[1].parent_type)