Refactor workspace delete to be consistent with other commands

GSoC/Meterpreter_Web_Console
James Barnett 2018-03-16 16:11:09 -05:00
parent 8ddaae5fe4
commit 35bc8e905e
No known key found for this signature in database
GPG Key ID: 647983861A4EC5EA
4 changed files with 67 additions and 36 deletions

View File

@ -2,7 +2,7 @@ module WorkspaceDataProxy
def find_workspace(workspace_name) def find_workspace(workspace_name)
begin begin
data_service = self.get_data_service() data_service = self.get_data_service
data_service.find_workspace(workspace_name) data_service.find_workspace(workspace_name)
rescue Exception => e rescue Exception => e
self.log_error(e, "Problem finding workspace") self.log_error(e, "Problem finding workspace")
@ -11,7 +11,7 @@ module WorkspaceDataProxy
def add_workspace(workspace_name) def add_workspace(workspace_name)
begin begin
data_service = self.get_data_service() data_service = self.get_data_service
data_service.add_workspace(workspace_name) data_service.add_workspace(workspace_name)
rescue Exception => e rescue Exception => e
self.log_error(e, "Problem adding workspace") self.log_error(e, "Problem adding workspace")
@ -20,7 +20,7 @@ module WorkspaceDataProxy
def default_workspace def default_workspace
begin begin
data_service = self.get_data_service() data_service = self.get_data_service
data_service.default_workspace data_service.default_workspace
rescue Exception => e rescue Exception => e
self.log_error(e, "Problem finding default workspace") self.log_error(e, "Problem finding default workspace")
@ -29,7 +29,7 @@ module WorkspaceDataProxy
def workspace def workspace
begin begin
data_service = self.get_data_service() data_service = self.get_data_service
data_service.workspace data_service.workspace
rescue Exception => e rescue Exception => e
self.log_error(e, "Problem retrieving workspace") self.log_error(e, "Problem retrieving workspace")
@ -38,7 +38,7 @@ module WorkspaceDataProxy
def workspace=(workspace) def workspace=(workspace)
begin begin
data_service = self.get_data_service() data_service = self.get_data_service
data_service.workspace = workspace data_service.workspace = workspace
rescue Exception => e rescue Exception => e
self.log_error(e, "Problem setting workspace") self.log_error(e, "Problem setting workspace")
@ -47,10 +47,21 @@ module WorkspaceDataProxy
def workspaces def workspaces
begin begin
data_service = self.get_data_service() data_service = self.get_data_service
data_service.workspaces data_service.workspaces
rescue Exception => e rescue Exception => e
self.log_error(e, "Problem retrieving workspaces") self.log_error(e, "Problem retrieving workspaces")
end end
end end
def delete_workspaces(workspace_ids)
begin
data_service = self.get_data_service
opts = {}
opts[:ids] = workspace_ids
data_service.delete_workspaces(opts)
rescue Exception => e
self.log_error(e, "Problem deleting workspaces")
end
end
end end

View File

@ -3,8 +3,6 @@ require 'metasploit/framework/data_service/remote/http/response_data_helper'
module RemoteWorkspaceDataService module RemoteWorkspaceDataService
include ResponseDataHelper include ResponseDataHelper
# TODO: should counts be a flag in query data for the workspaces resource?
WORKSPACE_COUNTS_API_PATH = '/api/v1/workspaces/counts'
WORKSPACE_API_PATH = '/api/v1/workspaces' WORKSPACE_API_PATH = '/api/v1/workspaces'
WORKSPACE_MDM_CLASS = 'Mdm::Workspace' WORKSPACE_MDM_CLASS = 'Mdm::Workspace'
DEFAULT_WORKSPACE_NAME = 'default' DEFAULT_WORKSPACE_NAME = 'default'
@ -38,6 +36,10 @@ module RemoteWorkspaceDataService
json_to_mdm_object(self.get_data(WORKSPACE_API_PATH, {:all => true}), WORKSPACE_MDM_CLASS, []) json_to_mdm_object(self.get_data(WORKSPACE_API_PATH, {:all => true}), WORKSPACE_MDM_CLASS, [])
end end
def delete_workspaces(opts)
json_to_mdm_object(self.delete_data(WORKSPACE_API_PATH, opts), WORKSPACE_MDM_CLASS, [])
end
######### #########
protected protected
######### #########
@ -50,4 +52,4 @@ module RemoteWorkspaceDataService
@current_workspace_name ||= DEFAULT_WORKSPACE_NAME @current_workspace_name ||= DEFAULT_WORKSPACE_NAME
end end
end end

View File

@ -34,33 +34,29 @@ module Msf::DBManager::Workspace
} }
end end
def delete_workspaces(names) def delete_workspaces(opts)
status_msg = [] raise ArgumentError.new("The following options are required: :ids") if opts[:ids].nil?
error_msg = []
switched = false ::ActiveRecord::Base.connection_pool.with_connection {
# Delete workspaces deleted = []
names.each do |name| default_deleted = false
workspace = framework.db.find_workspace(name) opts[:ids].each do |ws_id|
if workspace.nil? ws = Mdm::Workspace.find(ws_id)
error << "Workspace not found: #{name}" default_deleted = true if ws.default?
elsif workspace.default? if framework.db.workspace.name == ws.name
workspace.destroy
workspace = framework.db.add_workspace(name)
status_msg << 'Deleted and recreated the default workspace'
else
# switch to the default workspace if we're about to delete the current one
if framework.db.workspace.name == workspace.name
framework.db.workspace = framework.db.default_workspace framework.db.workspace = framework.db.default_workspace
switched = true
end end
# now destroy the named workspace begin
workspace.destroy deleted << ws.destroy
status_msg << "Deleted workspace: #{name}" framework.db.workspace = framework.db.add_workspace('default') if default_deleted
rescue
elog("Forcibly deleting #{workspace}")
deleted << ws.delete
end
end end
end
(status_msg << "Switched workspace: #{framework.db.workspace.name}") if switched return deleted
return status_msg, error_msg }
end end
# #

View File

@ -149,11 +149,21 @@ class Db
end end
framework.db.workspace = workspace framework.db.workspace = workspace
elsif deleting and names elsif deleting and names
status_msg, error_msg = framework.db.delete_workspaces(names) ws_ids_to_delete = []
print_msgs(status_msg, error_msg) starting_ws = framework.db.workspace
names.each do |n|
ws_ids_to_delete << framework.db.find_workspace(n).id
end
deleted = framework.db.delete_workspaces(ws_ids_to_delete)
print_deleted_workspaces(deleted, starting_ws)
elsif delete_all elsif delete_all
status_msg, error_msg = framework.db.delete_all_workspaces() ws_ids_to_delete = []
print_msgs(status_msg, error_msg) starting_ws = framework.db.workspace
framework.db.workspaces.each do |ws|
ws_ids_to_delete << ws.id
end
deleted = framework.db.delete_workspaces(ws_ids_to_delete)
print_deleted_workspaces(deleted, starting_ws)
elsif renaming elsif renaming
if names.length != 2 if names.length != 2
print_error("Wrong number of arguments to rename") print_error("Wrong number of arguments to rename")
@ -218,6 +228,18 @@ class Db
end end
end end
def print_deleted_workspaces(deleted_workspaces, starting_ws)
deleted_workspaces.each do |ws|
if ws.name == 'default'
print_status 'Deleted and recreated the default workspace'
elsif ws == starting_ws
print_status "Switched workspace: #{framework.db.workspace.name}"
else
print_status "Deleted workspace: #{ws.name}"
end
end
end
def cmd_workspace_tabs(str, words) def cmd_workspace_tabs(str, words)
return [] unless active? return [] unless active?
framework.db.workspaces.map { |s| s.name } if (words & ['-a','--add']).empty? framework.db.workspaces.map { |s| s.name } if (words & ['-a','--add']).empty?