From 639e2edbbb420e7c1885d879649389eda733c138 Mon Sep 17 00:00:00 2001 From: Brian Pearce Date: Fri, 18 Oct 2019 16:01:24 +0200 Subject: [PATCH] Refactor thor tasks Break them into different files for easier management. --- Thorfile | 1 + lib/tasks/thor/logs.rb | 14 ++++ lib/tasks/thor/reset.rb | 51 +++++++++++++ lib/tasks/thor/setup.rb | 94 ++++++++++++++++++++++++ lib/tasks/thorfile.rb | 158 ---------------------------------------- 5 files changed, 160 insertions(+), 158 deletions(-) create mode 100644 lib/tasks/thor/logs.rb create mode 100644 lib/tasks/thor/reset.rb create mode 100644 lib/tasks/thor/setup.rb diff --git a/Thorfile b/Thorfile index f815ac619..1be04bf80 100644 --- a/Thorfile +++ b/Thorfile @@ -7,6 +7,7 @@ require 'config/environment' # add the dradis core tasks, and define the namespaces for import, export, and # upload tasks require File.expand_path('../lib/tasks/thorfile', __FILE__) +Dir['./lib/tasks/thor/**/*.rb'].sort.each { |f| require f } # a gemified plugin can also add Thor tasks puts 'Loaded add-ons:' diff --git a/lib/tasks/thor/logs.rb b/lib/tasks/thor/logs.rb new file mode 100644 index 000000000..17b2d68eb --- /dev/null +++ b/lib/tasks/thor/logs.rb @@ -0,0 +1,14 @@ +class DradisTasks < Thor + class Logs < Thor + namespace 'dradis:logs' + + desc 'clean DAYS', 'delete all logs older than DAYS days (default 7)' + def clean(days=7) + puts 'Clearing old Logs...' + logs = Log.where('created_at < (?)', days.to_i.days.ago) + count = logs.count + logs.destroy_all + puts "Deleted #{count} Log#{"s" if count != 1}" + end + end +end diff --git a/lib/tasks/thor/reset.rb b/lib/tasks/thor/reset.rb new file mode 100644 index 000000000..58a77c592 --- /dev/null +++ b/lib/tasks/thor/reset.rb @@ -0,0 +1,51 @@ +class DradisTasks < Thor + class Reset < Thor + namespace 'dradis:reset' + + desc 'attachments', 'removes all attachments' + def attachments + print '** Deleting all attachments... ' + FileUtils.rm_rf(Dir.glob( Attachment::AttachmentPwd.join('*')) ) + puts(Dir.glob( Attachment::AttachmentPwd.join('*')).empty? ? '[ DONE ]' : '[ FAILED ]') + end + + desc 'database', 'removes all data from a dradis repository, except configurations' + def database + return if defined?(Dradis::Pro) + + require 'config/environment' + print '** Cleaning database... ' + + Rails.application.eager_load! + (ApplicationRecord.descendants - [Configuration]).each do |model| + ActiveRecord::Base.connection.execute("DELETE FROM #{model.table_name}") + ActiveRecord::Base.connection.execute("DELETE FROM sqlite_sequence WHERE name='#{model.table_name}'") + end + + puts '[ DONE ]' + end + + desc 'logs', 'removes all log files' + def logs + print '** Deleting all log files... ' + FileUtils.rm_rf(Dir.glob('log/*.log')) + puts(Dir.glob('log/*.log').empty? ? '[ DONE ]' : '[ FAILED ]') + end + + desc 'password', 'Set a new shared password to access the web interface' + def password() + require 'config/environment' + + say 'Changing password for Dradis server.' + password = ask 'Enter new Dradis password:' + confirmation = ask 'Retype new Dradis password:' + + if !password.blank? && password == confirmation + Configuration.find_or_create_by(name: 'admin:password').update_attribute(:value, ::BCrypt::Password.create(password)) + say('Password Changed.', Thor::Shell::Color::GREEN) + else + say('Passwords do not match. Password Unchanged.', Thor::Shell::Color::RED) + end + end + end +end diff --git a/lib/tasks/thor/setup.rb b/lib/tasks/thor/setup.rb new file mode 100644 index 000000000..ccc570c44 --- /dev/null +++ b/lib/tasks/thor/setup.rb @@ -0,0 +1,94 @@ +class DradisTasks < Thor + class Setup < Thor + include Thor::Actions + include ::Rails.application.config.dradis.thor_helper_module + + namespace 'dradis:setup' + + def self.source_root + File.join(File.dirname(__FILE__), 'templates') + end + + desc 'configure', 'Creates the Dradis configuration files from their templates (see config/*.yml.template)' + def configure + # init the config files + init_all = false + Dir['config/*.template'].each do |template| + config = File.join( 'config', File.basename(template, '.template') ) + if !(File.exists?( config )) + if (init_all) + puts "Initilizing #{config}..." + FileUtils.cp(template, config) + else + puts "The config file [#{template}] was found not to be ready to use." + puts 'Do you want to initialize it? [y]es | [N]o | initialize [a]ll' + response = STDIN.gets.chomp.downcase + response = 'Y' if ( response.empty? || !['y', 'n', 'a'].include?(response) ) + + if response == 'n' + next + else + puts "Initilizing #{config}..." + FileUtils.cp(template, config) + if (response == 'a') + init_all = true + end + end + end + end + end + end + + desc 'migrate', 'ensures the database schema is up-to-date' + def migrate + require 'config/environment' + + print '** Checking database migrations... ' + ActiveRecord::Migrator.migrate('db/migrate/', nil) + puts '[ DONE ]' + end + + desc 'seed', 'adds initial values to the database (i.e., categories and configurations)' + def seed + require 'config/environment' + + print '** Seeding database... ' + require 'db/seeds' + puts '[ DONE ]' + end + + desc 'welcome', 'adds initial content to the repo for demonstration purposes' + def welcome + # --------------------------------------------------------- Note template + if NoteTemplate.pwd.exist? + say 'Note templates folder already exists. Skipping.' + else + template 'note.txt', NoteTemplate.pwd.join('basic_fields.txt') + end + + # ----------------------------------------------------------- Methodology + if Methodology.pwd.exist? + say 'Methodology templates folder already exists. Skipping.' + else + template 'methodology.xml', Methodology.pwd.join('owasp2017.xml') + end + + # ---------------------------------------------------------- Project data + detect_and_set_project_scope + + task_options.merge!({ + plugin: Dradis::Plugins::Projects::Upload::Template, + default_user_id: 1 + }) + + importer = Dradis::Plugins::Projects::Upload::Template::Importer.new(task_options) + importer.import(file: File.expand_path('../templates/project.xml', __FILE__)) + + # dradis:reset:database truncates the tables and resets the :id column so + # we know the right node ID we're going to get based on the project.xml + # structure. + Dir.mkdir(Attachment.pwd.join('5')) + template 'command-01.png', Attachment.pwd.join('5/command-01.png') + end + end +end diff --git a/lib/tasks/thorfile.rb b/lib/tasks/thorfile.rb index b1aef35da..c24de728b 100644 --- a/lib/tasks/thorfile.rb +++ b/lib/tasks/thorfile.rb @@ -56,165 +56,7 @@ def version puts Core::Pro::VERSION::string end - class Import < Thor; end class Export < Thor; end class Upload < Thor; end - - - class Setup < Thor - include Thor::Actions - include ::Rails.application.config.dradis.thor_helper_module - - namespace 'dradis:setup' - - def self.source_root - File.join(File.dirname(__FILE__), 'templates') - end - - desc 'configure', 'Creates the Dradis configuration files from their templates (see config/*.yml.template)' - def configure - # init the config files - init_all = false - Dir['config/*.template'].each do |template| - config = File.join( 'config', File.basename(template, '.template') ) - if !(File.exists?( config )) - if (init_all) - puts "Initilizing #{config}..." - FileUtils.cp(template, config) - else - puts "The config file [#{template}] was found not to be ready to use." - puts 'Do you want to initialize it? [y]es | [N]o | initialize [a]ll' - response = STDIN.gets.chomp.downcase - response = 'Y' if ( response.empty? || !['y', 'n', 'a'].include?(response) ) - - if response == 'n' - next - else - puts "Initilizing #{config}..." - FileUtils.cp(template, config) - if (response == 'a') - init_all = true - end - end - end - end - end - end - - desc 'migrate', 'ensures the database schema is up-to-date' - def migrate - require 'config/environment' - - print '** Checking database migrations... ' - ActiveRecord::Migrator.migrate('db/migrate/', nil) - puts '[ DONE ]' - end - - desc 'seed', 'adds initial values to the database (i.e., categories and configurations)' - def seed - require 'config/environment' - - print '** Seeding database... ' - require 'db/seeds' - puts '[ DONE ]' - end - - desc 'welcome', 'adds initial content to the repo for demonstration purposes' - def welcome - # --------------------------------------------------------- Note template - if NoteTemplate.pwd.exist? - say 'Note templates folder already exists. Skipping.' - else - template 'note.txt', NoteTemplate.pwd.join('basic_fields.txt') - end - - # ----------------------------------------------------------- Methodology - if Methodology.pwd.exist? - say 'Methodology templates folder already exists. Skipping.' - else - template 'methodology.xml', Methodology.pwd.join('owasp2017.xml') - end - - # ---------------------------------------------------------- Project data - detect_and_set_project_scope - - task_options.merge!({ - plugin: Dradis::Plugins::Projects::Upload::Template, - default_user_id: 1 - }) - - importer = Dradis::Plugins::Projects::Upload::Template::Importer.new(task_options) - importer.import(file: File.expand_path('../templates/project.xml', __FILE__)) - - # dradis:reset:database truncates the tables and resets the :id column so - # we know the right node ID we're going to get based on the project.xml - # structure. - Dir.mkdir(Attachment.pwd.join('5')) - template 'command-01.png', Attachment.pwd.join('5/command-01.png') - end - end - - class Logs < Thor - namespace 'dradis:logs' - - desc 'clean DAYS', 'delete all logs older than DAYS days (default 7)' - def clean(days=7) - puts 'Clearing old Logs...' - logs = Log.where('created_at < (?)', days.to_i.days.ago) - count = logs.count - logs.destroy_all - puts "Deleted #{count} Log#{"s" if count != 1}" - end - end - - class Reset < Thor - namespace 'dradis:reset' - - desc 'attachments', 'removes all attachments' - def attachments - print '** Deleting all attachments... ' - FileUtils.rm_rf(Dir.glob( Attachment::AttachmentPwd.join('*')) ) - puts(Dir.glob( Attachment::AttachmentPwd.join('*')).empty? ? '[ DONE ]' : '[ FAILED ]') - end - - desc 'database', 'removes all data from a dradis repository, except configurations' - def database - return if defined?(Dradis::Pro) - - require 'config/environment' - print '** Cleaning database... ' - - Rails.application.eager_load! - (ApplicationRecord.descendants - [Configuration]).each do |model| - ActiveRecord::Base.connection.execute("DELETE FROM #{model.table_name}") - ActiveRecord::Base.connection.execute("DELETE FROM sqlite_sequence WHERE name='#{model.table_name}'") - end - - puts '[ DONE ]' - end - - desc 'logs', 'removes all log files' - def logs - print '** Deleting all log files... ' - FileUtils.rm_rf(Dir.glob('log/*.log')) - puts(Dir.glob('log/*.log').empty? ? '[ DONE ]' : '[ FAILED ]') - end - - desc 'password', 'Set a new shared password to access the web interface' - def password() - require 'config/environment' - - say 'Changing password for Dradis server.' - password = ask 'Enter new Dradis password:' - confirmation = ask 'Retype new Dradis password:' - - if !password.blank? && password == confirmation - Configuration.find_or_create_by(name: 'admin:password').update_attribute(:value, ::BCrypt::Password.create(password)) - say('Password Changed.', Thor::Shell::Color::GREEN) - else - say('Passwords do not match. Password Unchanged.', Thor::Shell::Color::RED) - end - end - end end