Class: Dradis::Plugins::CSV::Importer

Inherits:
Upload::Importer
  • Object
show all
Defined in:
lib/dradis/plugins/csv/importer.rb

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.templatesObject

Sources are dynamic (one per mapped CSV format), so report the currently known sources grouped by entity for the Mappings Manager.



5
6
7
8
9
10
11
12
# File 'lib/dradis/plugins/csv/importer.rb', line 5

def self.templates
  sources = Dradis::Plugins::CSV.mapping_sources.map(&:to_s)

  {
    evidence: sources.grep(/\Aevidence_/),
    issue: sources.grep(/\Aissue_/)
  }
end

Instance Method Details

#import(params = {}) ⇒ Object

Runs as part of the standard upload flow, before the user would reach the column mapper. If this project already has a saved mapping for the file's headers, import immediately using it, so a recognized format never needs re-mapping and gets the same treatment (Rules Engine included) as any other plugin's upload. Unrecognized formats no-op here; UploadController sends the user to the mapper instead.



20
21
22
23
24
25
26
27
28
29
30
31
# File 'lib/dradis/plugins/csv/importer.rb', line 20

def import(params = {})
  return false if mapping_service.destination.blank?

  headers = CSV.open(params[:file], &:readline)

  unless Dradis::Plugins::CSV.mapping_exists?(headers: headers, destination: mapping_service.destination)
    logger.info { 'No saved mapping found for this CSV format.' }
    return false
  end

  import_rows(file: params[:file], headers: headers)
end

#import_rows(file:, headers:, mappings: nil) ⇒ Object

Entry point for both the column mapper form submission (see MappingImportJob) and the auto-recognized import above. mappings is the raw form submission and is only consulted as a fallback, for whichever of identifier/node/entity fields has no saved Mapping to read from instead (e.g. no RTP is set, so MappingForm never persisted one).



38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
# File 'lib/dradis/plugins/csv/importer.rb', line 38

def import_rows(file:, headers:, mappings: nil)
  filename = File.basename(file)
  @issue_lookup = {}

  @issue_source, @issue_fields, id_index = mapped_fields(entity: :issue, headers: headers)
  @evidence_source, @evidence_fields, node_index = mapped_fields(entity: :evidence, headers: headers)

  mappings_groups = (mappings || {}).group_by { |index, mapping| mapping['type'] }
  id_index ||= Integer(mappings_groups['identifier']&.first&.first, exception: false)
  @node_index = node_index || Integer(mappings_groups['node']&.first&.first, exception: false)
  @evidence_mappings = mappings_groups['evidence'] || []
  @issue_mappings = mappings_groups['issue'] || []

  CSV.foreach(file, headers: true).with_index do |row, index|
    csv_id = row[id_index] || "#{filename}-#{index}"
    process_issue(csv_id: csv_id, row: row)
    process_node(csv_id: csv_id, row: row)
  end

  true
end