inspec_tools 2.0.3 → 2.1.0

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.
@@ -0,0 +1,35 @@
1
+ module InspecTools
2
+ class GenerateMap
3
+ attr_accessor :text
4
+
5
+ def initialize(text = nil)
6
+ @text = text.nil? ? default_text : text
7
+ end
8
+
9
+ def generate_example(file)
10
+ File.write(file, @text)
11
+ end
12
+
13
+ private
14
+
15
+ def default_text
16
+ <<~YML
17
+ # Setting csv_header to true will skip the csv file header
18
+ skip_csv_header: true
19
+ width : 80
20
+
21
+
22
+ control.id: 0
23
+ control.title: 15
24
+ control.desc: 16
25
+ control.tags:
26
+ severity: 1
27
+ rid: 8
28
+ stig_id: 3
29
+ cci: 2
30
+ check: 12
31
+ fix: 10
32
+ YML
33
+ end
34
+ end
35
+ end
@@ -9,17 +9,14 @@ require_relative '../happy_mapper_tools/stig_checklist'
9
9
  require_relative '../happy_mapper_tools/benchmark'
10
10
  require_relative '../utilities/inspec_util'
11
11
  require_relative 'csv'
12
-
13
- # rubocop:disable Metrics/ClassLength
14
- # rubocop:disable Metrics/AbcSize
15
- # rubocop:disable Metrics/BlockLength
16
- # rubocop:disable Style/GuardClause
12
+ require_relative '../utilities/xccdf/from_inspec'
13
+ require_relative '../utilities/xccdf/to_xccdf'
17
14
 
18
15
  module InspecTools
19
- class Inspec
20
- def initialize(inspec_json, metadata = '{}')
16
+ class Inspec # rubocop:disable Metrics/ClassLength
17
+ def initialize(inspec_json, metadata = {})
21
18
  @json = JSON.parse(inspec_json.gsub(/\\+u0000/, ''))
22
- @metadata = JSON.parse(metadata)
19
+ @metadata = metadata
23
20
  end
24
21
 
25
22
  def to_ckl(title = nil, date = nil, cklist = nil)
@@ -36,16 +33,15 @@ module InspecTools
36
33
  @checklist.to_xml.encode('UTF-8').gsub('<?xml version="1.0"?>', '<?xml version="1.0" encoding="UTF-8"?>').chomp
37
34
  end
38
35
 
36
+ # Convert Inspec result data to XCCDF
37
+ #
38
+ # @param attributes [Hash] Optional input attributes
39
+ # @return [String] XML formatted String
39
40
  def to_xccdf(attributes, verbose = false)
40
- @data = Utils::InspecUtil.parse_data_for_xccdf(@json)
41
- @attribute = attributes
42
- @attribute = {} if @attribute.eql? false
41
+ data = Utils::FromInspec.new.parse_data_for_xccdf(@json)
43
42
  @verbose = verbose
44
- @benchmark = HappyMapperTools::Benchmark::Benchmark.new
45
- populate_header
46
- # populate_profiles @todo populate profiles; not implemented now because its use is deprecated
47
- populate_groups
48
- @benchmark.to_xml
43
+
44
+ Utils::ToXCCDF.new(attributes || {}, data).to_xml(@metadata)
49
45
  end
50
46
 
51
47
  ####
@@ -70,7 +66,7 @@ module InspecTools
70
66
  #
71
67
  # @param inspec_json : an inspec profile formatted as a json object
72
68
  ###
73
- def inspec_json_to_array(inspec_json)
69
+ def inspec_json_to_array(inspec_json) # rubocop:disable Metrics/CyclomaticComplexity
74
70
  data = []
75
71
  headers = {}
76
72
  inspec_json['controls'].each do |control|
@@ -97,10 +93,11 @@ module InspecTools
97
93
  @data['controls'] << control
98
94
  end
99
95
  end
100
- if json['profiles'].nil?
101
- json['controls'].each do |control|
102
- @data['controls'] << control
103
- end
96
+
97
+ return unless json['profiles'].nil?
98
+
99
+ json['controls'].each do |control|
100
+ @data['controls'] << control
104
101
  end
105
102
  end
106
103
 
@@ -161,7 +158,7 @@ module InspecTools
161
158
  vuln
162
159
  end
163
160
 
164
- def generate_asset
161
+ def generate_asset # rubocop:disable Metrics/AbcSize
165
162
  asset = HappyMapperTools::StigChecklist::Asset.new
166
163
  asset.role = !@metadata['role'].nil? ? @metadata['role'] : 'Workstation'
167
164
  asset.type = !@metadata['type'].nil? ? @metadata['type'] : 'Computing'
@@ -223,75 +220,6 @@ module InspecTools
223
220
  ip
224
221
  end
225
222
 
226
- def populate_header
227
- @benchmark.title = @attribute['benchmark.title']
228
- @benchmark.id = @attribute['benchmark.id']
229
- @benchmark.description = @attribute['benchmark.description']
230
- @benchmark.version = @attribute['benchmark.version']
231
-
232
- @benchmark.status = HappyMapperTools::Benchmark::Status.new
233
- @benchmark.status.status = @attribute['benchmark.status']
234
- @benchmark.status.date = @attribute['benchmark.status.date']
235
-
236
- @benchmark.notice = HappyMapperTools::Benchmark::Notice.new
237
- @benchmark.notice.id = @attribute['benchmark.notice.id']
238
-
239
- @benchmark.plaintext = HappyMapperTools::Benchmark::Plaintext.new
240
- @benchmark.plaintext.plaintext = @attribute['benchmark.plaintext']
241
- @benchmark.plaintext.id = @attribute['benchmark.plaintext.id']
242
-
243
- @benchmark.reference = HappyMapperTools::Benchmark::ReferenceBenchmark.new
244
- @benchmark.reference.href = @attribute['reference.href']
245
- @benchmark.reference.dc_publisher = @attribute['reference.dc.publisher']
246
- @benchmark.reference.dc_source = @attribute['reference.dc.source']
247
- end
248
-
249
- def populate_groups
250
- group_array = []
251
- @data['controls'].each do |control|
252
- group = HappyMapperTools::Benchmark::Group.new
253
- group.id = control['id']
254
- group.title = control['gtitle']
255
- group.description = "<GroupDescription>#{control['gdescription']}</GroupDescription>"
256
-
257
- group.rule = HappyMapperTools::Benchmark::Rule.new
258
- group.rule.id = control['rid']
259
- group.rule.severity = control['severity']
260
- group.rule.weight = control['rweight']
261
- group.rule.version = control['rversion']
262
- group.rule.title = control['title'].tr("\n", ' ')
263
- group.rule.description = "<VulnDiscussion>#{control['desc'].tr("\n", ' ')}</VulnDiscussion><FalsePositives></FalsePositives><FalseNegatives></FalseNegatives><Documentable>false</Documentable><Mitigations></Mitigations><SeverityOverrideGuidance></SeverityOverrideGuidance><PotentialImpacts></PotentialImpacts><ThirdPartyTools></ThirdPartyTools><MitigationControl></MitigationControl><Responsibility></Responsibility><IAControls></IAControls>"
264
-
265
- group.rule.reference = HappyMapperTools::Benchmark::ReferenceGroup.new
266
- group.rule.reference.dc_publisher = @attribute['reference.dc.publisher']
267
- group.rule.reference.dc_title = @attribute['reference.dc.title']
268
- group.rule.reference.dc_subject = @attribute['reference.dc.subject']
269
- group.rule.reference.dc_type = @attribute['reference.dc.type']
270
- group.rule.reference.dc_identifier = @attribute['reference.dc.identifier']
271
-
272
- group.rule.ident = HappyMapperTools::Benchmark::Ident.new
273
- group.rule.ident.system = 'https://public.cyber.mil/stigs/cci/'
274
- group.rule.ident.ident = control['cci']
275
-
276
- group.rule.fixtext = HappyMapperTools::Benchmark::Fixtext.new
277
- group.rule.fixtext.fixref = control['fixref']
278
- group.rule.fixtext.fixtext = control['fix']
279
-
280
- group.rule.fix = HappyMapperTools::Benchmark::Fix.new
281
- group.rule.fix.id = control['fixref']
282
-
283
- group.rule.check = HappyMapperTools::Benchmark::Check.new
284
- group.rule.check.system = control['checkref']
285
- group.rule.check.content_ref = HappyMapperTools::Benchmark::ContentRef.new
286
- group.rule.check.content_ref.name = @attribute['content_ref.name']
287
- group.rule.check.content_ref.href = @attribute['content_ref.href']
288
- group.rule.check.content = control['check']
289
-
290
- group_array << group
291
- end
292
- @benchmark.group = group_array
293
- end
294
-
295
223
  def generate_title(title, json, date)
296
224
  title ||= "Untitled - Checklist Created from Automated InSpec Results JSON; Profiles: #{json['profiles'].map { |x| x['name'] }.join(' | ')}"
297
225
  title + " Checklist Date: #{date || Date.today.to_s}"
@@ -2,9 +2,9 @@ require 'digest'
2
2
 
3
3
  require_relative '../utilities/inspec_util'
4
4
  require_relative '../utilities/extract_pdf_text'
5
- require_relative '../utilities/extract_nist_cis_mapping'
6
5
  require_relative '../utilities/parser'
7
6
  require_relative '../utilities/text_cleaner'
7
+ require_relative '../utilities/cis_to_nist'
8
8
 
9
9
  # rubocop:disable Metrics/AbcSize
10
10
  # rubocop:disable Metrics/PerceivedComplexity
@@ -24,7 +24,7 @@ module InspecTools
24
24
  @controls = []
25
25
  @csv_handle = nil
26
26
  @cci_xml = nil
27
- @nist_mapping = nil
27
+ @nist_mapping = Utils::CisToNist.get_mapping('cis_to_nist_critical_controls')
28
28
  @pdf_text = ''
29
29
  @clean_text = ''
30
30
  @transformed_data = ''
@@ -33,7 +33,6 @@ module InspecTools
33
33
  @title ||= extract_title
34
34
  clean_pdf_text
35
35
  transform_data
36
- read_excl
37
36
  insert_json_metadata
38
37
  @profile['controls'] = parse_controls
39
38
  @profile['sha256'] = Digest::SHA256.hexdigest @profile.to_s
@@ -122,15 +121,5 @@ module InspecTools
122
121
  def write_clean_text
123
122
  File.write('debug_text', @clean_text)
124
123
  end
125
-
126
- def read_excl
127
- nist_map_path = File.join(File.dirname(__FILE__), '../data/NIST_Map_09212017B_CSC-CIS_Critical_Security_Controls_VER_6.1_Excel_9.1.2016.xlsx')
128
- excel = Util::ExtractNistMappings.new(nist_map_path)
129
- @nist_mapping = excel.full_excl
130
- rescue StandardError => e
131
- puts "Exception: #{e.message}"
132
- puts 'Existing...'
133
- exit
134
- end
135
124
  end
136
125
  end
@@ -15,6 +15,7 @@ module InspecTools
15
15
  autoload :Summary, 'inspec_tools/summary'
16
16
  autoload :Threshold, 'inspec_tools/threshold'
17
17
  autoload :XLSXTool, 'inspec_tools/xlsx_tool'
18
+ autoload :GenerateMap, 'inspec_tools/generate_map'
18
19
  end
19
20
 
20
21
  # rubocop:disable Style/GuardClause
@@ -23,7 +24,7 @@ module InspecPlugins
23
24
  class CliCommand < Inspec.plugin(2, :cli_command) # rubocop:disable Metrics/ClassLength
24
25
  POSSIBLE_LOG_LEVELS = %w{debug info warn error fatal}.freeze
25
26
 
26
- class_option :log_directory, type: :string, aliases: :l, desc: 'Provie log location'
27
+ class_option :log_directory, type: :string, aliases: :l, desc: 'Provide log location'
27
28
  class_option :log_level, type: :string, desc: "Set the logging level: #{POSSIBLE_LOG_LEVELS}"
28
29
 
29
30
  subcommand_desc 'tools [COMMAND]', 'Runs inspec_tools commands through Inspec'
@@ -54,12 +55,18 @@ module InspecPlugins
54
55
 
55
56
  desc 'inspec2xccdf', 'inspec2xccdf translates an inspec profile and attributes files to an xccdf file'
56
57
  long_desc InspecTools::Help.text(:inspec2xccdf)
57
- option :inspec_json, required: true, aliases: '-j'
58
- option :attributes, required: true, aliases: '-a'
59
- option :output, required: true, aliases: '-o'
58
+ option :inspec_json, required: true, aliases: '-j',
59
+ desc: 'path to InSpec JSON file created'
60
+ option :attributes, required: true, aliases: '-a',
61
+ desc: 'path to yml file that provides the required attributes for the XCCDF document. These attributes are parts of XCCDF document which do not fit into the InSpec schema.'
62
+ option :output, required: true, aliases: '-o',
63
+ desc: 'name or path to create the XCCDF and title to give the XCCDF'
64
+ option :metadata, required: false, type: :string, aliases: '-m',
65
+ desc: 'path to JSON file with additional host metadata for the XCCDF file'
60
66
  def inspec2xccdf
61
67
  json = File.read(options[:inspec_json])
62
- inspec_tool = InspecTools::Inspec.new(json)
68
+ metadata = options[:metadata] ? JSON.parse(File.read(options[:metadata])) : {}
69
+ inspec_tool = InspecTools::Inspec.new(json, metadata)
63
70
  attr_hsh = YAML.load_file(options[:attributes])
64
71
  xccdf = inspec_tool.to_xccdf(attr_hsh)
65
72
  File.write(options[:output], xccdf)
@@ -136,26 +143,8 @@ module InspecPlugins
136
143
 
137
144
  desc 'generate_map', 'Generates mapping template from CSV to Inspec Controls'
138
145
  def generate_map
139
- template = '
140
- # Setting csv_header to true will skip the csv file header
141
- skip_csv_header: true
142
- width : 80
143
-
144
-
145
- control.id: 0
146
- control.title: 15
147
- control.desc: 16
148
- control.tags:
149
- severity: 1
150
- rid: 8
151
- stig_id: 3
152
- cci: 2
153
- check: 12
154
- fix: 10
155
- '
156
- myfile = File.new('mapping.yml', 'w')
157
- myfile.puts template
158
- myfile.close
146
+ generator = InspecTools::GenerateMap.new
147
+ generator.generate_example('mapping.yml')
159
148
  end
160
149
 
161
150
  desc 'generate_ckl_metadata', 'Generate metadata file that can be passed to inspec2ckl'
@@ -140,6 +140,7 @@ module InspecTools
140
140
  control['tags']['documentable'] = group.rule.description.documentable if group.rule.description.documentable != ''
141
141
  control['tags']['mitigations'] = group.rule.description.false_negatives if group.rule.description.mitigations != ''
142
142
  control['tags']['severity_override_guidance'] = group.rule.description.severity_override_guidance if group.rule.description.severity_override_guidance != ''
143
+ control['tags']['security_override_guidance'] = group.rule.description.security_override_guidance if group.rule.description.security_override_guidance != ''
143
144
  control['tags']['potential_impacts'] = group.rule.description.potential_impacts if group.rule.description.potential_impacts != ''
144
145
  control['tags']['third_party_tools'] = group.rule.description.third_party_tools if group.rule.description.third_party_tools != ''
145
146
  control['tags']['mitigation_controls'] = group.rule.description.mitigation_controls if group.rule.description.mitigation_controls != ''
@@ -3,9 +3,10 @@ require 'inspec-objects'
3
3
  require 'word_wrap'
4
4
  require 'yaml'
5
5
  require 'digest'
6
- require 'roo'
7
6
 
8
7
  require_relative '../utilities/inspec_util'
8
+ require_relative '../utilities/cis_to_nist'
9
+ require_relative '../utilities/mapping_validator'
9
10
 
10
11
  # rubocop:disable Metrics/AbcSize
11
12
  # rubocop:disable Metrics/PerceivedComplexity
@@ -14,15 +15,14 @@ require_relative '../utilities/inspec_util'
14
15
  module InspecTools
15
16
  # Methods for converting from XLS to various formats
16
17
  class XLSXTool
17
- CIS_2_NIST_XLSX = Roo::Spreadsheet.open(File.join(File.dirname(__FILE__), '../data/NIST_Map_02052020_CIS_Controls_Version_7.1_Implementation_Groups_1.2.xlsx'))
18
18
  LATEST_NIST_REV = 'Rev_4'.freeze
19
19
 
20
20
  def initialize(xlsx, mapping, name, verbose = false)
21
21
  @name = name
22
22
  @xlsx = xlsx
23
- @mapping = mapping
23
+ @mapping = Utils::MappingValidator.validate(mapping)
24
24
  @verbose = verbose
25
- @cis_to_nist = get_cis_to_nist_control_mapping(CIS_2_NIST_XLSX)
25
+ @cis_to_nist = Utils::CisToNist.get_mapping('cis_to_nist_mapping')
26
26
  end
27
27
 
28
28
  def to_ckl
@@ -46,18 +46,6 @@ module InspecTools
46
46
 
47
47
  private
48
48
 
49
- def get_cis_to_nist_control_mapping(spreadsheet)
50
- cis_to_nist = {}
51
- spreadsheet.sheet(3).each do |row|
52
- if row[3].is_a? Numeric
53
- cis_to_nist[row[3].to_s] = row[0]
54
- else
55
- cis_to_nist[row[2].to_s] = row[0] unless (row[2] == '') || row[2].to_i.nil?
56
- end
57
- end
58
- cis_to_nist
59
- end
60
-
61
49
  def insert_json_metadata
62
50
  @profile['name'] = @name
63
51
  @profile['title'] = 'InSpec Profile'
@@ -0,0 +1,13 @@
1
+ require 'nokogiri'
2
+
3
+ module Utils
4
+ class CciXml
5
+ def self.get_cci_list(cci_list_file)
6
+ path = File.expand_path(File.join(File.expand_path(__dir__), '..', 'data', cci_list_file))
7
+ raise "CCI list does not exist at #{path}" unless File.exist?(path)
8
+
9
+ cci_list = Nokogiri::XML(File.open(path))
10
+ cci_list.remove_namespaces!
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,11 @@
1
+ module Utils
2
+ class CisToNist
3
+ def self.get_mapping(mapping_file)
4
+ path = File.expand_path(File.join(File.expand_path(__dir__), '..', 'data', mapping_file))
5
+ raise "CIS to NIST control mapping does not exist at #{path}. Has it been generated?" unless File.exist?(path)
6
+
7
+ mapping = File.open(path)
8
+ Marshal.load(mapping)
9
+ end
10
+ end
11
+ end
@@ -11,16 +11,10 @@ require 'overrides/true_class'
11
11
  require 'overrides/nil_class'
12
12
  require 'overrides/object'
13
13
  require 'overrides/string'
14
-
15
- # rubocop:disable Metrics/ClassLength
16
- # rubocop:disable Metrics/AbcSize
17
- # rubocop:disable Metrics/PerceivedComplexity
18
- # rubocop:disable Metrics/CyclomaticComplexity
19
- # rubocop:disable Metrics/MethodLength
14
+ require 'rubocop'
20
15
 
21
16
  module Utils
22
- class InspecUtil
23
- DATA_NOT_FOUND_MESSAGE = 'N/A'.freeze
17
+ class InspecUtil # rubocop:disable Metrics/ClassLength
24
18
  WIDTH = 80
25
19
  IMPACT_SCORES = {
26
20
  'none' => 0.0,
@@ -30,56 +24,7 @@ module Utils
30
24
  'critical' => 0.9
31
25
  }.freeze
32
26
 
33
- def self.parse_data_for_xccdf(json)
34
- data = {}
35
-
36
- controls = []
37
- if json['profiles'].nil?
38
- controls = json['controls']
39
- elsif json['profiles'].length == 1
40
- controls = json['profiles'].last['controls']
41
- else
42
- json['profiles'].each do |profile|
43
- controls.concat(profile['controls'])
44
- end
45
- end
46
- c_data = {}
47
-
48
- controls.each do |control|
49
- c_id = control['id'].to_sym
50
- c_data[c_id] = {}
51
- c_data[c_id]['id'] = control['id'] || DATA_NOT_FOUND_MESSAGE
52
- c_data[c_id]['title'] = control['title'] || DATA_NOT_FOUND_MESSAGE
53
- c_data[c_id]['desc'] = control['desc'] || DATA_NOT_FOUND_MESSAGE
54
- c_data[c_id]['severity'] = control['tags']['severity'] || DATA_NOT_FOUND_MESSAGE
55
- c_data[c_id]['gid'] = control['tags']['gid'] || DATA_NOT_FOUND_MESSAGE
56
- c_data[c_id]['gtitle'] = control['tags']['gtitle'] || DATA_NOT_FOUND_MESSAGE
57
- c_data[c_id]['gdescription'] = control['tags']['gdescription'] || DATA_NOT_FOUND_MESSAGE
58
- c_data[c_id]['rid'] = control['tags']['rid'] || DATA_NOT_FOUND_MESSAGE
59
- c_data[c_id]['rversion'] = control['tags']['rversion'] || DATA_NOT_FOUND_MESSAGE
60
- c_data[c_id]['rweight'] = control['tags']['rweight'] || DATA_NOT_FOUND_MESSAGE
61
- c_data[c_id]['stig_id'] = control['tags']['stig_id'] || DATA_NOT_FOUND_MESSAGE
62
- c_data[c_id]['cci'] = control['tags']['cci'] || DATA_NOT_FOUND_MESSAGE
63
- c_data[c_id]['nist'] = control['tags']['nist'] || ['unmapped']
64
- c_data[c_id]['check'] = control['tags']['check'] || DATA_NOT_FOUND_MESSAGE
65
- c_data[c_id]['checkref'] = control['tags']['checkref'] || DATA_NOT_FOUND_MESSAGE
66
- c_data[c_id]['fix'] = control['tags']['fix'] || DATA_NOT_FOUND_MESSAGE
67
- c_data[c_id]['fixref'] = control['tags']['fixref'] || DATA_NOT_FOUND_MESSAGE
68
- c_data[c_id]['fix_id'] = control['tags']['fix_id'] || DATA_NOT_FOUND_MESSAGE
69
- c_data[c_id]['rationale'] = control['tags']['rationale'] || DATA_NOT_FOUND_MESSAGE
70
- c_data[c_id]['cis_family'] = control['tags']['cis_family'] || DATA_NOT_FOUND_MESSAGE
71
- c_data[c_id]['cis_rid'] = control['tags']['cis_rid'] || DATA_NOT_FOUND_MESSAGE
72
- c_data[c_id]['cis_level'] = control['tags']['cis_level'] || DATA_NOT_FOUND_MESSAGE
73
- c_data[c_id]['impact'] = control['impact'].to_s || DATA_NOT_FOUND_MESSAGE
74
- c_data[c_id]['code'] = control['code'].to_s || DATA_NOT_FOUND_MESSAGE
75
- end
76
-
77
- data['controls'] = c_data.values
78
- data['status'] = 'success'
79
- data
80
- end
81
-
82
- def self.parse_data_for_ckl(json)
27
+ def self.parse_data_for_ckl(json) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
83
28
  data = {}
84
29
 
85
30
  # Parse for inspec profile results json
@@ -220,7 +165,7 @@ module Utils
220
165
  end
221
166
 
222
167
  private_class_method def self.string_to_impact(severity, use_cvss_terms)
223
- if /none|na|n\/a|not[_|(\s*)]?applicable/i.match?(severity)
168
+ if %r{none|na|n/a|not[_|(\s*)]?applicable}i.match?(severity)
224
169
  impact = 0.0 # Informative
225
170
  elsif /low|cat(egory)?\s*(iii|3)/i.match?(severity)
226
171
  impact = 0.3 # Low Impact
@@ -247,13 +192,10 @@ module Utils
247
192
  end
248
193
 
249
194
  IMPACT_SCORES.reverse_each do |name, impact_score|
250
- if name == 'critical' && value >= impact_score && use_cvss_terms
251
- return 'high'
252
- elsif value >= impact_score
253
- return name
254
- else
255
- next
256
- end
195
+ return 'high' if name == 'critical' && value >= impact_score && use_cvss_terms
196
+ return name if value >= impact_score
197
+
198
+ next
257
199
  end
258
200
  end
259
201
 
@@ -276,7 +218,7 @@ module Utils
276
218
  WordWrap.ww(str.to_s, width)
277
219
  end
278
220
 
279
- private_class_method def self.generate_controls(inspec_json)
221
+ private_class_method def self.generate_controls(inspec_json) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
280
222
  controls = []
281
223
  inspec_json['controls'].each do |json_control|
282
224
  control = ::Inspec::Object::Control.new
@@ -314,6 +256,7 @@ module Utils
314
256
  control.add_tag(::Inspec::Object::Tag.new('documentable', json_control['tags']['documentable'])) unless json_control['tags']['documentable'].blank?
315
257
  control.add_tag(::Inspec::Object::Tag.new('mitigations', json_control['tags']['mitigations'])) unless json_control['tags']['mitigations'].blank?
316
258
  control.add_tag(::Inspec::Object::Tag.new('severity_override_guidance', json_control['tags']['severity_override_guidance'])) unless json_control['tags']['severity_override_guidance'].blank?
259
+ control.add_tag(::Inspec::Object::Tag.new('security_override_guidance', json_control['tags']['security_override_guidance'])) unless json_control['tags']['security_override_guidance'].blank?
317
260
  control.add_tag(::Inspec::Object::Tag.new('potential_impacts', json_control['tags']['potential_impacts'])) unless json_control['tags']['potential_impacts'].blank?
318
261
  control.add_tag(::Inspec::Object::Tag.new('third_party_tools', json_control['tags']['third_party_tools'])) unless json_control['tags']['third_party_tools'].blank?
319
262
  control.add_tag(::Inspec::Object::Tag.new('mitigation_controls', json_control['tags']['mitigation_controls'])) unless json_control['tags']['mitigation_controls'].blank?
@@ -382,7 +325,7 @@ module Utils
382
325
  myfile.puts readme_contents
383
326
  end
384
327
 
385
- private_class_method def self.unpack_profile(directory, controls, separated, output_format)
328
+ private_class_method def self.unpack_profile(directory, controls, separated, output_format) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
386
329
  FileUtils.rm_rf(directory) if Dir.exist?(directory)
387
330
  Dir.mkdir directory unless Dir.exist?(directory)
388
331
  Dir.mkdir "#{directory}/controls" unless Dir.exist?("#{directory}/controls")
@@ -393,7 +336,7 @@ module Utils
393
336
  file_name = control.id.to_s
394
337
  myfile = File.new("#{directory}/controls/#{file_name}.rb", 'w')
395
338
  myfile.puts "# encoding: UTF-8\n\n"
396
- myfile.puts wrap(control.to_ruby.gsub('"', "\'"), WIDTH) + "\n"
339
+ myfile.puts wrap(control.to_ruby, WIDTH) + "\n"
397
340
  myfile.close
398
341
  end
399
342
  else
@@ -424,12 +367,10 @@ module Utils
424
367
  end
425
368
  myfile.close
426
369
  end
370
+ config_store = ::RuboCop::ConfigStore.new
371
+ config_store.options_config = File.join(File.dirname(__FILE__), '../data/rubocop.yml')
372
+ rubocop = ::RuboCop::Runner.new({ auto_correct: true }, config_store)
373
+ rubocop.run([directory])
427
374
  end
428
375
  end
429
376
  end
430
-
431
- # rubocop:enable Metrics/ClassLength
432
- # rubocop:enable Metrics/AbcSize
433
- # rubocop:enable Metrics/PerceivedComplexity
434
- # rubocop:enable Metrics/CyclomaticComplexity
435
- # rubocop:enable Metrics/MethodLength