dradis-projects 3.0.1 → 3.6.0

Sign up to get free protection for your applications and to get access to all the features.
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