dradis-plugins 3.18.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 +7 -0
- data/.gitignore +11 -0
- data/.rspec +2 -0
- data/CHANGELOG.md +77 -0
- data/CONTRIBUTING.md +3 -0
- data/Gemfile +10 -0
- data/LICENSE +339 -0
- data/README.md +31 -0
- data/Rakefile +2 -0
- data/app/controllers/concerns/dradis/plugins/persistent_permissions.rb +43 -0
- data/app/controllers/dradis/plugins/export/base_controller.rb +18 -0
- data/dradis-plugins.gemspec +31 -0
- data/lib/dradis-plugins.rb +1 -0
- data/lib/dradis/plugins.rb +80 -0
- data/lib/dradis/plugins/base.rb +45 -0
- data/lib/dradis/plugins/configurable.rb +26 -0
- data/lib/dradis/plugins/content_service/base.rb +26 -0
- data/lib/dradis/plugins/content_service/boards.rb +32 -0
- data/lib/dradis/plugins/content_service/categories.rb +9 -0
- data/lib/dradis/plugins/content_service/content_blocks.rb +44 -0
- data/lib/dradis/plugins/content_service/core.rb +53 -0
- data/lib/dradis/plugins/content_service/evidence.rb +36 -0
- data/lib/dradis/plugins/content_service/issues.rb +94 -0
- data/lib/dradis/plugins/content_service/nodes.rb +88 -0
- data/lib/dradis/plugins/content_service/notes.rb +43 -0
- data/lib/dradis/plugins/content_service/properties.rb +9 -0
- data/lib/dradis/plugins/engine.rb +15 -0
- data/lib/dradis/plugins/export.rb +1 -0
- data/lib/dradis/plugins/export/base.rb +57 -0
- data/lib/dradis/plugins/gem_version.rb +17 -0
- data/lib/dradis/plugins/import.rb +3 -0
- data/lib/dradis/plugins/import/filters.rb +51 -0
- data/lib/dradis/plugins/import/filters/base.rb +16 -0
- data/lib/dradis/plugins/import/result.rb +12 -0
- data/lib/dradis/plugins/settings.rb +91 -0
- data/lib/dradis/plugins/template_service.rb +104 -0
- data/lib/dradis/plugins/templates.rb +57 -0
- data/lib/dradis/plugins/thor.rb +30 -0
- data/lib/dradis/plugins/thor_helper.rb +29 -0
- data/lib/dradis/plugins/upload.rb +10 -0
- data/lib/dradis/plugins/upload/base.rb +57 -0
- data/lib/dradis/plugins/upload/field_processor.rb +35 -0
- data/lib/dradis/plugins/upload/importer.rb +78 -0
- data/lib/dradis/plugins/version.rb +11 -0
- data/spec/internal/log/test.log +0 -0
- data/spec/lib/dradis/plugins/content_service/boards_spec.rb +45 -0
- data/spec/lib/dradis/plugins/content_service/issues_spec.rb +64 -0
- data/spec/settings_spec.rb +88 -0
- data/spec/spec_helper.rb +2 -0
- metadata +138 -0
data/README.md
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
# Plugin manager for the Dradis Framework
|
2
|
+
|
3
|
+
[](http://travis-ci.org/dradis/dradis-plugins) [](https://codeclimate.com/github/dradis/dradis-plugins.png)
|
4
|
+
|
5
|
+
This gem contains the base classes needed to manage the plugins in Dradis.
|
6
|
+
|
7
|
+
The Dradis 3 gemified plugin Engines need to include Dradis::Plugins::Base which is defined in this class.
|
8
|
+
|
9
|
+
Warning, we may end up merging this gem with Dradis::Core!!
|
10
|
+
|
11
|
+
The add-on requires [Dradis CE](https://dradisframework.org/) > 3.0, or [Dradis Pro](https://dradisframework.com/pro/).
|
12
|
+
|
13
|
+
|
14
|
+
## More information
|
15
|
+
|
16
|
+
See the Dradis Framework's [README.md](https://github.com/dradis/dradisframework/blob/master/README.md)
|
17
|
+
|
18
|
+
|
19
|
+
## Contributing
|
20
|
+
|
21
|
+
See the Dradis Framework's [CONTRIBUTING.md](https://github.com/dradis/dradisframework/blob/master/CONTRIBUTING.md)
|
22
|
+
|
23
|
+
|
24
|
+
## License
|
25
|
+
|
26
|
+
Dradis Framework and all its components are released under [GNU General Public License version 2.0](http://www.gnu.org/licenses/old-licenses/gpl-2.0.html) as published by the Free Software Foundation and appearing in the file LICENSE included in the packaging of this file.
|
27
|
+
|
28
|
+
|
29
|
+
## Feature requests and bugs
|
30
|
+
|
31
|
+
Please use the [Dradis Framework issue tracker](https://github.com/dradis/dradis-ce/issues) for add-on improvements and bug reports.
|
data/Rakefile
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
module Dradis
|
2
|
+
module Plugins
|
3
|
+
module PersistentPermissions
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
def update
|
7
|
+
@user = User.authors.find(params[:id])
|
8
|
+
|
9
|
+
Permission.transaction do
|
10
|
+
Permission.where(component: self.class.component_name, user_id: params[:id]).destroy_all
|
11
|
+
|
12
|
+
permissions_params[:permissions]&.each do |permission|
|
13
|
+
# Validate the permission being created is a valid value
|
14
|
+
next unless self.class.permissions_validation.call(permission) if self.class.permissions_validation
|
15
|
+
|
16
|
+
Permission.create!(
|
17
|
+
component: self.class.component_name,
|
18
|
+
name: permission,
|
19
|
+
user_id: params[:id]
|
20
|
+
)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
redirect_to main_app.edit_admin_user_permissions_path(params[:id]), notice: "#{@user.name}'s permissions have been updated."
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def permissions_params
|
30
|
+
params.require(self.class.component_name).permit(permissions: [])
|
31
|
+
end
|
32
|
+
|
33
|
+
class_methods do
|
34
|
+
attr_accessor :component_name, :permissions_validation
|
35
|
+
|
36
|
+
def permissible_tool(component_name, opts = {})
|
37
|
+
self.component_name = component_name
|
38
|
+
self.permissions_validation = opts[:validation]
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Dradis
|
2
|
+
module Plugins
|
3
|
+
module Export
|
4
|
+
class BaseController < Rails.application.config.dradis.base_export_controller_class_name.to_s.constantize
|
5
|
+
|
6
|
+
protected
|
7
|
+
|
8
|
+
# Protected: allows export plugins to access the options sent from the
|
9
|
+
# framework via the session object (see Export#create).
|
10
|
+
#
|
11
|
+
# Returns a Hash with indifferent access.
|
12
|
+
def export_options
|
13
|
+
@export_options ||= session[:export_manager].with_indifferent_access
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,31 @@
|
|
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.email = ['etd@nomejortu.com']
|
17
|
+
spec.homepage = 'http://dradisframework.org'
|
18
|
+
|
19
|
+
spec.files = `git ls-files`.split($\)
|
20
|
+
spec.executables = spec.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
21
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
22
|
+
|
23
|
+
spec.add_development_dependency 'bundler', '~> 1.6'
|
24
|
+
spec.add_development_dependency 'rake', '~> 10.0'
|
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
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
require 'dradis/plugins'
|
@@ -0,0 +1,80 @@
|
|
1
|
+
module Dradis
|
2
|
+
module Plugins
|
3
|
+
class << self
|
4
|
+
@@extensions = []
|
5
|
+
|
6
|
+
# Returns an array of modules representing currently registered Dradis Plugins / engines
|
7
|
+
#
|
8
|
+
# Example:
|
9
|
+
# Dradis::Core::Plugins.list => [Dradis::Core, Dradis::Frontend]
|
10
|
+
def list
|
11
|
+
@@extensions
|
12
|
+
end
|
13
|
+
|
14
|
+
# Filters the list of plugins and only returns those that provide the
|
15
|
+
# requested feature.
|
16
|
+
def with_feature(feature)
|
17
|
+
@@extensions.select do |plugin|
|
18
|
+
# engine = "#{plugin}::Engine".constantize
|
19
|
+
plugin.provides?(feature)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
# Register a plugin with the framework
|
24
|
+
#
|
25
|
+
# Example:
|
26
|
+
# Dradis::Core::Plugins.register(Dradis::Core)
|
27
|
+
def register(const)
|
28
|
+
return if registered?(const)
|
29
|
+
|
30
|
+
validate_plugin!(const)
|
31
|
+
|
32
|
+
@@extensions << const
|
33
|
+
end
|
34
|
+
|
35
|
+
# Unregister a plugin from the framework
|
36
|
+
#
|
37
|
+
# Example:
|
38
|
+
# Dradis::Core::Plugins.unregister(Dradis::Core)
|
39
|
+
def unregister(const)
|
40
|
+
@@extensions.delete(const)
|
41
|
+
end
|
42
|
+
|
43
|
+
# Returns true if a plugin is currently registered with the framework
|
44
|
+
#
|
45
|
+
# Example:
|
46
|
+
# Dradis::Core::Plugins.registered?(Dradis::Core)
|
47
|
+
def registered?(const)
|
48
|
+
@@extensions.include?(const)
|
49
|
+
end
|
50
|
+
|
51
|
+
private
|
52
|
+
|
53
|
+
# Use this to ensure the Extension conforms with some expected interface
|
54
|
+
def validate_plugin!(const)
|
55
|
+
# unless const.respond_to?(:root) && const.root.is_a?(Pathname)
|
56
|
+
# raise InvalidEngineError, "Engine must define a root accessor that returns a pathname to its root"
|
57
|
+
# end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
|
64
|
+
require 'dradis/plugins/engine'
|
65
|
+
require 'dradis/plugins/version'
|
66
|
+
|
67
|
+
require 'dradis/plugins/content_service/base'
|
68
|
+
require 'dradis/plugins/template_service'
|
69
|
+
|
70
|
+
require 'dradis/plugins/base'
|
71
|
+
require 'dradis/plugins/export'
|
72
|
+
require 'dradis/plugins/import'
|
73
|
+
require 'dradis/plugins/upload'
|
74
|
+
|
75
|
+
# Common functionality
|
76
|
+
require 'dradis/plugins/configurable'
|
77
|
+
require 'dradis/plugins/settings'
|
78
|
+
require 'dradis/plugins/templates'
|
79
|
+
require 'dradis/plugins/thor'
|
80
|
+
require 'dradis/plugins/thor_helper'
|
@@ -0,0 +1,45 @@
|
|
1
|
+
module Dradis
|
2
|
+
module Plugins
|
3
|
+
module Base
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
included do
|
7
|
+
# mattr_accessor :plugin_name
|
8
|
+
|
9
|
+
@features = []
|
10
|
+
@name = 'Use plugin_info(args) with :name to provide a name for this plugin.'
|
11
|
+
Plugins::register(self)
|
12
|
+
|
13
|
+
# Extend the engine with other functionality
|
14
|
+
include Dradis::Plugins::Configurable
|
15
|
+
include Dradis::Plugins::Templates
|
16
|
+
include Dradis::Plugins::Thor
|
17
|
+
end
|
18
|
+
|
19
|
+
module ClassMethods
|
20
|
+
def description(new_description)
|
21
|
+
@description = new_description
|
22
|
+
end
|
23
|
+
|
24
|
+
def plugin_description
|
25
|
+
@description ||= "This plugin doesn't provide a :description"
|
26
|
+
end
|
27
|
+
|
28
|
+
def plugin_name
|
29
|
+
@plugin_name ||= self.name.split('::')[-2].underscore.to_sym
|
30
|
+
end
|
31
|
+
|
32
|
+
def provides(*list)
|
33
|
+
@features = list
|
34
|
+
if list.include?(:upload)
|
35
|
+
include Dradis::Plugins::Upload::Base
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def provides?(feature)
|
40
|
+
@features.include?(feature)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module Dradis::Plugins
|
2
|
+
module Configurable
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
module ClassMethods
|
6
|
+
delegate :settings, to: :instance
|
7
|
+
|
8
|
+
def settings_namespace
|
9
|
+
@settings_namespace || plugin_name
|
10
|
+
end
|
11
|
+
|
12
|
+
def addon_settings(namespace = nil, &block)
|
13
|
+
@settings_namespace = namespace if namespace
|
14
|
+
yield self if block_given?
|
15
|
+
end
|
16
|
+
|
17
|
+
def instance
|
18
|
+
@instance ||= new
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def settings
|
23
|
+
@settings ||= Dradis::Plugins::Settings.new(self.class.settings_namespace)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'dradis/plugins/content_service/boards'
|
2
|
+
require 'dradis/plugins/content_service/categories'
|
3
|
+
require 'dradis/plugins/content_service/content_blocks'
|
4
|
+
require 'dradis/plugins/content_service/core'
|
5
|
+
require 'dradis/plugins/content_service/evidence'
|
6
|
+
require 'dradis/plugins/content_service/issues'
|
7
|
+
require 'dradis/plugins/content_service/nodes'
|
8
|
+
require 'dradis/plugins/content_service/notes'
|
9
|
+
require 'dradis/plugins/content_service/properties'
|
10
|
+
|
11
|
+
module Dradis::Plugins::ContentService
|
12
|
+
class Base
|
13
|
+
include Core
|
14
|
+
|
15
|
+
include Boards
|
16
|
+
include Categories
|
17
|
+
include ContentBlocks if defined?(Dradis::Pro)
|
18
|
+
include Evidence
|
19
|
+
include Issues
|
20
|
+
include Nodes
|
21
|
+
include Notes
|
22
|
+
include Properties if defined?(Dradis::Pro)
|
23
|
+
|
24
|
+
ActiveSupport.run_load_hooks(:content_service, self)
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module Dradis::Plugins::ContentService
|
2
|
+
module Boards
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
def all_boards
|
6
|
+
project.boards
|
7
|
+
end
|
8
|
+
|
9
|
+
def project_boards
|
10
|
+
project.methodology_library.boards
|
11
|
+
end
|
12
|
+
|
13
|
+
def create_board(args={})
|
14
|
+
name = args.fetch(:name, default_board_name)
|
15
|
+
node_id = args.fetch(:node_id, default_node_id)
|
16
|
+
Board.create(
|
17
|
+
name: name,
|
18
|
+
node_id: node_id,
|
19
|
+
project: project
|
20
|
+
)
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
def default_board_name
|
25
|
+
"create_board() invoked by #{plugin} without a :name parameter"
|
26
|
+
end
|
27
|
+
|
28
|
+
def default_node_id
|
29
|
+
project.methodology_library.id
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module Dradis::Plugins::ContentService
|
2
|
+
module ContentBlocks
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
def all_content_blocks
|
6
|
+
project.content_blocks
|
7
|
+
end
|
8
|
+
|
9
|
+
def create_content_block(args={})
|
10
|
+
block_group = args.fetch(:block_group, default_content_block_group)
|
11
|
+
content = args.fetch(:content, default_content_block_content)
|
12
|
+
user_id = args.fetch(:user_id)
|
13
|
+
|
14
|
+
content_block = ContentBlock.new(
|
15
|
+
content: content,
|
16
|
+
block_group: block_group,
|
17
|
+
project_id: project.id,
|
18
|
+
user_id: user_id
|
19
|
+
)
|
20
|
+
|
21
|
+
if content_block.valid?
|
22
|
+
content_block.save
|
23
|
+
else
|
24
|
+
try_rescue_from_length_validation(
|
25
|
+
model: content_block,
|
26
|
+
field: :content,
|
27
|
+
text: content,
|
28
|
+
msg: 'Error in create_content_block()',
|
29
|
+
tail: plugin_details
|
30
|
+
)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
def default_content_block_content
|
37
|
+
"create_content_block() invoked by #{plugin} without a :content parameter"
|
38
|
+
end
|
39
|
+
|
40
|
+
def default_content_block_group
|
41
|
+
"create_content_block() invoked by #{plugin} without a :block_group parameter"
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
module Dradis::Plugins::ContentService
|
2
|
+
module Core
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
included do
|
6
|
+
attr_accessor :logger, :plugin, :project
|
7
|
+
end
|
8
|
+
|
9
|
+
# ----------------------------------------------------------- Initializer
|
10
|
+
#
|
11
|
+
|
12
|
+
# @option plugin [Class] the 'wrapper' module of a plugin, e.g.
|
13
|
+
# Dradis::Plugins::Nessus
|
14
|
+
def initialize(args={})
|
15
|
+
@logger = args.fetch(:logger, Rails.logger)
|
16
|
+
@plugin = args.fetch(:plugin)
|
17
|
+
@project = args[:project]
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def default_author
|
23
|
+
@default_author ||= "#{plugin::Engine.plugin_name.to_s.humanize} upload plugin"
|
24
|
+
end
|
25
|
+
|
26
|
+
def try_rescue_from_length_validation(args={})
|
27
|
+
model = args[:model]
|
28
|
+
field = args[:field]
|
29
|
+
text = args[:text]
|
30
|
+
msg = args[:msg]
|
31
|
+
tail = "..." + args[:tail].to_s
|
32
|
+
|
33
|
+
logger.error{ "Trying to rescue from a :length error" }
|
34
|
+
|
35
|
+
if model.errors[field]
|
36
|
+
# the plugin tried to store too much information
|
37
|
+
msg = "#[Title]#\nTruncation warning!\n\n"
|
38
|
+
msg << "#[Error]#\np(alert alert-error). The plugin tried to store content that was too big for the DB. Review the source to ensure no important data was lost.\n\n"
|
39
|
+
msg << text
|
40
|
+
model.send("#{field}=", msg.truncate(65300, omission: tail))
|
41
|
+
else
|
42
|
+
# bail
|
43
|
+
msg = "#[Title]#\n#{msg}\n\n"
|
44
|
+
msg << "#[Description]#\nbc. #{model.errors.inspect}\n\n"
|
45
|
+
model.send("#{field}=", msg)
|
46
|
+
end
|
47
|
+
if model.valid?
|
48
|
+
model.save
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
end
|