dradis-projects 3.0.1 → 3.6.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
  SHA1:
3
- metadata.gz: 49c15588026961bde0a45b0134a90d201652140b
4
- data.tar.gz: 1f293e40090e59155f8d62a144c214674c592093
3
+ metadata.gz: 1cab66cd7298c8c99104ed76957913173bde0225
4
+ data.tar.gz: 7a230d20b6e4e54abba7962c2bee781d40753e91
5
5
  SHA512:
6
- metadata.gz: 4f1f43f87498ba38e625448bf03f16e2ad4d585efe41c168ee24a51b87ee36348499082bbeb300d7628ab94281295e97b63bb9ca02f28b13b9d5819416315588
7
- data.tar.gz: 80501324eb22fbda873638fc93790509c0c28f32369527dc79cbe7b3d90279ab72ea17b25f56b15c4afd62551a7b6ebac327fe8a3e43f00d6fa4383a39575b4c
6
+ metadata.gz: 5c13c91fc60a01f1309dfb0e8071589e3fc8cac377542697c52e38eccb99e3aa314e4e4ef72a8bc35a4e7376900fecacc50c2de6c3689a0974ecf08e9d9bea40
7
+ data.tar.gz: 5da07252c8179dbfc343bf7134afe927a01b8e095a14a8ef85fcad4551ccff7c7bc6301a0321a293155a5c05550ccf1cf0b601becd8bc3d7e7fe27958baf9a20
data/CHANGELOG.md ADDED
@@ -0,0 +1,10 @@
1
+ ## Dradis Framework 3.6 (March XX, 2017) ##
2
+
3
+ * Include file version in project template export.
4
+
5
+ * Stop using homegrown configuration and use `Rails.application.config`.
6
+
7
+ * Make the project template exporter / uploader configurable.
8
+
9
+ * Break down the #export and #parse methods into smaller tasks.
10
+
@@ -1,17 +1,13 @@
1
1
  module Dradis::Plugins::Projects
2
2
  class PackagesController < Dradis::Plugins::Export::BaseController
3
3
  def show
4
- # these come from Export#create
5
- export_manager_hash = session[:export_manager].with_indifferent_access
6
- content_service_class = export_manager_hash[:content_service].constantize
4
+ filename = Rails.root.join('tmp', 'dradis-export.zip')
7
5
 
8
- exporter = Dradis::Plugins::Projects::Export::Package.new(
9
- content_service: content_service_class.new(plugin: Dradis::Plugins::Projects)
10
- )
6
+ options = export_options.merge(plugin: Dradis::Plugins::Projects)
7
+ exporter = Dradis::Plugins::Projects::Export::Package.new(options)
8
+ template = exporter.export(filename: filename)
11
9
 
12
- package_file = Rails.root.join('tmp', 'dradis-export.zip')
13
- template = exporter.export(export_manager_hash.merge(filename: package_file))
14
- send_file(package_file)
10
+ send_file(filename)
15
11
  end
16
12
  end
17
13
  end
@@ -1,15 +1,13 @@
1
1
  module Dradis::Plugins::Projects
2
2
  class TemplatesController < Dradis::Plugins::Export::BaseController
3
3
  def show
4
- # these come from Export#create
5
- export_manager_hash = session[:export_manager].with_indifferent_access
6
- content_service_class = export_manager_hash[:content_service].constantize
4
+ # this allows us to have different exporters in different editions
5
+ exporter_class = Rails.application.config.dradis.projects.template_exporter
7
6
 
8
- exporter = Dradis::Plugins::Projects::Export::Template.new(
9
- content_service: content_service_class.new(plugin: Dradis::Plugins::Projects)
10
- )
7
+ options = export_options.merge(plugin: Dradis::Plugins::Projects)
8
+ exporter = exporter_class.new(options)
9
+ template = exporter.export
11
10
 
12
- template = exporter.export(export_manager_hash)
13
11
  send_data(template, filename: 'dradis-template.xml', type: :xml)
14
12
  end
15
13
  end
@@ -25,6 +25,6 @@ Gem::Specification.new do |spec|
25
25
  spec.add_development_dependency 'rake', '~> 10.0'
26
26
  spec.add_development_dependency 'rspec'
27
27
 
28
- spec.add_dependency 'dradis-plugins', '~> 3.5'
28
+ spec.add_dependency 'dradis-plugins', '~> 3.6'
29
29
  spec.add_dependency 'rubyzip', '~> 1.2.1'
30
30
  end
@@ -13,3 +13,7 @@ require 'dradis/plugins/projects/export/template'
13
13
  require 'dradis/plugins/projects/upload/package'
14
14
  require 'dradis/plugins/projects/upload/template'
15
15
  require 'dradis/plugins/projects/version'
16
+
17
+ module Dradis::Plugins::Projects
18
+ ActiveSupport.run_load_hooks(:dradis_projects, self)
19
+ end
@@ -4,6 +4,8 @@ module Dradis
4
4
  class Engine < ::Rails::Engine
5
5
  isolate_namespace Dradis::Plugins::Projects
6
6
 
7
+ config.dradis.projects = ActiveSupport::OrderedOptions.new
8
+
7
9
  include ::Dradis::Plugins::Base
8
10
  description 'Save and restore project information'
9
11
  provides :export, :upload
@@ -14,6 +16,13 @@ module Dradis
14
16
  end
15
17
  end
16
18
 
19
+ initializer "dradis-projects.set_configs" do |app|
20
+ options = app.config.dradis.projects
21
+ options.template_exporter ||= Dradis::Plugins::Projects::Export::V1::Template
22
+ options.template_uploader ||= Dradis::Plugins::Projects::Upload::V1::Template::Importer
23
+ end
24
+
25
+
17
26
  # Because this plugin provides two export modules, we have to overwrite
18
27
  # the default .uploaders() method.
19
28
  #
@@ -28,4 +37,4 @@ module Dradis
28
37
  end
29
38
  end
30
39
  end
31
- end
40
+ end
@@ -4,15 +4,16 @@ module Dradis::Plugins::Projects::Export
4
4
  # Create a new project export bundle. It will include an XML file with the
5
5
  # contents of the repository (see db_only) and all the attachments that
6
6
  # have been uploaded into the system.
7
- def export(params={})
8
- raise ":filename not provided" unless params.key?(:filename)
7
+ def export(args={})
8
+ raise ":filename not provided" unless args.key?(:filename)
9
9
 
10
- filename = params[:filename]
11
- logger = params.fetch(:logger, Rails.logger)
10
+ filename = args[:filename]
11
+ logger = options.fetch(:logger, Rails.logger)
12
12
 
13
13
  File.delete(filename) if File.exists?(filename)
14
14
 
15
15
  logger.debug{ "Creating a new Zip file in #{filename}..." }
16
+
16
17
  Zip::File.open(filename, Zip::File::CREATE) do |zipfile|
17
18
  Node.all.each do |node|
18
19
  node_path = Attachment.pwd.join(node.id.to_s)
@@ -24,12 +25,16 @@ module Dradis::Plugins::Projects::Export
24
25
  end
25
26
 
26
27
  logger.debug{ "\tAdding XML repository dump" }
27
- template_exporter = Template.new(content_service: content_service)
28
- template = template_exporter.export(params)
28
+
29
+ exporter_class = Rails.application.config.dradis.projects.template_exporter
30
+ template_exporter = exporter_class.new(options)
31
+ template = template_exporter.export
32
+
29
33
  zipfile.get_output_stream('dradis-repository.xml') { |out|
30
34
  out << template
31
35
  }
32
36
  end
37
+
33
38
  logger.debug{ 'Done.' }
34
39
  end
35
40
 
@@ -2,10 +2,10 @@ module Dradis::Plugins::Projects::Export
2
2
  class Template < Dradis::Plugins::Export::Base
3
3
  # This method returns an XML representation of current repository which
4
4
  # includes Categories, Nodes and Notes
5
- def export(params={})
5
+ def export(args={})
6
6
  builder = Builder::XmlMarkup.new
7
7
  builder.instruct!
8
- result = builder.tag!('dradis-template') do |template_builder|
8
+ result = builder.tag!('dradis-template', version: version) do |template_builder|
9
9
  build_nodes(template_builder)
10
10
  build_issues(template_builder)
11
11
  build_methodologies(template_builder)
@@ -16,158 +16,13 @@ module Dradis::Plugins::Projects::Export
16
16
  end
17
17
 
18
18
  private
19
-
20
- def build_activities_for(builder, trackable)
21
- builder.activities do |activities_builder|
22
- trackable.activities.each do |activity|
23
- activities_builder.activity do |activity_builder|
24
- activity_builder.action(activity.action)
25
- activity_builder.user_email(user_email_for_activity(activity))
26
- activity_builder.created_at(activity.created_at.to_i)
27
- end
28
- end
29
- end
30
- end
31
-
32
- def build_categories(builder)
33
- categories = []
34
- categories << Category.issue if @issues.any?
35
- categories += @nodes.map do |node|
36
- node.notes.map { |note| note.category }.uniq
37
- end.flatten.uniq
38
-
39
- builder.categories do |categories_builder|
40
- categories.each do |category|
41
- categories_builder.category do |category_builder|
42
- category_builder.id(category.id)
43
- category_builder.name(category.name)
44
- end
45
- end
46
- end
47
- end
48
-
49
- def build_evidence_for_node(builder, node)
50
- builder.evidence do |evidences_builder|
51
- node.evidence.each do |evidence|
52
- evidences_builder.evidence do |evidence_builder|
53
- evidence_builder.id(evidence.id)
54
- evidence_builder.author(evidence.author)
55
- evidence_builder.tag!('issue-id', evidence.issue_id)
56
- evidence_builder.content do
57
- evidence_builder.cdata!(evidence.content)
58
- end
59
- build_activities_for(evidence_builder, evidence)
60
- end
61
- end
62
- end
63
- end
64
-
65
- def build_issues(builder)
66
- @issues = Issue.where(node_id: Node.issue_library).includes(:activities)
67
-
68
- builder.issues do |issues_builder|
69
- @issues.each do |issue|
70
- issues_builder.issue do |issue_builder|
71
- issue_builder.id(issue.id)
72
- issue_builder.author(issue.author)
73
- issue_builder.text do
74
- issue_builder.cdata!(issue.text)
75
- end
76
- build_activities_for(issue_builder, issue)
77
- end
78
- end
79
- end
80
- end
81
-
82
- def build_methodologies(builder)
83
- methodologies = Node.methodology_library.notes
84
- builder.methodologies do |methodologies_builder|
85
- methodologies.each do |methodology|
86
- methodologies_builder.methodology do |methodology_builder|
87
- methodology_builder.text do
88
- methodology_builder.cdata!(methodology.text)
89
- end
90
- end
91
- end
92
- end
93
- end
94
-
95
- def build_nodes(builder)
96
- @nodes = Node.includes(:activities, :evidence, :notes, evidence: [:activities], notes: [:activities, :category]).all.reject do |node|
97
- [Node::Types::METHODOLOGY,
98
- Node::Types::ISSUELIB].include?(node.type_id)
99
- end
100
-
101
- builder.nodes do |nodes_builder|
102
- @nodes.each do |node|
103
- nodes_builder.node do |node_builder|
104
- node_builder.id(node.id)
105
- node_builder.label(node.label)
106
- node_builder.tag!('parent-id', node.parent_id)
107
- node_builder.position(node.position)
108
- node_builder.properties do
109
- node_builder.cdata!(node.raw_properties)
110
- end
111
- node_builder.tag!('type-id', node.type_id)
112
- # Notes
113
- build_notes_for_node(node_builder, node)
114
- # Evidence
115
- build_evidence_for_node(node_builder, node)
116
- build_activities_for(node_builder, node)
117
- end
118
- end
119
- end
120
- end
121
-
122
- def build_notes_for_node(builder, node)
123
- builder.notes do |notes_builder|
124
- node.notes.each do |note|
125
- notes_builder.note do |note_builder|
126
- note_builder.id(note.id)
127
- note_builder.author(note.author)
128
- note_builder.tag!('category-id', note.category_id)
129
- note_builder.text do
130
- note_builder.cdata!(note.text)
131
- end
132
- build_activities_for(note_builder, note)
133
- end
134
- end
135
- end
136
- end
137
-
138
- def build_tags(builder)
139
- tags = Tag.all
140
- builder.tags do |tags_builder|
141
- tags.each do |tag|
142
- tags_builder.tag do |tag_builder|
143
- tag_builder.id(tag.id)
144
- tag_builder.name(tag.name)
145
- tag_builder.taggings do |taggings_builder|
146
- tag.taggings.each do |tagging|
147
- taggings_builder.tagging do |tagging_builder|
148
- tagging_builder.tag!('taggable-id', tagging.taggable_id)
149
- tagging_builder.tag!('taggable-type', tagging.taggable_type)
150
- end
151
- end
152
- end
153
- end
154
- end
155
- end
156
- end
157
-
158
-
159
- # Cache user emails so we don't have to make an extra SQL request
160
- # for every activity
161
- def user_email_for_activity(activity)
162
- return activity.user if activity.user.is_a?(String)
163
-
164
- @user_emails ||= begin
165
- User.select([:id, :email]).all.each_with_object({}) do |user, hash|
166
- hash[user.id] = user.email
167
- end
168
- end
169
- @user_emails[activity.user_id]
170
- end
171
-
19
+ def build_categories(builder); raise NotImplementedError; end
20
+ def build_issues(builder); raise NotImplementedError; end
21
+ def build_methodologies(builder); raise NotImplementedError; end
22
+ def build_nodes(builder); raise NotImplementedError; end
23
+ def build_tags(builder); raise NotImplementedError; end
24
+ def version; raise NotImplementedError; end
172
25
  end
173
26
  end
27
+
28
+ require_relative 'v1/template'
@@ -0,0 +1,167 @@
1
+ module Dradis::Plugins::Projects::Export::V1
2
+ class Template < Dradis::Plugins::Projects::Export::Template
3
+ VERSION = 1
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
+ end
48
+ end
49
+ end
50
+ end
51
+
52
+ def build_issues(builder)
53
+ @issues = Issue.where(node_id: Node.issue_library).includes(:activities)
54
+
55
+ builder.issues do |issues_builder|
56
+ @issues.each do |issue|
57
+ issues_builder.issue do |issue_builder|
58
+ issue_builder.id(issue.id)
59
+ issue_builder.author(issue.author)
60
+ issue_builder.text do
61
+ issue_builder.cdata!(issue.text)
62
+ end
63
+ build_activities_for(issue_builder, issue)
64
+ end
65
+ end
66
+ end
67
+ end
68
+
69
+ def build_methodologies(builder)
70
+ methodologies = Node.methodology_library.notes
71
+ builder.methodologies do |methodologies_builder|
72
+ methodologies.each do |methodology|
73
+ methodologies_builder.methodology do |methodology_builder|
74
+ methodology_builder.text do
75
+ methodology_builder.cdata!(methodology.text)
76
+ end
77
+ end
78
+ end
79
+ end
80
+ end
81
+
82
+ def build_nodes(builder)
83
+ @nodes = Node.includes(:activities, :evidence, :notes, evidence: [:activities], notes: [:activities, :category]).all.reject do |node|
84
+ [Node::Types::METHODOLOGY,
85
+ Node::Types::ISSUELIB].include?(node.type_id)
86
+ end
87
+
88
+ builder.nodes do |nodes_builder|
89
+ @nodes.each do |node|
90
+ nodes_builder.node do |node_builder|
91
+ node_builder.id(node.id)
92
+ node_builder.label(node.label)
93
+ node_builder.tag!('parent-id', node.parent_id)
94
+ node_builder.position(node.position)
95
+ node_builder.properties do
96
+ node_builder.cdata!(node.raw_properties)
97
+ end
98
+ node_builder.tag!('type-id', node.type_id)
99
+ # Notes
100
+ build_notes_for_node(node_builder, node)
101
+ # Evidence
102
+ build_evidence_for_node(node_builder, node)
103
+ build_activities_for(node_builder, node)
104
+ end
105
+ end
106
+ end
107
+ end
108
+
109
+ def build_notes_for_node(builder, node)
110
+ builder.notes do |notes_builder|
111
+ node.notes.each do |note|
112
+ notes_builder.note do |note_builder|
113
+ note_builder.id(note.id)
114
+ note_builder.author(note.author)
115
+ note_builder.tag!('category-id', note.category_id)
116
+ note_builder.text do
117
+ note_builder.cdata!(note.text)
118
+ end
119
+ build_activities_for(note_builder, note)
120
+ end
121
+ end
122
+ end
123
+ end
124
+
125
+ def build_tags(builder)
126
+ tags = Tag.all
127
+ builder.tags do |tags_builder|
128
+ tags.each do |tag|
129
+ tags_builder.tag do |tag_builder|
130
+ tag_builder.id(tag.id)
131
+ tag_builder.name(tag.name)
132
+ tag_builder.taggings do |taggings_builder|
133
+ tag.taggings.each do |tagging|
134
+ taggings_builder.tagging do |tagging_builder|
135
+ tagging_builder.tag!('taggable-id', tagging.taggable_id)
136
+ tagging_builder.tag!('taggable-type', tagging.taggable_type)
137
+ end
138
+ end
139
+ end
140
+ end
141
+ end
142
+ end
143
+ end
144
+
145
+
146
+ # Cache user emails so we don't have to make an extra SQL request
147
+ # for every activity
148
+ def user_email_for_activity(activity)
149
+ return activity.user if activity.user.is_a?(String)
150
+
151
+ @user_emails ||= begin
152
+ User.select([:id, :email]).all.each_with_object({}) do |user, hash|
153
+ hash[user.id] = user.email
154
+ end
155
+ end
156
+ @user_emails[activity.user_id]
157
+ end
158
+
159
+ # Use the class VERSION constant, but allow for subclasses to overwrite it.
160
+ #
161
+ # See:
162
+ # http://stackoverflow.com/questions/3174563/how-to-use-an-overridden-constant-in-an-inheritanced-class
163
+ def version
164
+ self.class::VERSION
165
+ end
166
+ end
167
+ end