ceb8a0f5c2
MSP-10905 `Metasplot::Framework::Require.optionally` can be used to optionally require a library and then issue a warning if the require fails or run a block when it succeeds.
107 lines
3.0 KiB
Ruby
107 lines
3.0 KiB
Ruby
#
|
|
# Gems
|
|
#
|
|
|
|
require 'active_support/core_ext/module/introspection'
|
|
|
|
#
|
|
# Project
|
|
#
|
|
|
|
require 'metasploit/framework/command'
|
|
require 'metasploit/framework/parsed_options'
|
|
require 'metasploit/framework/require'
|
|
|
|
# Based on pattern used for lib/rails/commands in the railties gem.
|
|
class Metasploit::Framework::Command::Base
|
|
#
|
|
# Attributes
|
|
#
|
|
|
|
# @!attribute [r] application
|
|
# The Rails application for metasploit-framework.
|
|
#
|
|
# @return [Metasploit::Framework::Application]
|
|
attr_reader :application
|
|
|
|
# @!attribute [r] parsed_options
|
|
# The parsed options from the command line.
|
|
#
|
|
# @return (see parsed_options)
|
|
attr_reader :parsed_options
|
|
|
|
#
|
|
# Class Methods
|
|
#
|
|
|
|
# @note {require_environment!} should be called to load `config/application.rb` to so that the RAILS_ENV can be set
|
|
# from the command line options in `ARGV` prior to `Rails.env` being set.
|
|
# @note After returning, `Rails.application` will be defined and configured.
|
|
#
|
|
# Parses `ARGV` for command line arguments to configure the `Rails.application`.
|
|
#
|
|
# @return (see parsed_options)
|
|
def self.require_environment!
|
|
parsed_options = self.parsed_options
|
|
# RAILS_ENV must be set before requiring 'config/application.rb'
|
|
parsed_options.environment!
|
|
ARGV.replace(parsed_options.positional)
|
|
|
|
# @see https://github.com/rails/rails/blob/v3.2.17/railties/lib/rails/commands.rb#L39-L40
|
|
require Pathname.new(__FILE__).parent.parent.parent.parent.parent.join('config', 'application')
|
|
|
|
# have to configure before requiring environment because config/environment.rb calls initialize! and the initializers
|
|
# will use the configuration from the parsed options.
|
|
parsed_options.configure(Rails.application)
|
|
|
|
# support disabling the database
|
|
unless parsed_options.options.database.disable
|
|
Metasploit::Framework::Require.optionally_active_record_railtie
|
|
end
|
|
|
|
Rails.application.require_environment!
|
|
|
|
parsed_options
|
|
end
|
|
|
|
def self.parsed_options
|
|
parsed_options_class.new
|
|
end
|
|
|
|
def self.parsed_options_class
|
|
@parsed_options_class ||= parsed_options_class_name.constantize
|
|
end
|
|
|
|
def self.parsed_options_class_name
|
|
@parsed_options_class_name ||= "#{parent.parent}::ParsedOptions::#{name.demodulize}"
|
|
end
|
|
|
|
def self.start
|
|
parsed_options = require_environment!
|
|
new(application: Rails.application, parsed_options: parsed_options).start
|
|
end
|
|
|
|
#
|
|
# Instance Methods
|
|
#
|
|
|
|
# @param attributes [Hash{Symbol => ActiveSupport::OrderedOptions,Rails::Application}]
|
|
# @option attributes [Rails::Application] :application
|
|
# @option attributes [ActiveSupport::OrderedOptions] :parsed_options
|
|
# @raise [KeyError] if :application is not given
|
|
# @raise [KeyError] if :parsed_options is not given
|
|
def initialize(attributes={})
|
|
@application = attributes.fetch(:application)
|
|
@parsed_options = attributes.fetch(:parsed_options)
|
|
end
|
|
|
|
# @abstract Use {#application} to start this command.
|
|
#
|
|
# Starts this command.
|
|
#
|
|
# @return [void]
|
|
# @raise [NotImplementedError]
|
|
def start
|
|
raise NotImplementedError
|
|
end
|
|
end |