dradis-projects 4.6.0 → 4.8.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 +4 -4
- data/CHANGELOG.md +7 -0
- data/app/controllers/dradis/plugins/projects/packages_controller.rb +6 -1
- data/app/controllers/dradis/plugins/projects/templates_controller.rb +6 -1
- data/app/views/dradis/plugins/projects/export/_index-content.html.erb +1 -1
- data/dradis-projects.gemspec +2 -2
- data/lib/dradis/plugins/projects/engine.rb +2 -2
- data/lib/dradis/plugins/projects/export/template.rb +1 -3
- data/lib/dradis/plugins/projects/export/v1/template.rb +8 -0
- data/lib/dradis/plugins/projects/export/v2/template.rb +8 -0
- data/lib/dradis/plugins/projects/export/v3/template.rb +8 -0
- data/lib/dradis/plugins/projects/export/v4/template.rb +207 -0
- data/lib/dradis/plugins/projects/gem_version.rb +1 -1
- data/lib/dradis/plugins/projects/upload/template.rb +2 -4
- data/lib/dradis/plugins/projects/upload/v1/template.rb +8 -0
- data/lib/dradis/plugins/projects/upload/v2/template.rb +8 -0
- data/lib/dradis/plugins/projects/upload/v3/template.rb +8 -0
- data/lib/dradis/plugins/projects/upload/v4/template.rb +651 -0
- data/spec/fixtures/files/with_invalid_states.xml +111 -0
- data/spec/fixtures/files/with_states.xml +111 -0
- data/spec/lib/dradis/plugins/projects/export/v2/template_spec.rb +9 -1
- data/spec/lib/dradis/plugins/projects/export/v4/template_spec.rb +84 -0
- data/spec/lib/dradis/plugins/projects/upload/v1/template_spec.rb +8 -0
- data/spec/lib/dradis/plugins/projects/upload/v2/template_spec.rb +9 -1
- data/spec/lib/dradis/plugins/projects/upload/v4/template_spec.rb +168 -0
- metadata +20 -10
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f2bcef2954732f6a107819be6462b9b375503a822559a231090edd01f514862c
|
4
|
+
data.tar.gz: 1e9018effd346297a8903ac29a4c0bd6ee4041075c32acc3e7f8757da0d2ad50
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1066f56c7938bb4b8d3f8d4cb2c3f38118a579d7a33a5b4e0b012df413887058863190fd6e5e324567d463ce2a894ddb5a5a8cfb17de15f759b75116f83bf107
|
7
|
+
data.tar.gz: 061dd18d56a3e4a1b3c1d98d0a1df0d703afd974f95018e377b3c7c2d920f9791a5c51f7467bcb3c62051d3eb10c69146fdfd7c639a3e0c4191c20b61d4553b2
|
data/CHANGELOG.md
CHANGED
@@ -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 =
|
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 =
|
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%>
|
data/dradis-projects.gemspec
CHANGED
@@ -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', '
|
25
|
+
spec.add_development_dependency 'rake', '>= 12.3.3'
|
26
26
|
spec.add_development_dependency 'rspec'
|
27
27
|
|
28
|
-
spec.add_dependency 'dradis-plugins', '
|
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::
|
22
|
-
options.template_uploader ||= Dradis::Plugins::Projects::Upload::
|
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
|
|
@@ -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
|
@@ -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 '
|
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
|