dradis-projects 4.7.0 → 4.8.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (26) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +4 -0
  3. data/app/controllers/dradis/plugins/projects/packages_controller.rb +6 -1
  4. data/app/controllers/dradis/plugins/projects/templates_controller.rb +6 -1
  5. data/app/views/dradis/plugins/projects/export/_index-content.html.erb +1 -1
  6. data/dradis-projects.gemspec +2 -2
  7. data/lib/dradis/plugins/projects/engine.rb +2 -2
  8. data/lib/dradis/plugins/projects/export/template.rb +1 -3
  9. data/lib/dradis/plugins/projects/export/v1/template.rb +8 -0
  10. data/lib/dradis/plugins/projects/export/v2/template.rb +8 -0
  11. data/lib/dradis/plugins/projects/export/v3/template.rb +8 -0
  12. data/lib/dradis/plugins/projects/export/v4/template.rb +207 -0
  13. data/lib/dradis/plugins/projects/gem_version.rb +1 -1
  14. data/lib/dradis/plugins/projects/upload/template.rb +2 -4
  15. data/lib/dradis/plugins/projects/upload/v1/template.rb +8 -0
  16. data/lib/dradis/plugins/projects/upload/v2/template.rb +8 -0
  17. data/lib/dradis/plugins/projects/upload/v3/template.rb +8 -0
  18. data/lib/dradis/plugins/projects/upload/v4/template.rb +651 -0
  19. data/spec/fixtures/files/with_invalid_states.xml +111 -0
  20. data/spec/fixtures/files/with_states.xml +111 -0
  21. data/spec/lib/dradis/plugins/projects/export/v2/template_spec.rb +9 -1
  22. data/spec/lib/dradis/plugins/projects/export/v4/template_spec.rb +84 -0
  23. data/spec/lib/dradis/plugins/projects/upload/v1/template_spec.rb +8 -0
  24. data/spec/lib/dradis/plugins/projects/upload/v2/template_spec.rb +9 -1
  25. data/spec/lib/dradis/plugins/projects/upload/v4/template_spec.rb +168 -0
  26. metadata +20 -10
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ca68fe402bada36bc748cbd49bca421e49f5c72202458d016c34fcb08f791f9f
4
- data.tar.gz: defaf20a5a62316adf0aecc2143048e48548976d3f43b2118a86ae361fd1ce47
3
+ metadata.gz: f2bcef2954732f6a107819be6462b9b375503a822559a231090edd01f514862c
4
+ data.tar.gz: 1e9018effd346297a8903ac29a4c0bd6ee4041075c32acc3e7f8757da0d2ad50
5
5
  SHA512:
6
- metadata.gz: b30158708343ae732533082d9060562857dab90fa804660941ea694696f91220fbfd444e6393f956071e67d2b19ef947407cf89040080fd422275d1abe5e31d4
7
- data.tar.gz: 46a7a2a618f294de4e5267a62c0f46172e2c34cb1c5548d1e7666f965829de94031d26d75b60365ffd32f0064f626160ed1129a64d89baafd7f5f14afcbce4b7
6
+ metadata.gz: 1066f56c7938bb4b8d3f8d4cb2c3f38118a579d7a33a5b4e0b012df413887058863190fd6e5e324567d463ce2a894ddb5a5a8cfb17de15f759b75116f83bf107
7
+ data.tar.gz: 061dd18d56a3e4a1b3c1d98d0a1df0d703afd974f95018e377b3c7c2d920f9791a5c51f7467bcb3c62051d3eb10c69146fdfd7c639a3e0c4191c20b61d4553b2
data/CHANGELOG.md CHANGED
@@ -1,3 +1,7 @@
1
+ v4.8.0 (April 2023)
2
+ - Add exporting and uploading states
3
+ - Update export button copy
4
+
1
5
  v4.7.0 (February 2023)
2
6
  - No changes
3
7
 
@@ -1,9 +1,14 @@
1
1
  module Dradis::Plugins::Projects
2
2
  class PackagesController < Dradis::Plugins::Export::BaseController
3
+ skip_before_action :validate_scope
4
+
3
5
  def show
4
6
  filename = Rails.root.join('tmp', 'dradis-export.zip')
5
7
 
6
- options = export_options.merge(plugin: Dradis::Plugins::Projects)
8
+ options = export_params.merge(
9
+ plugin: Dradis::Plugins::Projects,
10
+ scope: :all
11
+ )
7
12
  exporter = Dradis::Plugins::Projects::Export::Package.new(options)
8
13
  template = exporter.export(filename: filename)
9
14
 
@@ -1,10 +1,15 @@
1
1
  module Dradis::Plugins::Projects
2
2
  class TemplatesController < Dradis::Plugins::Export::BaseController
3
+ skip_before_action :validate_scope
4
+
3
5
  def show
4
6
  # this allows us to have different exporters in different editions
5
7
  exporter_class = Rails.application.config.dradis.projects.template_exporter
6
8
 
7
- options = export_options.merge(plugin: Dradis::Plugins::Projects)
9
+ options = export_params.merge(
10
+ plugin: Dradis::Plugins::Projects,
11
+ scope: :all
12
+ )
8
13
  exporter = exporter_class.new(options)
9
14
  template = exporter.export
10
15
 
@@ -14,6 +14,6 @@
14
14
  <label class="custom-control-label" for='route_template'>Template</label>
15
15
  </div>
16
16
 
17
- <button id="export-button" class="btn btn-lg btn-primary mt-4">Export</button>
17
+ <button id="export-button" class="btn btn-lg btn-primary mt-4">Export All Records</button>
18
18
  <% end %>
19
19
  <% end%>
@@ -22,9 +22,9 @@ Gem::Specification.new do |spec|
22
22
 
23
23
  spec.add_development_dependency 'bundler', '~> 2.2'
24
24
  spec.add_development_dependency 'combustion'
25
- spec.add_development_dependency 'rake', '~> 10.0'
25
+ spec.add_development_dependency 'rake', '>= 12.3.3'
26
26
  spec.add_development_dependency 'rspec'
27
27
 
28
- spec.add_dependency 'dradis-plugins', '~> 4.0'
28
+ spec.add_dependency 'dradis-plugins', '>= 4.8.0'
29
29
  spec.add_dependency 'rubyzip'
30
30
  end
@@ -18,8 +18,8 @@ module Dradis
18
18
 
19
19
  initializer "dradis-projects.set_configs" do |app|
20
20
  options = app.config.dradis.projects
21
- options.template_exporter ||= Dradis::Plugins::Projects::Export::V3::Template
22
- options.template_uploader ||= Dradis::Plugins::Projects::Upload::V3::Template::Importer
21
+ options.template_exporter ||= Dradis::Plugins::Projects::Export::V4::Template
22
+ options.template_uploader ||= Dradis::Plugins::Projects::Upload::V4::Template::Importer
23
23
  end
24
24
 
25
25
 
@@ -27,6 +27,4 @@ module Dradis::Plugins::Projects::Export
27
27
  end
28
28
  end
29
29
 
30
- require_relative 'v1/template'
31
- require_relative 'v2/template'
32
- require_relative 'v3/template'
30
+ require_relative 'v4/template'
@@ -1,3 +1,11 @@
1
+ # DEPRECATED - this class is v1 of the Template Exporter and shouldn't be updated.
2
+ # V4 released on Apr 2022
3
+ # V1 can be removed on Apr 2024
4
+ #
5
+ # We're duplicating this file for v4, and even though the code lives in two
6
+ # places now, this file isn't expected to evolve and is now frozen to V1
7
+ # behavior.
8
+
1
9
  module Dradis::Plugins::Projects::Export::V1
2
10
  class Template < Dradis::Plugins::Projects::Export::Template
3
11
  VERSION = 1
@@ -1,3 +1,11 @@
1
+ # DEPRECATED - this class is v2 of the Template Exporter and shouldn't be updated.
2
+ # V4 released on Apr 2022
3
+ # V2 can be removed on Apr 2024
4
+ #
5
+ # We're duplicating this file for v4, and even though the code lives in two
6
+ # places now, this file isn't expected to evolve and is now frozen to V2
7
+ # behavior.
8
+
1
9
  module Dradis::Plugins::Projects::Export::V2
2
10
  class Template < Dradis::Plugins::Projects::Export::V1::Template
3
11
  VERSION = 2
@@ -1,3 +1,11 @@
1
+ # DEPRECATED - this class is v3 of the Template Exporter and shouldn't be updated.
2
+ # V4 released on Apr 2022
3
+ # V3 can be removed on Apr 2024
4
+ #
5
+ # We're duplicating this file for v4, and even though the code lives in two
6
+ # places now, this file isn't expected to evolve and is now frozen to V3
7
+ # behavior.
8
+
1
9
  module Dradis::Plugins::Projects::Export::V3
2
10
  class Template < Dradis::Plugins::Projects::Export::V2::Template
3
11
  VERSION = 3
@@ -0,0 +1,207 @@
1
+ module Dradis::Plugins::Projects::Export::V4
2
+ class Template < Dradis::Plugins::Projects::Export::Template
3
+ VERSION = 4
4
+
5
+ protected
6
+
7
+ def build_activities_for(builder, trackable)
8
+ builder.activities do |activities_builder|
9
+ trackable.activities.each do |activity|
10
+ activities_builder.activity do |activity_builder|
11
+ activity_builder.action(activity.action)
12
+ activity_builder.user_email(user_email_for_activity(activity))
13
+ activity_builder.created_at(activity.created_at.to_i)
14
+ end
15
+ end
16
+ end
17
+ end
18
+
19
+ def build_categories(builder)
20
+ categories = []
21
+ categories << Category.issue if @issues.any?
22
+ categories += @nodes.map do |node|
23
+ node.notes.map { |note| note.category }.uniq
24
+ end.flatten.uniq
25
+
26
+ builder.categories do |categories_builder|
27
+ categories.each do |category|
28
+ categories_builder.category do |category_builder|
29
+ category_builder.id(category.id)
30
+ category_builder.name(category.name)
31
+ end
32
+ end
33
+ end
34
+ end
35
+
36
+ def build_evidence_for_node(builder, node)
37
+ builder.evidence do |evidences_builder|
38
+ node.evidence.each do |evidence|
39
+ evidences_builder.evidence do |evidence_builder|
40
+ evidence_builder.id(evidence.id)
41
+ evidence_builder.author(evidence.author)
42
+ evidence_builder.tag!('issue-id', evidence.issue_id)
43
+ evidence_builder.content do
44
+ evidence_builder.cdata!(evidence.content)
45
+ end
46
+ build_activities_for(evidence_builder, evidence)
47
+ build_comments_for(evidence_builder, evidence)
48
+ end
49
+ end
50
+ end
51
+ end
52
+
53
+ def build_issues(builder)
54
+ @issues = Issue.where(node_id: project.issue_library).includes(:activities)
55
+
56
+ builder.issues do |issues_builder|
57
+ @issues.each do |issue|
58
+ issues_builder.issue do |issue_builder|
59
+ issue_builder.id(issue.id)
60
+ issue_builder.author(issue.author)
61
+ issue_builder.state(issue.state)
62
+ issue_builder.text do
63
+ issue_builder.cdata!(issue.text)
64
+ end
65
+ build_activities_for(issue_builder, issue)
66
+ build_comments_for(issue_builder, issue)
67
+ end
68
+ end
69
+ end
70
+ end
71
+
72
+ def build_methodologies(builder)
73
+ methodologies = project.methodology_library.notes
74
+ builder.methodologies do |methodologies_builder|
75
+ methodologies.each do |methodology|
76
+ methodologies_builder.methodology(version: VERSION) do |methodology_builder|
77
+ methodology_builder.text do
78
+ methodology_builder.cdata!(methodology.text)
79
+ end
80
+ end
81
+ end
82
+ end
83
+ end
84
+
85
+ def build_nodes(builder)
86
+ @nodes = project.nodes.includes(:activities, :evidence, :notes, evidence: [:activities], notes: [:activities, :category]).all.reject do |node|
87
+ [Node::Types::METHODOLOGY,
88
+ Node::Types::ISSUELIB].include?(node.type_id)
89
+ end
90
+
91
+ builder.nodes do |nodes_builder|
92
+ @nodes.each do |node|
93
+ nodes_builder.node do |node_builder|
94
+ node_builder.id(node.id)
95
+ node_builder.label(node.label)
96
+ node_builder.tag!('parent-id', node.parent_id)
97
+ node_builder.position(node.position)
98
+ node_builder.properties do
99
+ node_builder.cdata!(node.raw_properties)
100
+ end
101
+ node_builder.tag!('type-id', node.type_id)
102
+ # Notes
103
+ build_notes_for_node(node_builder, node)
104
+ # Evidence
105
+ build_evidence_for_node(node_builder, node)
106
+ build_activities_for(node_builder, node)
107
+ end
108
+ end
109
+ end
110
+ end
111
+
112
+ def build_notes_for_node(builder, node)
113
+ builder.notes do |notes_builder|
114
+ node.notes.each do |note|
115
+ notes_builder.note do |note_builder|
116
+ note_builder.id(note.id)
117
+ note_builder.author(note.author)
118
+ note_builder.tag!('category-id', note.category_id)
119
+ note_builder.text do
120
+ note_builder.cdata!(note.text)
121
+ end
122
+ build_activities_for(note_builder, note)
123
+ build_comments_for(note_builder, note)
124
+ end
125
+ end
126
+ end
127
+ end
128
+
129
+ # No-op here, overwritten in PRO
130
+ def build_report_content(builder); end
131
+
132
+ def build_tags(builder)
133
+ tags = project.tags
134
+ builder.tags do |tags_builder|
135
+ tags.each do |tag|
136
+ tags_builder.tag do |tag_builder|
137
+ tag_builder.id(tag.id)
138
+ tag_builder.name(tag.name)
139
+ tag_builder.taggings do |taggings_builder|
140
+ tag.taggings.each do |tagging|
141
+ taggings_builder.tagging do |tagging_builder|
142
+ tagging_builder.tag!('taggable-id', tagging.taggable_id)
143
+ tagging_builder.tag!('taggable-type', tagging.taggable_type)
144
+ end
145
+ end
146
+ end
147
+ end
148
+ end
149
+ end
150
+ end
151
+
152
+
153
+ # Cache user emails so we don't have to make an extra SQL request
154
+ # for every activity
155
+ def user_email_for_activity(activity)
156
+ return activity.user if activity.user.is_a?(String)
157
+
158
+ @user_emails ||= begin
159
+ User.select([:id, :email]).all.each_with_object({}) do |user, hash|
160
+ hash[user.id] = user.email
161
+ end
162
+ end
163
+ @user_emails[activity.user_id]
164
+ end
165
+
166
+ # Use the class VERSION constant, but allow for subclasses to overwrite it.
167
+ #
168
+ # See:
169
+ # http://stackoverflow.com/questions/3174563/how-to-use-an-overridden-constant-in-an-inheritanced-class
170
+ def version
171
+ self.class::VERSION
172
+ end
173
+
174
+
175
+ # Export::V2::Template
176
+ #
177
+ def build_comments_for(builder, commentable)
178
+ builder.comments do |comments_builder|
179
+ commentable.comments.each do |comment|
180
+ comments_builder.comment do |comment_builder|
181
+ comment_builder.content do
182
+ comment_builder.cdata!(comment.content)
183
+ end
184
+ comment_builder.author(comment.user&.email)
185
+ comment_builder.created_at(comment.created_at.to_i)
186
+ end
187
+ end
188
+ end
189
+ end
190
+
191
+ # Export::V3::Template
192
+ #
193
+ def build_methodologies(builder)
194
+ boards = content_service.all_boards
195
+
196
+ builder.methodologies do |methodologies_builder|
197
+
198
+ boards.each do |board|
199
+ node_id =
200
+ board.node == project.methodology_library ? nil : board.node_id
201
+
202
+ board.to_xml(methodologies_builder, includes: [:activities, :assignees, :comments], version: VERSION)
203
+ end
204
+ end
205
+ end
206
+ end
207
+ end
@@ -8,7 +8,7 @@ module Dradis
8
8
 
9
9
  module VERSION
10
10
  MAJOR = 4
11
- MINOR = 7
11
+ MINOR = 8
12
12
  TINY = 0
13
13
  PRE = nil
14
14
 
@@ -33,7 +33,6 @@ module Dradis::Plugins::Projects::Upload
33
33
  # table to re-associate the attachments in the project archive with the new
34
34
  # node IDs in the current project.
35
35
  def import(params={})
36
-
37
36
  # load the template
38
37
  logger.info { "Loading template file from: #{params[:file]}" }
39
38
  template = Nokogiri::XML(File.read(params[:file]))
@@ -44,6 +43,7 @@ module Dradis::Plugins::Projects::Upload
44
43
  return false
45
44
  end
46
45
 
46
+
47
47
  if template.xpath('/dradis-template').empty?
48
48
  error = "The uploaded file doesn't look like a Dradis project template (/dradis-template)."
49
49
  logger.fatal{ error }
@@ -91,6 +91,4 @@ module Dradis::Plugins::Projects::Upload
91
91
  end
92
92
  end
93
93
 
94
- require_relative 'v1/template'
95
- require_relative 'v2/template'
96
- require_relative 'v3/template'
94
+ require_relative 'v4/template'
@@ -1,3 +1,11 @@
1
+ # DEPRECATED - this class is v1 of the Template Importer and shouldn't be updated.
2
+ # V4 released on Apr 2022
3
+ # V1 can be removed on Apr 2024
4
+ #
5
+ # We're duplicating this file for v4, and even though the code lives in two
6
+ # places now, this file isn't expected to evolve and is now frozen to V1
7
+ # behavior.
8
+
1
9
  module Dradis::Plugins::Projects::Upload::V1
2
10
  module Template
3
11
 
@@ -1,3 +1,11 @@
1
+ # DEPRECATED - this class is v2 of the Template Importer and shouldn't be updated.
2
+ # V4 released on Apr 2022
3
+ # V2 can be removed on Apr 2024
4
+ #
5
+ # We're duplicating this file for v4, and even though the code lives in two
6
+ # places now, this file isn't expected to evolve and is now frozen to V2
7
+ # behavior.
8
+
1
9
  module Dradis::Plugins::Projects::Upload::V2
2
10
  module Template
3
11
  class Importer < Dradis::Plugins::Projects::Upload::V1::Template::Importer
@@ -1,3 +1,11 @@
1
+ # DEPRECATED - this class is v3 of the Template Importer and shouldn't be updated.
2
+ # V4 released on Apr 2022
3
+ # V3 can be removed on Apr 2024
4
+ #
5
+ # We're duplicating this file for v4, and even though the code lives in two
6
+ # places now, this file isn't expected to evolve and is now frozen to V3
7
+ # behavior.
8
+
1
9
  module Dradis::Plugins::Projects::Upload::V3
2
10
  module Template
3
11
  class Importer < Dradis::Plugins::Projects::Upload::V2::Template::Importer