dradis-html_export 3.16.0 → 3.21.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8e2bed448d7dd1b3038207793b3c1b22163d93b8cb8caaacac94c3232ac4b11f
4
- data.tar.gz: f56b207d4739c5eacde0cfa506aef41e41942dc7145cb632737e7f6296c071ec
3
+ metadata.gz: f29710e9f73ca0b7af15e9fbe8c3bd980d549393993c9dc6a801930921d01ceb
4
+ data.tar.gz: 221eb9afccb68af19eedb080964f9e60dca1518f473beaeaee91b7680b92bc7d
5
5
  SHA512:
6
- metadata.gz: a055468ffac66d7a13bb0d52fd60b4430421d834bc866d70510a70d6e1619fce75b96201c4ca12fe2462eef831ba9f4f4e89a757942132d008565dffed84ca63
7
- data.tar.gz: '096bc01b204b281c1a43f502a5cd6d16d827c7388229acb90f496a7ee858c3d1cf6d70f477869568ee034d69559a7133e2b183e3165521d02c34253438a0f7ab'
6
+ metadata.gz: b7c8395019a1b5e1eec2ab049ab9c475d6ee57a9d30819cc4023d14dbc78428355e5045c924265e4e3edb25bf7ca2da48af09fcc90e6810f62f0162fd43e3e46
7
+ data.tar.gz: 3f2912502311e65530cca4d8641a3e7d24d921dff1baefd3af118a195aaa90f288974849286d8ea397c17d8f06f51fde2ade20e9ebab6c2fc15279e89898acea
data/CHANGELOG.md CHANGED
@@ -1,15 +1,34 @@
1
- ## Dradis Framework 3.16 (February, 2020) ##
1
+ ## Dradis Framework 3.21 (February, 2021) ##
2
+
3
+ * Add a fix for Rails 6 not allowing HTML rendering outside the view directory.
4
+
5
+ ## Dradis Framework 3.20 (December, 2020) ##
6
+
7
+ * Add an option in the exporter to pass a controller for rendering.
8
+ * Add views for the export view.
9
+ * Use NamingService to build export filename.
10
+
11
+ ## Dradis Framework 3.19 (September, 2020) ##
2
12
 
3
13
  * No changes.
4
14
 
5
- ## Dradis Framework 3.15 (November, 2019) ##
15
+ ## Dradis Framework 3.18 (July, 2020) ##
16
+
17
+ * No changes.
18
+
19
+ ## Dradis Framework 3.17 (May, 2020) ##
20
+
21
+ * Render report using main app's ApplicationController#render.
22
+
23
+ ## Dradis Framework 3.16 (February, 2020) ##
6
24
 
7
25
  * No changes.
8
26
 
9
- ## Dradis Framework 3.15 (August, 2019) ##
27
+ ## Dradis Framework 3.15 (November, 2019) ##
10
28
 
11
29
  * No changes.
12
30
 
31
+
13
32
  ## Dradis Framework 3.14 (August, 2019) ##
14
33
 
15
34
  * No changes.
@@ -0,0 +1,23 @@
1
+ <%
2
+ templates_dir = File.join(::Configuration::paths_templates_reports, 'html_export')
3
+ templates = Dir["%s/*" % templates_dir].map { |t| File.basename(t) }.sort
4
+ %>
5
+
6
+ <%= content_tag :div, id: 'plugin-html_export', class: 'tab-pane fade' do %>
7
+ <%= form_tag project_export_manager_path(current_project), target: '_blank' do %>
8
+ <%= hidden_field_tag :plugin, :html_export %>
9
+ <%= hidden_field_tag :route, :root %>
10
+
11
+ <h4 class="header-underline">Choose a template</h4>
12
+ <p>Please choose one of the templates available for this plugin (find them in <code>.<%= templates_dir[Rails.root.to_s.length..-1] %></code>)</p>
13
+
14
+ <% templates.each do |template| %>
15
+ <div class="custom-control custom-radio">
16
+ <%= radio_button_tag :template, template, template == templates.first, :class => 'custom-control-input' %>
17
+ <label class="custom-control-label" for="template_<%= template %>"><%= template %></label>
18
+ </div>
19
+ <% end %>
20
+
21
+ <button id="export-button" class="btn btn-lg btn-primary mt-4">Export</button>
22
+ <% end %>
23
+ <% end%>
@@ -0,0 +1,3 @@
1
+ <li class='nav-item'>
2
+ <a href='#html_export' class='nav-link' data-toggle='tab' data-target='#plugin-html_export'>Generate advanced HTML reports</a>
3
+ </li>
@@ -3,75 +3,110 @@ module Dradis
3
3
  module HtmlExport
4
4
 
5
5
  class Exporter < Dradis::Plugins::Export::Base
6
- # Add auto_link support to the ERB processor (see rails_autolink)
7
- include ::ActionView::Helpers::TextHelper
8
- # For auto_link feature (requires #mail_to)
9
- include ::ActionView::Helpers::UrlHelper
10
-
11
6
  def export(args = {})
12
- template_path = options.fetch(:template)
13
- template_properties = ::ReportTemplateProperties.find_by_template_file(File.basename(template_path)) rescue nil
14
-
15
- # Build title
16
- title = if Dradis.constants.include?(:Pro)
17
- "Dradis Professional Edition v#{Dradis::Pro.version}"
18
- else
19
- "Dradis Community Edition v#{Dradis::CE.version}"
20
- end
21
- logger.debug{ "Report title: #{title}"}
22
-
23
- # Prepare notes
24
- reporting_cat = content_service.report_category
25
- notes = content_service.all_notes
26
- logger.debug{ "Found #{notes.count} notes assigned to the reporting category."}
27
-
28
- # Prepare issues
29
- issues = content_service.all_issues
30
- if issues
31
- # Sort our issues based on the ReportTemplateProperties rules.
32
- if template_properties && template_properties.sort_field
33
- sort_by = template_properties.sort_field
34
-
35
- logger.debug{ "Template properties define a sort field: #{sort_by}. Sorting..." }
36
-
37
- # FIXME: Assume the Field :type is :number, so cast .to_f and sort
38
- issues.to_a.sort! do |a, b|
39
- b.fields.fetch(sort_by, '0').to_f <=> a.fields.fetch(sort_by, '0').to_f
40
- end
41
-
42
- logger.debug{ "Done." }
43
- end
7
+ log_report
8
+
9
+ controller = args[:controller] || ApplicationController
10
+
11
+ with_temporary_template(options[:template]) do |temporary_template|
12
+ # Render template
13
+ controller.render(
14
+ template: temporary_template,
15
+ layout: false,
16
+ locals: {
17
+ categorized_issues: categorized_issues,
18
+ content_service: content_service,
19
+ issues: issues,
20
+ nodes: nodes,
21
+ notes: notes,
22
+ project: project,
23
+ reporting_cat: content_service.report_category,
24
+ tags: tags,
25
+ title: title,
26
+ user: options[:user]
27
+ }
28
+ )
29
+ end
30
+ end
44
31
 
45
- # FIXME: This is an ugly piece of code and the list of nodes should
46
- # come from the ContentService.
47
- nodes = issues.map(&:evidence).flatten.map(&:node).uniq
32
+ private
33
+ def log_report
34
+ logger.debug { "Report title: #{title}" }
35
+ logger.debug { "Template properties define a sort field: #{sort_field}" }
48
36
 
49
- logger.debug{ "Found #{issues.count} issues affecting #{nodes.count} nodes" }
37
+ if issues&.any?
38
+ logger.debug { "Found #{issues.count} issues affecting #{nodes.count} nodes" }
50
39
  else
51
- logger.warning { "No issue library node found in this project" }
40
+ logger.warn { 'No issue library node found in this project' }
52
41
  end
53
42
 
54
- # Render template
55
- erb = ERB.new( File.read(template_path) )
56
- erb.result( binding )
43
+ logger.debug { "Found #{notes.count} notes assigned to the reporting category." }
57
44
  end
58
45
 
59
- private
46
+ def nodes
47
+ # FIXME: This is an ugly piece of code and the list of nodes should
48
+ # come from the ContentService.
49
+ @nodes ||= issues.map(&:evidence).flatten.map(&:node).uniq
50
+ end
51
+
52
+ def notes
53
+ @notes ||= content_service.all_notes
54
+ end
55
+
56
+ def issues
57
+ @issues ||= sort_issues content_service.all_issues.includes(:tags)
58
+ end
59
+
60
+ def categorized_issues
61
+ @categorized_issues ||= tags
62
+ .each_with_object({}) do |tag, hash|
63
+ hash[tag.id] = issues.select { |issue| issue.tags.include?(tag) }
64
+ end
65
+ .tap do |hash|
66
+ hash[:untagged] = issues.select { |issue| issue.tags.empty? }
67
+ end
68
+ end
60
69
 
61
- # FIXME This method is a behavioural duplicate of ApplicationHelper#markup
62
- # from the main app, it would be better to re-use that code.
63
- def markup(text)
64
- return unless text.present?
70
+ def sort_field
71
+ @sort_field ||= begin
72
+ template_path = options.fetch(:template)
73
+ properties = ::ReportTemplateProperties.find_by_template_file(File.basename(template_path)) rescue nil
74
+ properties&.sort_field
75
+ end
76
+ end
65
77
 
66
- # escape HTML 'manually' instead of using RedCloth's "filter_html"
67
- # for security reasons
68
- output = ERB::Util.html_escape(text.dup)
78
+ def sort_issues(unsorted_issues)
79
+ return unsorted_issues unless unsorted_issues.any? && sort_field
69
80
 
70
- Hash[ *text.scan(/#\[(.+?)\]#[\r|\n](.*?)(?=#\[|\z)/m).flatten.collect{ |str| str.strip } ].keys.each do |field|
71
- output.gsub!(/#\[#{Regexp.escape(field)}\]#[\r|\n]/, "h4. #{field}\n\n")
81
+ # FIXME: Assume the Field :type is :number, so cast .to_f and sort
82
+ unsorted_issues.sort do |a, b|
83
+ b.fields.fetch(sort_field, '0').to_f <=> a.fields.fetch(sort_field, '0').to_f
72
84
  end
85
+ end
86
+
87
+ def tags
88
+ @tags ||= project.tags
89
+ end
90
+
91
+ def title
92
+ @title ||= if Dradis.constants.include?(:Pro)
93
+ "Dradis Professional Edition v#{Dradis::Pro.version}"
94
+ else
95
+ "Dradis Community Edition v#{Dradis::CE.version}"
96
+ end
97
+ end
98
+
99
+ def with_temporary_template(original, &block)
100
+ filename = File.basename(Dir::Tmpname.create(['', '.html.erb']) {})
101
+ destination_path = Rails.root.join('app', 'views', 'tmp', filename)
102
+
103
+ FileUtils.mkdir_p(File.dirname(destination_path))
104
+ FileUtils.cp(original, destination_path)
73
105
 
74
- auto_link(RedCloth.new(output, [:no_span_caps]).to_html).html_safe
106
+ yield("tmp/#{filename}")
107
+ ensure
108
+ file_path = Rails.root.join("app/views/tmp/#{filename}")
109
+ File.delete(file_path) if File.exists?(file_path)
75
110
  end
76
111
  end
77
112
  end
@@ -8,7 +8,7 @@ module Dradis
8
8
 
9
9
  module VERSION
10
10
  MAJOR = 3
11
- MINOR = 16
11
+ MINOR = 21
12
12
  TINY = 0
13
13
  PRE = nil
14
14
 
@@ -15,9 +15,15 @@ class HtmlExportTasks < Thor
15
15
 
16
16
  report_path = options.output || Rails.root
17
17
  unless report_path.to_s =~ /\.html\z/
18
- date = DateTime.now.strftime("%Y-%m-%d")
19
- sequence = Dir.glob(File.join(report_path, "dradis-report_#{date}_*.html")).collect { |a| a.match(/_([0-9]+)\.html\z/)[1].to_i }.max || 0
20
- report_path = File.join(report_path, "dradis-report_#{date}_#{sequence + 1}.html")
18
+ date = DateTime.now.strftime("%Y-%m-%d")
19
+ base_filename = "dradis-report_#{date}.html"
20
+
21
+ report_filename = NamingService.name_file(
22
+ original_filename: base_filename,
23
+ pathname: Pathname.new(report_path)
24
+ )
25
+
26
+ report_path = File.join(report_path, report_filename)
21
27
  end
22
28
 
23
29
  if template = options.template
@@ -0,0 +1,12 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>My Title</title>
5
+ </head>
6
+ <body>
7
+ <h2>Issues</h2>
8
+ <% issues.each do |issue| %>
9
+ <p><%= markup(issue.text) %></p>
10
+ <% end %>
11
+ </body>
12
+ </html>
@@ -0,0 +1,25 @@
1
+ require 'rails_helper'
2
+
3
+ describe Dradis::Plugins::HtmlExport::Exporter do
4
+ let!(:project) { create(:project) }
5
+ let!(:issues) { create_list(:issue, 3, node: project.issue_library) }
6
+
7
+ let(:export_options) do
8
+ {
9
+ project_id: project.id,
10
+ template: Dradis::Plugins::HtmlExport::Engine.root.join(
11
+ 'spec/fixtures/files/template.html.erb'
12
+ )
13
+ }
14
+ end
15
+
16
+ let(:exporter) { described_class.new(export_options) }
17
+
18
+ it 'exports html' do
19
+ html = exporter.export
20
+
21
+ issues.each do |issue|
22
+ expect(html.include?(issue.title))
23
+ end
24
+ end
25
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dradis-html_export
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.16.0
4
+ version: 3.21.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Daniel Martin
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-02-26 00:00:00.000000000 Z
11
+ date: 2021-02-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: dradis-plugins
@@ -70,6 +70,8 @@ files:
70
70
  - README.md
71
71
  - Rakefile
72
72
  - app/controllers/dradis/plugins/html_export/base_controller.rb
73
+ - app/views/dradis/plugins/html_export/export/_index-content.html.erb
74
+ - app/views/dradis/plugins/html_export/export/_index-tabs.html.erb
73
75
  - config/routes.rb
74
76
  - dradis-html_export.gemspec
75
77
  - lib/dradis-html_export.rb
@@ -79,6 +81,8 @@ files:
79
81
  - lib/dradis/plugins/html_export/gem_version.rb
80
82
  - lib/dradis/plugins/html_export/version.rb
81
83
  - lib/tasks/thorfile.rb
84
+ - spec/fixtures/files/template.html.erb
85
+ - spec/lib/dradis/plugins/html_export/exporter_spec.rb
82
86
  - spec/requests/html_export_spec.rb
83
87
  - spec/spec_helper.rb
84
88
  - templates/basic.html.erb
@@ -87,7 +91,7 @@ homepage: http://dradisframework.org
87
91
  licenses:
88
92
  - GPL-2
89
93
  metadata: {}
90
- post_install_message:
94
+ post_install_message:
91
95
  rdoc_options: []
92
96
  require_paths:
93
97
  - lib
@@ -102,10 +106,12 @@ required_rubygems_version: !ruby/object:Gem::Requirement
102
106
  - !ruby/object:Gem::Version
103
107
  version: '0'
104
108
  requirements: []
105
- rubygems_version: 3.0.1
106
- signing_key:
109
+ rubygems_version: 3.2.4
110
+ signing_key:
107
111
  specification_version: 4
108
112
  summary: Dradis HTML export plugin
109
113
  test_files:
114
+ - spec/fixtures/files/template.html.erb
115
+ - spec/lib/dradis/plugins/html_export/exporter_spec.rb
110
116
  - spec/requests/html_export_spec.rb
111
117
  - spec/spec_helper.rb