lib/msf/core/db_manager/workspace.rb
module Msf::DBManager::Workspace
DEFAULT_WORKSPACE_NAME = 'default'
#
# Creates a new workspace in the database
#
def add_workspace(opts)
::ApplicationRecord.connection_pool.with_connection {
::Mdm::Workspace.where(name: opts[:name]).first_or_create
}
end
def default_workspace
# Workspace tracking is handled on the client side, so attempting to call it directly from the DbManager
# will not return the correct results. Run it back through the proxy.
wlog "[DEPRECATION] Setting the workspace from within DbManager is no longer supported. Please call from WorkspaceDataProxy instead."
# Proxied to fix tests, will be cleaned up in remote test patch
framework.db.default_workspace
end
def find_workspace(name)
::ApplicationRecord.connection_pool.with_connection {
::Mdm::Workspace.find_by_name(name)
}
end
def workspace
# The @current_workspace is tracked on the client side, so attempting to call it directly from the DbManager
# will not return the correct results. Run it back through the proxy.
wlog "[DEPRECATION] Calling workspace from within DbManager is no longer supported. Please call from WorkspaceDataProxy instead."
# Proxied to fix tests, will be cleaned up in remote test patch
framework.db.workspace
end
def workspace=(workspace)
# The @current_workspace is tracked on the client side, so attempting to call it directly from the DbManager
# will not return the correct results. Run it back through the proxy.
wlog "[DEPRECATION] Setting the workspace from within DbManager is no longer supported. Please call from WorkspaceDataProxy instead."
# Proxied to fix tests, will be cleaned up in remote test patch
framework.db.workspace=workspace
end
def workspaces(opts = {})
::ApplicationRecord.connection_pool.with_connection {
# If we have the ID, there is no point in creating a complex query.
if opts[:id] && !opts[:id].to_s.empty?
return Array.wrap(Mdm::Workspace.find(opts[:id]))
end
opts = opts.clone() # protect the original caller's opts
search_term = opts.delete(:search_term)
# Passing these values to the search will cause exceptions, so remove them if they accidentally got passed in.
opts.delete(:workspace)
::ApplicationRecord.connection_pool.with_connection {
if search_term && !search_term.empty?
column_search_conditions = Msf::Util::DBManager.create_all_column_search_conditions(Mdm::Workspace, search_term)
Mdm::Workspace.where(opts).where(column_search_conditions)
else
Mdm::Workspace.where(opts)
end
}
}
end
def delete_workspaces(opts)
raise ArgumentError.new("The following options are required: :ids") if opts[:ids].nil?
::ApplicationRecord.connection_pool.with_connection {
deleted = []
default_deleted = false
opts[:ids].each do |ws_id|
ws = Mdm::Workspace.find(ws_id)
default_deleted = true if ws.default?
begin
deleted << ws.destroy
if default_deleted
add_workspace({ name: DEFAULT_WORKSPACE_NAME })
default_deleted = false
end
rescue
elog("Forcibly deleting #{ws.name}")
deleted << ws.delete
end
end
return deleted
}
end
def update_workspace(opts)
raise ArgumentError.new("The following options are required: :id") if opts[:id].nil?
opts = opts.clone() # protect the original caller's opts
opts.delete(:workspace)
::ApplicationRecord.connection_pool.with_connection {
ws_id = opts.delete(:id)
ws_to_update = workspaces({ id: ws_id }).first
default_renamed = true if ws_to_update.name == DEFAULT_WORKSPACE_NAME
begin
ws_to_update.update!(opts) # will raise exception if it fails
rescue ActiveRecord::RecordInvalid => e
raise ArgumentError.new(e.message)
end
add_workspace({ name: DEFAULT_WORKSPACE_NAME }) if default_renamed
workspaces({ id: ws_id }).first
}
end
end