RSpec.describe Mdm::Session, type: :model do it_should_behave_like 'Metasploit::Concern.run' context 'factory' do it 'should be valid' do session = FactoryGirl.build(:mdm_session) expect(session).to be_valid end end context '#destroy' do it 'should successfully destroy the object' do session = FactoryGirl.create(:mdm_session) expect { session.destroy }.to_not raise_error expect { session.reload }.to raise_error(ActiveRecord::RecordNotFound) end end context 'database' do context 'timestamps'do it { is_expected.to have_db_column(:closed_at).of_type(:datetime) } it { is_expected.to have_db_column(:last_seen).of_type(:datetime) } it { is_expected.to have_db_column(:opened_at).of_type(:datetime).with_options(:null => false) } end context 'columns' do it { is_expected.to have_db_column(:datastore).of_type(:text) } it { is_expected.to have_db_column(:desc).of_type(:string) } it { is_expected.to have_db_column(:host_id).of_type(:integer) } it { is_expected.to have_db_column(:local_id).of_type(:integer) } it { is_expected.to have_db_column(:module_run_id).of_type(:integer) } it { is_expected.to have_db_column(:platform).of_type(:string) } it { is_expected.to have_db_column(:port).of_type(:integer) } it { is_expected.to have_db_column(:stype).of_type(:string) } it { is_expected.to have_db_column(:via_exploit).of_type(:string) } it { is_expected.to have_db_column(:via_payload).of_type(:string) } end end context 'associations' do it { is_expected.to have_many(:events).class_name('Mdm::SessionEvent').dependent(:delete_all) } it { is_expected.to belong_to(:host).class_name('Mdm::Host') } it { is_expected.to belong_to(:originating_module_run).class_name('MetasploitDataModels::ModuleRun') } it { is_expected.to have_many(:routes).class_name('Mdm::Route').dependent(:delete_all) } it { is_expected.to have_many(:target_module_runs).class_name('MetasploitDataModels::ModuleRun') } it { is_expected.to have_many(:tasks).class_name('Mdm::Task').through(:task_sessions)} it { is_expected.to have_many(:task_sessions).class_name('Mdm::TaskSession').dependent(:destroy) } it { is_expected.to have_one(:workspace).class_name('Mdm::Workspace').through(:host) } end context 'scopes' do context 'alive' do it 'should return sessions that have not been closed' do alive_session = FactoryGirl.create(:mdm_session) dead_session = FactoryGirl.create(:mdm_session, :closed_at => Time.now) alive_set = Mdm::Session.alive expect(alive_set).to include(alive_session) expect(alive_set).not_to include(dead_session) end end context 'dead' do it 'should return sessions that have been closed' do alive_session = FactoryGirl.create(:mdm_session) dead_session = FactoryGirl.create(:mdm_session, :closed_at => Time.now) dead_set = Mdm::Session.dead expect(dead_set).not_to include(alive_session) expect(dead_set).to include(dead_session) end end context 'upgradeable' do it 'should return sessions that can be upgraded to meterpreter' do win_shell = FactoryGirl.create(:mdm_session, :stype => 'shell', :platform => 'Windows') linux_shell = FactoryGirl.create(:mdm_session, :stype => 'shell', :platform => 'Linux') win_meterp = FactoryGirl.create(:mdm_session, :stype => 'meterpreter', :platform => 'Windows') upgrade_set = Mdm::Session.upgradeable expect(upgrade_set).to include(win_shell) expect(upgrade_set).not_to include(linux_shell) expect(upgrade_set).not_to include(win_meterp) end end end context 'callbacks' do context 'before_destroy' do it 'should call #stop' do mysession = FactoryGirl.create(:mdm_session) expect(mysession).to receive(:stop) mysession.destroy end end end context 'methods' do context '#upgradeable?' do it 'should return true for windows shells' do win_shell = FactoryGirl.create(:mdm_session, :stype => 'shell', :platform => 'Windows') expect(win_shell.upgradeable?).to eq(true) end it 'should return false for non-windows shells' do linux_shell = FactoryGirl.create(:mdm_session, :stype => 'shell', :platform => 'Linux') expect(linux_shell.upgradeable?).to eq(false) end it 'should return false for Windows Meterpreter Sessions' do win_meterp = FactoryGirl.create(:mdm_session, :stype => 'meterpreter', :platform => 'Windows') expect(win_meterp.upgradeable?).to eq(false) end end end end