dradis-plugins 5.2.0 → 5.4.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: 27463a50ab791e6e6e647c44c07d6db13b64dc884aaf0908c9ed4a373eac1ca9
4
- data.tar.gz: 9fb60f1832800289ad84b195cd21be24fbf9c912221e2468f5a63ebcec773d00
3
+ metadata.gz: 9196b027f8ec18eba847d75a36b13e7bd4ddf9eb56dfffa311a180246bd1ce87
4
+ data.tar.gz: 73af5ab0eff64ed64556063f788ba31152b107ee21cce8309e88a9b001b13d0d
5
5
  SHA512:
6
- metadata.gz: 9aa312de4c83dd08a7286b50ede29b0ef0d790ce34e67198cb5fa8c408d53e8408d9ff3734c93a561a40160a28c9c31193111dfc97e3f359188716d476448697
7
- data.tar.gz: 7da6e8ca0b7f4c0a7bb3a22ef5b7ef0c2f716981a81c0181f2835549e55328551426daea75a94ddf402d5e41f1e9a215fdd270bb9a62d6a61c37004eed945e0a
6
+ metadata.gz: 06c271b66c5b2a02e9529db1c173355dd8592a03915e4e2501f5485278f4d0e836dba4fef4c49c240d1d169e1bfaa7301c488e14be4e5c0472fe079322185603
7
+ data.tar.gz: b8a81d714fe395ccf553ad7bb4146fe2a806c16f07195419ee3aaa320ddae9c41cf98afe93b1689f311e021f0cae14f123e1e1c1557965685c017590cbeee47a
data/CHANGELOG.md CHANGED
@@ -1,3 +1,10 @@
1
+ v5.4.0 (September 2026)
2
+ - Add `all_evidence` to the Evidence content service, scoping evidence by the export's published/all scope
3
+ - Cascade chosen state on upload to Evidence records
4
+
5
+ v5.3.0 (August 2026)
6
+ - Add shared report template source resolution for mappings across ticketing integrations (Jira, DevOps, ServiceNow)
7
+
1
8
  v5.2.0 (June 2026)
2
9
  - No changes
3
10
 
@@ -0,0 +1,43 @@
1
+ module Dradis
2
+ module Plugins
3
+ module Mappings
4
+ module Ticketing
5
+ # Shared by ticketing integrations' MappingsControllers (e.g. Jira,
6
+ # VSTS, ServiceNow) to list Dradis Report Templates as mapping
7
+ # sources. Distinct from Dradis::Plugins::Mappings::Base, which
8
+ # handles the opposite direction (mapping inbound upload data into
9
+ # Dradis fields).
10
+ module FieldsAndSources
11
+ extend ActiveSupport::Concern
12
+
13
+ def set_rtp_fields_and_sources
14
+ set_rtp_fields
15
+ set_sources
16
+ end
17
+
18
+ def set_rtp_fields
19
+ @rtp_fields = ReportTemplateProperties.all.filter_map do |rtp|
20
+ next if rtp.issue_fields.count == 0
21
+ [rtp.id, rtp.issue_fields.map(&:name)]
22
+ end.to_h
23
+ end
24
+
25
+ def set_sources
26
+ @sources = ReportTemplateProperties.all.group_by(&:plugin_name).map do |plugin_name, rtps|
27
+ mapped_rtps = rtps.map do |rtp|
28
+ suffix = ''
29
+ options = {}
30
+ if rtp.issue_fields.count == 0
31
+ suffix = ' (no issue fields)'
32
+ options = { disabled: 'disabled' }
33
+ end
34
+ [rtp.title + suffix, rtp.id, options]
35
+ end
36
+ [plugin_name.titleize, mapped_rtps]
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
@@ -2,16 +2,33 @@ module Dradis::Plugins::ContentService
2
2
  module Evidence
3
3
  extend ActiveSupport::Concern
4
4
 
5
+ def all_evidence
6
+ case scope
7
+ when :all
8
+ project.evidence
9
+ when :published
10
+ project.evidence.published
11
+ else
12
+ raise 'Unsupported scope!'
13
+ end
14
+ end
15
+
5
16
  def create_evidence(args = {})
6
17
  content = args.fetch(:content, default_evidence_content)
7
- node = args.fetch(:node, default_node_parent)
8
- issue = args[:issue] || default_evidence_issue
18
+ issue = args[:issue] || default_evidence_issue
19
+ node = args.fetch(:node, default_node_parent)
20
+ state = args.fetch(:state, @state)
9
21
 
10
22
  # Using node.evidence.new would result in some evidence being saved later on.
11
- evidence = ::Evidence.new(issue_id: issue.id, content: content, node_id: node.id)
23
+ evidence = ::Evidence.new(issue_id: issue.id, content: content, node_id: node.id, state: state)
12
24
 
13
25
  if evidence.valid?
14
- evidence = ::Evidence.find_or_create_by(issue_id: issue.id, node_id: node.id, content: content)
26
+ # find_or_create_by is used here to avoid creating duplicate evidence for the same issue/node/content combination.
27
+ # Don't include state in the query because we dont' want to create duplicate evidence with different states.
28
+ # If a new evidence is created, set the state otherwise leave it as-is
29
+ evidence = ::Evidence.find_or_create_by(issue_id: issue.id, node_id: node.id, content: content) do |e|
30
+ e.state = state
31
+ end
15
32
  else
16
33
  try_rescue_from_length_validation(
17
34
  model: evidence,
@@ -7,9 +7,9 @@ module Dradis
7
7
 
8
8
  module VERSION
9
9
  MAJOR = 5
10
- MINOR = 2
10
+ MINOR = 4
11
11
  TINY = 0
12
- PRE = nil
12
+ PRE = nil
13
13
 
14
14
  STRING = [MAJOR, MINOR, TINY, PRE].compact.join('.')
15
15
  end
@@ -7,7 +7,6 @@ module Dradis
7
7
  @destination = destination
8
8
  @integration = integration
9
9
  @component = @integration.meta[:name].to_s
10
- @sample_dir = default_sample_dir
11
10
  end
12
11
 
13
12
  def apply_mapping(data:, source:, mapping_fields: nil)
@@ -31,21 +30,14 @@ module Dradis
31
30
  # This returns a sample of valid entry for the Mappings Manager
32
31
  def sample
33
32
  @sample ||= {}
34
- if valid_source?
35
- @sample[source] ||= begin
36
- sample_file = File.join(@sample_dir, "#{source}.sample")
37
- File.read(sample_file)
38
- end
39
- end
33
+ @sample[source] ||= integration.sample(source) if valid_source?
40
34
  end
41
35
 
42
36
  private
43
37
 
44
- # This method returns the default location in which integrations store their sample files
45
- def default_sample_dir
46
- @default_sample_dir ||= begin
47
- File.join(Configuration.paths_templates_plugins, component)
48
- end
38
+ def source_fields
39
+ @source_fields ||= {}
40
+ @source_fields[source] ||= integration.source_fields(source)
49
41
  end
50
42
 
51
43
  def get_mapping_fields
@@ -61,7 +53,7 @@ module Dradis
61
53
  content.gsub(/{{\s?#{component}\[(\S*?)\]\s?}}/) do |field|
62
54
  name = field.split(/\[|\]/)[1]
63
55
 
64
- if integration.source_fields(source).include?(name)
56
+ if source_fields.include?(name)
65
57
  field_processor.value(field: name)
66
58
  else
67
59
  "Field [#{field}] not recognized by the integration"
@@ -70,7 +62,8 @@ module Dradis
70
62
  end
71
63
 
72
64
  def valid_source?
73
- @source = source if integration.mapping_sources.include?(source.to_sym)
65
+ valid_sources ||= integration.mapping_sources
66
+ @source = source if valid_sources.include?(source.to_sym)
74
67
  end
75
68
  end
76
69
  end
@@ -72,6 +72,17 @@ module Dradis::Plugins::Mappings::Base
72
72
  self::Mapping::SOURCE_FIELDS.keys
73
73
  end
74
74
 
75
+ # The sample content for a source, used by the Mappings Manager to
76
+ # preview an integration's mapping fields applied to real-looking data.
77
+ # Static-source integrations ship a real .sample file in the gem (see
78
+ # Dradis::Plugins::Templates::Samples, copied into place at boot);
79
+ # integrations whose sources aren't known ahead of time (e.g. csv) can
80
+ # override this instead.
81
+ def sample(source)
82
+ sample_file = File.join(Configuration.paths_templates_plugins, component, "#{source}.sample")
83
+ File.read(sample_file)
84
+ end
85
+
75
86
  def source_fields(source)
76
87
  if mapping_sources.include?(source.to_sym)
77
88
  self::Mapping::SOURCE_FIELDS[source.to_sym]
@@ -0,0 +1,30 @@
1
+ module Dradis
2
+ module Plugins
3
+ module Mappings
4
+ module Ticketing
5
+ # Shared by ticketing integrations' Mapping::Source classes (e.g.
6
+ # Jira, VSTS, ServiceNow) to identify a Report Template as a mapping
7
+ # source. Distinct from Dradis::Plugins::Mappings::Base, which
8
+ # handles the opposite direction (mapping inbound upload data into
9
+ # Dradis fields).
10
+ class Source
11
+ attr_reader :rtp_id, :source
12
+
13
+ def initialize(args)
14
+ if args[:source]
15
+ @source = args[:source]
16
+ @rtp_id = args[:source][/rtp_(\d+)/, 1]
17
+ elsif args[:rtp_id]
18
+ @rtp_id = args[:rtp_id]
19
+ @source = "rtp_#{args[:rtp_id]}"
20
+ end
21
+ end
22
+
23
+ def to_s
24
+ source
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -6,3 +6,4 @@ module Dradis
6
6
  end
7
7
 
8
8
  require 'dradis/plugins/mappings/base'
9
+ require 'dradis/plugins/mappings/ticketing/source'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dradis-plugins
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.2.0
4
+ version: 5.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Daniel Martin
@@ -70,21 +70,14 @@ executables: []
70
70
  extensions: []
71
71
  extra_rdoc_files: []
72
72
  files:
73
- - ".github/pull_request_template.md"
74
- - ".gitignore"
75
- - ".rspec"
76
- - ".rubocop.yml"
77
73
  - CHANGELOG.md
78
- - CHANGELOG.template
79
- - CONTRIBUTING.md
80
- - Gemfile
81
74
  - LICENSE
82
75
  - README.md
83
76
  - Rakefile
84
77
  - app/controllers/concerns/dradis/plugins/exportable.rb
78
+ - app/controllers/concerns/dradis/plugins/mappings/ticketing/fields_and_sources.rb
85
79
  - app/controllers/concerns/dradis/plugins/persistent_permissions.rb
86
80
  - app/controllers/dradis/plugins/export/base_controller.rb
87
- - dradis-plugins.gemspec
88
81
  - lib/dradis-plugins.rb
89
82
  - lib/dradis/plugins.rb
90
83
  - lib/dradis/plugins/base.rb
@@ -110,6 +103,7 @@ files:
110
103
  - lib/dradis/plugins/mapping_service.rb
111
104
  - lib/dradis/plugins/mappings.rb
112
105
  - lib/dradis/plugins/mappings/base.rb
106
+ - lib/dradis/plugins/mappings/ticketing/source.rb
113
107
  - lib/dradis/plugins/settings.rb
114
108
  - lib/dradis/plugins/settings/adapters/db.rb
115
109
  - lib/dradis/plugins/settings/adapters/encrypted_configuration.rb
@@ -122,16 +116,6 @@ files:
122
116
  - lib/dradis/plugins/upload/field_processor.rb
123
117
  - lib/dradis/plugins/upload/importer.rb
124
118
  - lib/dradis/plugins/version.rb
125
- - spec/engine_spec.rb
126
- - spec/internal/log/test.log
127
- - spec/lib/dradis/plugins/content_service/boards_spec.rb
128
- - spec/lib/dradis/plugins/content_service/content_blocks_spec.rb
129
- - spec/lib/dradis/plugins/content_service/issues_spec.rb
130
- - spec/lib/dradis/plugins/mapping_service_spec.rb
131
- - spec/lib/dradis/plugins/settings/adapters/encrypted_configuration_spec.rb
132
- - spec/settings_spec.rb
133
- - spec/spec_helper.rb
134
- - spec/support/spec_macros.rb
135
119
  homepage: http://dradis.com/ce/
136
120
  licenses:
137
121
  - GPL-2
@@ -153,14 +137,4 @@ requirements: []
153
137
  rubygems_version: 3.6.9
154
138
  specification_version: 4
155
139
  summary: Plugin manager for the Dradis Framework project.
156
- test_files:
157
- - spec/engine_spec.rb
158
- - spec/internal/log/test.log
159
- - spec/lib/dradis/plugins/content_service/boards_spec.rb
160
- - spec/lib/dradis/plugins/content_service/content_blocks_spec.rb
161
- - spec/lib/dradis/plugins/content_service/issues_spec.rb
162
- - spec/lib/dradis/plugins/mapping_service_spec.rb
163
- - spec/lib/dradis/plugins/settings/adapters/encrypted_configuration_spec.rb
164
- - spec/settings_spec.rb
165
- - spec/spec_helper.rb
166
- - spec/support/spec_macros.rb
140
+ test_files: []
@@ -1,45 +0,0 @@
1
- Please review [CONTRIBUTING.md](https://github.com/dradis/dradis-ce/blob/develop/CONTRIBUTING.md) and remove this line.
2
-
3
- ### Summary
4
-
5
- Provide a general description of the code changes in your pull
6
- request... were there any bugs you had fixed? If so, mention them. If
7
- these bugs have open GitHub issues, be sure to tag them here as well,
8
- to keep the conversation linked together.
9
-
10
-
11
- ### Testing Steps
12
-
13
- Provide steps to test functionality, described in detail for someone not familiar with this part of the application / code base
14
-
15
-
16
- ### Other Information
17
-
18
- If there's anything else that's important and relevant to your pull
19
- request, mention that information here. This could include
20
- benchmarks, or other information.
21
-
22
- Thanks for contributing to Dradis!
23
-
24
-
25
- ### Copyright assignment
26
-
27
- Collaboration is difficult with commercial closed source but we want
28
- to keep as much of the OSS ethos as possible available to users
29
- who want to fix it themselves.
30
-
31
- In order to unambiguously own and sell Dradis Framework commercial
32
- products, we must have the copyright associated with the entire
33
- codebase. Any code you create which is merged must be owned by us.
34
- That's not us trying to be a jerks, that's just the way it works.
35
-
36
- You can delete this section, but the following sentence needs to
37
- remain in the PR's description:
38
-
39
- > I assign all rights, including copyright, to any future Dradis
40
- > work by myself to Security Roots.
41
-
42
- ### Check List
43
-
44
- - [ ] Added a CHANGELOG entry
45
- - [ ] Added specs
data/.gitignore DELETED
@@ -1,11 +0,0 @@
1
- # See http://help.github.com/ignore-files/ for more about ignoring files.
2
- #
3
- # If you find yourself ignoring temporary files generated by your text editor
4
- # or operating system, you probably want to add a global ignore instead:
5
- # git config --global core.excludesfile ~/.gitignore_global
6
-
7
- # Ignore bundler config
8
- /.bundle
9
- /Gemfile.lock
10
- /pkg/
11
- /vendor/bundle/
data/.rspec DELETED
@@ -1,2 +0,0 @@
1
- --color
2
- -f d
data/.rubocop.yml DELETED
@@ -1,129 +0,0 @@
1
- AllCops:
2
- # RuboCop has a bunch of cops enabled by default. This setting tells RuboCop
3
- # to ignore them, so only the ones explicitly set in this file are enabled.
4
- DisabledByDefault: true
5
- SuggestExtensions: false
6
- Exclude:
7
- - '**/templates/**/*'
8
-
9
- # Prefer &&/|| over and/or.
10
- Style/AndOr:
11
- Enabled: true
12
-
13
- # Do not use braces for hash literals when they are the last argument of a
14
- # method call.
15
- Style/HashAsLastArrayItem:
16
- Enabled: true
17
-
18
- # Align `when` with `case`.
19
- Layout/CaseIndentation:
20
- Enabled: true
21
-
22
- # Align comments with method definitions.
23
- Layout/CommentIndentation:
24
- Enabled: true
25
-
26
- Layout/EmptyLineAfterMagicComment:
27
- Enabled: true
28
-
29
- # No extra empty lines.
30
- Layout/EmptyLines:
31
- Enabled: true
32
-
33
- # In a regular class definition, no empty lines around the body.
34
- Layout/EmptyLinesAroundClassBody:
35
- Enabled: true
36
-
37
- # In a regular method definition, no empty lines around the body.
38
- Layout/EmptyLinesAroundMethodBody:
39
- Enabled: true
40
-
41
- # In a regular module definition, no empty lines around the body.
42
- Layout/EmptyLinesAroundModuleBody:
43
- Enabled: true
44
-
45
- Layout/FirstArgumentIndentation:
46
- Enabled: true
47
-
48
- # Use Ruby >= 1.9 syntax for hashes. Prefer { a: :b } over { :a => :b }.
49
- Style/HashSyntax:
50
- Enabled: true
51
- EnforcedShorthandSyntax: never
52
-
53
- # Method definitions after `private` or `protected` isolated calls need one
54
- # extra level of indentation.
55
- Layout/IndentationConsistency:
56
- Enabled: true
57
- EnforcedStyle: normal
58
-
59
- # Two spaces, no tabs (for indentation).
60
- Layout/IndentationWidth:
61
- Enabled: true
62
-
63
- Layout/SpaceAfterColon:
64
- Enabled: true
65
-
66
- Layout/SpaceAfterComma:
67
- Enabled: true
68
-
69
- Layout/SpaceAroundEqualsInParameterDefault:
70
- Enabled: true
71
-
72
- Layout/SpaceAroundKeyword:
73
- Enabled: true
74
-
75
- Layout/SpaceAroundOperators:
76
- Enabled: true
77
-
78
- Layout/SpaceBeforeFirstArg:
79
- Enabled: true
80
-
81
- # Defining a method with parameters needs parentheses.
82
- Style/MethodDefParentheses:
83
- Enabled: true
84
-
85
- # Use `foo {}` not `foo{}`.
86
- Layout/SpaceBeforeBlockBraces:
87
- Enabled: true
88
-
89
- # Use `foo { bar }` not `foo {bar}`.
90
- Layout/SpaceInsideBlockBraces:
91
- Enabled: true
92
-
93
- # Use `{ a: 1 }` not `{a:1}`.
94
- Layout/SpaceInsideHashLiteralBraces:
95
- Enabled: true
96
-
97
- Layout/SpaceInsideParens:
98
- Enabled: true
99
-
100
- # Check quotes usage according to lint rule below.
101
- Style/StringLiterals:
102
- Enabled: true
103
- EnforcedStyle: single_quotes
104
-
105
- # Detect hard tabs, no hard tabs.
106
- Layout/IndentationStyle:
107
- Enabled: true
108
-
109
- # Blank lines should not have any spaces.
110
- Layout/TrailingEmptyLines:
111
- Enabled: true
112
-
113
- # No trailing whitespace.
114
- Layout/TrailingWhitespace:
115
- Enabled: true
116
-
117
- # Use quotes for string literals when they are enough.
118
- Style/RedundantPercentQ:
119
- Enabled: true
120
-
121
- # Align `end` with the matching keyword or starting expression except for
122
- # assignments, where it should be aligned with the LHS.
123
- Layout/EndAlignment:
124
- Enabled: true
125
- EnforcedStyleAlignWith: variable
126
-
127
- # Use my_method(my_arg) not my_method( my_arg ) or my_method my_arg.
128
- Lint/RequireParentheses:
129
- Enabled: true
data/CHANGELOG.template DELETED
@@ -1,12 +0,0 @@
1
- [v#.#.#] ([month] [YYYY])
2
- - [future tense verb] [feature]
3
- - Upgraded gems:
4
- - [gem]
5
- - Bugs fixes:
6
- - [future tense verb] [bug fix]
7
- - Bug tracker items:
8
- - [item]
9
- - Security Fixes:
10
- - High: (Authenticated|Unauthenticated) (admin|author|contributor) [vulnerability description]
11
- - Medium: (Authenticated|Unauthenticated) (admin|author|contributor) [vulnerability description]
12
- - Low: (Authenticated|Unauthenticated) (admin|author|contributor) [vulnerability description]
data/CONTRIBUTING.md DELETED
@@ -1,3 +0,0 @@
1
- # Plugin contribution guidelines
2
-
3
- See the Dradis Framework's [CONTRIBUTING.md](https://github.com/dradis/dradisframework/blob/master/CONTRIBUTING.md)
data/Gemfile DELETED
@@ -1,6 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- source 'https://rubygems.org'
4
-
5
- # Specify your gem's dependencies in dradis-html_export.gemspec
6
- gemspec
@@ -1,26 +0,0 @@
1
- $:.push File.expand_path('../lib', __FILE__)
2
-
3
- require 'dradis/plugins/version'
4
-
5
- # Describe your gem and declare its dependencies:
6
- Gem::Specification.new do |spec|
7
- spec.platform = Gem::Platform::RUBY
8
- spec.name = 'dradis-plugins'
9
- spec.version = Dradis::Plugins::VERSION::STRING
10
- spec.summary = 'Plugin manager for the Dradis Framework project.'
11
- spec.description = 'Required dependency for Dradis Framework.'
12
-
13
- spec.license = 'GPL-2'
14
-
15
- spec.authors = ['Daniel Martin']
16
- spec.homepage = 'http://dradis.com/ce/'
17
-
18
- spec.files = `git ls-files`.split($\)
19
- spec.executables = spec.files.grep(%r{^bin/}).map { |f| File.basename(f) }
20
- spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
21
-
22
- spec.add_development_dependency 'bundler', '~> 2.0'
23
- spec.add_development_dependency 'rake'
24
- spec.add_development_dependency 'rspec-rails'
25
- spec.add_development_dependency 'rubocop', '1.79.0'
26
- end
data/spec/engine_spec.rb DELETED
@@ -1,39 +0,0 @@
1
- require 'rails_helper'
2
-
3
- class TestEngine < ::Rails::Engine
4
- include ::Dradis::Plugins::Base
5
- addon_settings :test_engine do
6
- end
7
- end
8
-
9
- describe Dradis::Plugins::Base do
10
- before(:each) do
11
- TestEngine::settings.reset_defaults!
12
- end
13
-
14
- describe '#enabled?' do
15
- it 'returns default value' do
16
- expect(TestEngine.enabled?).to eq(true)
17
- end
18
- end
19
- describe '#enable!' do
20
- it 'sets enabled to true' do
21
- TestEngine.settings.enabled = false
22
- TestEngine.settings.save
23
-
24
- expect { TestEngine.enable! }.to change {
25
- TestEngine.enabled?
26
- }.from(false).to(true)
27
- end
28
- end
29
- describe '#disable!' do
30
- it 'sets enabled to false' do
31
- TestEngine.settings.enabled = true
32
- TestEngine.settings.save
33
-
34
- expect { TestEngine.disable! }.to change {
35
- TestEngine.enabled?
36
- }.from(true).to(false)
37
- end
38
- end
39
- end
File without changes
@@ -1,45 +0,0 @@
1
- require 'rails_helper'
2
-
3
- # To run, execute from Dradis main app folder:
4
- # bin/rspec [dradis-plugins path]/spec/lib/dradis/plugins/content_service/boards_spec.rb
5
- describe Dradis::Plugins::ContentService::Boards do
6
- let(:plugin) { Dradis::Plugins::Nessus }
7
- let(:project) { create(:project) }
8
- let(:service) do
9
- Dradis::Plugins::ContentService::Base.new(
10
- plugin: plugin,
11
- logger: Rails.logger,
12
- project: project
13
- )
14
- end
15
-
16
- describe 'Boards' do
17
- describe '#all_boards' do
18
- it 'returns all the project-level boards' do
19
- board = create(:board, project: project)
20
- node = create(:node, project: project)
21
- node_board = create(:board, node: node, project: project)
22
-
23
- boards = service.project_boards
24
-
25
- expect(boards).to include(board)
26
- expect(boards).to_not include(node_board)
27
- end
28
- end
29
-
30
- describe '#create_board' do
31
- it 'creates a board without a node' do
32
- service.create_board(name: 'NodelessBoard')
33
-
34
- expect(project.reload.boards.where(name: 'NodelessBoard')).to_not be_nil
35
- end
36
-
37
- it 'creates a board with a node' do
38
- node = create(:node, project: project)
39
- service.create_board(name: 'NodeBoard', node_id: node.id)
40
-
41
- expect(project.reload.boards.where(name: 'NodeBoard')).to_not be_nil
42
- end
43
- end
44
- end
45
- end
@@ -1,29 +0,0 @@
1
- require 'rails_helper'
2
-
3
- # To run, execute from Dradis Pro main app folder:
4
- # bin/rspec [dradis-plugins path]/spec/lib/dradis/plugins/content_service/content_blocks_spec.rb
5
-
6
- describe 'Content Block content service' do
7
- let(:plugin) { Dradis::Plugins::Nessus }
8
- let(:plugin_id) { '111' }
9
- let(:project) { create(:project) }
10
- let(:service) do
11
- Dradis::Plugins::ContentService::Base.new(
12
- plugin: plugin,
13
- logger: Rails.logger,
14
- project: project
15
- )
16
- end
17
-
18
- describe '#all_content_blocks' do
19
- before do
20
- @draft_content = create_list(:content_block, 10, project: project, state: :draft)
21
- @review_content = create_list(:content_block, 10, project: project, state: :ready_for_review)
22
- @published_content = create_list(:content_block, 10, project: project, state: :published)
23
- end
24
-
25
- it 'returns only the published content blocks' do
26
- expect(service.all_content_blocks.to_a).to match_array(@published_content)
27
- end
28
- end
29
- end
@@ -1,56 +0,0 @@
1
- require 'rails_helper'
2
-
3
- # To run, execute from Dradis main app folder:
4
- # bin/rspec [dradis-plugins path]/spec/lib/dradis/plugins/content_service/issues_spec.rb
5
-
6
- describe 'Issues content service' do
7
- let(:plugin) { Dradis::Plugins::Nessus }
8
- let(:plugin_id) { '111' }
9
- let(:project) { create(:project) }
10
- let(:service) do
11
- Dradis::Plugins::ContentService::Base.new(
12
- plugin: plugin,
13
- logger: Rails.logger,
14
- project: project
15
- )
16
- end
17
-
18
- describe 'Issues' do
19
- let(:create_issue) do
20
- service.create_issue(text: "#[Title]#\nTest Issue\n", id: plugin_id, state: :ready_for_review)
21
- end
22
-
23
- describe 'when the issue already exists in the cache' do
24
- before do
25
- issue = create(:issue, text: "#[Title]#\nTest Issue\n", id: plugin_id)
26
- service.issue_cache.store("nessus-#{plugin_id}", issue)
27
- end
28
-
29
- it 'does not create a new issue' do
30
- expect { create_issue }.not_to change { Issue.count }
31
- end
32
- end
33
-
34
- describe "when the issue doesn't already exist in the cache" do
35
- it "creates a new Issue containing 'plugin' and 'plugin_id'" do
36
- new_issue = nil
37
- plugin_name = "#{plugin}::Engine".constantize.plugin_name
38
- expect { new_issue = create_issue }.to change { Issue.count }.by(1)
39
- expect(new_issue.text).to match(/#\[plugin\]#\n*#{plugin_name}/)
40
- expect(new_issue.text).to match(/#\[plugin_id\]#\n*#{plugin_id}/)
41
- end
42
- end
43
-
44
- describe '#all_issues' do
45
- before do
46
- @draft_issues = create_list(:issue, 10, project: project, state: :draft)
47
- @review_issues = create_list(:issue, 10, project: project, state: :ready_for_review)
48
- @published_issues = create_list(:issue, 10, project: project, state: :published)
49
- end
50
-
51
- it 'returns only the published issues' do
52
- expect(service.all_issues.to_a).to match_array(@published_issues)
53
- end
54
- end
55
- end
56
- end
@@ -1,54 +0,0 @@
1
- require 'rails_helper'
2
-
3
- # To run, execute from Dradis main app folder:
4
- # bin/rspec [dradis-plugins path]/spec/lib/dradis/plugins/mapping_service_spec.rb
5
- describe Dradis::Plugins::MappingService do
6
- describe '#apply_mapping' do
7
- let(:data) { double }
8
- let(:liquid_mapping_field) {
9
- create(:mapping_field, content: "{% if issue.evidence %}\n{% endif %} }}")
10
- }
11
- let(:integration) { Dradis::Plugins::Qualys }
12
- let(:project) { create(:project, :with_report_template_properties) }
13
- let(:qualys_mapping_field) {
14
- create(:mapping_field, destination_field: 'Test Field', content: 'test content')
15
- }
16
- let(:mapping_service) do
17
- Dradis::Plugins::MappingService.new(
18
- integration: integration,
19
- destination: "rtp_#{project.report_template_properties_id}"
20
- )
21
- end
22
- let(:mapping_processed) do
23
- mapping_service.apply_mapping(source: 'was_issue', data: data)
24
- end
25
-
26
- before do
27
- allow(data).to receive(:name).and_return('VULNERABILITY')
28
- end
29
-
30
- context 'with default mappings' do
31
- it 'applies default mappings when no mapping exists' do
32
- expect(mapping_processed).to include("#[Title]#\n")
33
- expect(mapping_processed).not_to include("#[Test Field]#\n")
34
- end
35
- end
36
-
37
- context 'with custom mappings' do
38
- it 'applies mappings when a mapping matching the uploader & source exists' do
39
- allow(mapping_service).to receive(:get_mapping_fields).and_return([qualys_mapping_field])
40
-
41
- expect(mapping_processed).to include("#[Test Field]#\ntest content")
42
- expect(mapping_processed).not_to include("#[Title]#\n")
43
- end
44
-
45
- context 'with liquid content' do
46
- it 'does not parse the liquid data as fields' do
47
- allow(mapping_service).to receive(:get_mapping_fields).and_return([liquid_mapping_field])
48
-
49
- expect(mapping_processed).to include("{% if issue.evidence %}\n{% endif %} }}")
50
- end
51
- end
52
- end
53
- end
54
- end
@@ -1,112 +0,0 @@
1
- #
2
- # This spec must be run from Dradis root dir.
3
- #
4
- # Configuration init from:
5
- # https://github.com/rails/rails/blob/main/activesupport/test/encrypted_configuration_test.rb
6
- #
7
- require 'rails_helper'
8
-
9
- describe Dradis::Plugins::Settings::Adapters::EncryptedConfiguration do
10
-
11
- subject do
12
- ec = Dradis::Plugins::Settings::Adapters::EncryptedConfiguration.new(:rspec)
13
- ec.config_path = @credentials_config_path
14
- ec.key_path = @credentials_key_path
15
- ec
16
- end
17
-
18
- context 'With an empty config file' do
19
- before(:all) do
20
- @tmpdir = Dir.mktmpdir('config-')
21
- @credentials_config_path = File.join(@tmpdir, 'empty.yml.enc')
22
- @credentials_key_path = File.join(@tmpdir, 'empty.key')
23
- end
24
-
25
- describe '#delete' do
26
- it 'becomes a no-op' do
27
- expect { subject.delete(:key) }.to_not raise_error
28
- end
29
- end
30
-
31
- describe '#exists' do
32
- it 'is always false' do
33
- expect(subject.exists?(:key)).to be(false)
34
- expect(subject.exists?(:key2)).to be(false)
35
- end
36
- end
37
-
38
- describe '#read' do
39
- it 'always returns nil' do
40
- expect(subject.read(:key)).to eq(nil)
41
- expect(subject.read(:key2)).to eq(nil)
42
- end
43
- end
44
-
45
- describe '#write' do
46
- it 'inits the namespace and stores the setting' do
47
- expect { subject.write(:key, :value) }.to_not raise_error
48
- expect(File.size(@credentials_config_path)).to_not be(0)
49
-
50
- File.unlink @credentials_config_path
51
- end
52
- end
53
- end
54
-
55
- context 'With a working config file' do
56
- DEFAULT_CONFIG = { rspec: { key: :lorem_ipsum, key2: :dolor_sit } }.to_yaml.freeze
57
-
58
- before(:all) do
59
- @tmpdir = Dir.mktmpdir('config-')
60
- @credentials_config_path = File.join(@tmpdir, 'credentials.yml.enc')
61
- @credentials_key_path = File.join(@tmpdir, 'master.key')
62
-
63
- File.write(@credentials_key_path, ActiveSupport::EncryptedConfiguration.generate_key)
64
-
65
- @credentials = ActiveSupport::EncryptedConfiguration.new(
66
- config_path: @credentials_config_path, key_path: @credentials_key_path,
67
- env_key: 'RAILS_MASTER_KEY', raise_if_missing_key: true
68
- )
69
-
70
- @credentials.write(DEFAULT_CONFIG)
71
- end
72
-
73
- after(:all) do
74
- FileUtils.rm_rf @tmpdir
75
- end
76
-
77
- describe '#delete' do
78
- it 'removes a value from disk' do
79
- subject.delete(:key2)
80
-
81
- @credentials.instance_variable_set('@config', nil)
82
- expect(@credentials.config[:rspec].key?(:key)).to be(true)
83
- expect(@credentials.config[:rspec].key?(:key2)).to be(false)
84
- @credentials.write(DEFAULT_CONFIG)
85
- end
86
- end
87
-
88
- describe '#exists' do
89
- it 'finds an existing value' do
90
- expect(subject.exists?(:key)).to be(true)
91
- end
92
- it 'detects an inexisting value' do
93
- expect(subject.exists?(:key3)).to be(false)
94
- end
95
- end
96
-
97
- describe '#read' do
98
- it 'loads an already existing value' do
99
- expect(subject.read(:key)).to eq(:lorem_ipsum)
100
- end
101
- end
102
-
103
- describe '#write' do
104
- it 'stores a value on disk' do
105
- subject.write(:new_key, :new_value)
106
- @credentials.instance_variable_set('@config', nil)
107
- expect(@credentials.config[:rspec][:new_key]).to eq(:new_value)
108
- @credentials.write(DEFAULT_CONFIG)
109
- end
110
- end
111
- end
112
- end
@@ -1,85 +0,0 @@
1
- #
2
- # This spec must be ran from Dradis root dir
3
- #
4
- require 'rails_helper'
5
-
6
- class TestEngine < ::Rails::Engine
7
- include ::Dradis::Plugins::Base
8
- addon_settings :test_engine do
9
- settings.default_host = 'localhost'
10
- settings.default_port = 80
11
- settings.default_protocol = 'http'
12
- end
13
- end
14
-
15
- describe Dradis::Plugins::Settings do
16
-
17
- before(:each) do
18
- TestEngine::settings.reset_defaults!
19
- end
20
-
21
- it 'sets and return default values' do
22
- expect(TestEngine::settings.host).to eq('localhost')
23
- expect(TestEngine::settings.port).to eq(80)
24
- end
25
-
26
- it 'sets and returns user defined values' do
27
- expect(TestEngine::settings.host).to eq('localhost')
28
- TestEngine::settings.host = '127.0.0.1'
29
- expect(TestEngine::settings.host).to eq('127.0.0.1')
30
- expect(TestEngine::settings.port).to eq(80)
31
- end
32
-
33
- it 'sets and returns new value even if it equals default value' do
34
- expect(TestEngine::settings.host).to eq('localhost')
35
- TestEngine::settings.host = '127.0.0.1'
36
- expect(TestEngine::settings.host).to eq('127.0.0.1')
37
- TestEngine::settings.host = 'localhost'
38
- expect(TestEngine::settings.host).to eq('localhost')
39
- end
40
-
41
- it 'saves to db and returns persisted values' do
42
- expect(TestEngine::settings.host).to eq('localhost')
43
- TestEngine::settings.host = '127.0.0.1'
44
- expect(TestEngine::settings.save).to eq({ host: '127.0.0.1' })
45
- expect(TestEngine::settings.host).to eq('127.0.0.1')
46
- end
47
-
48
- it 'reads from db after saving' do
49
- expect(TestEngine::settings.host).to eq('localhost')
50
- TestEngine::settings.host = '127.0.0.1'
51
- expect(TestEngine::settings.save).to eq({ host: '127.0.0.1' })
52
- end
53
-
54
- end
55
-
56
- describe Dradis::Plugins::Settings, '#is_default?' do
57
- it 'knows if a string value equals its default integer value' do
58
- TestEngine::settings.is_default?(:port, '80')
59
- end
60
- end
61
-
62
- describe Dradis::Plugins::Settings, '#all' do
63
- it 'returns values from db, dirty state or default as needed and tells which one is default' do
64
- TestEngine::settings.host = '127.0.0.1'
65
- TestEngine::settings.save
66
- TestEngine::settings.protocol = 'https'
67
- expect(TestEngine::settings.all).to eq([
68
- {
69
- name: :host,
70
- value: '127.0.0.1',
71
- default: false
72
- },
73
- {
74
- name: :port,
75
- value: 80,
76
- default: true
77
- },
78
- {
79
- name: :protocol,
80
- value: 'https',
81
- default: false
82
- },
83
- ])
84
- end
85
- end
data/spec/spec_helper.rb DELETED
@@ -1,2 +0,0 @@
1
- RSpec.configure do |config|
2
- end
@@ -1,26 +0,0 @@
1
- module Dradis::Plugins::SpecMacros
2
- extend ActiveSupport::Concern
3
-
4
- def stub_content_service
5
- @content_service = Dradis::Plugins::ContentService::Base.new(
6
- logger: Logger.new(STDOUT),
7
- plugin: Dradis::Plugins::Nexpose
8
- )
9
-
10
- # Stub content_service methods
11
- # They return their argument hashes as objects mimicking
12
- # nodes, issues, etc
13
- allow(@content_service).to receive(:create_node) do |args|
14
- OpenStruct.new(args)
15
- end
16
- allow(@content_service).to receive(:create_note) do |args|
17
- OpenStruct.new(args)
18
- end
19
- allow(@content_service).to receive(:create_issue) do |args|
20
- OpenStruct.new(args)
21
- end
22
- allow(@content_service).to receive(:create_evidence) do |args|
23
- OpenStruct.new(args)
24
- end
25
- end
26
- end