dradis-plugins 4.7.0 → 4.9.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/export/base_controller.rb +9 -6
- data/dradis-plugins.gemspec +2 -7
- data/lib/dradis/plugins/configurable.rb +13 -4
- data/lib/dradis/plugins/content_service/base.rb +2 -0
- data/lib/dradis/plugins/content_service/content_blocks.rb +12 -1
- data/lib/dradis/plugins/content_service/core.rb +5 -3
- data/lib/dradis/plugins/content_service/issues.rb +16 -4
- data/lib/dradis/plugins/export/base.rb +4 -2
- data/lib/dradis/plugins/gem_version.rb +1 -1
- data/lib/dradis/plugins/settings/adapters/db.rb +30 -0
- data/lib/dradis/plugins/settings/adapters/encrypted_configuration.rb +58 -0
- data/lib/dradis/plugins/settings.rb +22 -21
- data/lib/dradis/plugins/thor_helper.rb +1 -1
- data/lib/dradis/plugins/upload/importer.rb +7 -4
- data/lib/dradis/plugins.rb +2 -0
- data/spec/engine_spec.rb +7 -2
- data/spec/lib/dradis/plugins/content_service/boards_spec.rb +1 -1
- data/spec/lib/dradis/plugins/content_service/content_blocks_spec.rb +29 -0
- data/spec/lib/dradis/plugins/content_service/issues_spec.rb +21 -29
- data/spec/lib/dradis/plugins/settings/adapters/encrypted_configuration_spec.rb +112 -0
- data/spec/settings_spec.rb +0 -1
- metadata +16 -10
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 76e20a999e5f8a6309b837043fc488dc8d7f8f6bafae273482f9f1027078aa04
|
4
|
+
data.tar.gz: aa7c0068193b07f847ea8f0ddb6b7a8f2fb4705922ebb3da01df2859837fe4f7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: efcd0183333ddf9271c3ecca1a7c4793bb864c7e6172d46bc1f335e543ecbbfcedc640953230d976c5ba9e052df2988a5077921f78a61f95e6fa188782f44357
|
7
|
+
data.tar.gz: 0c73436e1dd6d733a37fe4ccf10519f0d710137eab88eb6170fc44756d993c142372751e7f41dbc3ca5798ae6c2494d6d1829e9ba5d68cd4b1ed341fa7c92467
|
data/CHANGELOG.md
CHANGED
@@ -2,15 +2,18 @@ module Dradis
|
|
2
2
|
module Plugins
|
3
3
|
module Export
|
4
4
|
class BaseController < Rails.application.config.dradis.base_export_controller_class_name.to_s.constantize
|
5
|
+
before_action :validate_scope
|
5
6
|
|
6
7
|
protected
|
7
8
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
def
|
13
|
-
|
9
|
+
def export_params
|
10
|
+
params.permit(:project_id, :scope, :template)
|
11
|
+
end
|
12
|
+
|
13
|
+
def validate_scope
|
14
|
+
unless Dradis::Plugins::ContentService::Base::VALID_SCOPES.include?(params[:scope])
|
15
|
+
raise 'Something fishy is going on...'
|
16
|
+
end
|
14
17
|
end
|
15
18
|
end
|
16
19
|
end
|
data/dradis-plugins.gemspec
CHANGED
@@ -20,12 +20,7 @@ Gem::Specification.new do |spec|
|
|
20
20
|
spec.executables = spec.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
21
21
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
22
22
|
|
23
|
-
spec.add_development_dependency 'bundler'
|
24
|
-
spec.add_development_dependency 'rake'
|
23
|
+
spec.add_development_dependency 'bundler'
|
24
|
+
spec.add_development_dependency 'rake'
|
25
25
|
spec.add_development_dependency 'rspec-rails'
|
26
|
-
|
27
|
-
# By not including Rails as a dependency, we can use the gem with different
|
28
|
-
# versions of Rails (a sure recipe for disaster, I'm sure), which is needed
|
29
|
-
# until we bump Dradis Pro to 4.1.
|
30
|
-
# s.add_dependency 'rails', '~> 4.1.1'
|
31
26
|
end
|
@@ -3,14 +3,19 @@ module Dradis::Plugins
|
|
3
3
|
extend ActiveSupport::Concern
|
4
4
|
|
5
5
|
module ClassMethods
|
6
|
-
delegate :settings, to: :instance
|
6
|
+
delegate :encrypted_settings, :settings, to: :instance
|
7
7
|
|
8
8
|
def settings_namespace
|
9
|
-
@settings_namespace
|
9
|
+
@settings_namespace ||= plugin_name
|
10
|
+
end
|
11
|
+
|
12
|
+
def addon_encrypted_settings(namespace = nil, &block)
|
13
|
+
@settings_namespace = namespace
|
14
|
+
yield self if block_given?
|
10
15
|
end
|
11
16
|
|
12
17
|
def addon_settings(namespace = nil, &block)
|
13
|
-
@settings_namespace = namespace
|
18
|
+
@settings_namespace = namespace
|
14
19
|
yield self if block_given?
|
15
20
|
end
|
16
21
|
|
@@ -19,8 +24,12 @@ module Dradis::Plugins
|
|
19
24
|
end
|
20
25
|
end
|
21
26
|
|
27
|
+
def encrypted_settings
|
28
|
+
@encrypted_settings ||= Dradis::Plugins::Settings.new(self.class.settings_namespace, adapter: :encrypted_configuration)
|
29
|
+
end
|
30
|
+
|
22
31
|
def settings
|
23
|
-
@settings ||= Dradis::Plugins::Settings.new(self.class.settings_namespace)
|
32
|
+
@settings ||= Dradis::Plugins::Settings.new(self.class.settings_namespace, adapter: :db)
|
24
33
|
end
|
25
34
|
end
|
26
35
|
end
|
@@ -3,23 +3,34 @@ module Dradis::Plugins::ContentService
|
|
3
3
|
extend ActiveSupport::Concern
|
4
4
|
|
5
5
|
def all_content_blocks
|
6
|
-
|
6
|
+
case scope
|
7
|
+
when :all
|
8
|
+
project.content_blocks
|
9
|
+
when :published
|
10
|
+
project.content_blocks.published
|
11
|
+
else
|
12
|
+
raise 'Unsupported scope!'
|
13
|
+
end
|
7
14
|
end
|
8
15
|
|
9
16
|
def create_content_block(args={})
|
10
17
|
block_group = args.fetch(:block_group, default_content_block_group)
|
11
18
|
content = args.fetch(:content, default_content_block_content)
|
19
|
+
state = args.fetch(:state, :published)
|
12
20
|
user_id = args.fetch(:user_id)
|
13
21
|
|
14
22
|
content_block = ContentBlock.new(
|
15
23
|
content: content,
|
16
24
|
block_group: block_group,
|
17
25
|
project_id: project.id,
|
26
|
+
state: state,
|
18
27
|
user_id: user_id
|
19
28
|
)
|
20
29
|
|
21
30
|
if content_block.valid?
|
22
31
|
content_block.save
|
32
|
+
|
33
|
+
return content_block
|
23
34
|
else
|
24
35
|
try_rescue_from_length_validation(
|
25
36
|
model: content_block,
|
@@ -3,7 +3,7 @@ module Dradis::Plugins::ContentService
|
|
3
3
|
extend ActiveSupport::Concern
|
4
4
|
|
5
5
|
included do
|
6
|
-
attr_accessor :logger, :plugin, :project
|
6
|
+
attr_accessor :logger, :plugin, :project, :scope
|
7
7
|
end
|
8
8
|
|
9
9
|
# ----------------------------------------------------------- Initializer
|
@@ -12,9 +12,11 @@ module Dradis::Plugins::ContentService
|
|
12
12
|
# @option plugin [Class] the 'wrapper' module of a plugin, e.g.
|
13
13
|
# Dradis::Plugins::Nessus
|
14
14
|
def initialize(args={})
|
15
|
-
@logger
|
16
|
-
@plugin
|
15
|
+
@logger = args.fetch(:logger, Rails.logger)
|
16
|
+
@plugin = args.fetch(:plugin)
|
17
17
|
@project = args[:project]
|
18
|
+
@scope = args.fetch(:scope, :published)
|
19
|
+
@state = args[:state]
|
18
20
|
end
|
19
21
|
|
20
22
|
private
|
@@ -3,7 +3,17 @@ module Dradis::Plugins::ContentService
|
|
3
3
|
extend ActiveSupport::Concern
|
4
4
|
|
5
5
|
def all_issues
|
6
|
-
|
6
|
+
issues =
|
7
|
+
case scope
|
8
|
+
when :all
|
9
|
+
project.issues
|
10
|
+
when :published
|
11
|
+
project.issues.published
|
12
|
+
else
|
13
|
+
raise 'Unsupported scope!'
|
14
|
+
end
|
15
|
+
|
16
|
+
issues.where(category_id: default_issue_category.id)
|
7
17
|
end
|
8
18
|
|
9
19
|
def create_issue(args={})
|
@@ -11,6 +21,7 @@ module Dradis::Plugins::ContentService
|
|
11
21
|
# NOTE that ID is the unique issue identifier assigned by the plugin,
|
12
22
|
# and is not to be confused with the Issue#id primary key
|
13
23
|
id = args.fetch(:id, default_issue_id)
|
24
|
+
state = args.fetch(:state, @state)
|
14
25
|
|
15
26
|
# Bail if we already have this issue in the cache
|
16
27
|
uuid = [plugin::Engine::plugin_name, id]
|
@@ -25,9 +36,10 @@ module Dradis::Plugins::ContentService
|
|
25
36
|
text << plugin_details
|
26
37
|
|
27
38
|
issue = Issue.new(text: text) do |i|
|
28
|
-
i.author
|
29
|
-
i.node
|
39
|
+
i.author = default_author
|
40
|
+
i.node = project.issue_library
|
30
41
|
i.category = default_issue_category
|
42
|
+
i.state = state
|
31
43
|
end
|
32
44
|
|
33
45
|
if issue.valid?
|
@@ -64,7 +76,7 @@ module Dradis::Plugins::ContentService
|
|
64
76
|
# the issue library cache has been initialized.
|
65
77
|
def issue_cache
|
66
78
|
@issue_cache ||= begin
|
67
|
-
issues_map =
|
79
|
+
issues_map = project.issues.map do |issue|
|
68
80
|
cache_key = [
|
69
81
|
issue.fields['plugin'],
|
70
82
|
issue.fields['plugin_id']
|
@@ -5,7 +5,7 @@ module Dradis
|
|
5
5
|
module Plugins
|
6
6
|
module Export
|
7
7
|
class Base
|
8
|
-
attr_accessor :content_service, :logger, :options, :plugin, :project
|
8
|
+
attr_accessor :content_service, :logger, :options, :plugin, :project, :scope
|
9
9
|
|
10
10
|
def initialize(args={})
|
11
11
|
# Save everything just in case the implementing class needs any of it.
|
@@ -15,6 +15,7 @@ module Dradis
|
|
15
15
|
@logger = args.fetch(:logger, Rails.logger)
|
16
16
|
@plugin = args[:plugin] || default_plugin
|
17
17
|
@project = args.key?(:project_id) ? Project.find(args[:project_id]) : nil
|
18
|
+
@scope = args.fetch(:scope, :published).to_sym
|
18
19
|
|
19
20
|
@content_service = args.fetch(:content_service, default_content_service)
|
20
21
|
|
@@ -34,7 +35,8 @@ module Dradis
|
|
34
35
|
@content ||= Dradis::Plugins::ContentService::Base.new(
|
35
36
|
logger: logger,
|
36
37
|
plugin: plugin,
|
37
|
-
project: project
|
38
|
+
project: project,
|
39
|
+
scope: scope
|
38
40
|
)
|
39
41
|
end
|
40
42
|
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Dradis::Plugins::Settings::Adapters
|
2
|
+
class Db
|
3
|
+
def initialize(namespace)
|
4
|
+
@namespace = namespace.to_s
|
5
|
+
end
|
6
|
+
|
7
|
+
def delete(key)
|
8
|
+
Configuration.find_by(name: namespaced_key(key)).destroy
|
9
|
+
end
|
10
|
+
|
11
|
+
def exists?(key)
|
12
|
+
Configuration.exists?(name: namespaced_key(key))
|
13
|
+
end
|
14
|
+
|
15
|
+
def read(key)
|
16
|
+
Configuration.find_by(name: namespaced_key(key))&.value
|
17
|
+
end
|
18
|
+
|
19
|
+
def write(key, value)
|
20
|
+
db_setting = Configuration.find_or_create_by(name: namespaced_key(key))
|
21
|
+
db_setting.update_attribute(:value, value)
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def namespaced_key(key)
|
27
|
+
[@namespace, key.to_s.underscore].join(':')
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
module Dradis::Plugins::Settings::Adapters
|
2
|
+
class EncryptedConfiguration
|
3
|
+
attr_writer :config_path
|
4
|
+
|
5
|
+
def initialize(namespace)
|
6
|
+
@namespace = namespace
|
7
|
+
end
|
8
|
+
|
9
|
+
def delete(key)
|
10
|
+
if exists?(key)
|
11
|
+
configuration.config[@namespace].delete(key)
|
12
|
+
configuration.write(configuration.config.to_yaml)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def exists?(key)
|
17
|
+
!!configuration.config[@namespace]&.key?(key)
|
18
|
+
end
|
19
|
+
|
20
|
+
def read(key)
|
21
|
+
configuration.config.fetch(@namespace, {}).fetch(key, nil)
|
22
|
+
end
|
23
|
+
|
24
|
+
def write(key, value)
|
25
|
+
configuration.config[@namespace] ||= {}
|
26
|
+
configuration.config[@namespace][key] = value
|
27
|
+
configuration.write(configuration.config.to_yaml)
|
28
|
+
end
|
29
|
+
|
30
|
+
def key_path=(string_or_pathname)
|
31
|
+
@key_path = Pathname.new(string_or_pathname)
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
def config_path
|
36
|
+
@config_path ||= Rails.root.join('config', 'shared', 'dradis-plugins.yml.enc')
|
37
|
+
end
|
38
|
+
|
39
|
+
def configuration
|
40
|
+
@configuration ||= begin
|
41
|
+
create_key unless key_path.exist?
|
42
|
+
|
43
|
+
ActiveSupport::EncryptedConfiguration.new(
|
44
|
+
config_path: config_path, key_path: key_path,
|
45
|
+
env_key: 'RAILS_MASTER_KEY', raise_if_missing_key: true
|
46
|
+
)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def create_key
|
51
|
+
File.write(key_path, ActiveSupport::EncryptedConfiguration.generate_key)
|
52
|
+
end
|
53
|
+
|
54
|
+
def key_path
|
55
|
+
@key_path ||= Rails.root.join('config', 'shared', 'dradis-plugins.key')
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -2,10 +2,11 @@ module Dradis::Plugins
|
|
2
2
|
class Settings
|
3
3
|
attr_reader :namespace
|
4
4
|
|
5
|
-
def initialize(namespace)
|
5
|
+
def initialize(namespace, adapter: :db)
|
6
6
|
@namespace = namespace
|
7
7
|
@dirty_options ||= {}
|
8
8
|
@default_options ||= { enabled: true }.with_indifferent_access
|
9
|
+
assign_adapter(adapter)
|
9
10
|
end
|
10
11
|
|
11
12
|
def respond_to?(name)
|
@@ -16,14 +17,18 @@ module Dradis::Plugins
|
|
16
17
|
@default_options.except(:enabled).map do |key, value|
|
17
18
|
{
|
18
19
|
name: key.to_sym,
|
19
|
-
value: value =
|
20
|
+
value: value = dirty_or_stored_or_default(key.to_sym),
|
20
21
|
default: is_default?(key, value)
|
21
22
|
}
|
22
23
|
end.sort_by{ |o| o[:name] }
|
23
24
|
end
|
24
25
|
|
25
26
|
def save
|
26
|
-
@dirty_options.reject
|
27
|
+
@dirty_options.reject do |k, v|
|
28
|
+
v.present? && v == read(k)
|
29
|
+
end.each do |k, v|
|
30
|
+
write(k, v)
|
31
|
+
end
|
27
32
|
end
|
28
33
|
|
29
34
|
def update_settings(opts = {})
|
@@ -36,7 +41,7 @@ module Dradis::Plugins
|
|
36
41
|
def reset_defaults!
|
37
42
|
@dirty_options = {}
|
38
43
|
@default_options.each do |key, value|
|
39
|
-
|
44
|
+
delete(key) if exists?(key)
|
40
45
|
end
|
41
46
|
end
|
42
47
|
|
@@ -45,6 +50,8 @@ module Dradis::Plugins
|
|
45
50
|
end
|
46
51
|
|
47
52
|
private
|
53
|
+
attr_reader :adapter
|
54
|
+
delegate :delete, :exists?, :read, :write, to: :adapter
|
48
55
|
|
49
56
|
# ---------------------------------------------------- Method missing magic
|
50
57
|
def method_missing(name, *args, &blk)
|
@@ -53,39 +60,33 @@ module Dradis::Plugins
|
|
53
60
|
elsif name.to_s =~ /=$/
|
54
61
|
@dirty_options[$`.to_sym] = args.first
|
55
62
|
elsif @default_options.key?(name)
|
56
|
-
|
63
|
+
dirty_or_stored_or_default(name)
|
57
64
|
else
|
58
65
|
super
|
59
66
|
end
|
60
67
|
end
|
61
68
|
# --------------------------------------------------- /Method missing magic
|
62
69
|
|
63
|
-
def
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
Configuration.where(name: namespaced_key(key)).first.value rescue nil
|
70
|
+
def assign_adapter(name)
|
71
|
+
adapters = { db: Adapters::Db, encrypted_configuration: Adapters::EncryptedConfiguration }
|
72
|
+
if adapters.key?(name)
|
73
|
+
@adapter = adapters[name].new(namespace)
|
74
|
+
else
|
75
|
+
raise ArgumentError
|
76
|
+
end
|
71
77
|
end
|
72
78
|
|
73
79
|
# This method looks up in the configuration repository DB to see if the
|
74
80
|
# user has provided a value for the given setting. If not, the default
|
75
81
|
# value is returned.
|
76
|
-
def
|
82
|
+
def dirty_or_stored_or_default(key)
|
77
83
|
if @dirty_options.key?(key)
|
78
84
|
@dirty_options[key]
|
79
|
-
elsif
|
80
|
-
|
85
|
+
elsif exists?(key)
|
86
|
+
read(key)
|
81
87
|
else
|
82
88
|
@default_options[key]
|
83
89
|
end
|
84
90
|
end
|
85
|
-
|
86
|
-
# Builds namespaced key
|
87
|
-
def namespaced_key(key)
|
88
|
-
[self.namespace.to_s, key.to_s.underscore].join(":")
|
89
|
-
end
|
90
91
|
end
|
91
92
|
end
|
@@ -12,6 +12,7 @@ module Dradis
|
|
12
12
|
:options,
|
13
13
|
:plugin,
|
14
14
|
:project,
|
15
|
+
:state,
|
15
16
|
:template_service
|
16
17
|
)
|
17
18
|
|
@@ -22,10 +23,11 @@ module Dradis
|
|
22
23
|
def initialize(args={})
|
23
24
|
@options = args
|
24
25
|
|
25
|
-
@logger = args.fetch(:logger, Rails.logger)
|
26
|
-
@plugin = args[:plugin] || default_plugin
|
27
|
-
@project = args.key?(:project_id) ? Project.find(args[:project_id]) : nil
|
28
26
|
@default_user_id = args[:default_user_id] || -1
|
27
|
+
@logger = args.fetch(:logger, Rails.logger)
|
28
|
+
@plugin = args[:plugin] || default_plugin
|
29
|
+
@project = args.key?(:project_id) ? Project.find(args[:project_id]) : nil
|
30
|
+
@state = args.fetch(:state, :published)
|
29
31
|
|
30
32
|
@content_service = args.fetch(:content_service, default_content_service)
|
31
33
|
@template_service = args.fetch(:template_service, default_template_service)
|
@@ -46,7 +48,8 @@ module Dradis
|
|
46
48
|
@content ||= Dradis::Plugins::ContentService::Base.new(
|
47
49
|
logger: logger,
|
48
50
|
plugin: plugin,
|
49
|
-
project: project
|
51
|
+
project: project,
|
52
|
+
state: state
|
50
53
|
)
|
51
54
|
end
|
52
55
|
|
data/lib/dradis/plugins.rb
CHANGED
@@ -84,6 +84,8 @@ require 'dradis/plugins/upload'
|
|
84
84
|
# Common functionality
|
85
85
|
require 'dradis/plugins/configurable'
|
86
86
|
require 'dradis/plugins/settings'
|
87
|
+
require 'dradis/plugins/settings/adapters/db'
|
88
|
+
require 'dradis/plugins/settings/adapters/encrypted_configuration'
|
87
89
|
require 'dradis/plugins/templates'
|
88
90
|
require 'dradis/plugins/thor'
|
89
91
|
require 'dradis/plugins/thor_helper'
|
data/spec/engine_spec.rb
CHANGED
@@ -13,11 +13,14 @@ describe Dradis::Plugins::Base do
|
|
13
13
|
|
14
14
|
describe '#enabled?' do
|
15
15
|
it 'returns default value' do
|
16
|
-
expect(TestEngine.enabled?).to eq(
|
16
|
+
expect(TestEngine.enabled?).to eq(true)
|
17
17
|
end
|
18
18
|
end
|
19
19
|
describe '#enable!' do
|
20
20
|
it 'sets enabled to true' do
|
21
|
+
TestEngine.settings.enabled = false
|
22
|
+
TestEngine.settings.save
|
23
|
+
|
21
24
|
expect { TestEngine.enable! }.to change {
|
22
25
|
TestEngine.enabled?
|
23
26
|
}.from(false).to(true)
|
@@ -25,7 +28,9 @@ describe Dradis::Plugins::Base do
|
|
25
28
|
end
|
26
29
|
describe '#disable!' do
|
27
30
|
it 'sets enabled to false' do
|
28
|
-
TestEngine.
|
31
|
+
TestEngine.settings.enabled = true
|
32
|
+
TestEngine.settings.save
|
33
|
+
|
29
34
|
expect { TestEngine.disable! }.to change {
|
30
35
|
TestEngine.enabled?
|
31
36
|
}.from(true).to(false)
|
@@ -20,7 +20,7 @@ describe Dradis::Plugins::ContentService::Boards do
|
|
20
20
|
node = create(:node, project: project)
|
21
21
|
node_board = create(:board, node: node, project: project)
|
22
22
|
|
23
|
-
boards = service.
|
23
|
+
boards = service.project_boards
|
24
24
|
|
25
25
|
expect(boards).to include(board)
|
26
26
|
expect(boards).to_not include(node_board)
|
@@ -0,0 +1,29 @@
|
|
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,11 +1,11 @@
|
|
1
1
|
require 'rails_helper'
|
2
2
|
|
3
|
-
# These specs are coming from engines/dradispro-rules/spec/content_service_spec.rb
|
4
3
|
# To run, execute from Dradis main app folder:
|
5
4
|
# bin/rspec [dradis-plugins path]/spec/lib/dradis/plugins/content_service/issues_spec.rb
|
6
5
|
|
7
|
-
describe
|
8
|
-
let(:plugin)
|
6
|
+
describe 'Issues content service' do
|
7
|
+
let(:plugin) { Dradis::Plugins::Nessus }
|
8
|
+
let(:plugin_id) { '111' }
|
9
9
|
let(:project) { create(:project) }
|
10
10
|
let(:service) do
|
11
11
|
Dradis::Plugins::ContentService::Base.new(
|
@@ -17,47 +17,39 @@ describe Dradis::Plugins::ContentService::Base do
|
|
17
17
|
|
18
18
|
describe 'Issues' do
|
19
19
|
let(:create_issue) do
|
20
|
-
service.
|
20
|
+
service.create_issue(text: "#[Title]#\nTest Issue\n", id: plugin_id, state: :ready_for_review)
|
21
21
|
end
|
22
22
|
|
23
|
-
# Remember: even though we're calling create_issue_without_callback,
|
24
|
-
# that method will still call issue_cache_with_callback internally.
|
25
|
-
# So when we store an issue in the issue_cache/finding_cache below,
|
26
|
-
# it's being stored within an instance of FindingCache, which
|
27
|
-
# automatically wraps Issues in Findings.
|
28
|
-
|
29
23
|
describe 'when the issue already exists in the cache' do
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
it "doesn't create a new issue" do
|
34
|
-
expect{create_issue}.not_to change{Issue.count}
|
24
|
+
before do
|
25
|
+
issue = create(:issue, text: "#[Title]#\nTest Issue\n", id: plugin_id)
|
26
|
+
service.issue_cache.store("nessus-#{plugin_id}", issue)
|
35
27
|
end
|
36
28
|
|
37
|
-
it '
|
38
|
-
|
39
|
-
expect(finding).to be_a(Finding)
|
40
|
-
expect(finding).to eq Finding.from_issue(existing_issue)
|
29
|
+
it 'does not create a new issue' do
|
30
|
+
expect { create_issue }.not_to change { Issue.count }
|
41
31
|
end
|
42
32
|
end
|
43
33
|
|
44
34
|
describe "when the issue doesn't already exist in the cache" do
|
45
35
|
it "creates a new Issue containing 'plugin' and 'plugin_id'" do
|
46
36
|
new_issue = nil
|
47
|
-
|
48
|
-
expect
|
49
|
-
expect(new_issue.
|
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}/)
|
50
41
|
end
|
42
|
+
end
|
51
43
|
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
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)
|
56
49
|
end
|
57
50
|
|
58
|
-
it '
|
59
|
-
|
60
|
-
expect(cache[cache_key]).to eq finding
|
51
|
+
it 'returns only the published issues' do
|
52
|
+
expect(service.all_issues.to_a).to match_array(@published_issues)
|
61
53
|
end
|
62
54
|
end
|
63
55
|
end
|
@@ -0,0 +1,112 @@
|
|
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
|
data/spec/settings_spec.rb
CHANGED
metadata
CHANGED
@@ -1,43 +1,43 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dradis-plugins
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 4.
|
4
|
+
version: 4.9.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Daniel Martin
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-
|
11
|
+
date: 2023-05-31 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - "
|
17
|
+
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '
|
19
|
+
version: '0'
|
20
20
|
type: :development
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- - "
|
24
|
+
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '
|
26
|
+
version: '0'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: rake
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- - "
|
31
|
+
- - ">="
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: '
|
33
|
+
version: '0'
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- - "
|
38
|
+
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: '
|
40
|
+
version: '0'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: rspec-rails
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -94,6 +94,8 @@ files:
|
|
94
94
|
- lib/dradis/plugins/import/filters/base.rb
|
95
95
|
- lib/dradis/plugins/import/result.rb
|
96
96
|
- lib/dradis/plugins/settings.rb
|
97
|
+
- lib/dradis/plugins/settings/adapters/db.rb
|
98
|
+
- lib/dradis/plugins/settings/adapters/encrypted_configuration.rb
|
97
99
|
- lib/dradis/plugins/template_service.rb
|
98
100
|
- lib/dradis/plugins/templates.rb
|
99
101
|
- lib/dradis/plugins/thor.rb
|
@@ -106,7 +108,9 @@ files:
|
|
106
108
|
- spec/engine_spec.rb
|
107
109
|
- spec/internal/log/test.log
|
108
110
|
- spec/lib/dradis/plugins/content_service/boards_spec.rb
|
111
|
+
- spec/lib/dradis/plugins/content_service/content_blocks_spec.rb
|
109
112
|
- spec/lib/dradis/plugins/content_service/issues_spec.rb
|
113
|
+
- spec/lib/dradis/plugins/settings/adapters/encrypted_configuration_spec.rb
|
110
114
|
- spec/settings_spec.rb
|
111
115
|
- spec/spec_helper.rb
|
112
116
|
homepage: http://dradisframework.org
|
@@ -136,6 +140,8 @@ test_files:
|
|
136
140
|
- spec/engine_spec.rb
|
137
141
|
- spec/internal/log/test.log
|
138
142
|
- spec/lib/dradis/plugins/content_service/boards_spec.rb
|
143
|
+
- spec/lib/dradis/plugins/content_service/content_blocks_spec.rb
|
139
144
|
- spec/lib/dradis/plugins/content_service/issues_spec.rb
|
145
|
+
- spec/lib/dradis/plugins/settings/adapters/encrypted_configuration_spec.rb
|
140
146
|
- spec/settings_spec.rb
|
141
147
|
- spec/spec_helper.rb
|